diff options
author | 2023-07-29 06:18:51 -0700 | |
---|---|---|
committer | 2023-07-29 06:18:51 -0700 | |
commit | 681be10294c19b8ce402ec44df5cd6554e2c86c0 (patch) | |
tree | d7729f1c4b2cd6f2f9e9ad45002b8fa3f44ba8fe | |
parent | dccf82b1c682a84c42540ba9e00e5e9296cc7e5f (diff) | |
download | bun-681be10294c19b8ce402ec44df5cd6554e2c86c0.tar.gz bun-681be10294c19b8ce402ec44df5cd6554e2c86c0.tar.zst bun-681be10294c19b8ce402ec44df5cd6554e2c86c0.zip |
Make `bun:jsc` memoryUsage more accurate (#3876)
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
-rw-r--r-- | src/bun.js/bindings/BunJSCModule.cpp | 105 | ||||
-rw-r--r-- | src/bun.js/bindings/BunJSCModule.h | 5 | ||||
-rw-r--r-- | src/bun.js/bindings/Process.cpp | 2 | ||||
-rw-r--r-- | src/bun.js/bindings/Process.h | 3 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 8 | ||||
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.h | 6 |
6 files changed, 61 insertions, 68 deletions
diff --git a/src/bun.js/bindings/BunJSCModule.cpp b/src/bun.js/bindings/BunJSCModule.cpp index 5e7a047ea..444318632 100644 --- a/src/bun.js/bindings/BunJSCModule.cpp +++ b/src/bun.js/bindings/BunJSCModule.cpp @@ -28,6 +28,8 @@ #include "ExceptionOr.h" #include "MessagePort.h" +#include "Process.h" + #if ENABLE(REMOTE_INSPECTOR) #include "JavaScriptCore/RemoteInspectorServer.h" #endif @@ -146,73 +148,20 @@ JSC_DEFINE_HOST_FUNCTION(functionHeapSize, (JSGlobalObject * globalObject, CallF return JSValue::encode(jsNumber(vm.heap.size())); } -class JSCMemoryFootprint : public JSDestructibleObject { - using Base = JSDestructibleObject; - -public: - template<typename CellType, SubspaceAccess> - static CompleteSubspace* subspaceFor(VM& vm) - { - return &vm.destructibleObjectSpace(); - } - - JSCMemoryFootprint(VM& vm, Structure* structure) - : Base(vm, structure) - { - } - - static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype) - { - return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info()); - } - - static JSCMemoryFootprint* create(VM& vm, JSGlobalObject* globalObject) - { - Structure* structure = createStructure(vm, globalObject, jsNull()); - JSCMemoryFootprint* footprint = new (NotNull, allocateCell<JSCMemoryFootprint>(vm)) JSCMemoryFootprint(vm, structure); - footprint->finishCreation(vm); - return footprint; - } - - void finishCreation(VM& vm) - { - Base::finishCreation(vm); - - auto addProperty = [&](VM& vm, ASCIILiteral name, JSValue value) { - JSCMemoryFootprint::addProperty(vm, name, value); - }; - - size_t elapsed_msecs = 0; - size_t user_msecs = 0; - size_t system_msecs = 0; - size_t current_rss = 0; - size_t peak_rss = 0; - size_t current_commit = 0; - size_t peak_commit = 0; - size_t page_faults = 0; - - mi_process_info(&elapsed_msecs, &user_msecs, &system_msecs, - ¤t_rss, &peak_rss, - ¤t_commit, &peak_commit, &page_faults); - - addProperty(vm, "current"_s, jsNumber(current_rss)); - addProperty(vm, "peak"_s, jsNumber(peak_rss)); - addProperty(vm, "currentCommit"_s, jsNumber(current_commit)); - addProperty(vm, "peakCommit"_s, jsNumber(peak_commit)); - addProperty(vm, "pageFaults"_s, jsNumber(page_faults)); - } +JSC::Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject) +{ - DECLARE_INFO; + JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(globalObject, globalObject->objectPrototype(), 5); + JSC::PropertyOffset offset; -private: - void addProperty(VM& vm, ASCIILiteral name, JSValue value) - { - Identifier identifier = Identifier::fromString(vm, name); - putDirect(vm, identifier, value); - } -}; + structure = structure->addPropertyTransition(vm, structure, Identifier::fromString(vm, "current"_s), 0, offset); + structure = structure->addPropertyTransition(vm, structure, Identifier::fromString(vm, "peak"_s), 0, offset); + structure = structure->addPropertyTransition(vm, structure, Identifier::fromString(vm, "currentCommit"_s), 0, offset); + structure = structure->addPropertyTransition(vm, structure, Identifier::fromString(vm, "peakCommit"_s), 0, offset); + structure = structure->addPropertyTransition(vm, structure, Identifier::fromString(vm, "pageFaults"_s), 0, offset); -const ClassInfo JSCMemoryFootprint::s_info = { "MemoryFootprint"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSCMemoryFootprint) }; + return structure; +} JSC_DECLARE_HOST_FUNCTION(functionMemoryUsageStatistics); JSC_DEFINE_HOST_FUNCTION(functionMemoryUsageStatistics, (JSGlobalObject * globalObject, CallFrame*)) @@ -245,9 +194,33 @@ JSC_DEFINE_HOST_FUNCTION(functionMemoryUsageStatistics, (JSGlobalObject * global JSC_DECLARE_HOST_FUNCTION(functionCreateMemoryFootprint); JSC_DEFINE_HOST_FUNCTION(functionCreateMemoryFootprint, (JSGlobalObject * globalObject, CallFrame*)) { + + size_t elapsed_msecs = 0; + size_t user_msecs = 0; + size_t system_msecs = 0; + size_t current_rss = 0; + size_t peak_rss = 0; + size_t current_commit = 0; + size_t peak_commit = 0; + size_t page_faults = 0; + + mi_process_info(&elapsed_msecs, &user_msecs, &system_msecs, + ¤t_rss, &peak_rss, + ¤t_commit, &peak_commit, &page_faults); + + // mi_process_info produces incorrect rss size on linux. + Zig::getRSS(¤t_rss); + VM& vm = globalObject->vm(); - JSLockHolder lock(vm); - return JSValue::encode(JSCMemoryFootprint::create(vm, globalObject)); + JSC::JSObject* object = JSC::constructEmptyObject(vm, JSC::jsCast<Zig::GlobalObject*>(globalObject)->memoryFootprintStructure()); + + object->putDirectOffset(vm, 0, jsNumber(current_rss)); + object->putDirectOffset(vm, 1, jsNumber(peak_rss)); + object->putDirectOffset(vm, 2, jsNumber(current_commit)); + object->putDirectOffset(vm, 3, jsNumber(peak_commit)); + object->putDirectOffset(vm, 4, jsNumber(page_faults)); + + return JSValue::encode(object); } JSC_DECLARE_HOST_FUNCTION(functionNeverInlineFunction); diff --git a/src/bun.js/bindings/BunJSCModule.h b/src/bun.js/bindings/BunJSCModule.h index 7df47a566..d2ddcf6a7 100644 --- a/src/bun.js/bindings/BunJSCModule.h +++ b/src/bun.js/bindings/BunJSCModule.h @@ -1,4 +1,7 @@ +#pragma once + #include "root.h" #include "JavaScriptCore/JSObject.h" -JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject);
\ No newline at end of file +JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject); +JSC::Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);
\ No newline at end of file diff --git a/src/bun.js/bindings/Process.cpp b/src/bun.js/bindings/Process.cpp index 78f473ec2..4c684f0c0 100644 --- a/src/bun.js/bindings/Process.cpp +++ b/src/bun.js/bindings/Process.cpp @@ -1313,7 +1313,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionCpuUsage, RELEASE_AND_RETURN(throwScope, JSC::JSValue::encode(result)); } -static int getRSS(size_t* rss) +int getRSS(size_t* rss) { #if defined(__APPLE__) mach_msg_type_number_t count; diff --git a/src/bun.js/bindings/Process.h b/src/bun.js/bindings/Process.h index 0ee6f4243..ab344c7fe 100644 --- a/src/bun.js/bindings/Process.h +++ b/src/bun.js/bindings/Process.h @@ -8,6 +8,9 @@ namespace Zig { +// TODO: find a better place for this +int getRSS(size_t* rss); + using namespace JSC; class Process : public WebCore::JSEventEmitter { diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 1aefe476c..ffd6e990a 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -3222,6 +3222,13 @@ void GlobalObject::finishCreation(VM& vm) init.set(Bun::createCommonJSModuleStructure(reinterpret_cast<Zig::GlobalObject*>(init.owner))); }); + m_memoryFootprintStructure.initLater( + [](const JSC::LazyProperty<JSC::JSGlobalObject, Structure>::Initializer& init) { + init.set( + createMemoryFootprintStructure( + init.vm, reinterpret_cast<Zig::GlobalObject*>(init.owner))); + }); + m_commonJSFunctionArgumentsStructure.initLater( [](const Initializer<Structure>& init) { auto* globalObject = reinterpret_cast<Zig::GlobalObject*>(init.owner); @@ -4688,6 +4695,7 @@ void GlobalObject::visitChildrenImpl(JSCell* cell, Visitor& visitor) thisObject->m_lazyTestModuleObject.visit(visitor); thisObject->m_lazyPreloadTestModuleObject.visit(visitor); thisObject->m_commonJSModuleObjectStructure.visit(visitor); + thisObject->m_memoryFootprintStructure.visit(visitor); thisObject->m_lazyPasswordObject.visit(visitor); thisObject->m_commonJSFunctionArgumentsStructure.visit(visitor); thisObject->m_cachedGlobalObjectStructure.visit(visitor); diff --git a/src/bun.js/bindings/ZigGlobalObject.h b/src/bun.js/bindings/ZigGlobalObject.h index 9d04786d5..12f5d9d32 100644 --- a/src/bun.js/bindings/ZigGlobalObject.h +++ b/src/bun.js/bindings/ZigGlobalObject.h @@ -390,6 +390,11 @@ public: mutable WriteBarrier<JSFunction> m_thenables[promiseFunctionsSize + 1]; + Structure* memoryFootprintStructure() + { + return m_memoryFootprintStructure.getInitializedOnMainThread(this); + } + JSObject* navigatorObject(); JSFunction* nativeMicrotaskTrampoline() { return m_nativeMicrotaskTrampoline.getInitializedOnMainThread(this); } @@ -522,6 +527,7 @@ private: LazyProperty<JSGlobalObject, Structure> m_cachedGlobalProxyStructure; LazyProperty<JSGlobalObject, Structure> m_commonJSModuleObjectStructure; LazyProperty<JSGlobalObject, Structure> m_commonJSFunctionArgumentsStructure; + LazyProperty<JSGlobalObject, Structure> m_memoryFootprintStructure; LazyProperty<JSGlobalObject, JSC::JSObject> m_requireFunctionUnbound; LazyProperty<JSGlobalObject, JSC::JSObject> m_requireResolveFunctionUnbound; |