[misctools] Add cold jsc start test

This commit is contained in:
Jarred Sumner
2023-05-05 20:01:26 -07:00
parent 31cb49a026
commit 9d7ecf7909
3 changed files with 210 additions and 0 deletions

3
.gitignore vendored
View File

@@ -116,3 +116,6 @@ src/bun.js/debug-bindings-obj
failing-tests.txt
test.txt
myscript.sh
cold-jsc-start
cold-jsc-start.d

View File

@@ -1827,6 +1827,22 @@ copy-to-bun-release-dir-bin:
PACKAGE_MAP = --pkg-begin async_io $(BUN_DIR)/src/io/io_darwin.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin javascript_core $(BUN_DIR)/src/jsc.zig --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end --pkg-end --pkg-begin bun $(BUN_DIR)/src/bun_redirect.zig --pkg-end
.PHONY: cold-jsc-start
cold-jsc-start:
$(CXX_WITH_CCACHE) $(CLANG_FLAGS) \
$(MACOS_MIN_FLAG) \
$(OPTIMIZATION_LEVEL) \
-MMD \
-fno-exceptions \
-fno-rtti \
-ferror-limit=1000 \
$(LIBICONV_PATH) \
$(DEFAULT_LINKER_FLAGS) \
$(PLATFORM_LINKER_FLAGS) \
$(ICU_FLAGS) \
$(JSC_FILES) \
misctools/cold-jsc-start.cpp -o cold-jsc-start
.PHONY: vendor-without-npm
vendor-without-npm: node-fallbacks runtime_js fallback_decoder bun_error mimalloc picohttp zlib boringssl libarchive lolhtml sqlite usockets uws tinycc c-ares

View File

@@ -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;
}
}