Github User Fetcher 1.0.0
C Application with Server and GUI
Loading...
Searching...
No Matches
duk_heap_refcount.c File Reference
#include "duk_internal.h"

Go to the source code of this file.

Functions

DUK_LOCAL void duk__queue_refzero (duk_heap *heap, duk_heaphdr *hdr)
 
DUK_LOCAL void duk__refcount_finalize_hobject (duk_hthread *thr, duk_hobject *h)
 
DUK_INTERNAL void duk_heaphdr_refcount_finalize (duk_hthread *thr, duk_heaphdr *hdr)
 
DUK_LOCAL void duk__refzero_free_pending (duk_hthread *thr)
 
DUK_INTERNAL void duk_heaphdr_refzero (duk_hthread *thr, duk_heaphdr *h)
 
DUK_INTERNAL void duk_tval_decref (duk_hthread *thr, duk_tval *tv)
 
DUK_INTERNAL void duk_heaphdr_decref (duk_hthread *thr, duk_heaphdr *h)
 
DUK_INTERNAL void duk_heaphdr_decref_allownull (duk_hthread *thr, duk_heaphdr *h)
 

Function Documentation

◆ duk__queue_refzero()

DUK_LOCAL void duk__queue_refzero ( duk_heap * heap,
duk_heaphdr * hdr )

Definition at line 17 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

17 {
18 /* tail insert: don't disturb head in case refzero is running */
19
20 if (heap->refzero_list != NULL) {
21 duk_heaphdr *hdr_prev;
22
23 hdr_prev = heap->refzero_list_tail;
24 DUK_ASSERT(hdr_prev != NULL);
25 DUK_ASSERT(DUK_HEAPHDR_GET_NEXT(heap, hdr_prev) == NULL);
26
27 DUK_HEAPHDR_SET_NEXT(heap, hdr, NULL);
28 DUK_HEAPHDR_SET_PREV(heap, hdr, hdr_prev);
29 DUK_HEAPHDR_SET_NEXT(heap, hdr_prev, hdr);
30 DUK_ASSERT_HEAPHDR_LINKS(heap, hdr);
31 DUK_ASSERT_HEAPHDR_LINKS(heap, hdr_prev);
32 heap->refzero_list_tail = hdr;
33 } else {
35 DUK_HEAPHDR_SET_NEXT(heap, hdr, NULL);
36 DUK_HEAPHDR_SET_PREV(heap, hdr, NULL);
37 DUK_ASSERT_HEAPHDR_LINKS(heap, hdr);
38 heap->refzero_list = hdr;
39 heap->refzero_list_tail = hdr;
40 }
41}
#define DUK_HEAPHDR_SET_NEXT(heap, h, val)
#define DUK_HEAPHDR_SET_PREV(heap, h, val)
#define DUK_HEAPHDR_GET_NEXT(heap, h)
#define DUK_ASSERT_HEAPHDR_LINKS(heap, h)
#define NULL
Definition gmacros.h:924

References DUK_ASSERT, DUK_ASSERT_HEAPHDR_LINKS, DUK_HEAPHDR_GET_NEXT, DUK_HEAPHDR_SET_NEXT, DUK_HEAPHDR_SET_PREV, NULL, duk_heap::refzero_list, and duk_heap::refzero_list_tail.

Referenced by duk_heaphdr_refzero().

◆ duk__refcount_finalize_hobject()

DUK_LOCAL void duk__refcount_finalize_hobject ( duk_hthread * thr,
duk_hobject * h )

Definition at line 57 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

57 {
59
60 DUK_ASSERT(h);
62
63 /* XXX: better to get base and walk forwards? */
64
65 for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ENEXT(h); i++) {
66 duk_hstring *key = DUK_HOBJECT_E_GET_KEY(thr->heap, h, i);
67 if (!key) {
68 continue;
69 }
70 duk_heaphdr_decref(thr, (duk_heaphdr *) key);
71 if (DUK_HOBJECT_E_SLOT_IS_ACCESSOR(thr->heap, h, i)) {
74 } else {
76 }
77 }
78
79 for (i = 0; i < (duk_uint_fast32_t) DUK_HOBJECT_GET_ASIZE(h); i++) {
81 }
82
83 /* hash part is a 'weak reference' and does not contribute */
84
86
89 duk_tval *tv, *tv_end;
90 duk_hobject **funcs, **funcs_end;
91
95 while (tv < tv_end) {
96 duk_tval_decref(thr, tv);
97 tv++;
98 }
99
101 funcs_end = DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(thr->heap, f);
102 while (funcs < funcs_end) {
104 funcs++;
105 }
106 } else {
107 /* May happen in some out-of-memory corner cases. */
108 DUK_D(DUK_DPRINT("duk_hcompiledfunction 'data' is NULL, skipping decref"));
109 }
110
112 } else if (DUK_HOBJECT_IS_NATIVEFUNCTION(h)) {
114 DUK_UNREF(f);
115 /* nothing to finalize */
116 } else if (DUK_HOBJECT_IS_BUFFEROBJECT(h)) {
118 if (b->buf) {
120 }
121 } else if (DUK_HOBJECT_IS_THREAD(h)) {
122 duk_hthread *t = (duk_hthread *) h;
123 duk_tval *tv;
124
125 tv = t->valstack;
126 while (tv < t->valstack_top) {
127 duk_tval_decref(thr, tv);
128 tv++;
129 }
130
131 for (i = 0; i < (duk_uint_fast32_t) t->callstack_top; i++) {
132 duk_activation *act = t->callstack + i;
136#ifdef DUK_USE_NONSTD_FUNC_CALLER_PROPERTY
137 duk_heaphdr_decref_allownull(thr, (duk_heaphdr *) act->prev_caller);
138#endif
139 }
140
141#if 0 /* nothing now */
142 for (i = 0; i < (duk_uint_fast32_t) t->catchstack_top; i++) {
143 duk_catcher *cat = t->catchstack + i;
144 }
145#endif
146
147 for (i = 0; i < DUK_NUM_BUILTINS; i++) {
149 }
150
152 }
153}
duk_uint32_t duk_uint_fast32_t
#define DUK_HOBJECT_A_GET_VALUE_PTR(heap, h, i)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE(heap, h)
#define DUK_HEAPHDR_GET_TYPE(h)
#define DUK_HOBJECT_GET_PROTOTYPE(heap, h)
#define DUK_HOBJECT_GET_ENEXT(h)
#define DUK_HOBJECT_E_GET_VALUE_TVAL_PTR(heap, h, i)
#define DUK_HOBJECT_IS_COMPILEDFUNCTION(h)
#define DUK_HOBJECT_E_GET_VALUE_SETTER(heap, h, i)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE(heap, h)
#define DUK_HOBJECT_E_GET_KEY(heap, h, i)
#define DUK_HOBJECT_GET_ASIZE(h)
#define DUK_HOBJECT_IS_THREAD(h)
#define DUK_HOBJECT_IS_NATIVEFUNCTION(h)
#define DUK_HCOMPILEDFUNCTION_GET_FUNCS_END(heap, h)
#define DUK_HOBJECT_IS_BUFFEROBJECT(h)
#define DUK_HOBJECT_E_SLOT_IS_ACCESSOR(heap, h, i)
#define DUK_HCOMPILEDFUNCTION_GET_DATA(heap, h)
#define DUK_ACT_GET_FUNC(act)
#define DUK_HOBJECT_E_GET_VALUE_GETTER(heap, h, i)
#define DUK_HCOMPILEDFUNCTION_GET_CONSTS_END(heap, h)
DUK_INTERNAL void duk_heaphdr_decref_allownull(duk_hthread *thr, duk_heaphdr *h)
DUK_INTERNAL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h)
DUK_INTERNAL void duk_tval_decref(duk_hthread *thr, duk_tval *tv)
static const luaL_Reg funcs[]
duk_hobject * builtins[DUK_NUM_BUILTINS]

References duk_hbufferobject::buf, duk_hthread::builtins, duk_hthread::callstack, duk_hthread::callstack_top, duk_hthread::catchstack, duk_hthread::catchstack_top, DUK_ACT_GET_FUNC, DUK_ASSERT, DUK_D, DUK_DPRINT, DUK_HCOMPILEDFUNCTION_GET_CONSTS_BASE, DUK_HCOMPILEDFUNCTION_GET_CONSTS_END, DUK_HCOMPILEDFUNCTION_GET_DATA, DUK_HCOMPILEDFUNCTION_GET_FUNCS_BASE, DUK_HCOMPILEDFUNCTION_GET_FUNCS_END, duk_heaphdr_decref(), duk_heaphdr_decref_allownull(), DUK_HEAPHDR_GET_TYPE, DUK_HOBJECT_A_GET_VALUE_PTR, DUK_HOBJECT_E_GET_KEY, DUK_HOBJECT_E_GET_VALUE_GETTER, DUK_HOBJECT_E_GET_VALUE_SETTER, DUK_HOBJECT_E_GET_VALUE_TVAL_PTR, DUK_HOBJECT_E_SLOT_IS_ACCESSOR, DUK_HOBJECT_GET_ASIZE, DUK_HOBJECT_GET_ENEXT, DUK_HOBJECT_GET_PROTOTYPE, DUK_HOBJECT_IS_BUFFEROBJECT, DUK_HOBJECT_IS_COMPILEDFUNCTION, DUK_HOBJECT_IS_NATIVEFUNCTION, DUK_HOBJECT_IS_THREAD, DUK_HTYPE_OBJECT, DUK_NUM_BUILTINS, duk_tval_decref(), DUK_UNREF, funcs, duk_hthread::heap, duk_activation::lex_env, NULL, duk_hthread::resumer, duk_hthread::valstack, and duk_activation::var_env.

Referenced by duk__refzero_free_pending(), and duk_heaphdr_refcount_finalize().

◆ duk__refzero_free_pending()

DUK_LOCAL void duk__refzero_free_pending ( duk_hthread * thr)

Definition at line 237 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

237 {
238 duk_heaphdr *h1, *h2;
239 duk_heap *heap;
240 duk_int_t count = 0;
241
242 DUK_ASSERT(thr != NULL);
243 DUK_ASSERT(thr->heap != NULL);
244 heap = thr->heap;
245 DUK_ASSERT(heap != NULL);
246
247 /*
248 * Detect recursive invocation
249 */
250
252 DUK_DDD(DUK_DDDPRINT("refzero free running, skip run"));
253 return;
254 }
255
256 /*
257 * Churn refzero_list until empty
258 */
259
261 while (heap->refzero_list) {
262 duk_hobject *obj;
263 duk_bool_t rescued = 0;
264
265 /*
266 * Pick an object from the head (don't remove yet).
267 */
268
269 h1 = heap->refzero_list;
270 obj = (duk_hobject *) h1;
271 DUK_DD(DUK_DDPRINT("refzero processing %p: %!O", (void *) h1, (duk_heaphdr *) h1));
273 DUK_ASSERT(DUK_HEAPHDR_GET_TYPE(h1) == DUK_HTYPE_OBJECT); /* currently, always the case */
274
275#if defined(DUK_USE_REFZERO_FINALIZER_TORTURE)
276 /* Torture option to shake out finalizer side effect issues:
277 * make a bogus function call for every finalizable object,
278 * essentially simulating the case where everything has a
279 * finalizer.
280 */
281 DUK_DD(DUK_DDPRINT("refzero torture enabled, fake finalizer"));
283 DUK_HEAPHDR_PREINC_REFCOUNT(h1); /* bump refcount to prevent refzero during finalizer processing */
284 duk__refcount_run_torture_finalizer(thr, obj); /* must never longjmp */
285 DUK_HEAPHDR_PREDEC_REFCOUNT(h1); /* remove artificial bump */
286 DUK_ASSERT_DISABLE(h1->h_refcount >= 0); /* refcount is unsigned, so always true */
287#endif
288
289 /*
290 * Finalizer check.
291 *
292 * Note: running a finalizer may have arbitrary side effects, e.g.
293 * queue more objects on refzero_list (tail), or even trigger a
294 * mark-and-sweep.
295 *
296 * Note: quick reject check should match vast majority of
297 * objects and must be safe (not throw any errors, ever).
298 */
299
300 /* An object may have FINALIZED here if it was finalized by mark-and-sweep
301 * on a previous run and refcount then decreased to zero. We won't run the
302 * finalizer again here.
303 */
304
305 /* A finalizer is looked up from the object and up its prototype chain
306 * (which allows inherited finalizers).
307 */
309 DUK_DDD(DUK_DDDPRINT("object has a finalizer, run it"));
310
312 DUK_HEAPHDR_PREINC_REFCOUNT(h1); /* bump refcount to prevent refzero during finalizer processing */
313
314 duk_hobject_run_finalizer(thr, obj); /* must never longjmp */
315 DUK_ASSERT(DUK_HEAPHDR_HAS_FINALIZED(h1)); /* duk_hobject_run_finalizer() sets */
316
317 DUK_HEAPHDR_PREDEC_REFCOUNT(h1); /* remove artificial bump */
318 DUK_ASSERT_DISABLE(h1->h_refcount >= 0); /* refcount is unsigned, so always true */
319
320 if (DUK_HEAPHDR_GET_REFCOUNT(h1) != 0) {
321 DUK_DDD(DUK_DDDPRINT("-> object refcount after finalization non-zero, object will be rescued"));
322 rescued = 1;
323 } else {
324 DUK_DDD(DUK_DDDPRINT("-> object refcount still zero after finalization, object will be freed"));
325 }
326 }
327
328 /* Refzero head is still the same. This is the case even if finalizer
329 * inserted more refzero objects; they are inserted to the tail.
330 */
331 DUK_ASSERT(h1 == heap->refzero_list);
332
333 /*
334 * Remove the object from the refzero list. This cannot be done
335 * before a possible finalizer has been executed; the finalizer
336 * may trigger a mark-and-sweep, and mark-and-sweep must be able
337 * to traverse a complete refzero_list.
338 */
339
340 h2 = DUK_HEAPHDR_GET_NEXT(heap, h1);
341 if (h2) {
342 DUK_HEAPHDR_SET_PREV(heap, h2, NULL); /* not strictly necessary */
343 heap->refzero_list = h2;
344 } else {
345 heap->refzero_list = NULL;
346 heap->refzero_list_tail = NULL;
347 }
348
349 /*
350 * Rescue or free.
351 */
352
353 if (rescued) {
354 /* yes -> move back to heap allocated */
355 DUK_DD(DUK_DDPRINT("object rescued during refcount finalization: %p", (void *) h1));
359 h2 = heap->heap_allocated;
360 DUK_HEAPHDR_SET_PREV(heap, h1, NULL);
361 if (h2) {
362 DUK_HEAPHDR_SET_PREV(heap, h2, h1);
363 }
364 DUK_HEAPHDR_SET_NEXT(heap, h1, h2);
365 DUK_ASSERT_HEAPHDR_LINKS(heap, h1);
366 DUK_ASSERT_HEAPHDR_LINKS(heap, h2);
367 heap->heap_allocated = h1;
368 } else {
369 /* no -> decref members, then free */
372 }
373
374 count++;
375 }
377
378 DUK_DDD(DUK_DDDPRINT("refzero processed %ld objects", (long) count));
379
380 /*
381 * Once the whole refzero cascade has been freed, check for
382 * a voluntary mark-and-sweep.
383 */
384
385#if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_VOLUNTARY_GC)
386 /* 'count' is more or less comparable to normal trigger counter update
387 * which happens in memory block (re)allocation.
388 */
389 heap->mark_and_sweep_trigger_counter -= count;
390 if (heap->mark_and_sweep_trigger_counter <= 0) {
391 duk_bool_t rc;
392 duk_small_uint_t flags = 0; /* not emergency */
393 DUK_D(DUK_DPRINT("refcount triggering mark-and-sweep"));
394 rc = duk_heap_mark_and_sweep(heap, flags);
395 DUK_UNREF(rc);
396 DUK_D(DUK_DPRINT("refcount triggered mark-and-sweep => rc %ld", (long) rc));
397 }
398#endif /* DUK_USE_MARK_AND_SWEEP && DUK_USE_VOLUNTARY_GC */
399}
unsigned int duk_small_uint_t
duk_int_fast32_t duk_int_t
duk_small_int_t duk_bool_t
#define DUK_HEAPHDR_CLEAR_FINALIZED(h)
#define DUK_HEAPHDR_GET_PREV(heap, h)
#define DUK_HEAPHDR_PREDEC_REFCOUNT(h)
#define DUK_ASSERT_DISABLE(x)
#define DUK_HEAPHDR_PREINC_REFCOUNT(h)
#define DUK_HEAPHDR_GET_REFCOUNT(h)
#define DUK_HEAP_SET_REFZERO_FREE_RUNNING(heap)
DUK_INTERNAL_DECL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags)
DUK_INTERNAL_DECL duk_bool_t duk_hobject_hasprop_raw(duk_hthread *thr, duk_hobject *obj, duk_hstring *key)
#define DUK_HEAP_HAS_REFZERO_FREE_RUNNING(heap)
#define DUK_HEAPHDR_HAS_FINALIZED(h)
#define DUK_HEAP_CLEAR_REFZERO_FREE_RUNNING(heap)
#define DUK_HEAPHDR_HAS_FINALIZABLE(h)
#define DUK_HTHREAD_STRING_INT_FINALIZER(thr)
DUK_INTERNAL_DECL void duk_hobject_run_finalizer(duk_hthread *thr, duk_hobject *obj)
DUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr)
DUK_LOCAL void duk__refcount_finalize_hobject(duk_hthread *thr, duk_hobject *h)

References duk__refcount_finalize_hobject(), DUK_ASSERT, DUK_ASSERT_DISABLE, DUK_ASSERT_HEAPHDR_LINKS, DUK_D, DUK_DD, DUK_DDD, DUK_DDDPRINT, DUK_DDPRINT, DUK_DPRINT, DUK_HEAP_CLEAR_REFZERO_FREE_RUNNING, duk_heap_free_heaphdr_raw(), DUK_HEAP_HAS_REFZERO_FREE_RUNNING, duk_heap_mark_and_sweep(), DUK_HEAP_SET_REFZERO_FREE_RUNNING, DUK_HEAPHDR_CLEAR_FINALIZED, DUK_HEAPHDR_GET_NEXT, DUK_HEAPHDR_GET_PREV, DUK_HEAPHDR_GET_REFCOUNT, DUK_HEAPHDR_GET_TYPE, DUK_HEAPHDR_HAS_FINALIZABLE, DUK_HEAPHDR_HAS_FINALIZED, DUK_HEAPHDR_PREDEC_REFCOUNT, DUK_HEAPHDR_PREINC_REFCOUNT, DUK_HEAPHDR_SET_NEXT, DUK_HEAPHDR_SET_PREV, duk_hobject_hasprop_raw(), duk_hobject_run_finalizer(), DUK_HTHREAD_STRING_INT_FINALIZER, DUK_HTYPE_OBJECT, DUK_UNREF, duk_hthread::heap, duk_heap::heap_allocated, duk_heap::mark_and_sweep_trigger_counter, NULL, duk_heap::refzero_list, and duk_heap::refzero_list_tail.

Referenced by duk_heaphdr_refzero().

◆ duk_heaphdr_decref()

DUK_INTERNAL void duk_heaphdr_decref ( duk_hthread * thr,
duk_heaphdr * h )

Definition at line 571 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

571 {
572 DUK_ASSERT(thr != NULL);
573 DUK_ASSERT(thr->heap != NULL);
574 DUK_ASSERT(h != NULL);
577
578#if defined(DUK_USE_ROM_OBJECTS)
580 return;
581 }
582#endif
583 if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {
584 return;
585 }
586 duk_heaphdr_refzero(thr, h);
587}
#define DUK_HEAPHDR_HTYPE_VALID(h)
#define DUK_HEAPHDR_HAS_READONLY(h)
DUK_INTERNAL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h)

References DUK_ASSERT, DUK_HEAPHDR_GET_REFCOUNT, DUK_HEAPHDR_HAS_READONLY, DUK_HEAPHDR_HTYPE_VALID, DUK_HEAPHDR_PREDEC_REFCOUNT, duk_heaphdr_refzero(), duk_hthread::heap, and NULL.

Referenced by duk__refcount_finalize_hobject(), and duk_tval_decref().

◆ duk_heaphdr_decref_allownull()

DUK_INTERNAL void duk_heaphdr_decref_allownull ( duk_hthread * thr,
duk_heaphdr * h )

Definition at line 589 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

589 {
590 DUK_ASSERT(thr != NULL);
591 DUK_ASSERT(thr->heap != NULL);
592
593 if (h == NULL) {
594 return;
595 }
597
598#if defined(DUK_USE_ROM_OBJECTS)
600 return;
601 }
602#endif
604 if (DUK_HEAPHDR_PREDEC_REFCOUNT(h) != 0) {
605 return;
606 }
607 duk_heaphdr_refzero(thr, h);
608}

References DUK_ASSERT, DUK_HEAPHDR_GET_REFCOUNT, DUK_HEAPHDR_HAS_READONLY, DUK_HEAPHDR_HTYPE_VALID, DUK_HEAPHDR_PREDEC_REFCOUNT, duk_heaphdr_refzero(), duk_hthread::heap, and NULL.

Referenced by duk__refcount_finalize_hobject().

◆ duk_heaphdr_refcount_finalize()

DUK_INTERNAL void duk_heaphdr_refcount_finalize ( duk_hthread * thr,
duk_heaphdr * hdr )

Definition at line 155 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

155 {
156 DUK_ASSERT(hdr);
157
158 switch ((int) DUK_HEAPHDR_GET_TYPE(hdr)) {
159 case DUK_HTYPE_OBJECT:
161 break;
162 case DUK_HTYPE_BUFFER:
163 /* nothing to finalize */
164 break;
165 case DUK_HTYPE_STRING:
166 /* cannot happen: strings are not put into refzero list (they don't even have the next/prev pointers) */
167 default:
169 }
170}

References duk__refcount_finalize_hobject(), DUK_ASSERT, DUK_HEAPHDR_GET_TYPE, DUK_HTYPE_BUFFER, DUK_HTYPE_OBJECT, DUK_HTYPE_STRING, and DUK_UNREACHABLE.

◆ duk_heaphdr_refzero()

DUK_INTERNAL void duk_heaphdr_refzero ( duk_hthread * thr,
duk_heaphdr * h )

Definition at line 409 of file duktape-1.5.2/src-separate/duk_heap_refcount.c.

409 {
410 duk_heap *heap;
411
412 DUK_ASSERT(thr != NULL);
413 DUK_ASSERT(h != NULL);
414
415 heap = thr->heap;
416 DUK_DDD(DUK_DDDPRINT("refzero %p: %!O", (void *) h, (duk_heaphdr *) h));
417
418 /*
419 * Refzero handling is skipped entirely if (1) mark-and-sweep is
420 * running or (2) execution is paused in the debugger. The objects
421 * are left in the heap, and will be freed by mark-and-sweep or
422 * eventual heap destruction.
423 *
424 * This is necessary during mark-and-sweep because refcounts are also
425 * updated during the sweep phase (otherwise objects referenced by a
426 * swept object would have incorrect refcounts) which then calls here.
427 * This could be avoided by using separate decref macros in
428 * mark-and-sweep; however, mark-and-sweep also calls finalizers which
429 * would use the ordinary decref macros anyway and still call this
430 * function.
431 *
432 * This check must be enabled also when mark-and-sweep support has been
433 * disabled: the flag is also used in heap destruction when running
434 * finalizers for remaining objects, and the flag prevents objects from
435 * being moved around in heap linked lists.
436 */
437
438 /* XXX: ideally this would be just one flag (maybe a derived one) so
439 * that a single bit test is sufficient to check the condition.
440 */
441#if defined(DUK_USE_DEBUGGER_SUPPORT)
442 if (DUK_UNLIKELY(DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap) || DUK_HEAP_IS_PAUSED(heap))) {
443#else
445#endif
446 DUK_DDD(DUK_DDDPRINT("refzero handling suppressed when mark-and-sweep running, object: %p", (void *) h));
447 return;
448 }
449
451 case DUK_HTYPE_STRING:
452 /*
453 * Strings have no internal references but do have "weak"
454 * references in the string cache. Also note that strings
455 * are not on the heap_allocated list like other heap
456 * elements.
457 */
458
462 break;
463
464 case DUK_HTYPE_OBJECT:
465 /*
466 * Objects have internal references. Must finalize through
467 * the "refzero" work list.
468 */
469
471 duk__queue_refzero(heap, h);
473 break;
474
475 case DUK_HTYPE_BUFFER:
476 /*
477 * Buffers have no internal references. However, a dynamic
478 * buffer has a separate allocation for the buffer. This is
479 * freed by duk_heap_free_heaphdr_raw().
480 */
481
484 break;
485
486 default:
487 DUK_D(DUK_DPRINT("invalid heap type in decref: %ld", (long) DUK_HEAPHDR_GET_TYPE(h)));
489 }
490}
DUK_INTERNAL_DECL void duk_heap_remove_any_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr)
#define DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap)
DUK_INTERNAL_DECL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h)
DUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h)
DUK_LOCAL void duk__queue_refzero(duk_heap *heap, duk_heaphdr *hdr)
DUK_LOCAL void duk__refzero_free_pending(duk_hthread *thr)

References duk__queue_refzero(), duk__refzero_free_pending(), DUK_ASSERT, DUK_ASSERT_DISABLE, DUK_D, DUK_DDD, DUK_DDDPRINT, DUK_DPRINT, duk_heap_free_heaphdr_raw(), DUK_HEAP_HAS_MARKANDSWEEP_RUNNING, duk_heap_remove_any_from_heap_allocated(), duk_heap_strcache_string_remove(), duk_heap_string_remove(), DUK_HEAPHDR_GET_TYPE, DUK_HEAPHDR_HTYPE_VALID, DUK_HEAPHDR_PREINC_REFCOUNT, DUK_HTYPE_BUFFER, DUK_HTYPE_OBJECT, DUK_HTYPE_STRING, DUK_INTERNAL, DUK_TVAL_GET_HEAPHDR, DUK_TVAL_NEEDS_REFCOUNT_UPDATE, DUK_UNLIKELY, DUK_UNREACHABLE, duk_heaphdr::h_refcount, duk_hthread::heap, and NULL.

Referenced by duk_heaphdr_decref(), and duk_heaphdr_decref_allownull().

◆ duk_tval_decref()