From 54a7df8d4039916974300044d54e9c34a8206a53 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Thu, 8 May 2025 18:30:44 +0800 Subject: [PATCH] Move call/control of gc_hint to browser. It has more context than the env about when this should be called. Specifically it can be called once per session, whereas, in the env, we can only call it once per context - which could be too often. --- src/browser/browser.zig | 7 ++++--- src/runtime/js.zig | 34 ++++++++++++++-------------------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/browser/browser.zig b/src/browser/browser.zig index eed8dd60..339f354f 100644 --- a/src/browser/browser.zig +++ b/src/browser/browser.zig @@ -60,9 +60,7 @@ pub const Browser = struct { pub fn init(app: *App) !Browser { const allocator = app.allocator; - const env = try Env.init(allocator, .{ - .gc_hints = app.config.gc_hints, - }); + const env = try Env.init(allocator, .{}); errdefer env.deinit(); const notification = try Notification.init(allocator, app.notification); @@ -98,6 +96,9 @@ pub const Browser = struct { if (self.session) |*session| { session.deinit(); self.session = null; + if (self.app.config.gc_hints) { + self.env.lowMemoryNotification(); + } } } diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 8a15361c..b79b96c6 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -174,18 +174,13 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // index. prototype_lookup: [Types.len]u16, - // Send a lowMemoryNotification whenever we stop an executor - gc_hints: bool, - const Self = @This(); const TYPE_LOOKUP = TypeLookup{}; - const Opts = struct { - gc_hints: bool = false, - }; + const Opts = struct {}; - pub fn init(allocator: Allocator, opts: Opts) !*Self { + pub fn init(allocator: Allocator, _: Opts) !*Self { // var params = v8.initCreateParams(); var params = try allocator.create(v8.CreateParams); errdefer allocator.destroy(params); @@ -213,7 +208,6 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { .templates = undefined, .allocator = allocator, .isolate_params = params, - .gc_hints = opts.gc_hints, .prototype_lookup = undefined, }; @@ -274,6 +268,18 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { }; } + // V8 doesn't immediately free memory associated with + // a Context, it's managed by the garbage collector. So, when the + // `gc_hints` option is enabled, we'll use the `lowMemoryNotification` + // call on the isolate to encourage v8 to free any contexts which + // have been freed. + pub fn lowMemoryNotification(self: *Self) void { + var handle_scope: v8.HandleScope = undefined; + v8.HandleScope.init(&handle_scope, self.isolate); + defer handle_scope.deinit(); + self.isolate.lowMemoryNotification(); + } + pub const Executor = struct { env: *Self, @@ -304,18 +310,6 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { self.endScope(); } - // V8 doesn't immediately free memory associated with - // a Context, it's managed by the garbage collector. So, when the - // `gc_hints` option is enabled, we'll use the `lowMemoryNotification` - // call on the isolate to encourage v8 to free any contexts which - // have been freed. - if (self.env.gc_hints) { - var handle_scope: v8.HandleScope = undefined; - v8.HandleScope.init(&handle_scope, self.env.isolate); - defer handle_scope.deinit(); - - self.env.isolate.lowMemoryNotification(); // TODO we only need to call this for the main World Executor - } self.call_arena.deinit(); self.scope_arena.deinit(); }