diff options
author | 2022-12-13 20:47:51 -0800 | |
---|---|---|
committer | 2022-12-13 20:47:51 -0800 | |
commit | f61d9e340d35f982e8ad86b705af46464c7f1d2a (patch) | |
tree | eb89549abd0be7f7c63ce8c4eee8127dcca81acf /src/bun.js/bindings/BunJSCModule.cpp | |
parent | 47a2548cbfbb977e9b1f0c749bd83d47b4c4596b (diff) | |
download | bun-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.cpp | 53 |
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; |