diff --git a/.github/workflows/wpt.yml b/.github/workflows/wpt.yml index cdc24d00..38002671 100644 --- a/.github/workflows/wpt.yml +++ b/.github/workflows/wpt.yml @@ -5,6 +5,7 @@ env: AWS_SECRET_ACCESS_KEY: ${{ secrets.LPD_PERF_AWS_SECRET_ACCESS_KEY }} AWS_BUCKET: ${{ vars.LPD_PERF_AWS_BUCKET }} AWS_REGION: ${{ vars.LPD_PERF_AWS_REGION }} + LIGHTPANDA_DISABLE_TELEMETRY: true on: schedule: @@ -30,7 +31,7 @@ jobs: - uses: ./.github/actions/install - name: json output - run: zig build wpt -- --json > wpt.json + run: zig build -Doptimize=ReleaseFast wpt -- --json > wpt.json - name: write commit run: | diff --git a/src/TestHTTPServer.zig b/src/TestHTTPServer.zig index 11f44ee0..9867600d 100644 --- a/src/TestHTTPServer.zig +++ b/src/TestHTTPServer.zig @@ -74,6 +74,7 @@ pub fn sendFile(req: *std.http.Server.Request, file_path: []const u8) !void { error.FileNotFound => return req.respond("server error", .{ .status = .not_found }), else => return err, }; + defer file.close(); const stat = try file.stat(); var send_buffer: [4096]u8 = undefined; diff --git a/src/main_wpt.zig b/src/main_wpt.zig index 9632bca8..63b2d665 100644 --- a/src/main_wpt.zig +++ b/src/main_wpt.zig @@ -25,7 +25,6 @@ const ArenaAllocator = std.heap.ArenaAllocator; const App = @import("app.zig").App; const Env = @import("browser/env.zig").Env; const Browser = @import("browser/browser.zig").Browser; -const Session = @import("browser/session.zig").Session; const TestHTTPServer = @import("TestHTTPServer.zig"); const parser = @import("browser/netsurf.zig"); @@ -75,15 +74,15 @@ pub fn main() !void { var browser = try Browser.init(app); defer browser.deinit(); - const session = try browser.newSession(); + var i: usize = 0; while (try it.next()) |test_file| { defer _ = test_arena.reset(.retain_capacity); var err_out: ?[]const u8 = null; const result = run( test_arena.allocator(), - session, + &browser, test_file, &err_out, ) catch |err| blk: { @@ -93,16 +92,24 @@ pub fn main() !void { break :blk null; }; try writer.process(test_file, result, err_out); + // if (@mod(i, 10) == 0) { + // std.debug.print("\n\n=== V8 Memory {d}===\n", .{i}); + // browser.env.dumpMemoryStats(); + // } + i += 1; } try writer.finalize(); } fn run( arena: Allocator, - session: *Session, + browser: *Browser, test_file: []const u8, err_out: *?[]const u8, ) ![]const u8 { + const session = try browser.newSession(); + defer browser.closeSession(); + const page = try session.createPage(); defer session.removePage(); @@ -141,11 +148,7 @@ const Writer = struct { writer: std.fs.File.Writer, cases: std.ArrayListUnmanaged(Case) = .{}, - const Format = enum { - json, - text, - summary, - }; + const Format = enum { json, text, summary, quiet }; fn init(allocator: Allocator, format: Format) !Writer { const out = std.fs.File.stdout(); @@ -200,6 +203,7 @@ const Writer = struct { }, .{ .whitespace = .indent_2 }, writer); return writer.writeByte(','); }, + .quiet => {}, } // just make sure we didn't fall through by mistake unreachable; @@ -289,6 +293,7 @@ const Writer = struct { // separator, see `finalize` for the hack we use to terminate this try writer.writeByte(','); }, + .quiet => {}, } } @@ -309,7 +314,8 @@ fn parseArgs(arena: Allocator) !Command { \\ \\ -h, --help Print this help message and exit. \\ --json result is formatted in JSON. - \\ --summary print a summary result. Incompatible w/ --json + \\ --summary print a summary result. Incompatible w/ --json or --quiet + \\ --quiet No output. Incompatible w/ --json or --summary \\ ; @@ -331,6 +337,8 @@ fn parseArgs(arena: Allocator) !Command { format = .json; } else if (std.mem.eql(u8, "--summary", arg)) { format = .summary; + } else if (std.mem.eql(u8, "--quiet", arg)) { + format = .quiet; } else { try filters.append(arena, arg); } diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 32f1e382..9c1278ec 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -329,6 +329,27 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { self.isolate.lowMemoryNotification(); } + pub fn dumpMemoryStats(self: *Self) void { + const stats = self.isolate.getHeapStatistics(); + std.debug.print( + \\ Total Heap Size: {d} + \\ Total Heap Size Executable: {d} + \\ Total Physical Size: {d} + \\ Total Available Size: {d} + \\ Used Heap Size: {d} + \\ Heap Size Limit: {d} + \\ Malloced Memory: {d} + \\ External Memory: {d} + \\ Peak Malloced Memory: {d} + \\ Number Of Native Contexts: {d} + \\ Number Of Detached Contexts: {d} + \\ Total Global Handles Size: {d} + \\ Used Global Handles Size: {d} + \\ Zap Garbage: {any} + \\ + , .{stats.total_heap_size, stats.total_heap_size_executable, stats.total_physical_size, stats.total_available_size, stats.used_heap_size, stats.heap_size_limit, stats.malloced_memory, stats.external_memory, stats.peak_malloced_memory, stats.number_of_native_contexts, stats.number_of_detached_contexts, stats.total_global_handles_size, stats.used_global_handles_size, stats.does_zap_garbage}); + } + fn promiseRejectCallback(v8_msg: v8.C_PromiseRejectMessage) callconv(.c) void { const msg = v8.PromiseRejectMessage.initFromC(v8_msg); const isolate = msg.getPromise().toObject().getIsolate();