DUK_LOCAL void duk__mark_finalizable(duk_heap *heap) { duk_hthread *thr; duk_heaphdr *hdr; duk_size_t count_finalizable = 0; DUK_DD(DUK_DDPRINT("duk__mark_finalizable: %p", (void *) heap)); thr = duk__get_temp_hthread(heap); DUK_ASSERT(thr != NULL); hdr = heap->heap_allocated; while (hdr) { /* A finalizer is looked up from the object and up its prototype chain * (which allows inherited finalizers). A prototype loop must not cause * an error to be thrown here; duk_hobject_hasprop_raw() will ignore a * prototype loop silently and indicate that the property doesn't exist. */ if (!DUK_HEAPHDR_HAS_REACHABLE(hdr) && DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_OBJECT && !DUK_HEAPHDR_HAS_FINALIZED(hdr) && duk_hobject_hasprop_raw(thr, (duk_hobject *) hdr, DUK_HTHREAD_STRING_INT_FINALIZER(thr))) { /* heaphdr: * - is not reachable * - is an object * - is not a finalized object * - has a finalizer */ DUK_DD(DUK_DDPRINT("unreachable heap object will be " "finalized -> mark as finalizable " "and treat as a reachability root: %p", (void *) hdr)); DUK_ASSERT(!DUK_HEAPHDR_HAS_READONLY(hdr)); DUK_HEAPHDR_SET_FINALIZABLE(hdr); count_finalizable ++; } hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); } if (count_finalizable == 0) { return; } DUK_DD(DUK_DDPRINT("marked %ld heap objects as finalizable, now mark them reachable", (long) count_finalizable)); hdr = heap->heap_allocated; while (hdr) { if (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) { duk__mark_heaphdr(heap, hdr); } hdr = DUK_HEAPHDR_GET_NEXT(heap, hdr); } /* Caller will finish the marking process if we hit a recursion limit. */ }
static void duk__mark_finalizable(duk_heap *heap) { duk_hthread *thr; duk_heaphdr *hdr; int count_finalizable = 0; DUK_DD(DUK_DDPRINT("duk__mark_finalizable: %p", (void *) heap)); thr = duk__get_temp_hthread(heap); DUK_ASSERT(thr != NULL); hdr = heap->heap_allocated; while (hdr) { /* A finalizer is looked up from the object and up its prototype chain * (which allows inherited finalizers). */ if (!DUK_HEAPHDR_HAS_REACHABLE(hdr) && DUK_HEAPHDR_GET_TYPE(hdr) == DUK_HTYPE_OBJECT && !DUK_HEAPHDR_HAS_FINALIZED(hdr) && duk_hobject_hasprop_raw(thr, (duk_hobject *) hdr, DUK_HTHREAD_STRING_INT_FINALIZER(thr))) { /* heaphdr: * - is not reachable * - is an object * - is not a finalized object * - has a finalizer */ DUK_DD(DUK_DDPRINT("unreachable heap object will be finalized -> mark as finalizable and treat as a reachability root: %p", hdr)); DUK_HEAPHDR_SET_FINALIZABLE(hdr); count_finalizable ++; } hdr = DUK_HEAPHDR_GET_NEXT(hdr); } if (count_finalizable == 0) { return; } DUK_DD(DUK_DDPRINT("marked %d heap objects as finalizable, now mark them reachable", count_finalizable)); hdr = heap->heap_allocated; while (hdr) { if (DUK_HEAPHDR_HAS_FINALIZABLE(hdr)) { duk__mark_heaphdr(heap, hdr); } hdr = DUK_HEAPHDR_GET_NEXT(hdr); } /* Caller will finish the marking process if we hit a recursion limit. */ }