diff --git a/src/bake/BakeGlobalObject.cpp b/src/bake/BakeGlobalObject.cpp index abcaf83f6e..148d045064 100644 --- a/src/bake/BakeGlobalObject.cpp +++ b/src/bake/BakeGlobalObject.cpp @@ -189,7 +189,7 @@ extern "C" GlobalObject* BakeCreateProdGlobal(void* console) vm.heap.acquireAccess(); JSC::JSLockHolder locker(vm); BunVirtualMachine* bunVM = Bun__getVM(); - WebCore::JSVMClientData::create(&vm, bunVM); + WebCore::JSVMClientData::create(vm, bunVM, JSC::HeapType::Large); JSC::Structure* structure = Bake::GlobalObject::createStructure(vm); Bake::GlobalObject* global = Bake::GlobalObject::create( diff --git a/src/bun.js/bindings/BunClientData.cpp b/src/bun.js/bindings/BunClientData.cpp index 3aaba2acbd..831ff495ef 100644 --- a/src/bun.js/bindings/BunClientData.cpp +++ b/src/bun.js/bindings/BunClientData.cpp @@ -44,7 +44,7 @@ JSHeapData::JSHeapData(Heap& heap) #define CLIENT_ISO_SUBSPACE_INIT(subspace) subspace(m_heapData->subspace) -JSVMClientData::JSVMClientData(VM& vm, RefPtr sourceProvider) +JSVMClientData::JSVMClientData(VM& vm, RefPtr sourceProvider, JSC::HeapType heapType) : m_builtinNames(vm) , m_builtinFunctions(vm, sourceProvider, m_builtinNames) , m_heapData(JSHeapData::ensureHeapData(vm.heap)) @@ -52,7 +52,7 @@ JSVMClientData::JSVMClientData(VM& vm, RefPtr sourceProvider) , CLIENT_ISO_SUBSPACE_INIT(m_domConstructorSpace) , CLIENT_ISO_SUBSPACE_INIT(m_domNamespaceObjectSpace) , m_clientSubspaces(makeUnique()) - , m_gcController(vm) + , m_gcController(vm, heapType) { } @@ -78,27 +78,27 @@ JSVMClientData::~JSVMClientData() ASSERT(m_normalWorld->hasOneRef()); m_normalWorld = nullptr; } -void JSVMClientData::create(VM* vm, void* bunVM) +void JSVMClientData::create(VM& vm, void* bunVM, JSC::HeapType heapType) { auto provider = WebCore::createBuiltinsSourceProvider(); - JSVMClientData* clientData = new JSVMClientData(*vm, provider); + JSVMClientData* clientData = new JSVMClientData(vm, provider, heapType); clientData->bunVM = bunVM; clientData->m_gcController.bunVM = bunVM; - vm->deferredWorkTimer->onAddPendingWork = [clientData](Ref&& ticket, JSC::DeferredWorkTimer::WorkType kind) -> void { + vm.deferredWorkTimer->onAddPendingWork = [clientData](Ref&& ticket, JSC::DeferredWorkTimer::WorkType kind) -> void { Bun::JSCTaskScheduler::onAddPendingWork(clientData, WTFMove(ticket), kind); }; - vm->deferredWorkTimer->onScheduleWorkSoon = [clientData](JSC::DeferredWorkTimer::Ticket ticket, JSC::DeferredWorkTimer::Task&& task) -> void { + vm.deferredWorkTimer->onScheduleWorkSoon = [clientData](JSC::DeferredWorkTimer::Ticket ticket, JSC::DeferredWorkTimer::Task&& task) -> void { Bun::JSCTaskScheduler::onScheduleWorkSoon(clientData, ticket, WTFMove(task)); }; - vm->deferredWorkTimer->onCancelPendingWork = [clientData](JSC::DeferredWorkTimer::Ticket ticket) -> void { + vm.deferredWorkTimer->onCancelPendingWork = [clientData](JSC::DeferredWorkTimer::Ticket ticket) -> void { Bun::JSCTaskScheduler::onCancelPendingWork(clientData, ticket); }; - vm->clientData = clientData; // ~VM deletes this pointer. - clientData->m_normalWorld = DOMWrapperWorld::create(*vm, DOMWrapperWorld::Type::Normal); + vm.clientData = clientData; // ~VM deletes this pointer. + clientData->m_normalWorld = DOMWrapperWorld::create(vm, DOMWrapperWorld::Type::Normal); - vm->heap.addMarkingConstraint(makeUnique(*vm, clientData->heapData())); - vm->m_typedArrayController = adoptRef(new WebCoreTypedArrayController(true)); + vm.heap.addMarkingConstraint(makeUnique(vm, clientData->heapData())); + vm.m_typedArrayController = adoptRef(new WebCoreTypedArrayController(true)); clientData->builtinFunctions().exportNames(); } diff --git a/src/bun.js/bindings/BunClientData.h b/src/bun.js/bindings/BunClientData.h index 6409161e44..b763ea0c84 100644 --- a/src/bun.js/bindings/BunClientData.h +++ b/src/bun.js/bindings/BunClientData.h @@ -79,11 +79,9 @@ class JSVMClientData : public JSC::VM::ClientData { WTF_MAKE_FAST_ALLOCATED_WITH_HEAP_IDENTIFIER(JSVMClientData); public: - explicit JSVMClientData(JSC::VM&, RefPtr); - virtual ~JSVMClientData(); - static void create(JSC::VM*, void*); + static void create(JSC::VM& vm, void* bunVM, JSC::HeapType heapType); JSHeapData& heapData() { return *m_heapData; } BunBuiltinNames& builtinNames() { return m_builtinNames; } @@ -116,6 +114,8 @@ public: Bun::GCController& gcController() { return m_gcController; } private: + explicit JSVMClientData(JSC::VM&, RefPtr, JSC::HeapType heapType); + bool isWebCoreJSClientData() const final { return true; } BunBuiltinNames m_builtinNames; diff --git a/src/bun.js/bindings/BunGCController.cpp b/src/bun.js/bindings/BunGCController.cpp index 03b8de1c7b..2518dc4db3 100644 --- a/src/bun.js/bindings/BunGCController.cpp +++ b/src/bun.js/bindings/BunGCController.cpp @@ -27,7 +27,7 @@ class FullGCActivityCallback final : public JSC::FullGCActivityCallback { public: using Base = JSC::FullGCActivityCallback; - static RefPtr create(JSC::Heap& heap) + static Ref create(JSC::Heap& heap) { return adoptRef(*new FullGCActivityCallback(heap)); } @@ -54,7 +54,7 @@ class EdenGCActivityCallback final : public JSC::EdenGCActivityCallback { public: using Base = JSC::EdenGCActivityCallback; - static RefPtr create(JSC::Heap& heap) + static Ref create(JSC::Heap& heap) { return adoptRef(*new EdenGCActivityCallback(heap)); } @@ -237,33 +237,23 @@ void EdenGCActivityCallback::doCollectionEvenIfBusy(JSC::VM& vm) Base::doCollection(vm); } -GCController::GCController(JSC::VM& vm) - : m_vm(vm) -{ -} - -GCController::~GCController() -{ -} - extern "C" void Bun__GCController__setup(Bun::GCController* controller); -void GCController::initialize(bool miniMode) +GCController::GCController(JSC::VM& vm, JSC::HeapType heapType) + : m_vm(vm) + , m_edenCallback(EdenGCActivityCallback::create(vm.heap)) + , m_fullCallback(FullGCActivityCallback::create(vm.heap)) { - // Create Eden and Full GC callbacks - m_edenCallback = EdenGCActivityCallback::create(m_vm.heap); - m_fullCallback = FullGCActivityCallback::create(m_vm.heap); - // Set them as active callbacks in the heap - m_vm.heap.setEdenActivityCallback(m_edenCallback.get()); - m_vm.heap.setFullActivityCallback(m_fullCallback.get()); + m_vm.heap.setEdenActivityCallback(Ref(m_edenCallback)); + m_vm.heap.setFullActivityCallback(Ref(m_fullCallback)); { const char* disable_stop_if_necessary_timer = getenv("BUN_DISABLE_STOP_IF_NECESSARY_TIMER"); // Keep stopIfNecessaryTimer enabled by default when either: // - `--smol` is passed // - The machine has less than 4GB of RAM - bool shouldDisableStopIfNecessaryTimer = !miniMode; + bool shouldDisableStopIfNecessaryTimer = heapType == JSC::HeapType::Large; if (ramSize() < 1024ull * 1024ull * 1024ull * 4ull) { shouldDisableStopIfNecessaryTimer = false; } @@ -289,6 +279,10 @@ void GCController::initialize(bool miniMode) Bun__GCController__setup(this); } +GCController::~GCController() +{ +} + void GCController::performOpportunisticGC() { // runs after an HTTP request has completed @@ -330,9 +324,6 @@ void GCController::performOpportunisticGC() void GCController::configureEdenGC(bool enabled, unsigned intervalMs) { - if (!m_edenCallback) - return; - if (enabled) { m_edenCallback->setEnabled(true); m_edenCallback->setTimeUntilFire(WTF::Seconds::fromMilliseconds(intervalMs)); @@ -344,9 +335,6 @@ void GCController::configureEdenGC(bool enabled, unsigned intervalMs) void GCController::configureFullGC(bool enabled, unsigned intervalMs) { - if (!m_fullCallback) - return; - if (enabled) { m_fullCallback->setEnabled(true); m_fullCallback->setTimeUntilFire(WTF::Seconds::fromMilliseconds(intervalMs)); diff --git a/src/bun.js/bindings/BunGCController.h b/src/bun.js/bindings/BunGCController.h index af35136c9e..5463fa0bb7 100644 --- a/src/bun.js/bindings/BunGCController.h +++ b/src/bun.js/bindings/BunGCController.h @@ -1,5 +1,7 @@ #pragma once +#include "root.h" + namespace JSC { class VM; class JSObject; @@ -18,11 +20,9 @@ class FullGCActivityCallback; // The lifetime of this is tied to the JSVMClientData instance, which is tied to the JSC::VM instance class GCController { public: - GCController(JSC::VM&); + GCController(JSC::VM&, JSC::HeapType heapType); ~GCController(); - void initialize(bool miniMode); - // Configure the Eden GC for smaller, more frequent collections void configureEdenGC(bool enabled, unsigned intervalMs = 30); @@ -67,8 +67,8 @@ public: private: JSC::VM& m_vm; - RefPtr m_edenCallback; - RefPtr m_fullCallback; + Ref m_edenCallback; + Ref m_fullCallback; Metrics m_metrics = {}; bool m_hasMoreEventLoopWorkToDo = false; size_t m_lastBlockBytesAllocated = 0; diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 965bc8c58b..e897363869 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -876,8 +876,6 @@ void Zig::GlobalObject::resetOnEachMicrotaskTick() } } -extern "C" void* GCController__setup(Bun::GCController* controller); - // executionContextId: -1 for main thread // executionContextId: maxInt32 for macros // executionContextId: >-1 for workers @@ -897,10 +895,7 @@ extern "C" JSC__JSGlobalObject* Zig__GlobalObject__create(void* console_client, // Every JS VM's RunLoop should use Bun's RunLoop implementation ASSERT(vmPtr->runLoop().kind() == WTF::RunLoop::Kind::Bun); - WebCore::JSVMClientData::create(&vm, Bun__getVM()); - - auto* clientData = Bun::clientData(vm); - clientData->gcController().initialize(miniMode); + WebCore::JSVMClientData::create(vm, Bun__getVM(), heapSize); const auto createGlobalObject = [&]() -> Zig::GlobalObject* { if (UNLIKELY(executionContextId == std::numeric_limits::max() || executionContextId > -1)) {