diff --git a/src/mem.c b/src/mem.c index 41b76a73..651f167b 100644 --- a/src/mem.c +++ b/src/mem.c @@ -6,11 +6,14 @@ #include #endif +#include + #include static int64_t s_tf_malloc_size; static int64_t s_uv_malloc_size; static int64_t s_tls_malloc_size; +static int64_t s_js_malloc_size; static void* _tf_alloc(int64_t* total, size_t size) { @@ -184,3 +187,65 @@ size_t tf_mem_get_tf_malloc_size() { return s_tf_malloc_size; } + +static void* _tf_js_malloc(JSMallocState* state, size_t size) +{ + int64_t delta = 0; + void* ptr = _tf_alloc(&delta, size); + if (ptr) + { + __atomic_add_fetch(&s_js_malloc_size, delta, __ATOMIC_RELAXED); + state->malloc_count++; + state->malloc_size += delta; + } + return ptr; +} + +static void _tf_js_free(JSMallocState* state, void* ptr) +{ + if (ptr) + { + int64_t delta = 0; + _tf_free(&delta, ptr); + __atomic_add_fetch(&s_js_malloc_size, delta, __ATOMIC_RELAXED); + state->malloc_count--; + state->malloc_size += delta; + } +} + +static void* _tf_js_realloc(JSMallocState* state, void* ptr, size_t size) +{ + int64_t delta = 0; + void* result = _tf_realloc(&delta, ptr, size); + __atomic_add_fetch(&s_js_malloc_size, delta, __ATOMIC_RELAXED); + state->malloc_count += (ptr ? -1 : 0) + (result ? 1 : 0); + state->malloc_size += delta; + return result; +} + +static size_t _tf_js_malloc_usable_size(const void* ptr) +{ + void* old_ptr = ptr ? (void*)((intptr_t)ptr - sizeof(size_t)) : NULL; + size_t old_size = 0; + if (old_ptr) + { + memcpy(&old_size, old_ptr, sizeof(size_t)); + } + return old_size; +} + +void tf_get_js_malloc_functions(JSMallocFunctions* out) +{ + *out = (JSMallocFunctions) + { + .js_malloc = _tf_js_malloc, + .js_free = _tf_js_free, + .js_realloc = _tf_js_realloc, + .js_malloc_usable_size = _tf_js_malloc_usable_size, + }; +} + +size_t tf_mem_get_js_malloc_size() +{ + return s_js_malloc_size; +} diff --git a/src/mem.h b/src/mem.h index d2769b89..df3ff6be 100644 --- a/src/mem.h +++ b/src/mem.h @@ -2,6 +2,8 @@ #include +typedef struct JSMallocFunctions JSMallocFunctions; + void tf_mem_replace_uv_allocator(); size_t tf_mem_get_uv_malloc_size(); @@ -16,3 +18,6 @@ void tf_free(void* ptr); char* tf_strdup(const char* string); void* tf_resize_vec(void* ptr, size_t size); + +void tf_get_js_malloc_functions(JSMallocFunctions* out); +size_t tf_mem_get_js_malloc_size(); diff --git a/src/ssb.c b/src/ssb.c index 5b9671a2..4ba6fafe 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -1724,7 +1724,9 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const else { ssb->own_context = true; - ssb->runtime = JS_NewRuntime(); + JSMallocFunctions funcs = { 0 }; + tf_get_js_malloc_functions(&funcs); + ssb->runtime = JS_NewRuntime2(&funcs, NULL); ssb->context = JS_NewContext(ssb->runtime); } diff --git a/src/ssb.db.c b/src/ssb.db.c index 23a19a3c..c5477997 100644 --- a/src/ssb.db.c +++ b/src/ssb.db.c @@ -606,7 +606,9 @@ bool _tf_ssb_update_message_id(sqlite3* db, const char* old_id, const char* new_ bool tf_ssb_db_check(sqlite3* db, const char* check_author) { - JSRuntime* runtime = JS_NewRuntime(); + JSMallocFunctions funcs = { 0 }; + tf_get_js_malloc_functions(&funcs); + JSRuntime* runtime = JS_NewRuntime2(&funcs, NULL); JSContext* context = JS_NewContext(runtime); sqlite3_stmt* statement = NULL; diff --git a/src/task.c b/src/task.c index d83121b6..3a236f72 100644 --- a/src/task.c +++ b/src/task.c @@ -722,12 +722,7 @@ static JSValue _tf_task_getStats(JSContext* context, JSValueConst this_val, int } JS_SetPropertyStr(context, result, "sqlite3_memory_percent", JS_NewFloat64(context, 100.0f * sqlite3_memory_used() / total_memory)); - - JSMemoryUsage js = { 0 }; - JSRuntime* runtime = JS_GetRuntime(context); - JS_ComputeMemoryUsage(runtime, &js); - JS_SetPropertyStr(context, result, "js_malloc_percent", JS_NewFloat64(context, 100.0f * js.malloc_size / total_memory)); - + JS_SetPropertyStr(context, result, "js_malloc_percent", JS_NewFloat64(context, 100.0f * tf_mem_get_js_malloc_size() / total_memory)); JS_SetPropertyStr(context, result, "uv_malloc_percent", JS_NewFloat64(context, 100.0f * tf_mem_get_uv_malloc_size() / total_memory)); JS_SetPropertyStr(context, result, "tls_malloc_percent", JS_NewFloat64(context, 100.0f * tf_mem_get_tls_malloc_size() / total_memory)); JS_SetPropertyStr(context, result, "tf_malloc_percent", JS_NewFloat64(context, 100.0f * tf_mem_get_tf_malloc_size() / total_memory)); @@ -1276,7 +1271,10 @@ tf_task_t* tf_task_create() tf_task_t* task = tf_malloc(sizeof(tf_task_t)); *task = (tf_task_t) { 0 }; ++_count; - task->_runtime = JS_NewRuntime(); + + JSMallocFunctions funcs = { 0 }; + tf_get_js_malloc_functions(&funcs); + task->_runtime = JS_NewRuntime2(&funcs, NULL); task->_context = JS_NewContext(task->_runtime); JS_SetContextOpaque(task->_context, task);