Skip to content

Commit bea41a9

Browse files
committed
expose CpuProfiler
1 parent 5ce9ade commit bea41a9

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

src/binding.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cassert>
44
#include "include/libplatform/libplatform.h"
55
#include "include/v8-inspector.h"
6+
#include "include/v8-profiler.h"
67
#include "include/v8.h"
78
#include "src/api/api.h"
89
#include "src/inspector/protocol/Runtime.h"
@@ -1728,6 +1729,57 @@ void v8__base__SetDcheckFunction(void (*func)(const char*, int, const char*)) {
17281729
v8::base::SetDcheckFunction(func);
17291730
}
17301731

1732+
// CpuProfiler
1733+
// -----------
1734+
1735+
v8::CpuProfiler* v8__CpuProfiler__Get(v8::Isolate* isolate) {
1736+
return v8::CpuProfiler::New(isolate);
1737+
}
1738+
1739+
void v8__CpuProfiler__StartProfiling(v8::CpuProfiler* self, const v8::String& title) {
1740+
self->StartProfiling(ptr_to_local(&title), true);
1741+
}
1742+
1743+
const v8::CpuProfile* v8__CpuProfiler__StopProfiling(v8::CpuProfiler* self, const v8::String& title) {
1744+
return self->StopProfiling(ptr_to_local(&title));
1745+
}
1746+
1747+
void v8__CpuProfile__Delete(const v8::CpuProfile* self) {
1748+
const_cast<v8::CpuProfile*>(self)->Delete();
1749+
}
1750+
1751+
const v8::CpuProfileNode* v8__CpuProfile__GetTopDownRoot(const v8::CpuProfile* self) {
1752+
return self->GetTopDownRoot();
1753+
}
1754+
1755+
// Custom OutputStream that collects output into a string
1756+
class StringOutputStream : public v8::OutputStream {
1757+
public:
1758+
void EndOfStream() override {}
1759+
1760+
int GetChunkSize() override {
1761+
return 1024 * 1024; // 1MB chunks
1762+
}
1763+
1764+
v8::OutputStream::WriteResult WriteAsciiChunk(char* data, int size) override {
1765+
buffer_.append(data, size);
1766+
return v8::OutputStream::kContinue;
1767+
}
1768+
1769+
const std::string& str() const { return buffer_; }
1770+
1771+
private:
1772+
std::string buffer_;
1773+
};
1774+
1775+
const v8::String* v8__CpuProfile__Serialize(const v8::CpuProfile* self, v8::Isolate* isolate) {
1776+
StringOutputStream stream;
1777+
self->Serialize(&stream);
1778+
return maybe_local_to_ptr(
1779+
v8::String::NewFromUtf8(isolate, stream.str().c_str(), v8::NewStringType::kNormal, stream.str().length())
1780+
);
1781+
}
1782+
17311783
// Inspector
17321784
// ---------
17331785

src/binding.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,6 +1097,20 @@ typedef struct {
10971097
uint64_t len;
10981098
} CZigString;
10991099

1100+
// CpuProfiler
1101+
// -----------
1102+
1103+
typedef struct CpuProfiler CpuProfiler;
1104+
typedef struct CpuProfile CpuProfile;
1105+
typedef struct CpuProfileNode CpuProfileNode;
1106+
1107+
CpuProfiler* v8__CpuProfiler__Get(Isolate* isolate);
1108+
void v8__CpuProfiler__StartProfiling(CpuProfiler* self, const String* title);
1109+
const CpuProfile* v8__CpuProfiler__StopProfiling(CpuProfiler* self, const String* title);
1110+
void v8__CpuProfile__Delete(const CpuProfile* self);
1111+
const CpuProfileNode* v8__CpuProfile__GetTopDownRoot(const CpuProfile* self);
1112+
const String* v8__CpuProfile__Serialize(const CpuProfile* self, Isolate* isolate);
1113+
11001114
// Inspector
11011115
// ---------
11021116

src/v8.zig

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3098,6 +3098,55 @@ pub const UnwrappedObject = struct {
30983098
object_group: ?[]const u8,
30993099
};
31003100

3101+
pub const CpuProfiler = struct {
3102+
handle: *c.CpuProfiler,
3103+
3104+
pub fn init(isolate: Isolate) CpuProfiler {
3105+
return .{
3106+
.handle = c.v8__CpuProfiler__Get(isolate.handle).?,
3107+
};
3108+
}
3109+
3110+
pub fn startProfiling(self: CpuProfiler, title: String) void {
3111+
c.v8__CpuProfiler__StartProfiling(self.handle, title.handle);
3112+
}
3113+
3114+
pub fn stopProfiling(self: CpuProfiler, title: String) ?CpuProfile {
3115+
if (c.v8__CpuProfiler__StopProfiling(self.handle, title.handle)) |handle| {
3116+
return .{ .handle = handle };
3117+
}
3118+
return null;
3119+
}
3120+
};
3121+
3122+
pub const CpuProfile = struct {
3123+
handle: *const c.CpuProfile,
3124+
3125+
pub fn deinit(self: CpuProfile) void {
3126+
c.v8__CpuProfile__Delete(self.handle);
3127+
}
3128+
3129+
pub fn getTopDownRoot(self: CpuProfile) ?CpuProfileNode {
3130+
if (c.v8__CpuProfile__GetTopDownRoot(self.handle)) |handle| {
3131+
return .{ .handle = handle };
3132+
}
3133+
return null;
3134+
}
3135+
3136+
/// Serializes the profile to JSON format and returns it as a String.
3137+
pub fn serialize(self: CpuProfile, isolate: Isolate) ?String {
3138+
if (c.v8__CpuProfile__Serialize(self.handle, isolate.handle)) |handle| {
3139+
return String{ .handle = handle };
3140+
}
3141+
return null;
3142+
}
3143+
};
3144+
3145+
/// Represents a node in the CPU profile tree.
3146+
pub const CpuProfileNode = struct {
3147+
handle: *const c.CpuProfileNode,
3148+
};
3149+
31013150
/// Note: Some getters return owned memory (strings), while others return memory owned by V8 (objects).
31023151
/// The getters short-circuit if the default values is not available as converting the defaults to V8 causes unnecessary overhead.
31033152
///

0 commit comments

Comments
 (0)