git stack info

This commit is contained in:
2025-02-08 17:13:46 -06:00
parent 94bb2ed5d3
commit c0a398b732
2 changed files with 78 additions and 1 deletions

View File

@@ -6213,6 +6213,66 @@ struct gc_object {
JSAtom classname;
};
JSValue js_dump_stack_info(JSContext *ctx)
{
JSRuntime *rt = ctx->rt;
JSValue ret = JS_NewObject(ctx);
// We can do a rough usage estimate:
uintptr_t used = rt->stack_top ? (rt->stack_top - rt->stack_limit) : 0;
JS_SetPropertyStr(ctx, ret, "used", JS_NewUint32(ctx, (uint32_t)used));
JS_SetPropertyStr(ctx, ret, "maxSize", JS_NewUint32(ctx, (uint32_t)rt->stack_size));
return ret;
}
static JSValue js_dump_object_for_cycle(JSContext *ctx, JSObject *p) {
JSValue obj = JS_NewObject(ctx);
// For debugging, store pointer address as a string
char buf[64];
snprintf(buf, sizeof(buf), "%p", (void *)p);
JS_SetPropertyStr(ctx, obj, "addr", JS_NewString(ctx, buf));
// Class ID
JS_SetPropertyStr(ctx, obj, "class_id", JS_NewUint32(ctx, p->class_id));
// If desired, store shape pointer, etc.
if (p->shape) {
snprintf(buf, sizeof(buf), "%p", (void *)p->shape);
JS_SetPropertyStr(ctx, obj, "shape", JS_NewString(ctx, buf));
}
// Maybe also store class name (if class_id < rt->class_count)
if (p->class_id < ctx->rt->class_count) {
JSAtom cname = ctx->rt->class_array[p->class_id].class_name;
JSValue cname_val = JS_AtomToValue(ctx, cname);
JS_SetPropertyStr(ctx, obj, "class_name", cname_val);
}
return obj;
}
static JSValue build_cycle_array(JSContext *ctx, JSRuntime *rt) {
JSValue arr = JS_NewArray(ctx);
uint32_t idx = 0;
struct list_head *el;
list_for_each(el, &rt->tmp_obj_list) {
JSGCObjectHeader *p = list_entry(el, JSGCObjectHeader, link);
// We can dump whichever GC types we want:
if (p->gc_obj_type == JS_GC_OBJ_TYPE_JS_OBJECT) {
JSObject *obj = (JSObject *)p;
JSValue dump = js_dump_object_for_cycle(ctx, obj);
JS_SetPropertyUint32(ctx, arr, idx++, dump);
} else {
// For function bytecode or async function, you could create
// a smaller descriptor or skip them, if desired.
}
}
return arr;
}
static void JS_RunGCInternal(JSRuntime *rt, BOOL remove_weak_objects)
{
#ifdef TRACY_ENABLE

View File

@@ -1205,7 +1205,24 @@ JSValue js_debugger_fn_info(JSContext *ctx, JSValue fn);
JSValue js_debugger_backtrace_fns(JSContext *ctx, const uint8_t *cur_pc);
uint32_t js_debugger_stack_depth(JSContext *ctx);
JSValue js_dump_value(JSContext *ctx, JSValue v);
JSValue js_dump_object(JSContext *ctx, JSObject *p);
JSValue js_dump_object(JSContext *ctx, JSGCObjectHeader *p);
JSValue js_dump_leaks(JSContext *ctx);
JSVAlue js_dump_stack_info(JSContext *ctx);
JSValue js_get_memory_usage(JSContext *js);
JSValue js_dump_atoms(JSContext *js);
JSValue js_dump_objects(JSContext *js);
JSValue js_dump_shapes(JSContext *js);
JSValue js_get_object_class_distribution(JSContext *js);
JSValue js_get_object_type_overheads(JSContext *js);
typedef void (*js_hook)(JSContext*, JSValue);
#define JS_HOOK_CALL 0
#define JS_HOOK_RET 1
#define JS_HOOK_CYCLE 2
#define JS_HOOK_GC 3
void js_debug_sethook(JSContext *ctx, js_hook, int type);
#undef js_unlikely
#undef js_force_inline