Make bun:jsc memoryUsage more accurate (#3876)

Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
This commit is contained in:
Jarred Sumner
2023-07-29 06:18:51 -07:00
committed by GitHub
parent dccf82b1c6
commit 681be10294
6 changed files with 61 additions and 68 deletions

View File

@@ -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;
JSC::Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject)
{
public:
template<typename CellType, SubspaceAccess>
static CompleteSubspace* subspaceFor(VM& vm)
{
return &vm.destructibleObjectSpace();
}
JSC::Structure* structure = globalObject->structureCache().emptyObjectStructureForPrototype(globalObject, globalObject->objectPrototype(), 5);
JSC::PropertyOffset offset;
JSCMemoryFootprint(VM& vm, Structure* structure)
: Base(vm, structure)
{
}
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);
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));
}
DECLARE_INFO;
private:
void addProperty(VM& vm, ASCIILiteral name, JSValue value)
{
Identifier identifier = Identifier::fromString(vm, name);
putDirect(vm, identifier, value);
}
};
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);

View File

@@ -1,4 +1,7 @@
#pragma once
#include "root.h"
#include "JavaScriptCore/JSObject.h"
JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject);
JSC::JSObject* createJSCModule(JSC::JSGlobalObject* globalObject);
JSC::Structure* createMemoryFootprintStructure(JSC::VM& vm, JSC::JSGlobalObject* globalObject);

View File

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

View File

@@ -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 {

View File

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

View File

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