Files
browser/src/main_snapshot_creator.zig
Karl Seguin 03f542006d v8, mem: Add v8 configuration option + heap limit protection
The main addition in this commit is that we hook into the Isolate's
AddNearHeapLimitCallback callback and try to force the isolate to shutdown
rather than letting v8 hit an OOM which would take down the entire process.

In support of this, we now support a `--v8-max-heap-mb` command line option to
set an explicit heap limit. As a simple way to test this feature, load a
relatively heavy JS page with `--v8-max-heap-mb 1`.

There's also a `--v8-flags-unsafe` which is a mechanism to pass arbitrary
flags to v8 via its `SetFlagsFromString`. The parameter is called `unsafe`
because some [of the many] configurable flags could conflict with how the
snapshot is built and result in crashes. The snapshot creator also gains a
`--v8-flags-unsafe` flag, so advance users COULD create their snapshot and
run lightpanda with the same set of flags.
2026-07-07 12:40:23 +08:00

65 lines
2.2 KiB
Zig

// Copyright (C) 2023-2025 Lightpanda (Selecy SAS)
//
// Francis Bouvier <francis@lightpanda.io>
// Pierre Tachoire <pierre@lightpanda.io>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
const std = @import("std");
const lp = @import("lightpanda");
pub fn main() !void {
const allocator = std.heap.c_allocator;
// usage: snapshot_creator [--v8-flags-unsafe "<flags>"] [outfile]
// A snapshot only deserializes correctly under the flags it was created
// with, so a runtime using --v8-flags-unsafe needs a snapshot built with
// the same value.
var v8_flags: ?[]const u8 = null;
var out_path: ?[]const u8 = null;
var args = try std.process.argsWithAllocator(allocator);
_ = args.next(); // executable name
while (args.next()) |arg| {
if (std.mem.eql(u8, arg, "--v8-flags-unsafe")) {
v8_flags = args.next() orelse {
std.debug.print("--v8-flags-unsafe requires a value\n", .{});
return error.MissingArgument;
};
} else {
out_path = arg;
}
}
var platform = try lp.js.Platform.init(v8_flags);
defer platform.deinit();
const snapshot = try lp.js.Snapshot.create();
defer snapshot.deinit();
var is_stdout = true;
var file = std.fs.File.stdout();
if (out_path) |n| {
is_stdout = false;
file = try std.fs.cwd().createFile(n, .{});
}
defer if (!is_stdout) {
file.close();
};
var buffer: [4096]u8 = undefined;
var writer = file.writer(&buffer);
try snapshot.write(&writer.interface);
try writer.end();
}