aboutsummaryrefslogtreecommitdiff
path: root/src/bun.js/bindings/BunJSCModule.cpp
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-12-13 20:47:51 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-12-13 20:47:51 -0800
commitf61d9e340d35f982e8ad86b705af46464c7f1d2a (patch)
treeeb89549abd0be7f7c63ce8c4eee8127dcca81acf /src/bun.js/bindings/BunJSCModule.cpp
parent47a2548cbfbb977e9b1f0c749bd83d47b4c4596b (diff)
downloadbun-f61d9e340d35f982e8ad86b705af46464c7f1d2a.tar.gz
bun-f61d9e340d35f982e8ad86b705af46464c7f1d2a.tar.zst
bun-f61d9e340d35f982e8ad86b705af46464c7f1d2a.zip
[bun:jsc] Introduce `profile` function
Diffstat (limited to 'src/bun.js/bindings/BunJSCModule.cpp')
-rw-r--r--src/bun.js/bindings/BunJSCModule.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/bun.js/bindings/BunJSCModule.cpp b/src/bun.js/bindings/BunJSCModule.cpp
index fd92b817e..384882883 100644
--- a/src/bun.js/bindings/BunJSCModule.cpp
+++ b/src/bun.js/bindings/BunJSCModule.cpp
@@ -421,6 +421,58 @@ JSC_DEFINE_HOST_FUNCTION(functionDrainMicrotasks, (JSGlobalObject * globalObject
return JSValue::encode(jsUndefined());
}
+JSC_DEFINE_HOST_FUNCTION(functionRunProfiler, (JSGlobalObject * globalObject, CallFrame* callFrame))
+{
+ JSC::VM& vm = globalObject->vm();
+ JSC::SamplingProfiler& samplingProfiler = vm.ensureSamplingProfiler(WTF::Stopwatch::create());
+
+ JSC::JSValue callbackValue = callFrame->argument(0);
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ if (callbackValue.isUndefinedOrNull() || !callbackValue.isCallable()) {
+ throwException(globalObject, throwScope, createTypeError(globalObject, "First argument must be a function."_s));
+ return JSValue::encode(JSValue {});
+ }
+
+ JSC::JSFunction* function = jsCast<JSC::JSFunction*>(callbackValue);
+
+ JSC::JSValue sampleValue = callFrame->argument(1);
+ if (sampleValue.isNumber()) {
+ unsigned sampleInterval = sampleValue.toUInt32(globalObject);
+ samplingProfiler.setTimingInterval(Seconds::fromMicroseconds(sampleInterval));
+ }
+
+ JSC::CallData callData = JSC::getCallData(function);
+ MarkedArgumentBuffer args;
+
+ samplingProfiler.noticeCurrentThreadAsJSCExecutionThread();
+ samplingProfiler.start();
+ JSC::call(globalObject, function, callData, JSC::jsUndefined(), args);
+ samplingProfiler.pause();
+ if (throwScope.exception()) {
+ samplingProfiler.shutdown();
+ samplingProfiler.clearData();
+ return JSValue::encode(JSValue {});
+ }
+
+ StringPrintStream topFunctions;
+ samplingProfiler.reportTopFunctions(topFunctions);
+
+ StringPrintStream byteCodes;
+ samplingProfiler.reportTopBytecodes(byteCodes);
+
+ JSValue stackTraces = JSONParse(globalObject, samplingProfiler.stackTracesAsJSON());
+
+ samplingProfiler.shutdown();
+ samplingProfiler.clearData();
+
+ JSObject* result = constructEmptyObject(globalObject, globalObject->objectPrototype(), 3);
+ result->putDirect(vm, Identifier::fromString(vm, "functions"_s), jsString(vm, topFunctions.toString()));
+ result->putDirect(vm, Identifier::fromString(vm, "bytecodes"_s), jsString(vm, byteCodes.toString()));
+ result->putDirect(vm, Identifier::fromString(vm, "stackTraces"_s), stackTraces);
+
+ return JSValue::encode(result);
+}
+
JSC_DECLARE_HOST_FUNCTION(functionGenerateHeapSnapshotForDebugging);
JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshotForDebugging, (JSGlobalObject * globalObject, CallFrame*))
{
@@ -476,6 +528,7 @@ JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject)
object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "totalCompileTime"_s), 1, functionTotalCompileTime, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "getProtectedObjects"_s), 1, functionGetProtectedObjects, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "generateHeapSnapshotForDebugging"_s), 0, functionGenerateHeapSnapshotForDebugging, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
+ object->putDirectNativeFunction(vm, globalObject, JSC::Identifier::fromString(vm, "profile"_s), 0, functionRunProfiler, ImplementationVisibility::Public, NoIntrinsic, JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete | 0);
}
return object;