aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2023-07-29 06:18:51 -0700
committerGravatar GitHub <noreply@github.com> 2023-07-29 06:18:51 -0700
commit681be10294c19b8ce402ec44df5cd6554e2c86c0 (patch)
treed7729f1c4b2cd6f2f9e9ad45002b8fa3f44ba8fe
parentdccf82b1c682a84c42540ba9e00e5e9296cc7e5f (diff)
downloadbun-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.cpp105
-rw-r--r--src/bun.js/bindings/BunJSCModule.h5
-rw-r--r--src/bun.js/bindings/Process.cpp2
-rw-r--r--src/bun.js/bindings/Process.h3
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.cpp8
-rw-r--r--src/bun.js/bindings/ZigGlobalObject.h6
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,
- &current_rss, &peak_rss,
- &current_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,
+ &current_rss, &peak_rss,
+ &current_commit, &peak_commit, &page_faults);
+
+ // mi_process_info produces incorrect rss size on linux.
+ Zig::getRSS(&current_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;