aboutsummaryrefslogtreecommitdiff
path: root/misctools
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-05-05 20:01:26 -0700
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2023-05-05 20:01:26 -0700
commit9d7ecf7909f17835024c7754c38eed25e1dbb592 (patch)
treec8854114efa97b4b9b30b69848b803df783e3ac1 /misctools
parent31cb49a026610382d06f319cbe76ce0efeded345 (diff)
downloadbun-9d7ecf7909f17835024c7754c38eed25e1dbb592.tar.gz
bun-9d7ecf7909f17835024c7754c38eed25e1dbb592.tar.zst
bun-9d7ecf7909f17835024c7754c38eed25e1dbb592.zip
[misctools] Add cold jsc start test
Diffstat (limited to 'misctools')
-rw-r--r--misctools/cold-jsc-start.cpp191
1 files changed, 191 insertions, 0 deletions
diff --git a/misctools/cold-jsc-start.cpp b/misctools/cold-jsc-start.cpp
new file mode 100644
index 000000000..2703d7016
--- /dev/null
+++ b/misctools/cold-jsc-start.cpp
@@ -0,0 +1,191 @@
+// print how long each step took
+#define VERBOSE
+
+//
+// This loads up a JavaScriptCore global object which only has a "write"
+// global function and then calls eval
+//
+//
+// Usage:
+// ./cold-jsc-start <file>
+// ./cold-jsc-start -e "write('hey')"
+//
+#include "root.h"
+
+#include <wtf/FileSystem.h>
+
+#include <JavaScriptCore/JSGlobalObject.h>
+
+#include <JavaScriptCore/JSArrayBufferView.h>
+#include <JavaScriptCore/JSArrayBufferViewInlines.h>
+
+#include <JavaScriptCore/Completion.h>
+#include <JavaScriptCore/InitializeThreading.h>
+#include <unistd.h>
+#include <wtf/Stopwatch.h>
+
+using namespace JSC;
+
+JSC_DEFINE_HOST_FUNCTION(jsFunctionWrite, (JSC::JSGlobalObject * globalObject,
+ JSC::CallFrame *callframe)) {
+
+ if (callframe->argumentCount() < 1)
+ return JSValue::encode(jsUndefined());
+
+ JSValue arg1 = callframe->argument(0);
+ JSValue toWriteArg = callframe->argument(1);
+ auto &vm = globalObject->vm();
+ auto scope = DECLARE_CATCH_SCOPE(vm);
+
+ int32_t fd = STDOUT_FILENO;
+ if (callframe->argumentCount() > 1) {
+ fd = arg1.toInt32(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ } else {
+ toWriteArg = arg1;
+ }
+
+ if (auto *buffer = jsDynamicCast<JSC::JSArrayBufferView *>(toWriteArg)) {
+ auto *data = buffer->vector();
+ auto length = buffer->byteLength();
+ auto written = write(fd, data, length);
+ return JSValue::encode(jsNumber(written));
+ }
+
+ auto string = toWriteArg.toWTFString(globalObject);
+ RETURN_IF_EXCEPTION(scope, encodedJSValue());
+ auto utf8 = string.utf8();
+ auto length = utf8.length();
+ auto written = write(fd, utf8.data(), length);
+ return JSValue::encode(jsNumber(written));
+}
+
+int main(int argc, char **argv) {
+ if (argc < 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ return 1;
+ }
+#ifdef VERBOSE
+ auto stopwatch = Stopwatch::create();
+ stopwatch->start();
+#endif
+
+ {
+ WTF::initializeMainThread();
+ JSC::initialize();
+ {
+ JSC::Options::AllowUnfinalizedAccessScope scope;
+
+ JSC::Options::useConcurrentJIT() = true;
+ // JSC::Options::useSigillCrashAnalyzer() = true;
+ JSC::Options::useWebAssembly() = true;
+ JSC::Options::useSourceProviderCache() = true;
+ // JSC::Options::useUnlinkedCodeBlockJettisoning() = false;
+ JSC::Options::exposeInternalModuleLoader() = true;
+ JSC::Options::useSharedArrayBuffer() = true;
+ JSC::Options::useJIT() = true;
+ JSC::Options::useBBQJIT() = true;
+ JSC::Options::useJITCage() = false;
+ JSC::Options::useShadowRealm() = true;
+ JSC::Options::useResizableArrayBuffer() = true;
+ JSC::Options::showPrivateScriptsInStackTraces() = true;
+ JSC::Options::useSetMethods() = true;
+ JSC::Options::assertOptionsAreCoherent();
+ }
+ }
+
+#ifdef VERBOSE
+
+ fprintf(stderr, "JSC::Initialize took %f ms\n",
+ stopwatch->elapsedTime().milliseconds());
+ stopwatch->reset();
+ stopwatch->start();
+#endif
+
+ auto &vm = JSC::VM::create(JSC::HeapType::Large).leakRef();
+ vm.heap.acquireAccess();
+
+#ifdef VERBOSE
+ fprintf(stderr, "JSC::VM::create took %f ms\n",
+ stopwatch->elapsedTime().milliseconds());
+ stopwatch->reset();
+ stopwatch->start();
+#endif
+
+ JSC::JSLockHolder locker(vm);
+ auto *globalObject = JSC::JSGlobalObject::create(
+ vm, JSC::JSGlobalObject::createStructure(vm, JSC::jsNull()));
+
+#ifdef VERBOSE
+ fprintf(stderr, "JSC::JSGlobalObject::create took %f ms\n",
+ stopwatch->elapsedTime().milliseconds());
+ stopwatch->reset();
+ stopwatch->start();
+#endif
+
+ JSC::gcProtect(globalObject);
+ globalObject->putDirectNativeFunction(
+ vm, globalObject,
+ PropertyName(JSC::Identifier::fromString(vm, "write"_s)), 0,
+ jsFunctionWrite, ImplementationVisibility::Public, JSC::NoIntrinsic,
+ JSC::PropertyAttribute::ReadOnly | 0);
+
+ vm.ref();
+ if (argc > 2) {
+ auto source = JSC::makeSource(WTF::String::fromUTF8(argv[argc - 1]),
+ SourceOrigin(WTF::URL("file://eval.js"_s)),
+ "eval.js"_s);
+
+ NakedPtr<Exception> evaluationException;
+ JSValue returnValue =
+ JSC::profiledEvaluate(globalObject, ProfilingReason::API, source,
+ globalObject, evaluationException);
+
+#ifdef VERBOSE
+ fprintf(stderr, "\neval took %f ms\n",
+ stopwatch->elapsedTime().milliseconds());
+ stopwatch->reset();
+
+#endif
+
+ if (evaluationException) {
+ fprintf(
+ stderr, "Exception: %s\n",
+ evaluationException->value().toWTFString(globalObject).utf8().data());
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+ WTF::String fileURLString = WTF::String::fromUTF8(argv[argc - 1]);
+
+ if (auto contents = WTF::FileSystemImpl::readEntireFile(fileURLString)) {
+ auto source =
+ JSC::makeSource(WTF::String::fromUTF8(contents.value()),
+ SourceOrigin(WTF::URL(fileURLString)), fileURLString);
+
+ NakedPtr<Exception> evaluationException;
+ JSValue returnValue =
+ JSC::profiledEvaluate(globalObject, ProfilingReason::API, source,
+ globalObject, evaluationException);
+
+#ifdef VERBOSE
+ fprintf(stderr, "eval took %f ms\n",
+ stopwatch->elapsedTime().milliseconds());
+ stopwatch->reset();
+#endif
+
+ if (evaluationException) {
+ fprintf(
+ stderr, "Exception: %s\n",
+ evaluationException->value().toWTFString(globalObject).utf8().data());
+ return 1;
+ } else {
+ return 0;
+ }
+ } else {
+ fprintf(stderr, "Could not read file %s\n", argv[argc - 1]);
+ return 1;
+ }
+}