Merge pull request #1538 from lightpanda-io/browser_arenas

Remove custom-arenas, use ArenaPool instead
This commit is contained in:
Karl Seguin
2026-02-14 07:03:14 +08:00
committed by GitHub
4 changed files with 30 additions and 27 deletions

View File

@@ -85,3 +85,8 @@ pub fn release(self: *ArenaPool, allocator: Allocator) void {
self.free_list_len = free_list_len + 1;
self.free_list = entry;
}
pub fn reset(_: *const ArenaPool, allocator: Allocator, retain: usize) void {
const arena: *std.heap.ArenaAllocator = @ptrCast(@alignCast(allocator.ptr));
_ = arena.reset(.{ .retain_with_limit = retain });
}

View File

@@ -44,10 +44,6 @@ session: ?Session,
allocator: Allocator,
arena_pool: *ArenaPool,
http_client: *HttpClient,
call_arena: ArenaAllocator,
page_arena: ArenaAllocator,
session_arena: ArenaAllocator,
transfer_arena: ArenaAllocator,
const InitOpts = struct {
env: js.Env.InitOpts = .{},
@@ -66,20 +62,12 @@ pub fn init(app: *App, opts: InitOpts) !Browser {
.allocator = allocator,
.arena_pool = &app.arena_pool,
.http_client = app.http.client,
.call_arena = ArenaAllocator.init(allocator),
.page_arena = ArenaAllocator.init(allocator),
.session_arena = ArenaAllocator.init(allocator),
.transfer_arena = ArenaAllocator.init(allocator),
};
}
pub fn deinit(self: *Browser) void {
self.closeSession();
self.env.deinit();
self.call_arena.deinit();
self.page_arena.deinit();
self.session_arena.deinit();
self.transfer_arena.deinit();
}
pub fn newSession(self: *Browser, notification: *Notification) !*Session {
@@ -94,7 +82,6 @@ pub fn closeSession(self: *Browser) void {
if (self.session) |*session| {
session.deinit();
self.session = null;
_ = self.session_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
self.env.memoryPressureNotification(.critical);
}
}

View File

@@ -226,8 +226,12 @@ pub fn init(self: *Page, session: *Session) !void {
log.debug(.page, "page.init", .{});
}
const browser = session.browser;
const page_arena = browser.page_arena.allocator();
errdefer _ = browser.page_arena.reset(.free_all);
const arena_pool = browser.arena_pool;
const page_arena = try arena_pool.acquire();
errdefer arena_pool.release(page_arena);
const call_arena = try arena_pool.acquire();
errdefer arena_pool.release(call_arena);
var factory = Factory.init(page_arena, self);
@@ -240,8 +244,8 @@ pub fn init(self: *Page, session: *Session) !void {
.arena = page_arena,
.document = document,
.window = undefined,
.arena_pool = browser.arena_pool,
.call_arena = browser.call_arena.allocator(),
.arena_pool = arena_pool,
.call_arena = call_arena,
._session = session,
._factory = factory,
._script_manager = undefined,
@@ -306,6 +310,9 @@ pub fn deinit(self: *Page) void {
}
}
}
self.arena_pool.release(self.call_arena);
self.arena_pool.release(self.arena);
}
pub fn base(self: *const Page) [:0]const u8 {
@@ -808,7 +815,7 @@ fn pageErrorCallback(ctx: *anyopaque, err: anyerror) void {
// why would we want to) and requires the body to live until the transfer
// is complete.
fn clearTransferArena(self: *Page) void {
_ = self._session.browser.transfer_arena.reset(.{ .retain_with_limit = 4 * 1024 });
self.arena_pool.reset(self._session.transfer_arena, 4 * 1024);
}
pub fn wait(self: *Page, wait_ms: u32) Session.WaitResult {

View File

@@ -65,18 +65,22 @@ page: ?Page,
pub fn init(self: *Session, browser: *Browser, notification: *Notification) !void {
const allocator = browser.app.allocator;
const session_allocator = browser.session_arena.allocator();
const arena = try browser.arena_pool.acquire();
errdefer browser.arena_pool.release(arena);
const transfer_arena = try browser.arena_pool.acquire();
errdefer browser.arena_pool.release(transfer_arena);
self.* = .{
.page = null,
.arena = arena,
.history = .{},
.navigation = .{},
.storage_shed = .{},
.browser = browser,
.notification = notification,
.arena = session_allocator,
.transfer_arena = transfer_arena,
.cookie_jar = storage.Cookie.Jar.init(allocator),
.transfer_arena = browser.transfer_arena.allocator(),
};
}
@@ -84,8 +88,12 @@ pub fn deinit(self: *Session) void {
if (self.page != null) {
self.removePage();
}
const browser = self.browser;
self.cookie_jar.deinit();
self.storage_shed.deinit(self.browser.app.allocator);
self.storage_shed.deinit(browser.app.allocator);
browser.arena_pool.release(self.transfer_arena);
browser.arena_pool.release(self.arena);
}
// NOTE: the caller is not the owner of the returned value,
@@ -93,8 +101,6 @@ pub fn deinit(self: *Session) void {
pub fn createPage(self: *Session) !*Page {
lp.assert(self.page == null, "Session.createPage - page not null", .{});
_ = self.browser.page_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
self.page = @as(Page, undefined);
const page = &self.page.?;
try Page.init(page, self);
@@ -134,8 +140,6 @@ pub fn replacePage(self: *Session) !*Page {
lp.assert(self.page != null, "Session.replacePage null page", .{});
self.page.?.deinit();
_ = self.browser.page_arena.reset(.{ .retain_with_limit = 1 * 1024 * 1024 });
self.browser.env.memoryPressureNotification(.moderate);
self.page = @as(Page, undefined);
@@ -175,7 +179,7 @@ pub fn wait(self: *Session, wait_ms: u32) WaitResult {
}
fn processScheduledNavigation(self: *Session) !void {
defer _ = self.browser.transfer_arena.reset(.{ .retain_with_limit = 8 * 1024 });
defer self.browser.arena_pool.reset(self.transfer_arena, 4 * 1024);
const url, const opts = blk: {
const qn = self.page.?._queued_navigation.?;
// qn might not be safe to use after self.removePage is called, hence