diff --git a/archive/miniz.c b/archive/miniz.c index 2851b01e..7f0a8661 100644 --- a/archive/miniz.c +++ b/archive/miniz.c @@ -8,14 +8,14 @@ static JSClassID js_writer_class_id; static void js_reader_finalizer(JSRuntime *rt, JSValue val) { mz_zip_archive *zip = JS_GetOpaque(val, js_reader_class_id); mz_zip_reader_end(zip); - js_free_rt(rt,zip); + js_free_rt(zip); } static void js_writer_finalizer(JSRuntime *rt, JSValue val) { mz_zip_archive *zip = JS_GetOpaque(val, js_writer_class_id); mz_zip_writer_finalize_archive(zip); mz_zip_writer_end(zip); - js_free_rt(rt,zip); + js_free_rt(zip); } static JSClassDef js_reader_class = { diff --git a/debug/js.c b/debug/js.c index 2a075cd1..8e092509 100644 --- a/debug/js.c +++ b/debug/js.c @@ -2,7 +2,6 @@ JSC_CCALL(os_gc, JS_RunGC(JS_GetRuntime(js)) ) JSC_CCALL(os_mem_limit, JS_SetMemoryLimit(JS_GetRuntime(js), js2number(js,argv[0]))) -JSC_CCALL(os_gc_threshold, JS_SetGCThreshold(JS_GetRuntime(js), js2number(js,argv[0]))) JSC_CCALL(os_max_stacksize, JS_SetMaxStackSize(JS_GetRuntime(js), js2number(js,argv[0]))) // Compute the approximate size of a single JS value in memory. @@ -91,7 +90,6 @@ JSC_CCALL(js_fn_info, static const JSCFunctionListEntry js_js_funcs[] = { MIST_FUNC_DEF(os, calc_mem, 0), MIST_FUNC_DEF(os, mem_limit, 1), - MIST_FUNC_DEF(os, gc_threshold, 1), MIST_FUNC_DEF(os, max_stacksize, 1), MIST_FUNC_DEF(os, gc, 0), MIST_FUNC_DEF(os, eval, 2), diff --git a/qop.c b/qop.c index a1e6fe9a..6393bb88 100644 --- a/qop.c +++ b/qop.c @@ -8,10 +8,10 @@ static void js_qop_archive_finalizer(JSRuntime *rt, JSValue val) { qop_desc *qop = JS_GetOpaque(val, js_qop_archive_class_id); if (qop) { if (qop->hashmap) { - js_free_rt(rt, qop->hashmap); + js_free_rt(qop->hashmap); } qop_close(qop); - js_free_rt(rt, qop); + js_free_rt(qop); } } @@ -34,8 +34,8 @@ static void js_qop_writer_finalizer(JSRuntime *rt, JSValue val) { qop_writer *w = JS_GetOpaque(val, js_qop_writer_class_id); if (w) { if (w->fh) fclose(w->fh); - if (w->files) js_free_rt(rt, w->files); - js_free_rt(rt, w); + if (w->files) js_free_rt(w->files); + js_free_rt(w); } } diff --git a/source/quickjs.c b/source/quickjs.c index 3163de6e..5e1f4bd3 100644 --- a/source/quickjs.c +++ b/source/quickjs.c @@ -112,20 +112,8 @@ typedef struct JSFrame JSFrame; typedef struct JSCode JSCode; typedef struct JSVarRef JSVarRef; -/* JSGCObjectHeader - legacy header for ref counting compatibility. - With copying GC this is mostly unused but kept for layout compatibility. - All heap objects have this at offset 0, followed by mist objhdr_t at offset 8. */ -struct JSGCObjectHeader { - int ref_count; /* legacy ref count - unused with copying GC */ - uint8_t gc_obj_type; /* legacy type enum */ - uint8_t mark; /* GC mark flag */ - uint8_t pad[2]; - struct list_head link; /* link in gc_obj_list - unused with copying GC */ -}; - /* JSVarRef - variable reference for closures */ struct JSVarRef { - struct JSGCObjectHeader header; uint8_t is_detached; /* TRUE if pvalue points to value field */ uint8_t pad[7]; JSValue *pvalue; /* pointer to the value (stack or &value) */ @@ -307,20 +295,6 @@ static inline objhdr_t objhdr_set_cap56 (objhdr_t h, uint64_t cap) { return (h & 0xFF) | ((cap & OBJHDR_CAP_MASK) << OBJHDR_CAP_SHIFT); } -/* js_array_set_cap - defined after JSArray struct */ - -/* js_malloc_usable_size - with bump allocator, we don't track per-allocation size */ -static inline size_t js_malloc_usable_size (JSContext *ctx, void *ptr) { - (void)ctx; (void)ptr; - return 0; /* unknown - bump allocator doesn't track individual allocations */ -} - -typedef enum { - JS_GC_PHASE_NONE, - JS_GC_PHASE_DECREF, - JS_GC_PHASE_REMOVE_CYCLES, -} JSGCPhaseEnum; - typedef enum OPCodeEnum OPCodeEnum; /* ============================================================ @@ -353,10 +327,10 @@ static void buddy_free (BuddyAllocator *b, void *ptr, size_t size); static void buddy_destroy (BuddyAllocator *b); struct JSRuntime { - JSMallocFunctions mf; - JSMallocState malloc_state; const char *rt_info; + size_t malloc_limit; + /* Buddy allocator for actor memory blocks */ BuddyAllocator buddy; @@ -366,13 +340,6 @@ struct JSRuntime { /* see JS_SetStripInfo() */ uint8_t strip_flags; - /* Legacy GC fields - mostly unused with copying GC */ - struct list_head context_list; - struct list_head gc_obj_list; /* list of JSGCObjectHeader */ - struct list_head gc_zero_ref_count_list; - JSGCPhaseEnum gc_phase; - size_t malloc_gc_threshold; - /* Stack overflow protection */ size_t stack_size; const uint8_t *stack_top; @@ -385,8 +352,6 @@ struct JSRuntime { /* User data */ void *user_opaque; - /* Record key allocator */ - uint32_t rec_key_next; /* Interrupt handler for checking execution limits */ JSInterruptHandler *interrupt_handler; @@ -470,16 +435,6 @@ typedef struct { int is_tail_call; } VMCallInfo; -typedef enum { - JS_GC_OBJ_TYPE_RECORD, /* all objects are now records */ - JS_GC_OBJ_TYPE_FUNCTION_BYTECODE, - JS_GC_OBJ_TYPE_SHAPE, - JS_GC_OBJ_TYPE_VAR_REF, - JS_GC_OBJ_TYPE_JS_CONTEXT, - JS_GC_OBJ_TYPE_ARRAY, - JS_GC_OBJ_TYPE_FUNCTION, -} JSGCObjectTypeEnum; - static inline objhdr_t objhdr_set_s (objhdr_t h, bool s) { return s ? (h | OBJHDR_S_MASK) : (h & ~OBJHDR_S_MASK); } @@ -742,7 +697,6 @@ static JSValue js_key_new_len (JSContext *ctx, const char *str, size_t len); #define JS_INTERRUPT_COUNTER_INIT 10000 struct JSContext { - struct JSGCObjectHeader header; /* GC header for context itself */ JSRuntime *rt; struct list_head link; @@ -769,13 +723,15 @@ struct JSContext { uint16_t binary_object_count; int binary_object_size; + /* Record key allocator */ + uint32_t rec_key_next; + JSGCRef *top_gc_ref; /* used to reference temporary GC roots (stack top) */ JSGCRef *last_gc_ref; /* used to reference temporary GC roots (list) */ JSValue *class_proto; JSValue regexp_ctor; JSValue native_error_proto[JS_NATIVE_ERROR_COUNT]; - JSValue array_proto_values; JSValue throw_type_error; JSValue eval_obj; @@ -902,7 +858,7 @@ static void *st_alloc (JSContext *ctx, size_t bytes, size_t align) { /* No stone arena or not enough space - allocate a page */ size_t page_size = sizeof (StonePage) + bytes; - StonePage *page = rt->mf.js_malloc (&rt->malloc_state, page_size); + StonePage *page = malloc (page_size); if (!page) return NULL; page->next = ctx->st_pages; @@ -918,7 +874,7 @@ static void st_free_all (JSContext *ctx) { StonePage *page = ctx->st_pages; while (page) { StonePage *next = page->next; - rt->mf.js_free (&rt->malloc_state, page); + free (page); page = next; } ctx->st_pages = NULL; @@ -941,14 +897,14 @@ static int st_text_resize (JSContext *ctx) { new_resize = new_size * 3 / 4; /* 75% load factor */ /* Allocate new hash table (use runtime malloc, not bump allocator) */ - new_hash = rt->mf.js_malloc (&rt->malloc_state, new_size * sizeof (uint32_t)); + new_hash = js_malloc_rt (new_size * sizeof (uint32_t)); if (!new_hash) return -1; memset (new_hash, 0, new_size * sizeof (uint32_t)); /* Allocate new text array (one extra for 1-based indexing) */ - new_array = rt->mf.js_malloc (&rt->malloc_state, (new_size + 1) * sizeof (JSText *)); + new_array = js_malloc_rt ((new_size + 1) * sizeof (JSText *)); if (!new_array) { - rt->mf.js_free (&rt->malloc_state, new_hash); + js_free_rt(new_hash); return -1; } memset (new_array, 0, (new_size + 1) * sizeof (JSText *)); @@ -970,8 +926,8 @@ static int st_text_resize (JSContext *ctx) { } /* Free old tables */ - if (ctx->st_text_hash) rt->mf.js_free (&rt->malloc_state, ctx->st_text_hash); - if (ctx->st_text_array) rt->mf.js_free (&rt->malloc_state, ctx->st_text_array); + if (ctx->st_text_hash) js_free_rt (ctx->st_text_hash); + if (ctx->st_text_array) js_free_rt (ctx->st_text_array); ctx->st_text_hash = new_hash; ctx->st_text_array = new_array; @@ -1427,8 +1383,6 @@ static int rec_set_own (JSContext *ctx, JSRecord *rec, JSValue k, JSValue val) { Uses bump allocation. Slots are inline (flexible array member). Per memory.md: slots[0] is reserved for class_id, rec_id, and opaque. */ static JSRecord *js_new_record_class (JSContext *ctx, uint32_t initial_mask, JSClassID class_id) { - JSRuntime *rt = ctx->rt; - if (initial_mask == 0) initial_mask = JS_RECORD_INITIAL_MASK; /* Allocate record + inline slots in one bump allocation */ @@ -1449,7 +1403,7 @@ static JSRecord *js_new_record_class (JSContext *ctx, uint32_t initial_mask, JSC } /* slots[0] is reserved: store class_id (low 32) and rec_id (high 32) in key */ - uint32_t rec_id = ++rt->rec_key_next; + uint32_t rec_id = ++ctx->rec_key_next; rec->slots[0].key = (JSValue)class_id | ((JSValue)rec_id << 32); rec->slots[0].val = 0; /* opaque pointer, initially NULL */ @@ -1650,7 +1604,7 @@ JS_ThrowInternalError (JSContext *ctx, const char *fmt, ...); static __maybe_unused void JS_DumpString (JSRuntime *rt, const JSText *text); static __maybe_unused void JS_DumpObjectHeader (JSRuntime *rt); static __maybe_unused void JS_DumpObject (JSRuntime *rt, JSRecord *rec); -static __maybe_unused void JS_DumpGCObject (JSRuntime *rt, JSGCObjectHeader *p); +static __maybe_unused void JS_DumpGCObject (JSRuntime *rt, objhdr_t *p); static __maybe_unused void JS_DumpValue (JSContext *ctx, const char *str, JSValue val); static void js_dump_value_write (void *opaque, const char *buf, size_t len); static JSValue js_function_apply (JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic); @@ -1661,12 +1615,6 @@ static JSValue js_new_function (JSContext *ctx, JSFunctionKind kind); static void mark_function_children (JSRuntime *rt, JSFunction *func, JS_MarkFunc *mark_func); static void mark_function_children_decref (JSRuntime *rt, JSFunction *func); -/* Legacy GC decref - no-op with copying GC */ -static void gc_decref_child (JSRuntime *rt, JSGCObjectHeader *p) { - (void)rt; - (void)p; -} - /* Forward declarations for intrinsics (now declared in quickjs.h) */ /* Forward declaration - helper to set cap in objhdr */ @@ -1720,45 +1668,27 @@ static void free_arg_list (JSContext *ctx, JSValue *tab, uint32_t len); static JSValue *build_arg_list (JSContext *ctx, uint32_t *plen, JSValue array_arg); static BOOL js_get_fast_array (JSContext *ctx, JSValue obj, JSValue **arrpp, uint32_t *countp); static JSValue js_c_function_data_call (JSContext *ctx, JSValue func_obj, JSValue this_val, int argc, JSValue *argv); -/* With copying GC, these are no-ops since we don't track objects in a list */ -static void add_gc_object (JSRuntime *rt, struct JSGCObjectHeader *h, int type) { - (void)rt; (void)h; - h->gc_obj_type = type; -} -static void remove_gc_object (JSGCObjectHeader *h) { - (void)h; -} -static void JS_RunGCInternal (JSRuntime *rt); static JSValue js_regexp_toString (JSContext *ctx, JSValue this_val, int argc, JSValue *argv); static JSValue js_error_toString (JSContext *ctx, JSValue this_val, int argc, JSValue *argv); JSClassID js_class_id_alloc = JS_CLASS_INIT_COUNT; -static void js_trigger_gc (JSContext *ctx, size_t size) { +void *js_malloc_rt (size_t size) { + return malloc(size); } -static size_t js_malloc_usable_size_unknown (const void *ptr) { return 0; } - -void *js_malloc_rt (JSRuntime *rt, size_t size) { - return rt->mf.js_malloc (&rt->malloc_state, size); +void js_free_rt (void *ptr) { + free (ptr); } -void js_free_rt (JSRuntime *rt, void *ptr) { - rt->mf.js_free (&rt->malloc_state, ptr); +void *js_realloc_rt (void *ptr, size_t size) { + return realloc (ptr, size); } -void *js_realloc_rt (JSRuntime *rt, void *ptr, size_t size) { - return rt->mf.js_realloc (&rt->malloc_state, ptr, size); -} - -size_t js_malloc_usable_size_rt (JSRuntime *rt, const void *ptr) { - return rt->mf.js_malloc_usable_size (ptr); -} - -void *js_mallocz_rt (JSRuntime *rt, size_t size) { +void *js_mallocz_rt (size_t size) { void *ptr; - ptr = js_malloc_rt (rt, size); + ptr = js_malloc_rt (size); if (!ptr) return NULL; return memset (ptr, 0, size); } @@ -2122,8 +2052,7 @@ static size_t gc_object_size (void *ptr); /* Get size of a heap object based on its type */ static size_t gc_object_size (void *ptr) { - /* All mist objects have header at offset 8 (after JSGCObjectHeader) */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t *hdr = ptr; uint8_t type = objhdr_type (hdr); uint64_t cap = objhdr_cap56 (hdr); @@ -2166,8 +2095,7 @@ static JSValue gc_copy_value (JSContext *ctx, JSValue v, uint8_t **to_free, uint return v; } - /* Get object header (at offset 8 after JSGCObjectHeader) */ - objhdr_t *hdr_ptr = (objhdr_t *)((char *)ptr + 8); + objhdr_t *hdr_ptr = ptr; objhdr_t hdr = *hdr_ptr; /* Already forwarded? */ @@ -2196,7 +2124,7 @@ static JSValue gc_copy_value (JSContext *ctx, JSValue v, uint8_t **to_free, uint /* Scan a copied object and update its internal references */ static void gc_scan_object (JSContext *ctx, void *ptr, uint8_t **to_free, uint8_t *to_end) { - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; uint8_t type = objhdr_type (hdr); switch (type) { @@ -2261,7 +2189,6 @@ static int ctx_gc (JSContext *ctx) { ctx->regexp_ctor = gc_copy_value (ctx, ctx->regexp_ctor, &to_free, to_end); ctx->throw_type_error = gc_copy_value (ctx, ctx->throw_type_error, &to_free, to_end); ctx->eval_obj = gc_copy_value (ctx, ctx->eval_obj, &to_free, to_end); - ctx->array_proto_values = gc_copy_value (ctx, ctx->array_proto_values, &to_free, to_end); for (int i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { ctx->native_error_proto[i] = gc_copy_value (ctx, ctx->native_error_proto[i], &to_free, to_end); @@ -2322,29 +2249,12 @@ static int ctx_gc (JSContext *ctx) { return 0; } -JSRuntime *JS_NewRuntime2 (const JSMallocFunctions *mf, void *opaque) { +JSRuntime *JS_NewRuntime (void) { JSRuntime *rt; - JSMallocState ms; - memset (&ms, 0, sizeof (ms)); - ms.opaque = opaque; - ms.malloc_limit = -1; - - rt = mf->js_malloc (&ms, sizeof (JSRuntime)); + rt = malloc (sizeof (JSRuntime)); if (!rt) return NULL; memset (rt, 0, sizeof (*rt)); - rt->mf = *mf; - if (!rt->mf.js_malloc_usable_size) { - /* use dummy function if none provided */ - rt->mf.js_malloc_usable_size = js_malloc_usable_size_unknown; - } - rt->malloc_state = ms; - rt->malloc_gc_threshold = 256 * 1024; - - init_list_head (&rt->context_list); - init_list_head (&rt->gc_obj_list); - init_list_head (&rt->gc_zero_ref_count_list); - rt->gc_phase = JS_GC_PHASE_NONE; #ifdef DUMP_LEAKS init_list_head (&rt->string_list); @@ -2372,87 +2282,8 @@ void JS_SetRuntimeOpaque (JSRuntime *rt, void *opaque) { rt->user_opaque = opaque; } -/* default memory allocation functions with memory limitation */ -static size_t js_def_malloc_usable_size (const void *ptr) { -#if defined(__APPLE__) - return malloc_size (ptr); -#elif defined(_WIN32) - return _msize ((void *)ptr); -#elif defined(EMSCRIPTEN) - return 0; -#elif defined(__linux__) || defined(__GLIBC__) - return malloc_usable_size ((void *)ptr); -#else - /* change this to `return 0;` if compilation fails */ - return malloc_usable_size ((void *)ptr); -#endif -} - -static void *js_def_malloc (JSMallocState *s, size_t size) { - void *ptr; - - /* Do not allocate zero bytes: behavior is platform dependent */ - assert (size != 0); - - if (unlikely (s->malloc_size + size > s->malloc_limit)) return NULL; - - ptr = malloc (size); - if (!ptr) return NULL; - - s->malloc_count++; - s->malloc_size += js_def_malloc_usable_size (ptr) + MALLOC_OVERHEAD; - return ptr; -} - -static void js_def_free (JSMallocState *s, void *ptr) { - if (!ptr) return; - - s->malloc_count--; - s->malloc_size -= js_def_malloc_usable_size (ptr) + MALLOC_OVERHEAD; - free (ptr); -} - -static void *js_def_realloc (JSMallocState *s, void *ptr, size_t size) { - size_t old_size; - - if (!ptr) { - if (size == 0) return NULL; - return js_def_malloc (s, size); - } - old_size = js_def_malloc_usable_size (ptr); - if (size == 0) { - s->malloc_count--; - s->malloc_size -= old_size + MALLOC_OVERHEAD; - free (ptr); - return NULL; - } - if (s->malloc_size + size - old_size > s->malloc_limit) return NULL; - - ptr = realloc (ptr, size); - if (!ptr) return NULL; - - s->malloc_size += js_def_malloc_usable_size (ptr) - old_size; - return ptr; -} - -static const JSMallocFunctions def_malloc_funcs = { - js_def_malloc, - js_def_free, - js_def_realloc, - js_def_malloc_usable_size, -}; - -JSRuntime *JS_NewRuntime (void) { - return JS_NewRuntime2 (&def_malloc_funcs, NULL); -} - void JS_SetMemoryLimit (JSRuntime *rt, size_t limit) { - rt->malloc_state.malloc_limit = limit; -} - -/* use -1 to disable automatic GC */ -void JS_SetGCThreshold (JSRuntime *rt, size_t gc_threshold) { - rt->malloc_gc_threshold = gc_threshold; + rt->malloc_limit = limit; } /* Helper to call system free (for memory allocated by external libs like @@ -2491,29 +2322,13 @@ static JSText *js_alloc_string (JSContext *ctx, int max_len) { return str; } -/* Legacy mark functions - no-ops with copying GC */ -static inline void JS_MarkValueEdgeEx (JSRuntime *rt, JSValue val, JSGCObjectHeader *parent, const char *edge, uint32_t atom, int32_t prop_index) { - (void)rt; - (void)val; - (void)parent; - (void)edge; - (void)atom; - (void)prop_index; -} -static inline void JS_MarkValueEdge (JSRuntime *rt, JSValue val, JSGCObjectHeader *parent, const char *edge) { - (void)rt; - (void)val; - (void)parent; - (void)edge; -} - void JS_SetRuntimeInfo (JSRuntime *rt, const char *s) { if (rt) rt->rt_info = s; } void JS_FreeRuntime (JSRuntime *rt) { /* free the classes */ - js_free_rt (rt, rt->class_array); + js_free_rt (rt->class_array); /* Destroy buddy allocator */ buddy_destroy (&rt->buddy); @@ -2524,20 +2339,19 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) { JSContext *ctx; int i; - ctx = js_mallocz_rt (rt, sizeof (JSContext)); + ctx = js_mallocz_rt (sizeof (JSContext)); if (!ctx) return NULL; - ctx->header.ref_count = 1; ctx->trace_hook = NULL; ctx->class_proto - = js_malloc_rt (rt, sizeof (ctx->class_proto[0]) * rt->class_count); + = js_malloc_rt (sizeof (ctx->class_proto[0]) * rt->class_count); if (!ctx->class_proto) { - js_free_rt (rt, ctx); + js_free_rt (ctx); return NULL; } ctx->rt = rt; - list_add_tail (&ctx->link, &rt->context_list); + for (i = 0; i < rt->class_count; i++) ctx->class_proto[i] = JS_NULL; @@ -2546,21 +2360,21 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) { /* Initialize VM stacks for trampoline */ ctx->frame_stack_capacity = 512; ctx->frame_stack - = js_malloc_rt (rt, sizeof (struct VMFrame) * ctx->frame_stack_capacity); + = js_malloc_rt (sizeof (struct VMFrame) * ctx->frame_stack_capacity); if (!ctx->frame_stack) { - js_free_rt (rt, ctx->class_proto); - js_free_rt (rt, ctx); + js_free_rt (ctx->class_proto); + js_free_rt (ctx); return NULL; } ctx->frame_stack_top = -1; ctx->value_stack_capacity = 65536; /* 64K JSValue slots */ ctx->value_stack - = js_malloc_rt (rt, sizeof (JSValue) * ctx->value_stack_capacity); + = js_malloc_rt (sizeof (JSValue) * ctx->value_stack_capacity); if (!ctx->value_stack) { - js_free_rt (rt, ctx->frame_stack); - js_free_rt (rt, ctx->class_proto); - js_free_rt (rt, ctx); + js_free_rt (ctx->frame_stack); + js_free_rt (ctx->class_proto); + js_free_rt (ctx); return NULL; } ctx->value_stack_top = 0; @@ -2573,10 +2387,10 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) { ctx->st_text_size = 0; ctx->st_text_resize = 0; if (st_text_resize (ctx) < 0) { - js_free_rt (rt, ctx->value_stack); - js_free_rt (rt, ctx->frame_stack); - js_free_rt (rt, ctx->class_proto); - js_free_rt (rt, ctx); + js_free_rt (ctx->value_stack); + js_free_rt (ctx->frame_stack); + js_free_rt (ctx->class_proto); + js_free_rt (ctx); return NULL; } @@ -2585,12 +2399,12 @@ JSContext *JS_NewContextRaw (JSRuntime *rt) { ctx->next_block_size = ctx->current_block_size; ctx->heap_base = buddy_alloc (&rt->buddy, ctx->current_block_size); if (!ctx->heap_base) { - js_free_rt (rt, ctx->st_text_hash); - js_free_rt (rt, ctx->st_text_array); - js_free_rt (rt, ctx->value_stack); - js_free_rt (rt, ctx->frame_stack); - js_free_rt (rt, ctx->class_proto); - js_free_rt (rt, ctx); + js_free_rt (ctx->st_text_hash); + js_free_rt (ctx->st_text_array); + js_free_rt (ctx->value_stack); + js_free_rt (ctx->frame_stack); + js_free_rt (ctx->class_proto); + js_free_rt (ctx); return NULL; } ctx->heap_free = ctx->heap_base; @@ -2640,11 +2454,6 @@ JSValue JS_GetClassProto (JSContext *ctx, JSClassID class_id) { return ctx->class_proto[class_id]; } -JSContext *JS_DupContext (JSContext *ctx) { - ctx->header.ref_count++; - return ctx; -} - /* used by the GC */ static void JS_MarkContext (JSRuntime *rt, JSContext *ctx, JS_MarkFunc *mark_func) { int i; @@ -2655,7 +2464,6 @@ static void JS_MarkContext (JSRuntime *rt, JSContext *ctx, JS_MarkFunc *mark_fun JS_MarkValue (rt, ctx->throw_type_error, mark_func); JS_MarkValue (rt, ctx->eval_obj, mark_func); - JS_MarkValue (rt, ctx->array_proto_values, mark_func); for (i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { JS_MarkValue (rt, ctx->native_error_proto[i], mark_func); } @@ -2669,22 +2477,6 @@ void JS_FreeContext (JSContext *ctx) { JSRuntime *rt = ctx->rt; int i; - if (--ctx->header.ref_count > 0) return; - assert (ctx->header.ref_count == 0); - -#ifdef DUMP_OBJECTS - { - struct list_head *el; - JSGCObjectHeader *p; - printf ("JSRecords: {\n"); - JS_DumpObjectHeader (ctx->rt); - list_for_each (el, &rt->gc_obj_list) { - p = list_entry (el, JSGCObjectHeader, link); - JS_DumpGCObject (rt, p); - } - printf ("}\n"); - } -#endif #ifdef DUMP_MEM { JSMemoryUsage stats; @@ -2693,22 +2485,20 @@ void JS_FreeContext (JSContext *ctx) { } #endif - - for (i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { } for (i = 0; i < rt->class_count; i++) { } - js_free_rt (rt, ctx->class_proto); + js_free_rt (ctx->class_proto); /* Free VM stacks */ - if (ctx->frame_stack) js_free_rt (rt, ctx->frame_stack); - if (ctx->value_stack) js_free_rt (rt, ctx->value_stack); + if (ctx->frame_stack) js_free_rt (ctx->frame_stack); + if (ctx->value_stack) js_free_rt (ctx->value_stack); /* Free stone arena and intern table */ st_free_all (ctx); - js_free_rt (rt, ctx->st_text_hash); - js_free_rt (rt, ctx->st_text_array); + js_free_rt (ctx->st_text_hash); + js_free_rt (ctx->st_text_array); /* Free heap block back to buddy allocator */ if (ctx->heap_base) { @@ -2717,10 +2507,6 @@ void JS_FreeContext (JSContext *ctx) { ctx->heap_free = NULL; ctx->heap_end = NULL; } - - list_del (&ctx->link); - remove_gc_object (&ctx->header); - js_free_rt (ctx->rt, ctx); } JSRuntime *JS_GetRuntime (JSContext *ctx) { return ctx->rt; } @@ -2849,19 +2635,9 @@ static int JS_NewClass1 (JSRuntime *rt, JSClassID class_id, const JSClassDef *cl new_size = max_int (JS_CLASS_INIT_COUNT, max_int (class_id + 1, rt->class_count * 3 / 2)); - /* reallocate the context class prototype array, if any */ - list_for_each (el, &rt->context_list) { - JSContext *ctx = list_entry (el, JSContext, link); - JSValue *new_tab; - new_tab = js_realloc_rt (rt, ctx->class_proto, sizeof (ctx->class_proto[0]) * new_size); - if (!new_tab) return -1; - for (i = rt->class_count; i < new_size; i++) - new_tab[i] = JS_NULL; - ctx->class_proto = new_tab; - } /* reallocate the class array */ new_class_array - = js_realloc_rt (rt, rt->class_array, sizeof (JSClass) * new_size); + = js_realloc_rt (rt->class_array, sizeof (JSClass) * new_size); if (!new_class_array) return -1; memset (new_class_array + rt->class_count, 0, (new_size - rt->class_count) * sizeof (JSClass)); rt->class_array = new_class_array; @@ -3079,7 +2855,7 @@ static JSValue pretext_end (JSContext *ctx, JSText *s) { if (len < cap) { /* Try to shrink, but OK if realloc fails */ size_t new_size = sizeof (JSText) + ((len + 1) / 2) * sizeof (uint64_t); - JSText *new_str = js_realloc_rt (ctx->rt, s, new_size); + JSText *new_str = js_realloc_rt (s, new_size); if (new_str) s = new_str; } #ifdef DUMP_LEAKS @@ -3277,10 +3053,10 @@ static JSValue JS_ConcatString1 (JSContext *ctx, const JSText *p1, const JSText return JS_MKPTR (p); } +// TODO: this function is fucked. static BOOL JS_ConcatStringInPlace (JSContext *ctx, JSText *p1, JSValue op2) { if (JS_VALUE_GET_TAG (op2) == JS_TAG_STRING) { JSText *p2 = JS_VALUE_GET_STRING (op2); - size_t size1; int64_t new_len; size_t words_needed; int64_t len1 = JSText_len (p1); @@ -3291,16 +3067,13 @@ static BOOL JS_ConcatStringInPlace (JSContext *ctx, JSText *p1, JSValue op2) { new_len = len1 + len2; /* UTF-32: 2 chars per 64-bit word, round up */ words_needed = (new_len + 1) / 2; - size1 = js_malloc_usable_size (ctx, p1); - if (size1 >= sizeof (*p1) + words_needed * sizeof (uint64_t)) { - /* Append p2's characters using string_put/string_get */ - for (int64_t i = 0; i < len2; i++) { - string_put (p1, len1 + i, string_get (p2, i)); - } - objhdr_set_cap56 (&p1->hdr, new_len); - return TRUE; + /* Append p2's characters using string_put/string_get */ + for (int64_t i = 0; i < len2; i++) { + string_put (p1, len1 + i, string_get (p2, i)); } + objhdr_set_cap56 (&p1->hdr, new_len); + return TRUE; } return FALSE; } @@ -3501,7 +3274,7 @@ static JSValue JS_NewCFunction3 (JSContext *ctx, JSCFunction *func, const char * func_obj = js_new_function (ctx, JS_FUNC_KIND_C); if (JS_IsException (func_obj)) return func_obj; f = JS_VALUE_GET_FUNCTION (func_obj); - f->u.cfunc.realm = JS_DupContext (ctx); + f->u.cfunc.realm = ctx; f->u.cfunc.c_function.generic = func; f->u.cfunc.cproto = cproto; f->u.cfunc.magic = magic; @@ -3662,90 +3435,6 @@ static JSValue js_new_function (JSContext *ctx, JSFunctionKind kind) { return JS_MKPTR (func); } -static void mark_function_children (JSRuntime *rt, JSFunction *func, JS_MarkFunc *mark_func) { - switch (func->kind) { - case JS_FUNC_KIND_C: - if (func->u.cfunc.realm) mark_func (rt, &func->u.cfunc.realm->header); - break; - case JS_FUNC_KIND_BYTECODE: - if (func->u.func.function_bytecode) { - JSFunctionBytecode *b = func->u.func.function_bytecode; - if (func->u.func.var_refs) { - for (int i = 0; i < b->closure_var_count; i++) { - JSVarRef *var_ref = func->u.func.var_refs[i]; - if (var_ref) { mark_func (rt, &var_ref->header); } - } - } - JS_MarkValue (rt, JS_MKPTR (b), mark_func); - } - break; - case JS_FUNC_KIND_BOUND: - if (func->u.bound_function) { - JSBoundFunction *bf = func->u.bound_function; - JS_MarkValue (rt, bf->func_obj, mark_func); - JS_MarkValue (rt, bf->this_val, mark_func); - for (int i = 0; i < bf->argc; i++) { - JS_MarkValue (rt, bf->argv[i], mark_func); - } - } - break; - case JS_FUNC_KIND_C_DATA: - if (func->u.c_function_data_record) { - JSCFunctionDataRecord *s = func->u.c_function_data_record; - for (int i = 0; i < s->data_len; i++) { - JS_MarkValue (rt, s->data[i], mark_func); - } - } - break; - default: - break; - } -} - -static void mark_function_children_decref (JSRuntime *rt, JSFunction *func) { - switch (func->kind) { - case JS_FUNC_KIND_C: - if (func->u.cfunc.realm) { - gc_decref_child (rt, &func->u.cfunc.realm->header); - } - break; - case JS_FUNC_KIND_BYTECODE: - if (func->u.func.function_bytecode) { - JSFunctionBytecode *b = func->u.func.function_bytecode; - if (func->u.func.var_refs) { - for (int i = 0; i < b->closure_var_count; i++) { - JSVarRef *var_ref = func->u.func.var_refs[i]; - if (var_ref) { - gc_decref_child (rt, &var_ref->header); - } - } - } - JS_MarkValueEdge (rt, JS_MKPTR (b), &func->header, "func.bytecode"); - } - break; - case JS_FUNC_KIND_BOUND: - if (func->u.bound_function) { - JSBoundFunction *bf = func->u.bound_function; - JS_MarkValueEdge (rt, bf->func_obj, &func->header, "func.bound.func_obj"); - JS_MarkValueEdge (rt, bf->this_val, &func->header, "func.bound.this_val"); - for (int i = 0; i < bf->argc; i++) { - JS_MarkValueEdge (rt, bf->argv[i], &func->header, "func.bound.argv"); - } - } - break; - case JS_FUNC_KIND_C_DATA: - if (func->u.c_function_data_record) { - JSCFunctionDataRecord *s = func->u.c_function_data_record; - for (int i = 0; i < s->data_len; i++) { - JS_MarkValueEdge (rt, s->data[i], &func->header, "func.cdata"); - } - } - break; - default: - break; - } -} - /* Compute memory used by various object types */ /* XXX: poor man's approach to handling multiply referenced objects */ typedef struct JSMemoryUsage_helper { @@ -3817,172 +3506,9 @@ static void compute_value_size (JSValue val, JSMemoryUsage_helper *hp) { } void JS_ComputeMemoryUsage (JSRuntime *rt, JSMemoryUsage *s) { - struct list_head *el; - JSMemoryUsage_helper mem = { 0 }, *hp = &mem; - - memset (s, 0, sizeof (*s)); - s->malloc_count = rt->malloc_state.malloc_count; - s->malloc_size = rt->malloc_state.malloc_size; - s->malloc_limit = rt->malloc_state.malloc_limit; - - s->memory_used_count = 2; /* rt + rt->class_array */ - s->memory_used_size - = sizeof (JSRuntime) + sizeof (JSValue) * rt->class_count; - - list_for_each (el, &rt->context_list) { - JSContext *ctx = list_entry (el, JSContext, link); - s->memory_used_count += 2; /* ctx + ctx->class_proto */ - s->memory_used_size - += sizeof (JSContext) + sizeof (JSValue) * rt->class_count; - s->binary_object_count += ctx->binary_object_count; - s->binary_object_size += ctx->binary_object_size; - } - - list_for_each (el, &rt->gc_obj_list) { - JSGCObjectHeader *gp = list_entry (el, JSGCObjectHeader, link); - - /* XXX: could count the other GC object types too */ - if (gp->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE) { - compute_bytecode_size ((JSFunctionBytecode *)gp, hp); - continue; - } else if (gp->gc_obj_type == JS_GC_OBJ_TYPE_RECORD) { - /* Count record properties */ - JSRecord *rec = (JSRecord *)gp; - uint32_t mask = (uint32_t)objhdr_cap56 (rec->mist_hdr); - s->obj_count++; - s->prop_count += rec->len; - /* Estimate record table size */ - s->prop_size += (mask + 1) * sizeof (JSRecordEntry); - /* Class-specific stats - use REC_GET_CLASS_ID and REC_GET_OPAQUE */ - switch (REC_GET_CLASS_ID(rec)) { - case JS_CLASS_REGEXP: /* regexp data stored separately, not in slots[0] */ - /* TODO: regexp pattern/bytecode tracking needs rework for new layout */ - break; - default: - /* Check if opaque data exists */ - if (REC_GET_OPAQUE(rec)) { s->memory_used_count += 1; } - break; - } - continue; - } - } - s->obj_size += s->obj_count * sizeof (JSRecord); - - /* shapes removed - just zero out the stats */ - s->shape_count = 0; - s->shape_size = 0; - - s->str_count = round (mem.str_count); - s->str_size = round (mem.str_size); - s->js_func_count = mem.js_func_count; - s->js_func_size = round (mem.js_func_size); - s->js_func_code_size = mem.js_func_code_size; - s->js_func_pc2line_count = mem.js_func_pc2line_count; - s->js_func_pc2line_size = mem.js_func_pc2line_size; - s->memory_used_count += round (mem.memory_used_count) + s->str_count - + s->obj_count + s->js_func_count - + s->js_func_pc2line_count; - s->memory_used_size += s->str_size + s->obj_size + s->prop_size - + s->js_func_size + s->js_func_code_size - + s->js_func_pc2line_size; } void JS_DumpMemoryUsage (FILE *fp, const JSMemoryUsage *s, JSRuntime *rt) { -// fprintf(fp, "QuickJS memory usage -- " CONFIG_VERSION " version, %d-bit, -// malloc limit: %"PRId64"\n\n", -// (int)sizeof(void *) * 8, s->malloc_limit); -#if 1 - if (rt) { - static const struct { - const char *name; - size_t size; - } object_types[] = { - { "JSRuntime", sizeof (JSRuntime) }, - { "JSContext", sizeof (JSContext) }, - { "JSRecord", sizeof (JSRecord) }, - { "JSText", sizeof (JSText) }, - { "JSFunctionBytecode", sizeof (JSFunctionBytecode) }, - }; - int i, usage_size_ok = 0; - for (i = 0; i < countof (object_types); i++) { - unsigned int size = object_types[i].size; - void *p = js_malloc_rt (rt, size); - if (p) { - unsigned int size1 = js_malloc_usable_size_rt (rt, p); - if (size1 >= size) { - usage_size_ok = 1; - fprintf (fp, " %3u + %-2u %s\n", size, size1 - size, object_types[i].name); - } - js_free_rt (rt, p); - } - } - if (!usage_size_ok) { fprintf (fp, " malloc_usable_size unavailable\n"); } - { - int obj_classes[JS_CLASS_INIT_COUNT + 1] = { 0 }; - int class_id; - struct list_head *el; - list_for_each (el, &rt->gc_obj_list) { - JSGCObjectHeader *gp = list_entry (el, JSGCObjectHeader, link); - if (gp->gc_obj_type == JS_GC_OBJ_TYPE_RECORD) { - JSRecord *rec = (JSRecord *)gp; - obj_classes[min_uint32 (REC_GET_CLASS_ID(rec), JS_CLASS_INIT_COUNT)]++; - } - } - fprintf (fp, "\n" - "JSRecord classes\n"); - if (obj_classes[0]) - fprintf (fp, " %5d %2.0d %s\n", obj_classes[0], 0, "none"); - for (class_id = 1; class_id < JS_CLASS_INIT_COUNT; class_id++) { - if (obj_classes[class_id] && class_id < rt->class_count) { - /* class_name is now const char* directly */ - const char *name = rt->class_array[class_id].class_name; - fprintf (fp, " %5d %2.0d %s\n", obj_classes[class_id], class_id, name ? name : "?"); - } - } - if (obj_classes[JS_CLASS_INIT_COUNT]) - fprintf (fp, " %5d %2.0d %s\n", obj_classes[JS_CLASS_INIT_COUNT], 0, "other"); - } - fprintf (fp, "\n"); - } -#endif - fprintf (fp, "%-20s %8s %8s\n", "NAME", "COUNT", "SIZE"); - - if (s->malloc_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per block)\n", "memory allocated", s->malloc_count, s->malloc_size, (double)s->malloc_size / s->malloc_count); - fprintf ( - fp, - "%-20s %8" PRId64 " %8" PRId64 " (%d overhead, %0.1f average slack)\n", - "memory used", - s->memory_used_count, - s->memory_used_size, - MALLOC_OVERHEAD, - ((double)(s->malloc_size - s->memory_used_size) / s->memory_used_count)); - } - /* atoms removed - no longer tracked */ - if (s->str_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per string)\n", "strings", s->str_count, s->str_size, (double)s->str_size / s->str_count); - } - if (s->obj_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per object)\n", "objects", s->obj_count, s->obj_size, (double)s->obj_size / s->obj_count); - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per object)\n", " properties", s->prop_count, s->prop_size, (double)s->prop_count / s->obj_count); - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per shape)\n", " shapes", s->shape_count, s->shape_size, (double)s->shape_size / s->shape_count); - } - if (s->js_func_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 "\n", "bytecode functions", s->js_func_count, s->js_func_size); - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per function)\n", " bytecode", s->js_func_count, s->js_func_code_size, (double)s->js_func_code_size / s->js_func_count); - if (s->js_func_pc2line_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 " (%0.1f per function)\n", " pc2line", s->js_func_pc2line_count, s->js_func_pc2line_size, (double)s->js_func_pc2line_size / s->js_func_pc2line_count); - } - } - if (s->c_func_count) { - fprintf (fp, "%-20s %8" PRId64 "\n", "C functions", s->c_func_count); - } - if (s->array_count) { - fprintf (fp, "%-20s %8" PRId64 "\n", "arrays", s->array_count); - } - if (s->binary_object_count) { - fprintf (fp, "%-20s %8" PRId64 " %8" PRId64 "\n", "binary objects", s->binary_object_count, s->binary_object_size); - } } JSValue JS_GetGlobalObject (JSContext *ctx) { @@ -4527,7 +4053,7 @@ static uint32_t js_string_get_length (JSValue val) { if (JS_IsPtr (val)) { void *ptr = JS_VALUE_GET_PTR (val); /* Check objhdr_t at offset 8 for type */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; if (objhdr_type (hdr) == OBJ_TEXT) { /* String (JSText or JSText) */ return (uint32_t)objhdr_cap56 (hdr); @@ -5159,8 +4685,7 @@ int JS_ToBool (JSContext *ctx, JSValue val) { /* Check for pointer types first (new tagging system) */ if (JS_IsPtr (val)) { void *ptr = JS_VALUE_GET_PTR (val); - /* Check objhdr_t at offset 8 for type */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; if (objhdr_type (hdr) == OBJ_TEXT) { /* String (JSText or JSText) - truthy if non-empty */ BOOL ret = objhdr_cap56 (hdr) != 0; @@ -5347,7 +4872,7 @@ static JSValue js_atof (JSContext *ctx, const char *str, const char **pp, int ra buf_allocated = FALSE; len = p - p_start; if (unlikely ((len + 2) > sizeof (buf1))) { - buf = js_malloc_rt (ctx->rt, len + 2); /* no exception raised */ + buf = js_malloc_rt (len + 2); /* no exception raised */ if (!buf) goto mem_error; buf_allocated = TRUE; } @@ -5384,7 +4909,7 @@ static JSValue js_atof (JSContext *ctx, const char *str, const char **pp, int ra } done: - if (buf_allocated) js_free_rt (ctx->rt, buf); + if (buf_allocated) js_free_rt (buf); if (pp) *pp = p; return val; fail: @@ -5402,8 +4927,7 @@ static JSValue JS_ToNumber (JSContext *ctx, JSValue val) { /* Handle pointer types (new tagging system) */ if (JS_IsPtr (val)) { void *ptr = JS_VALUE_GET_PTR (val); - /* Check objhdr_t at offset 8 for type */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; if (objhdr_type (hdr) == OBJ_TEXT) { /* String */ return JS_ThrowTypeError (ctx, "cannot convert text to a number"); @@ -5699,25 +5223,19 @@ static JSValue js_dtoa2 (JSContext *ctx, double d, int radix, int n_digits, int return res; } -static JSValue JS_ToStringInternal (JSContext *ctx, JSValue val, BOOL is_ToPropertyKey) { +JSValue JS_ToString (JSContext *ctx, JSValue val) { uint32_t tag; char buf[32]; /* Handle pointer types (new tagging system) */ if (JS_IsPtr (val)) { void *ptr = JS_VALUE_GET_PTR (val); - /* Check objhdr_t at offset 8 for type */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; uint8_t mist_type = objhdr_type (hdr); if (mist_type == OBJ_TEXT) { /* String - return as-is */ return val; } - /* For GC objects, check gc_obj_type */ - JSGCObjectHeader *p = (JSGCObjectHeader *)ptr; - if (p->gc_obj_type == JS_GC_OBJ_TYPE_FUNCTION_BYTECODE) { - return js_new_string8 (ctx, "[function bytecode]"); - } /* Objects (record, array, function) */ return JS_KEY_true; } @@ -5744,17 +5262,6 @@ static JSValue JS_ToStringInternal (JSContext *ctx, JSValue val, BOOL is_ToPrope } } -JSValue JS_ToString (JSContext *ctx, JSValue val) { - return JS_ToStringInternal (ctx, val, FALSE); -} - -JSValue JS_ToPropertyKey (JSContext *ctx, JSValue val) { - /* Objects are handled directly via objkey map, not through atoms */ - if (JS_IsRecord (val)) { return val; } - - return JS_ToStringInternal (ctx, val, TRUE); -} - static JSValue JS_ToStringCheckObject (JSContext *ctx, JSValue val) { uint32_t tag = JS_VALUE_GET_TAG (val); if (tag == JS_TAG_NULL) return JS_ThrowTypeError (ctx, "null is forbidden"); @@ -6038,7 +5545,7 @@ static void js_print_value (JSPrintValueState *s, JSValue val) { if (JS_IsPtr (val)) { void *ptr = JS_VALUE_GET_PTR (val); /* Check objhdr_t at offset 8 for type */ - objhdr_t hdr = *((objhdr_t *)((char *)ptr + 8)); + objhdr_t hdr = *(objhdr_t *)ptr; uint8_t mist_type = objhdr_type (hdr); if (mist_type == OBJ_TEXT) { @@ -6046,80 +5553,6 @@ static void js_print_value (JSPrintValueState *s, JSValue val) { js_print_string (s, val); return; } - - /* For GC objects, use gc_obj_type */ - JSGCObjectHeader *p = (JSGCObjectHeader *)ptr; - JSGCObjectTypeEnum obj_type = p->gc_obj_type; - - switch (obj_type) { - case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: { - JSFunctionBytecode *b = (JSFunctionBytecode *)p; - js_puts (s, "[bytecode "); - if (JS_IsText (b->func_name)) { - js_print_value (s, b->func_name); - } else { - js_puts (s, ""); - } - js_putc (s, ']'); - } break; - case JS_GC_OBJ_TYPE_FUNCTION: { - JSFunction *f = (JSFunction *)p; - js_puts (s, "[Function"); - if (JS_IsText (f->name)) { - js_putc (s, ' '); - js_print_value (s, f->name); - } else if (f->kind == JS_FUNC_KIND_BYTECODE - && f->u.func.function_bytecode) { - JSFunctionBytecode *b = f->u.func.function_bytecode; - if (JS_IsText (b->func_name)) { - js_putc (s, ' '); - js_print_value (s, b->func_name); - } - } - js_putc (s, ']'); - } break; - case JS_GC_OBJ_TYPE_ARRAY: { - JSArray *arr = (JSArray *)p; - uint32_t i, count; - js_putc (s, '['); - count = min_uint32 (arr->len, s->options.max_item_count); - for (i = 0; i < count; i++) { - if (i > 0) js_puts (s, ", "); - if (s->level < s->options.max_depth) { - s->level++; - js_print_value (s, arr->values[i]); - s->level--; - } else { - js_puts (s, "..."); - } - } - if (arr->len > count) { - js_printf (s, ", ... %u more", arr->len - count); - } - js_putc (s, ']'); - } break; - case JS_GC_OBJ_TYPE_RECORD: { - JSRecord *rec = (JSRecord *)p; - int idx; - idx = js_print_stack_index (s, rec); - if (idx >= 0) { - js_printf (s, "[circular %d]", idx); - } else if (s->level < s->options.max_depth) { - s->print_stack[s->level++] = rec; - js_print_object (s, rec); - s->level--; - } else { - const char *class_name = s->rt->class_array[REC_GET_CLASS_ID(rec)].class_name; - js_putc (s, '['); - js_puts (s, class_name ? class_name : "Object"); - if (s->options.raw_dump) { js_printf (s, " %p", (void *)rec); } - js_putc (s, ']'); - } - } break; - default: - js_printf (s, "[gc_obj_type %d]", obj_type); - break; - } return; } @@ -6232,32 +5665,22 @@ static __maybe_unused void JS_DumpObject (JSRuntime *rt, JSRecord *rec) { } static __maybe_unused void JS_DumpGCObject (JSRuntime *rt, - JSGCObjectHeader *p) { - if (p->gc_obj_type == JS_GC_OBJ_TYPE_RECORD) { + objhdr_t *p) { + if (objhdr_type (p) == OBJ_RECORD) { JS_DumpObject (rt, (JSRecord *)p); } else { - printf ("%14p %4d ", (void *)p, p->ref_count); - switch (p->gc_obj_type) { - case JS_GC_OBJ_TYPE_FUNCTION_BYTECODE: + switch (objhdr_type (p)) { + case OBJ_CODE: printf ("[function bytecode]"); break; - case JS_GC_OBJ_TYPE_SHAPE: - printf ("[shape]"); - break; - case JS_GC_OBJ_TYPE_VAR_REF: - printf ("[var_ref]"); - break; - case JS_GC_OBJ_TYPE_JS_CONTEXT: - printf ("[js_context]"); - break; - case JS_GC_OBJ_TYPE_ARRAY: + case OBJ_ARRAY: printf ("[array]"); break; - case JS_GC_OBJ_TYPE_RECORD: + case OBJ_RECORD: printf ("[record]"); break; default: - printf ("[unknown %d]", p->gc_obj_type); + printf ("[unknown %d]", objhdr_type (p)); break; } printf ("\n"); @@ -6700,7 +6123,6 @@ static JSVarRef *get_var_ref (JSContext *ctx, JSStackFrame *sf, int var_idx, BOO var_ref = js_malloc (ctx, sizeof (JSVarRef)); if (!var_ref) return NULL; /* ref_count not needed with copying GC */ - add_gc_object (ctx->rt, &var_ref->header, JS_GC_OBJ_TYPE_VAR_REF); var_ref->is_detached = FALSE; list_add_tail (&var_ref->var_ref_link, &sf->var_ref_list); var_ref->pvalue = pvalue; @@ -8159,7 +7581,7 @@ restart: goto exception; } sf->cur_pc = pc; - ret_val = JS_ToPropertyKey (ctx, sp[-1]); + ret_val = sp[-1]; // JS_ToPropertyKey (ctx, sp[-1]); // is this correct? No conversion can happen. if (JS_IsException (ret_val)) goto exception; sp[-1] = ret_val; break; @@ -8843,7 +8265,7 @@ restart: break; default: sf->cur_pc = pc; - ret_val = JS_ToPropertyKey (ctx, sp[-1]); + ret_val = sp[-1]; // JS_ToPropertyKey (ctx, sp[-1]); // is this correct? No conversion can happen. if (JS_IsException (ret_val)) goto exception; sp[-1] = ret_val; break; @@ -17266,9 +16688,7 @@ static JSValue js_create_function (JSContext *ctx, JSFunctionDef *fd) { b->is_direct_or_indirect_eval = (fd->eval_type == JS_EVAL_TYPE_DIRECT || fd->eval_type == JS_EVAL_TYPE_INDIRECT); - b->realm = JS_DupContext (ctx); - - add_gc_object (ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); + b->realm = ctx; #if defined(DUMP_BYTECODE) && (DUMP_BYTECODE & 1) if (!fd->strip_debug) { js_dump_function_bytecode (ctx, b); } @@ -18887,8 +18307,6 @@ static JSValue JS_ReadFunctionTag (BCReaderState *s) { b->cpool = (void *)((uint8_t *)b + cpool_offset); } - add_gc_object (ctx->rt, &b->header, JS_GC_OBJ_TYPE_FUNCTION_BYTECODE); - obj = JS_MKPTR (b); #ifdef DUMP_READ_OBJECT @@ -18986,7 +18404,7 @@ static JSValue JS_ReadFunctionTag (BCReaderState *s) { } bc_read_trace (s, "}\n"); } - b->realm = JS_DupContext (ctx); + b->realm = ctx; return obj; fail: return JS_EXCEPTION; @@ -19788,7 +19206,7 @@ int lre_check_timeout (void *opaque) { void *lre_realloc (void *opaque, void *ptr, size_t size) { JSContext *ctx = opaque; /* No JS exception is raised here */ - return js_realloc_rt (ctx->rt, ptr, size); + return js_realloc_rt (ptr, size); } /* Convert UTF-32 JSText to UTF-16 buffer for regex engine. @@ -24499,7 +23917,7 @@ void JS_AddIntrinsicBasicObjects (JSContext *ctx) { int i; ctx->class_proto[JS_CLASS_OBJECT] = JS_NewObjectProto (ctx, JS_NULL); - + ctx->class_proto[JS_CLASS_ERROR] = JS_NewObject (ctx); for (i = 0; i < JS_NATIVE_ERROR_COUNT; i++) { diff --git a/source/quickjs.h b/source/quickjs.h index c0280c88..5afae884 100644 --- a/source/quickjs.h +++ b/source/quickjs.h @@ -386,13 +386,11 @@ JSRuntime *JS_NewRuntime (void); /* info lifetime must exceed that of rt */ void JS_SetRuntimeInfo (JSRuntime *rt, const char *info); void JS_SetMemoryLimit (JSRuntime *rt, size_t limit); -void JS_SetGCThreshold (JSRuntime *rt, size_t gc_threshold); /* use 0 to disable maximum stack size check */ void JS_SetMaxStackSize (JSRuntime *rt, size_t stack_size); /* should be called when changing thread to update the stack top value used to check stack overflow. */ void JS_UpdateStackTop (JSRuntime *rt); -JSRuntime *JS_NewRuntime2 (const JSMallocFunctions *mf, void *opaque); void JS_FreeRuntime (JSRuntime *rt); void *JS_GetRuntimeOpaque (JSRuntime *rt); void JS_SetRuntimeOpaque (JSRuntime *rt, void *opaque); @@ -1016,10 +1014,9 @@ void js_free (JSContext *ctx, void *ptr); char *js_strdup (JSContext *ctx, const char *str); /* Runtime-level memory functions */ -void *js_malloc_rt (JSRuntime *rt, size_t size); -void *js_mallocz_rt (JSRuntime *rt, size_t size); -void js_free_rt (JSRuntime *rt, void *ptr); -size_t js_malloc_usable_size_rt (JSRuntime *rt, const void *ptr); +void *js_malloc_rt (size_t size); +void *js_mallocz_rt (size_t size); +void js_free_rt (void *ptr); /* Intrinsic setup functions */ void JS_AddIntrinsicBaseObjects (JSContext *ctx);