Skip to content

Commit ad1a4fe

Browse files
authored
Merge pull request #652 from lightpanda-io/transfer_arena
Introduce a "transfer_arena"
2 parents afd29fe + 2bc1192 commit ad1a4fe

File tree

3 files changed

+28
-11
lines changed

3 files changed

+28
-11
lines changed

src/browser/browser.zig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ pub const Browser = struct {
3838
allocator: Allocator,
3939
http_client: *http.Client,
4040
page_arena: ArenaAllocator,
41+
session_arena: ArenaAllocator,
42+
transfer_arena: ArenaAllocator,
4143
notification: *Notification,
4244

4345
pub fn init(app: *App) !Browser {
@@ -57,13 +59,17 @@ pub const Browser = struct {
5759
.notification = notification,
5860
.http_client = &app.http_client,
5961
.page_arena = ArenaAllocator.init(allocator),
62+
.session_arena = ArenaAllocator.init(allocator),
63+
.transfer_arena = ArenaAllocator.init(allocator),
6064
};
6165
}
6266

6367
pub fn deinit(self: *Browser) void {
6468
self.closeSession();
6569
self.env.deinit();
6670
self.page_arena.deinit();
71+
self.session_arena.deinit();
72+
self.transfer_arena.deinit();
6773
self.notification.deinit();
6874
}
6975

@@ -79,6 +85,7 @@ pub const Browser = struct {
7985
if (self.session) |*session| {
8086
session.deinit();
8187
self.session = null;
88+
_ = self.session_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
8289
if (self.app.config.gc_hints) {
8390
self.env.lowMemoryNotification();
8491
}

src/browser/session.zig

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
const std = @import("std");
2020

21-
const ArenaAllocator = std.heap.ArenaAllocator;
21+
const Allocator = std.mem.Allocator;
2222

2323
const Env = @import("env.zig").Env;
2424
const Page = @import("page.zig").Page;
@@ -37,7 +37,17 @@ pub const Session = struct {
3737
browser: *Browser,
3838

3939
// Used to create our Inspector and in the BrowserContext.
40-
arena: ArenaAllocator,
40+
arena: Allocator,
41+
42+
// The page's arena is unsuitable for data that has to existing while
43+
// navigating from one page to another. For example, if we're clicking
44+
// on an HREF, the URL exists in the original page (where the click
45+
// originated) but also has to exist in the new page.
46+
// While we could use the Session's arena, this could accumulate a lot of
47+
// memory if we do many navigation events. The `transfer_arena` is meant to
48+
// bridge the gap: existing long enough to store any data needed to end one
49+
// page and start another.
50+
transfer_arena: Allocator,
4151

4252
executor: Env.Executor,
4353
storage_shed: storage.Shed,
@@ -53,17 +63,17 @@ pub const Session = struct {
5363
self.* = .{
5464
.browser = browser,
5565
.executor = executor,
56-
.arena = ArenaAllocator.init(allocator),
66+
.arena = browser.session_arena.allocator(),
5767
.storage_shed = storage.Shed.init(allocator),
5868
.cookie_jar = storage.CookieJar.init(allocator),
69+
.transfer_arena = browser.transfer_arena.allocator(),
5970
};
6071
}
6172

6273
pub fn deinit(self: *Session) void {
6374
if (self.page != null) {
6475
self.removePage();
6576
}
66-
self.arena.deinit();
6777
self.cookie_jar.deinit();
6878
self.storage_shed.deinit();
6979
self.executor.deinit();
@@ -116,12 +126,12 @@ pub const Session = struct {
116126
// it isn't null!
117127
std.debug.assert(self.page != null);
118128

119-
// can't use the page arena, because we're about to reset it
120-
// and don't want to use the session's arena, because that'll start to
121-
// look like a leak if we navigate from page to page a lot.
122-
var buf: [2048]u8 = undefined;
123-
var fba = std.heap.FixedBufferAllocator.init(&buf);
124-
const url = try self.page.?.url.resolve(fba.allocator(), url_string);
129+
defer _ = self.browser.transfer_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
130+
131+
// it's safe to use the transfer arena here, because the page will
132+
// eventually clone the URL using its own page_arena (after it gets
133+
// the final URL, possibly following redirects)
134+
const url = try self.page.?.url.resolve(self.transfer_arena, url_string);
125135

126136
self.removePage();
127137
var page = try self.createPage();

src/cdp/cdp.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
314314
const allocator = cdp.allocator;
315315

316316
const session = try cdp.browser.newSession();
317-
const arena = session.arena.allocator();
317+
const arena = session.arena;
318318

319319
const inspector = try cdp.browser.env.newInspector(arena, self);
320320

0 commit comments

Comments
 (0)