perf: Make promise stack trace collection opt-in.
Some checks failed
Build Tilde Friends / Build-All (push) Has been cancelled

This commit is contained in:
2025-02-27 19:41:21 -05:00
parent 8912212d8e
commit 8b47938238
4 changed files with 50 additions and 31 deletions

View File

@ -164,6 +164,7 @@ typedef struct _tf_task_t
promise_stack_t* _promise_stacks;
int _promise_stack_count;
bool _promise_stack_debug;
timeout_t* timeouts;
@ -1252,10 +1253,13 @@ static void _add_promise_stack(tf_task_t* task, uint32_t hash, const char* stack
static void _remove_promise_stack(tf_task_t* task, uint32_t hash)
{
promise_stack_t* found = bsearch(&hash, task->_promise_stacks, task->_promise_stack_count, sizeof(promise_stack_t), _promise_stack_compare);
if (found)
if (task->_promise_stack_debug)
{
found->count--;
promise_stack_t* found = bsearch(&hash, task->_promise_stacks, task->_promise_stack_count, sizeof(promise_stack_t), _promise_stack_compare);
if (found)
{
found->count--;
}
}
}
@ -1271,33 +1275,26 @@ static void _tf_task_free_promise(tf_task_t* task, promiseid_t id)
}
}
uint32_t fnv32a(const void* buffer, int length, uint32_t start)
{
uint32_t result = 0x811c9dc5;
for (int i = 0; i < length; i++)
{
result ^= ((const uint8_t*)buffer)[i];
result += (result << 1) + (result << 4) + (result << 7) + (result << 8) + (result << 24);
}
return result;
}
JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise)
{
JSValue error = JS_ThrowInternalError(task->_context, "promise callstack");
JSValue exception = JS_GetException(task->_context);
JSValue stack_value = JS_GetPropertyStr(task->_context, exception, "stack");
size_t length = 0;
const char* stack = JS_ToCStringLen(task->_context, &length, stack_value);
uint32_t stack_hash = fnv32a((const void*)stack, (int)length, 0);
void* buffer[32];
int count = tf_util_backtrace(buffer, sizeof(buffer) / sizeof(*buffer));
stack_hash = fnv32a((const void*)buffer, sizeof(void*) * count, stack_hash);
_add_promise_stack(task, stack_hash, stack, buffer, count);
JS_FreeCString(task->_context, stack);
JS_FreeValue(task->_context, stack_value);
JS_FreeValue(task->_context, exception);
JS_FreeValue(task->_context, error);
uint32_t stack_hash = 0;
if (task->_promise_stack_debug)
{
JSValue error = JS_ThrowInternalError(task->_context, "promise callstack");
JSValue exception = JS_GetException(task->_context);
JSValue stack_value = JS_GetPropertyStr(task->_context, exception, "stack");
size_t length = 0;
const char* stack = JS_ToCStringLen(task->_context, &length, stack_value);
stack_hash = tf_util_fnv32a((const void*)stack, (int)length, 0);
void* buffer[32];
int count = tf_util_backtrace(buffer, sizeof(buffer) / sizeof(*buffer));
stack_hash = tf_util_fnv32a((const void*)buffer, sizeof(void*) * count, stack_hash);
_add_promise_stack(task, stack_hash, stack, buffer, count);
JS_FreeCString(task->_context, stack);
JS_FreeValue(task->_context, stack_value);
JS_FreeValue(task->_context, exception);
JS_FreeValue(task->_context, error);
}
promiseid_t promiseId;
do
@ -1592,6 +1589,10 @@ tf_task_t* tf_task_create()
*task = (tf_task_t) { 0 };
++_count;
char buffer[8] = { 0 };
size_t buffer_size = sizeof(buffer);
task->_promise_stack_debug = uv_os_getenv("TF_PROMISE_DEBUG", buffer, &buffer_size) == 0 && strcmp(buffer, "1") == 0;
JSMallocFunctions funcs = { 0 };
tf_get_js_malloc_functions(&funcs);
task->_runtime = JS_NewRuntime2(&funcs, NULL);