本文整理汇总了C++中DUK_D函数的典型用法代码示例。如果您正苦于以下问题:C++ DUK_D函数的具体用法?C++ DUK_D怎么用?C++ DUK_D使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了DUK_D函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: duk_selftest_run_tests
DUK_INTERNAL duk_uint_t duk_selftest_run_tests(duk_alloc_function alloc_func,
duk_realloc_function realloc_func,
duk_free_function free_func,
void *udata) {
duk_uint_t error_count = 0;
DUK_D(DUK_DPRINT("self test starting"));
error_count += duk__selftest_types();
error_count += duk__selftest_packed_tval();
error_count += duk__selftest_twos_complement();
error_count += duk__selftest_byte_order();
error_count += duk__selftest_bswap_macros();
error_count += duk__selftest_double_union_size();
error_count += duk__selftest_double_aliasing();
error_count += duk__selftest_double_zero_sign();
error_count += duk__selftest_double_rounding();
error_count += duk__selftest_struct_align();
error_count += duk__selftest_64bit_arithmetic();
error_count += duk__selftest_cast_double_to_small_uint();
error_count += duk__selftest_cast_double_to_uint32();
error_count += duk__selftest_alloc_funcs(alloc_func, realloc_func, free_func, udata);
DUK_D(DUK_DPRINT("self test complete, total error count: %ld", (long) error_count));
return error_count;
}
示例2: duk_debug_dump_callstack
void duk_debug_dump_callstack(duk_hthread *thr) {
duk_uint_fast32_t i;
DUK_D(DUK_DPRINT("=== hthread %p callstack: %d entries ===",
(void *) thr,
(thr == NULL ? 0 : thr->callstack_top)));
if (!thr) {
return;
}
for (i = 0; i < thr->callstack_top; i++) {
duk_activation *act = &thr->callstack[i];
duk_tval *this_binding = NULL;
this_binding = thr->valstack + act->idx_bottom - 1;
if (this_binding < thr->valstack || this_binding >= thr->valstack_top) {
this_binding = NULL;
}
DUK_D(DUK_DPRINT(" [%d] -> flags=0x%08x, func=%!O, var_env=%!iO, lex_env=%!iO, pc=%d, idx_bottom=%d, idx_retval=%d, this_binding=%!T",
i,
act->flags,
(duk_heaphdr *) act->func,
(duk_heaphdr *) act->var_env,
(duk_heaphdr *) act->lex_env,
act->pc,
act->idx_bottom,
act->idx_retval,
this_binding));
}
}
示例3: duk__run_object_finalizers
DUK_LOCAL void duk__run_object_finalizers(duk_heap *heap, duk_small_uint_t flags) {
duk_heaphdr *curr;
duk_heaphdr *next;
#if defined(DUK_USE_DEBUG)
duk_size_t count = 0;
#endif
duk_hthread *thr;
DUK_DD(DUK_DDPRINT("duk__run_object_finalizers: %p", (void *) heap));
thr = duk__get_temp_hthread(heap);
DUK_ASSERT(thr != NULL);
curr = heap->finalize_list;
while (curr) {
DUK_DDD(DUK_DDDPRINT("mark-and-sweep finalize: %p", (void *) curr));
DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(curr) == DUK_HTYPE_OBJECT); /* only objects have finalizers */
DUK_ASSERT(!DUK_HEAPHDR_HAS_REACHABLE(curr)); /* flags have been already cleared */
DUK_ASSERT(!DUK_HEAPHDR_HAS_TEMPROOT(curr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZABLE(curr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(curr)); /* No finalizers for ROM objects */
if (DUK_LIKELY((flags & DUK_MS_FLAG_SKIP_FINALIZERS) == 0)) {
/* Run the finalizer, duk_hobject_run_finalizer() sets FINALIZED.
* Next mark-and-sweep will collect the object unless it has
* become reachable (i.e. rescued). FINALIZED prevents the
* finalizer from being executed again before that.
*/
duk_hobject_run_finalizer(thr, (duk_hobject *) curr); /* must never longjmp */
DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(curr));
} else {
/* Used during heap destruction: don't actually run finalizers
* because we're heading into forced finalization. Instead,
* queue finalizable objects back to the heap_allocated list.
*/
DUK_D(DUK_DPRINT("skip finalizers flag set, queue object to heap_allocated without finalizing"));
DUK_ASSERT(!DUK_HEAPHDR_HAS_FINALIZED(curr));
}
/* queue back to heap_allocated */
next = DUK_HEAPHDR_GET_NEXT(heap, curr);
DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap, curr);
curr = next;
#if defined(DUK_USE_DEBUG)
count++;
#endif
}
/* finalize_list will always be processed completely */
heap->finalize_list = NULL;
#if defined(DUK_USE_DEBUG)
DUK_D(DUK_DPRINT("mark-and-sweep finalize objects: %ld finalizers called", (long) count));
#endif
}
示例4: duk_hobject_run_finalizer
DUK_INTERNAL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj) {
duk_context *ctx = (duk_context *) thr;
duk_ret_t rc;
#if defined(DUK_USE_ASSERTIONS)
duk_idx_t entry_top;
#endif
DUK_DDD(DUK_DDDPRINT("running object finalizer for object: %p", (void *) obj));
DUK_ASSERT(thr != NULL);
DUK_ASSERT(ctx != NULL);
DUK_ASSERT(obj != NULL);
DUK_ASSERT_VALSTACK_SPACE(thr, 1);
#if defined(DUK_USE_ASSERTIONS)
entry_top = duk_get_top(ctx);
#endif
/*
* Get and call the finalizer. All of this must be wrapped
* in a protected call, because even getting the finalizer
* may trigger an error (getter may throw one, for instance).
*/
DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY((duk_heaphdr *) obj));
if (DUK_HEAPHDR_HAS_FINALIZED((duk_heaphdr *) obj)) {
DUK_D(DUK_DPRINT("object already finalized, avoid running finalizer twice: %!O", obj));
return;
}
DUK_HEAPHDR_SET_FINALIZED((duk_heaphdr *) obj); /* ensure never re-entered until rescue cycle complete */
if (DUK_HOBJECT_HAS_EXOTIC_PROXYOBJ(obj)) {
/* This shouldn't happen; call sites should avoid looking up
* _Finalizer "through" a Proxy, but ignore if we come here
* with a Proxy to avoid finalizer re-entry.
*/
DUK_D(DUK_DPRINT("object is a proxy, skip finalizer call"));
return;
}
/* XXX: use a NULL error handler for the finalizer call? */
DUK_DDD(DUK_DDDPRINT("-> finalizer found, calling wrapped finalize helper"));
duk_push_hobject(ctx, obj); /* this also increases refcount by one */
rc = duk_safe_call(ctx, duk__finalize_helper, NULL /*udata*/, 0 /*nargs*/, 1 /*nrets*/); /* -> [... obj retval/error] */
DUK_ASSERT_TOP(ctx, entry_top + 2); /* duk_safe_call discipline */
if (rc != DUK_EXEC_SUCCESS) {
/* Note: we ask for one return value from duk_safe_call to get this
* error debugging here.
*/
DUK_D(DUK_DPRINT("wrapped finalizer call failed for object %p (ignored); error: %!T",
(void *) obj, (duk_tval *) duk_get_tval(ctx, -1)));
}
duk_pop_2(ctx); /* -> [...] */
DUK_ASSERT_TOP(ctx, entry_top);
}
示例5: duk_err_setup_heap_ljstate
DUK_INTERNAL void duk_err_setup_heap_ljstate(duk_hthread *thr, duk_small_int_t lj_type) {
duk_tval tv_tmp;
#if defined(DUK_USE_DEBUGGER_SUPPORT)
/* If something is thrown with the debugger attached and nobody will
* catch it, execution is paused before the longjmp, turning over
* control to the debug client. This allows local state to be examined
* before the stack is unwound.
*/
/* TODO: Allow customizing the pause and notify behavior */
if (DUK_HEAP_IS_DEBUGGER_ATTACHED(thr->heap) && lj_type == DUK_LJ_TYPE_THROW) {
duk_context *ctx = (duk_context *) thr;
duk_bool_t fatal;
duk_hobject *h_obj;
/* Don't intercept a DoubleError, we may have caused the initial double
* fault and attempting to intercept it will cause us to be called
* recursively and exhaust the C stack.
*/
h_obj = duk_get_hobject(ctx, -1);
if (h_obj == thr->builtins[DUK_BIDX_DOUBLE_ERROR]) {
DUK_D(DUK_DPRINT("built-in DoubleError instance thrown, not intercepting"));
goto skip_throw_intercept;
}
DUK_D(DUK_DPRINT("throw with debugger attached, report to client"));
fatal = !duk__have_active_catcher(thr);
/* Report it to the debug client */
duk_debug_send_throw(thr, fatal);
if (fatal) {
DUK_D(DUK_DPRINT("throw will be fatal, halt before longjmp"));
duk_debug_halt_execution(thr, 1 /*use_prev_pc*/);
}
}
skip_throw_intercept:
#endif
thr->heap->lj.type = lj_type;
DUK_ASSERT(thr->valstack_top > thr->valstack);
DUK_TVAL_SET_TVAL(&tv_tmp, &thr->heap->lj.value1);
DUK_TVAL_SET_TVAL(&thr->heap->lj.value1, thr->valstack_top - 1);
DUK_TVAL_INCREF(thr, &thr->heap->lj.value1);
DUK_TVAL_DECREF(thr, &tv_tmp);
duk_pop((duk_context *) thr);
}
示例6: duk__dump_stringtable
static void duk__dump_stringtable(duk_heap *heap) {
duk_uint_fast32_t i;
char buf[64+1];
DUK_D(DUK_DPRINT("stringtable %p, used %ld, size %ld, load %ld%%",
(void *) heap->st,
(long) heap->st_used,
(long) heap->st_size,
(long) (((double) heap->st_used) / ((double) heap->st_size) * 100.0)));
for (i = 0; i < (duk_uint_fast32_t) heap->st_size; i++) {
duk_hstring *e = heap->st[i];
if (!e) {
DUK_D(DUK_DPRINT(" [%ld]: NULL", (long) i));
} else if (e == DUK_STRTAB_DELETED_MARKER(heap)) {
DUK_D(DUK_DPRINT(" [%ld]: DELETED", (long) i));
} else {
duk__sanitize_snippet(buf, sizeof(buf), e);
#ifdef DUK_USE_REFERENCE_COUNTING
DUK_D(DUK_DPRINT(" [%ld]: %p (flags: 0x%08lx, ref: %ld) '%s', strhash=0x%08lx, blen=%ld, clen=%ld, "
"arridx=%ld, internal=%ld, reserved_word=%ld, strict_reserved_word=%ld, eval_or_arguments=%ld",
(long) i,
(void *) e,
(unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) e),
(long) DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) e),
(const char *) buf,
(unsigned long) e->hash,
(long) e->blen,
(long) e->clen,
(long) (DUK_HSTRING_HAS_ARRIDX(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_INTERNAL(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_RESERVED_WORD(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(e) ? 1 : 0)));
#else
DUK_D(DUK_DPRINT(" [%ld]: %p (flags: 0x%08lx) '%s', strhash=0x%08lx, blen=%ld, clen=%ld, "
"arridx=%ld, internal=%ld, reserved_word=%ld, strict_reserved_word=%ld, eval_or_arguments=%ld",
(long) i,
(void *) e,
(unsigned long) DUK_HEAPHDR_GET_FLAGS((duk_heaphdr *) e),
(const char *) buf,
(long) e->hash,
(long) e->blen,
(long) e->clen,
(long) (DUK_HSTRING_HAS_ARRIDX(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_INTERNAL(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_RESERVED_WORD(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_STRICT_RESERVED_WORD(e) ? 1 : 0),
(long) (DUK_HSTRING_HAS_EVAL_OR_ARGUMENTS(e) ? 1 : 0)));
#endif
}
}
}
示例7: DUK_REALLOC
//.........这里部分代码省略.........
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str != NULL &&
DUK_HSTRING_GET_BYTELEN(e->u.str) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(e->u.str), (size_t) blen) == 0) {
return e->u.str;
}
} else {
DUK_ASSERT(e->u.strlist != NULL);
lst = e->u.strlist;
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] != NULL &&
DUK_HSTRING_GET_BYTELEN(lst[i]) == blen &&
DUK_MEMCMP((const void *) str, (const void *) DUK_HSTRING_GET_DATA(lst[i]), (size_t) blen) == 0) {
return lst[i];
}
}
}
return NULL;
}
#endif /* DUK_USE_HEAPPTR16 */
#if defined(DUK_USE_HEAPPTR16)
DUK_LOCAL void duk__remove_matching_hstring_chain(duk_heap *heap, duk_hstring *h) {
duk_small_uint_t slotidx;
duk_strtab_entry *e;
duk_uint16_t *lst;
duk_size_t i, n;
duk_uint16_t h16;
duk_uint16_t null16 = heap->heapptr_null16;
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
slotidx = DUK_HSTRING_GET_HASH(h) % DUK_STRTAB_CHAIN_SIZE;
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
DUK_ASSERT(h != NULL);
h16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
if (e->u.str16 == h16) {
e->u.str16 = null16;
return;
}
} else {
DUK_ASSERT(e->u.strlist16 != null16);
lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16);
DUK_ASSERT(lst != NULL);
for (i = 0, n = e->listlen; i < n; i++) {
if (lst[i] == h16) {
lst[i] = null16;
return;
}
}
}
DUK_D(DUK_DPRINT("failed to find string that should be in stringtable"));
DUK_UNREACHABLE();
return;
}
#else /* DUK_USE_HEAPPTR16 */
DUK_LOCAL void duk__remove_matching_hstring_chain(duk_heap *heap, duk_hstring *h) {
duk_small_uint_t slotidx;
duk_strtab_entry *e;
duk_hstring **lst;
duk_size_t i, n;
DUK_ASSERT(heap != NULL);
DUK_ASSERT(h != NULL);
slotidx = DUK_HSTRING_GET_HASH(h) % DUK_STRTAB_CHAIN_SIZE;
DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE);
e = heap->strtable + slotidx;
if (e->listlen == 0) {
DUK_ASSERT(h != NULL);
if (e->u.str == h) {
e->u.str = NULL;
return;
}
} else {
DUK_ASSERT(e->u.strlist != NULL);
lst = e->u.strlist;
for (i = 0, n = e->listlen; i < n; i++) {
DUK_ASSERT(h != NULL);
if (lst[i] == h) {
lst[i] = NULL;
return;
}
}
}
DUK_D(DUK_DPRINT("failed to find string that should be in stringtable"));
DUK_UNREACHABLE();
return;
}
示例8: duk__compact_objects
DUK_LOCAL void duk__compact_objects(duk_heap *heap) {
/* XXX: which lists should participate? to be finalized? */
#if defined(DUK_USE_DEBUG)
duk_size_t count_check = 0;
duk_size_t count_compact = 0;
duk_size_t count_bytes_saved = 0;
#endif
duk_hthread *thr;
DUK_DD(DUK_DDPRINT("duk__compact_objects: %p", (void *) heap));
thr = duk__get_temp_hthread(heap);
DUK_ASSERT(thr != NULL);
#if defined(DUK_USE_DEBUG)
duk__compact_object_list(heap, thr, heap->heap_allocated, &count_check, &count_compact, &count_bytes_saved);
duk__compact_object_list(heap, thr, heap->finalize_list, &count_check, &count_compact, &count_bytes_saved);
#if defined(DUK_USE_REFERENCE_COUNTING)
duk__compact_object_list(heap, thr, heap->refzero_list, &count_check, &count_compact, &count_bytes_saved);
#endif
#else
duk__compact_object_list(heap, thr, heap->heap_allocated);
duk__compact_object_list(heap, thr, heap->finalize_list);
#if defined(DUK_USE_REFERENCE_COUNTING)
duk__compact_object_list(heap, thr, heap->refzero_list);
#endif
#endif
#if defined(DUK_USE_DEBUG)
DUK_D(DUK_DPRINT("mark-and-sweep compact objects: %ld checked, %ld compaction attempts, %ld bytes saved by compaction",
(long) count_check, (long) count_compact, (long) count_bytes_saved));
#endif
}
示例9: duk__assert_valid_refcounts
DUK_LOCAL void duk__assert_valid_refcounts(duk_heap *heap) {
duk_heaphdr *hdr = heap->heap_allocated;
while (hdr) {
if (DUK_HEAPHDR_GET_REFCOUNT(hdr) == 0 &&
DUK_HEAPHDR_HAS_FINALIZED(hdr)) {
/* An object may be in heap_allocated list with a zero
* refcount if it has just been finalized and is waiting
* to be collected by the next cycle.
*/
} else if (DUK_HEAPHDR_GET_REFCOUNT(hdr) == 0) {
/* An object may be in heap_allocated list with a zero
* refcount also if it is a temporary object created by
* a finalizer; because finalization now runs inside
* mark-and-sweep, such objects will not be queued to
* refzero_list and will thus appear here with refcount
* zero.
*/
#if 0 /* this case can no longer occur because refcount is unsigned */
} else if (DUK_HEAPHDR_GET_REFCOUNT(hdr) < 0) {
DUK_D(DUK_DPRINT("invalid refcount: %ld, %p -> %!O",
(hdr != NULL ? (long) DUK_HEAPHDR_GET_REFCOUNT(hdr) : (long) 0),
(void *) hdr, (duk_heaphdr *) hdr));
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT(hdr) > 0);
#endif
}
hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr);
}
}
示例10: duk__init_heap_thread
static int duk__init_heap_thread(duk_heap *heap) {
duk_hthread *thr;
DUK_DD(DUK_DDPRINT("heap init: alloc heap thread"));
thr = duk_hthread_alloc(heap,
DUK_HOBJECT_FLAG_EXTENSIBLE |
DUK_HOBJECT_FLAG_THREAD |
DUK_HOBJECT_CLASS_AS_FLAGS(DUK_HOBJECT_CLASS_THREAD));
if (!thr) {
DUK_D(DUK_DPRINT("failed to alloc heap_thread"));
return 0;
}
thr->state = DUK_HTHREAD_STATE_INACTIVE;
thr->strs = heap->strs;
heap->heap_thread = thr;
DUK_HTHREAD_INCREF(thr, thr); /* Note: first argument not really used */
/* 'thr' is now reachable */
if (!duk_hthread_init_stacks(heap, thr)) {
return 0;
}
/* FIXME: this may now fail, and is not handled correctly */
duk_hthread_create_builtin_objects(thr);
/* default prototype (Note: 'thr' must be reachable) */
DUK_HOBJECT_SET_PROTOTYPE_UPDREF(thr, (duk_hobject *) thr, thr->builtins[DUK_BIDX_THREAD_PROTOTYPE]);
return 1;
}
示例11: duk_hthread_callstack_shrink_check
void duk_hthread_callstack_shrink_check(duk_hthread *thr) {
duk_size_t new_size;
duk_activation *p;
DUK_ASSERT(thr != NULL);
DUK_ASSERT_DISABLE(thr->callstack_top >= 0); /* avoid warning (unsigned) */
DUK_ASSERT(thr->callstack_size >= thr->callstack_top);
if (thr->callstack_size - thr->callstack_top < DUK_CALLSTACK_SHRINK_THRESHOLD) {
return;
}
new_size = thr->callstack_top + DUK_CALLSTACK_SHRINK_SPARE;
DUK_ASSERT(new_size >= thr->callstack_top);
DUK_DD(DUK_DDPRINT("shrinking callstack %d -> %d", thr->callstack_size, new_size));
/*
* Note: must use indirect variant of DUK_REALLOC() because underlying
* pointer may be changed by mark-and-sweep.
*/
/* shrink failure is not fatal */
p = (duk_activation *) DUK_REALLOC_INDIRECT(thr->heap, duk_hthread_get_callstack_ptr, (void *) thr, sizeof(duk_activation) * new_size);
if (p) {
thr->callstack = p;
thr->callstack_size = new_size;
} else {
DUK_D(DUK_DPRINT("callstack shrink failed, ignoring"));
}
/* note: any entries above the callstack top are garbage and not zeroed */
}
示例12: duk__selftest_bswap_macros
DUK_LOCAL duk_uint_t duk__selftest_bswap_macros(void) {
duk_uint_t error_count = 0;
duk_uint32_t x32;
duk_uint16_t x16;
duk_double_union du;
duk_double_t du_diff;
x16 = 0xbeefUL;
x16 = DUK_BSWAP16(x16);
if (x16 != (duk_uint16_t) 0xefbeUL) {
DUK__FAILED("DUK_BSWAP16");
}
x32 = 0xdeadbeefUL;
x32 = DUK_BSWAP32(x32);
if (x32 != (duk_uint32_t) 0xefbeaddeUL) {
DUK__FAILED("DUK_BSWAP32");
}
/* >>> struct.unpack('>d', '4000112233445566'.decode('hex'))
* (2.008366013071895,)
*/
du.uc[0] = 0x40; du.uc[1] = 0x00; du.uc[2] = 0x11; du.uc[3] = 0x22;
du.uc[4] = 0x33; du.uc[5] = 0x44; du.uc[6] = 0x55; du.uc[7] = 0x66;
DUK_DBLUNION_DOUBLE_NTOH(&du);
du_diff = du.d - 2.008366013071895;
#if 0
DUK_D(DUK_DPRINT("du_diff: %lg\n", (double) du_diff));
#endif
if (du_diff > 1e-15) {
/* Allow very small lenience because some compilers won't parse
* exact IEEE double constants (happened in matrix testing with
* Linux gcc-4.8 -m32 at least).
*/
#if 0
DUK_D(DUK_DPRINT("Result of DUK_DBLUNION_DOUBLE_NTOH: %02x %02x %02x %02x %02x %02x %02x %02x\n",
(unsigned int) du.uc[0], (unsigned int) du.uc[1],
(unsigned int) du.uc[2], (unsigned int) du.uc[3],
(unsigned int) du.uc[4], (unsigned int) du.uc[5],
(unsigned int) du.uc[6], (unsigned int) du.uc[7]));
#endif
DUK__FAILED("DUK_DBLUNION_DOUBLE_NTOH");
}
return error_count;
}
示例13: duk__mark_heaphdr
/* recursion tracking happens here only */
DUK_LOCAL void duk__mark_heaphdr(duk_heap *heap, duk_heaphdr *h) {
DUK_DDD(DUK_DDDPRINT("duk__mark_heaphdr %p, type %ld",
(void *) h,
(h != NULL ? (long) DUK_HEAPHDR_GET_TYPE(h) : (long) -1)));
if (!h) {
return;
}
#if defined(DUK_USE_ROM_OBJECTS)
if (DUK_HEAPHDR_HAS_READONLY(h)) {
DUK_DDD(DUK_DDDPRINT("readonly object %p, skip", (void *) h));
return;
}
#endif
if (DUK_HEAPHDR_HAS_REACHABLE(h)) {
DUK_DDD(DUK_DDDPRINT("already marked reachable, skip"));
return;
}
DUK_HEAPHDR_SET_REACHABLE(h);
if (heap->mark_and_sweep_recursion_depth >= DUK_USE_MARK_AND_SWEEP_RECLIMIT) {
/* log this with a normal debug level because this should be relatively rare */
DUK_D(DUK_DPRINT("mark-and-sweep recursion limit reached, marking as temproot: %p", (void *) h));
DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap);
DUK_HEAPHDR_SET_TEMPROOT(h);
return;
}
heap->mark_and_sweep_recursion_depth++;
switch (DUK_HEAPHDR_GET_TYPE(h)) {
case DUK_HTYPE_STRING:
duk__mark_hstring(heap, (duk_hstring *) h);
break;
case DUK_HTYPE_OBJECT:
duk__mark_hobject(heap, (duk_hobject *) h);
break;
case DUK_HTYPE_BUFFER:
/* nothing to mark */
break;
default:
DUK_D(DUK_DPRINT("attempt to mark heaphdr %p with invalid htype %ld", (void *) h, (long) DUK_HEAPHDR_GET_TYPE(h)));
DUK_UNREACHABLE();
}
heap->mark_and_sweep_recursion_depth--;
}
示例14: duk__sweep_stringtable
static void duk__sweep_stringtable(duk_heap *heap, duk_size_t *out_count_keep) {
duk_hstring *h;
duk_uint_fast32_t i;
#ifdef DUK_USE_DEBUG
duk_size_t count_free = 0;
#endif
duk_size_t count_keep = 0;
DUK_DD(DUK_DDPRINT("duk__sweep_stringtable: %p", (void *) heap));
for (i = 0; i < heap->st_size; i++) {
h = heap->st[i];
if (h == NULL || h == DUK_STRTAB_DELETED_MARKER(heap)) {
continue;
} else if (DUK_HEAPHDR_HAS_REACHABLE((duk_heaphdr *) h)) {
DUK_HEAPHDR_CLEAR_REACHABLE((duk_heaphdr *) h);
count_keep++;
continue;
}
#ifdef DUK_USE_DEBUG
count_free++;
#endif
#if defined(DUK_USE_REFERENCE_COUNTING)
/* Non-zero refcounts should not happen for unreachable strings,
* because we refcount finalize all unreachable objects which
* should have decreased unreachable string refcounts to zero
* (even for cycles).
*/
DUK_ASSERT(DUK_HEAPHDR_GET_REFCOUNT((duk_heaphdr *) h) == 0);
#endif
DUK_DDD(DUK_DDDPRINT("sweep string, not reachable: %p", (void *) h));
/* deal with weak references first */
duk_heap_strcache_string_remove(heap, (duk_hstring *) h);
/* remove the string (mark DELETED), could also call
* duk_heap_string_remove() but that would be slow and
* pointless because we already know the slot.
*/
heap->st[i] = DUK_STRTAB_DELETED_MARKER(heap);
/* then free */
#if 1
DUK_FREE(heap, (duk_heaphdr *) h); /* no inner refs/allocs, just free directly */
#else
duk_heap_free_heaphdr_raw(heap, (duk_heaphdr *) h); /* this would be OK but unnecessary */
#endif
}
#ifdef DUK_USE_DEBUG
DUK_D(DUK_DPRINT("mark-and-sweep sweep stringtable: %d freed, %d kept",
(int) count_free, (int) count_keep));
#endif
*out_count_keep = count_keep;
}
示例15: duk__dump_indented
static void duk__dump_indented(duk_heaphdr *obj, int index) {
#ifdef DUK_USE_REFERENCE_COUNTING
DUK_D(DUK_DPRINT(" [%ld]: %p %s (flags: 0x%08lx, ref: %ld) -> %!O",
(long) index,
(void *) obj,
(const char *) duk__get_heap_type_string(obj),
(unsigned long) DUK_HEAPHDR_GET_FLAGS(obj),
(long) DUK_HEAPHDR_GET_REFCOUNT(obj),
(duk_heaphdr *) obj));
#else
DUK_D(DUK_DPRINT(" [%ld]: %p %s (flags: 0x%08lx) -> %!O",
(long) index,
(void *) obj,
(const char *) duk__get_heap_type_string(obj),
(unsigned long) DUK_HEAPHDR_GET_FLAGS(obj),
(duk_heaphdr *) obj));
#endif
}