mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-02-04 06:23:45 +00:00
Ability to capture a V8 heap profile and a heap snapshot
This commit is contained in:
2
.github/actions/install/action.yml
vendored
2
.github/actions/install/action.yml
vendored
@@ -13,7 +13,7 @@ inputs:
|
|||||||
zig-v8:
|
zig-v8:
|
||||||
description: 'zig v8 version to install'
|
description: 'zig v8 version to install'
|
||||||
required: false
|
required: false
|
||||||
default: 'v0.2.4'
|
default: 'v0.2.5'
|
||||||
v8:
|
v8:
|
||||||
description: 'v8 version to install'
|
description: 'v8 version to install'
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ FROM debian:stable-slim
|
|||||||
ARG MINISIG=0.12
|
ARG MINISIG=0.12
|
||||||
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
|
ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U
|
||||||
ARG V8=14.0.365.4
|
ARG V8=14.0.365.4
|
||||||
ARG ZIG_V8=v0.2.4
|
ARG ZIG_V8=v0.2.5
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
RUN apt-get update -yq && \
|
RUN apt-get update -yq && \
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
.minimum_zig_version = "0.15.2",
|
.minimum_zig_version = "0.15.2",
|
||||||
.dependencies = .{
|
.dependencies = .{
|
||||||
.v8 = .{
|
.v8 = .{
|
||||||
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/v0.2.4.tar.gz",
|
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/v0.2.5.tar.gz",
|
||||||
.hash = "v8-0.0.0-xddH66YvBAD0YI9xr6F0Xgnw9wN30FdZ10FLyuoV3e66",
|
.hash = "v8-0.0.0-xddH641NBAC3MqKV44YCkwvnUenhQyGlgJI8OScx0tlP",
|
||||||
},
|
},
|
||||||
//.v8 = .{ .path = "../zig-v8-fork" },
|
//.v8 = .{ .path = "../zig-v8-fork" },
|
||||||
.@"boringssl-zig" = .{
|
.@"boringssl-zig" = .{
|
||||||
|
|||||||
@@ -50,6 +50,8 @@ entered: bool,
|
|||||||
|
|
||||||
cpu_profiler: ?*v8.CpuProfiler = null,
|
cpu_profiler: ?*v8.CpuProfiler = null,
|
||||||
|
|
||||||
|
heap_profiler: ?*v8.HeapProfiler = null,
|
||||||
|
|
||||||
// references Env.templates
|
// references Env.templates
|
||||||
templates: []*const v8.FunctionTemplate,
|
templates: []*const v8.FunctionTemplate,
|
||||||
|
|
||||||
@@ -823,6 +825,10 @@ pub fn startCpuProfiler(self: *Context) void {
|
|||||||
@compileError("CPU Profiling is only available in debug builds");
|
@compileError("CPU Profiling is only available in debug builds");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ls: js.Local.Scope = undefined;
|
||||||
|
self.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
std.debug.assert(self.cpu_profiler == null);
|
std.debug.assert(self.cpu_profiler == null);
|
||||||
v8.v8__CpuProfiler__UseDetailedSourcePositionsForProfiling(self.isolate.handle);
|
v8.v8__CpuProfiler__UseDetailedSourcePositionsForProfiling(self.isolate.handle);
|
||||||
|
|
||||||
@@ -833,8 +839,55 @@ pub fn startCpuProfiler(self: *Context) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn stopCpuProfiler(self: *Context) ![]const u8 {
|
pub fn stopCpuProfiler(self: *Context) ![]const u8 {
|
||||||
|
var ls: js.Local.Scope = undefined;
|
||||||
|
self.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
const title = self.isolate.initStringHandle("v8_cpu_profile");
|
const title = self.isolate.initStringHandle("v8_cpu_profile");
|
||||||
const handle = v8.v8__CpuProfiler__StopProfiling(self.cpu_profiler.?, title) orelse return error.NoProfiles;
|
const handle = v8.v8__CpuProfiler__StopProfiling(self.cpu_profiler.?, title) orelse return error.NoProfiles;
|
||||||
const string_handle = v8.v8__CpuProfile__Serialize(handle, self.isolate.handle) orelse return error.NoProfile;
|
const string_handle = v8.v8__CpuProfile__Serialize(handle, self.isolate.handle) orelse return error.NoProfile;
|
||||||
return self.jsStringToZig(string_handle, .{});
|
return ls.local.jsStringToZig(string_handle, .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn startHeapProfiler(self: *Context) void {
|
||||||
|
if (comptime !IS_DEBUG) {
|
||||||
|
@compileError("Heap Profiling is only available in debug builds");
|
||||||
|
}
|
||||||
|
|
||||||
|
var ls: js.Local.Scope = undefined;
|
||||||
|
self.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
|
std.debug.assert(self.heap_profiler == null);
|
||||||
|
const heap_profiler = v8.v8__HeapProfiler__Get(self.isolate.handle).?;
|
||||||
|
|
||||||
|
// Sample every 32KB, stack depth 32
|
||||||
|
v8.v8__HeapProfiler__StartSamplingHeapProfiler(heap_profiler, 32 * 1024, 32);
|
||||||
|
v8.v8__HeapProfiler__StartTrackingHeapObjects(heap_profiler, true);
|
||||||
|
|
||||||
|
self.heap_profiler = heap_profiler;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stopHeapProfiler(self: *Context) !struct{[]const u8, []const u8} {
|
||||||
|
var ls: js.Local.Scope = undefined;
|
||||||
|
self.localScope(&ls);
|
||||||
|
defer ls.deinit();
|
||||||
|
|
||||||
|
const allocating = blk: {
|
||||||
|
const profile = v8.v8__HeapProfiler__GetAllocationProfile(self.heap_profiler.?);
|
||||||
|
const string_handle = v8.v8__AllocationProfile__Serialize(profile, self.isolate.handle);
|
||||||
|
v8.v8__HeapProfiler__StopSamplingHeapProfiler(self.heap_profiler.?);
|
||||||
|
v8.v8__AllocationProfile__Delete(profile);
|
||||||
|
break :blk try ls.local.jsStringToZig(string_handle, .{});
|
||||||
|
};
|
||||||
|
|
||||||
|
const snapshot = blk: {
|
||||||
|
const snapshot = v8.v8__HeapProfiler__TakeHeapSnapshot(self.heap_profiler.?, null) orelse return error.NoProfiles;
|
||||||
|
const string_handle = v8.v8__HeapSnapshot__Serialize(snapshot, self.isolate.handle);
|
||||||
|
v8.v8__HeapProfiler__StopTrackingHeapObjects(self.heap_profiler.?);
|
||||||
|
v8.v8__HeapSnapshot__Delete(snapshot);
|
||||||
|
break :blk try ls.local.jsStringToZig(string_handle, .{});
|
||||||
|
};
|
||||||
|
|
||||||
|
return .{allocating, snapshot};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void {
|
|||||||
// defer {
|
// defer {
|
||||||
// if (page.js.stopCpuProfiler()) |profile| {
|
// if (page.js.stopCpuProfiler()) |profile| {
|
||||||
// std.fs.cwd().writeFile(.{
|
// std.fs.cwd().writeFile(.{
|
||||||
// .sub_path = "v8/profile.json",
|
// .sub_path = ".lp-cache/cpu_profile.json",
|
||||||
// .data = profile,
|
// .data = profile,
|
||||||
// }) catch |err| {
|
// }) catch |err| {
|
||||||
// log.err(.app, "profile write error", .{ .err = err });
|
// log.err(.app, "profile write error", .{ .err = err });
|
||||||
@@ -61,6 +61,27 @@ pub fn fetch(app: *App, url: [:0]const u8, opts: FetchOpts) !void {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// // Comment this out to get a heap V8 heap profil
|
||||||
|
// page.js.startHeapProfiler();
|
||||||
|
// defer {
|
||||||
|
// if (page.js.stopHeapProfiler()) |profile| {
|
||||||
|
// std.fs.cwd().writeFile(.{
|
||||||
|
// .sub_path = ".lp-cache/allocating.heapprofile",
|
||||||
|
// .data = profile.@"0",
|
||||||
|
// }) catch |err| {
|
||||||
|
// log.err(.app, "allocating write error", .{ .err = err });
|
||||||
|
// };
|
||||||
|
// std.fs.cwd().writeFile(.{
|
||||||
|
// .sub_path = ".lp-cache/snapshot.heapsnapshot",
|
||||||
|
// .data = profile.@"1",
|
||||||
|
// }) catch |err| {
|
||||||
|
// log.err(.app, "heapsnapshot write error", .{ .err = err });
|
||||||
|
// };
|
||||||
|
// } else |err| {
|
||||||
|
// log.err(.app, "profile error", .{ .err = err });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
_ = try page.navigate(url, .{
|
_ = try page.navigate(url, .{
|
||||||
.reason = .address_bar,
|
.reason = .address_bar,
|
||||||
.kind = .{ .push = null },
|
.kind = .{ .push = null },
|
||||||
|
|||||||
Reference in New Issue
Block a user