]> git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.3.0/src-separate/duk_heap.h
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / civetweb / src / third_party / duktape-1.3.0 / src-separate / duk_heap.h
1 /*
2 * Heap structure.
3 *
4 * Heap contains allocated heap objects, interned strings, and built-in
5 * strings for one or more threads.
6 */
7
8 #ifndef DUK_HEAP_H_INCLUDED
9 #define DUK_HEAP_H_INCLUDED
10
11 /* alloc function typedefs in duktape.h */
12
13 /*
14 * Heap flags
15 */
16
17 #define DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING (1 << 0) /* mark-and-sweep is currently running */
18 #define DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED (1 << 1) /* mark-and-sweep marking reached a recursion limit and must use multi-pass marking */
19 #define DUK_HEAP_FLAG_REFZERO_FREE_RUNNING (1 << 2) /* refcount code is processing refzero list */
20 #define DUK_HEAP_FLAG_ERRHANDLER_RUNNING (1 << 3) /* an error handler (user callback to augment/replace error) is running */
21 #define DUK_HEAP_FLAG_INTERRUPT_RUNNING (1 << 4) /* executor interrupt running (used to avoid nested interrupts) */
22
23 #define DUK__HEAP_HAS_FLAGS(heap,bits) ((heap)->flags & (bits))
24 #define DUK__HEAP_SET_FLAGS(heap,bits) do { \
25 (heap)->flags |= (bits); \
26 } while (0)
27 #define DUK__HEAP_CLEAR_FLAGS(heap,bits) do { \
28 (heap)->flags &= ~(bits); \
29 } while (0)
30
31 #define DUK_HEAP_HAS_MARKANDSWEEP_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING)
32 #define DUK_HEAP_HAS_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
33 #define DUK_HEAP_HAS_REFZERO_FREE_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_REFZERO_FREE_RUNNING)
34 #define DUK_HEAP_HAS_ERRHANDLER_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
35 #define DUK_HEAP_HAS_INTERRUPT_RUNNING(heap) DUK__HEAP_HAS_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
36
37 #define DUK_HEAP_SET_MARKANDSWEEP_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING)
38 #define DUK_HEAP_SET_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
39 #define DUK_HEAP_SET_REFZERO_FREE_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_REFZERO_FREE_RUNNING)
40 #define DUK_HEAP_SET_ERRHANDLER_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
41 #define DUK_HEAP_SET_INTERRUPT_RUNNING(heap) DUK__HEAP_SET_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
42
43 #define DUK_HEAP_CLEAR_MARKANDSWEEP_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RUNNING)
44 #define DUK_HEAP_CLEAR_MARKANDSWEEP_RECLIMIT_REACHED(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_MARKANDSWEEP_RECLIMIT_REACHED)
45 #define DUK_HEAP_CLEAR_REFZERO_FREE_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_REFZERO_FREE_RUNNING)
46 #define DUK_HEAP_CLEAR_ERRHANDLER_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_ERRHANDLER_RUNNING)
47 #define DUK_HEAP_CLEAR_INTERRUPT_RUNNING(heap) DUK__HEAP_CLEAR_FLAGS((heap), DUK_HEAP_FLAG_INTERRUPT_RUNNING)
48
49 /*
50 * Longjmp types, also double as identifying continuation type for a rethrow (in 'finally')
51 */
52
53 #define DUK_LJ_TYPE_UNKNOWN 0 /* unused */
54 #define DUK_LJ_TYPE_RETURN 1 /* value1 -> return value */
55 #define DUK_LJ_TYPE_THROW 2 /* value1 -> error object */
56 #define DUK_LJ_TYPE_BREAK 3 /* value1 -> label number */
57 #define DUK_LJ_TYPE_CONTINUE 4 /* value1 -> label number */
58 #define DUK_LJ_TYPE_YIELD 5 /* value1 -> yield value, iserror -> error / normal */
59 #define DUK_LJ_TYPE_RESUME 6 /* value1 -> resume value, value2 -> resumee thread, iserror -> error/normal */
60 #define DUK_LJ_TYPE_NORMAL 7 /* pseudo-type to indicate a normal continuation (for 'finally' rethrowing) */
61
62 /*
63 * Mark-and-sweep flags
64 *
65 * These are separate from heap level flags now but could be merged.
66 * The heap structure only contains a 'base mark-and-sweep flags'
67 * field and the GC caller can impose further flags.
68 */
69
70 #define DUK_MS_FLAG_EMERGENCY (1 << 0) /* emergency mode: try extra hard */
71 #define DUK_MS_FLAG_NO_STRINGTABLE_RESIZE (1 << 1) /* don't resize stringtable (but may sweep it); needed during stringtable resize */
72 #define DUK_MS_FLAG_NO_FINALIZERS (1 << 2) /* don't run finalizers (which may have arbitrary side effects) */
73 #define DUK_MS_FLAG_NO_OBJECT_COMPACTION (1 << 3) /* don't compact objects; needed during object property allocation resize */
74
75 /*
76 * Thread switching
77 *
78 * To switch heap->curr_thread, use the macro below so that interrupt counters
79 * get updated correctly. The macro allows a NULL target thread because that
80 * happens e.g. in call handling.
81 */
82
83 #if defined(DUK_USE_INTERRUPT_COUNTER)
84 #define DUK_HEAP_SWITCH_THREAD(heap,newthr) duk_heap_switch_thread((heap), (newthr))
85 #else
86 #define DUK_HEAP_SWITCH_THREAD(heap,newthr) do { \
87 (heap)->curr_thread = (newthr); \
88 } while (0)
89 #endif
90
91 /*
92 * Other heap related defines
93 */
94
95 /* Mark-and-sweep interval is relative to combined count of objects and
96 * strings kept in the heap during the latest mark-and-sweep pass.
97 * Fixed point .8 multiplier and .0 adder. Trigger count (interval) is
98 * decreased by each (re)allocation attempt (regardless of size), and each
99 * refzero processed object.
100 *
101 * 'SKIP' indicates how many (re)allocations to wait until a retry if
102 * GC is skipped because there is no thread do it with yet (happens
103 * only during init phases).
104 */
105 #if defined(DUK_USE_MARK_AND_SWEEP)
106 #if defined(DUK_USE_REFERENCE_COUNTING)
107 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT 12800L /* 50x heap size */
108 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L
109 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP 256L
110 #else
111 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_MULT 256L /* 1x heap size */
112 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_ADD 1024L
113 #define DUK_HEAP_MARK_AND_SWEEP_TRIGGER_SKIP 256L
114 #endif
115 #endif
116
117 /* Stringcache is used for speeding up char-offset-to-byte-offset
118 * translations for non-ASCII strings.
119 */
120 #define DUK_HEAP_STRCACHE_SIZE 4
121 #define DUK_HEAP_STRINGCACHE_NOCACHE_LIMIT 16 /* strings up to the this length are not cached */
122
123 /* helper to insert a (non-string) heap object into heap allocated list */
124 #define DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap,hdr) duk_heap_insert_into_heap_allocated((heap),(hdr))
125
126 /*
127 * Stringtable
128 */
129
130 /* initial stringtable size, must be prime and higher than DUK_UTIL_MIN_HASH_PRIME */
131 #define DUK_STRTAB_INITIAL_SIZE 17
132
133 /* indicates a deleted string; any fixed non-NULL, non-hstring pointer works */
134 #define DUK_STRTAB_DELETED_MARKER(heap) ((duk_hstring *) heap)
135
136 /* resizing parameters */
137 #define DUK_STRTAB_MIN_FREE_DIVISOR 4 /* load factor max 75% */
138 #define DUK_STRTAB_MIN_USED_DIVISOR 4 /* load factor min 25% */
139 #define DUK_STRTAB_GROW_ST_SIZE(n) ((n) + (n)) /* used entries + approx 100% -> reset load to 50% */
140
141 #define DUK_STRTAB_U32_MAX_STRLEN 10 /* 4'294'967'295 */
142 #define DUK_STRTAB_HIGHEST_32BIT_PRIME 0xfffffffbUL
143
144 /* probe sequence (open addressing) */
145 #define DUK_STRTAB_HASH_INITIAL(hash,h_size) ((hash) % (h_size))
146 #define DUK_STRTAB_HASH_PROBE_STEP(hash) DUK_UTIL_GET_HASH_PROBE_STEP((hash))
147
148 /* fixed top level hashtable size (separate chaining) */
149 #define DUK_STRTAB_CHAIN_SIZE DUK_USE_STRTAB_CHAIN_SIZE
150
151 /*
152 * Built-in strings
153 */
154
155 /* heap string indices are autogenerated in duk_strings.h */
156 #if defined(DUK_USE_HEAPPTR16)
157 #define DUK_HEAP_GET_STRING(heap,idx) \
158 ((duk_hstring *) DUK_USE_HEAPPTR_DEC16((heap)->heap_udata, (heap)->strs16[(idx)]))
159 #else
160 #define DUK_HEAP_GET_STRING(heap,idx) \
161 ((heap)->strs[(idx)])
162 #endif
163
164 /*
165 * Raw memory calls: relative to heap, but no GC interaction
166 */
167
168 #define DUK_ALLOC_RAW(heap,size) \
169 ((heap)->alloc_func((heap)->heap_udata, (size)))
170
171 #define DUK_REALLOC_RAW(heap,ptr,newsize) \
172 ((heap)->realloc_func((heap)->heap_udata, (void *) (ptr), (newsize)))
173
174 #define DUK_FREE_RAW(heap,ptr) \
175 ((heap)->free_func((heap)->heap_udata, (void *) (ptr)))
176
177 /*
178 * Memory calls: relative to heap, GC interaction, but no error throwing.
179 *
180 * XXX: Currently a mark-and-sweep triggered by memory allocation will run
181 * using the heap->heap_thread. This thread is also used for running
182 * mark-and-sweep finalization; this is not ideal because it breaks the
183 * isolation between multiple global environments.
184 *
185 * Notes:
186 *
187 * - DUK_FREE() is required to ignore NULL and any other possible return
188 * value of a zero-sized alloc/realloc (same as ANSI C free()).
189 *
190 * - There is no DUK_REALLOC_ZEROED because we don't assume to know the
191 * old size. Caller must zero the reallocated memory.
192 *
193 * - DUK_REALLOC_INDIRECT() must be used when a mark-and-sweep triggered
194 * by an allocation failure might invalidate the original 'ptr', thus
195 * causing a realloc retry to use an invalid pointer. Example: we're
196 * reallocating the value stack and a finalizer resizes the same value
197 * stack during mark-and-sweep. The indirect variant requests for the
198 * current location of the pointer being reallocated using a callback
199 * right before every realloc attempt; this circuitous approach is used
200 * to avoid strict aliasing issues in a more straightforward indirect
201 * pointer (void **) approach. Note: the pointer in the storage
202 * location is read but is NOT updated; the caller must do that.
203 */
204
205 /* callback for indirect reallocs, request for current pointer */
206 typedef void *(*duk_mem_getptr)(duk_heap *heap, void *ud);
207
208 #define DUK_ALLOC(heap,size) duk_heap_mem_alloc((heap), (size))
209 #define DUK_ALLOC_ZEROED(heap,size) duk_heap_mem_alloc_zeroed((heap), (size))
210 #define DUK_REALLOC(heap,ptr,newsize) duk_heap_mem_realloc((heap), (ptr), (newsize))
211 #define DUK_REALLOC_INDIRECT(heap,cb,ud,newsize) duk_heap_mem_realloc_indirect((heap), (cb), (ud), (newsize))
212 #define DUK_FREE(heap,ptr) duk_heap_mem_free((heap), (ptr))
213
214 /*
215 * Memory constants
216 */
217
218 #define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_LIMIT 5 /* Retry allocation after mark-and-sweep for this
219 * many times. A single mark-and-sweep round is
220 * not guaranteed to free all unreferenced memory
221 * because of finalization (in fact, ANY number of
222 * rounds is strictly not enough).
223 */
224
225 #define DUK_HEAP_ALLOC_FAIL_MARKANDSWEEP_EMERGENCY_LIMIT 3 /* Starting from this round, use emergency mode
226 * for mark-and-sweep.
227 */
228
229 /*
230 * Debugger support
231 */
232
233 /* Maximum number of breakpoints. Only breakpoints that are set are
234 * consulted so increasing this has no performance impact.
235 */
236 #define DUK_HEAP_MAX_BREAKPOINTS 16
237
238 /* Opcode interval for a Date-based status/peek rate limit check. Only
239 * relevant when debugger is attached. Requesting a timestamp may be a
240 * slow operation on some platforms so this shouldn't be too low. On the
241 * other hand a high value makes Duktape react to a pause request slowly.
242 */
243 #define DUK_HEAP_DBG_RATELIMIT_OPCODES 4000
244
245 /* Milliseconds between status notify and transport peeks. */
246 #define DUK_HEAP_DBG_RATELIMIT_MILLISECS 200
247
248 /* Step types */
249 #define DUK_STEP_TYPE_NONE 0
250 #define DUK_STEP_TYPE_INTO 1
251 #define DUK_STEP_TYPE_OVER 2
252 #define DUK_STEP_TYPE_OUT 3
253
254 struct duk_breakpoint {
255 duk_hstring *filename;
256 duk_uint32_t line;
257 };
258
259 #if defined(DUK_USE_DEBUGGER_SUPPORT)
260 #define DUK_HEAP_IS_DEBUGGER_ATTACHED(heap) ((heap)->dbg_read_cb != NULL)
261 #define DUK_HEAP_CLEAR_STEP_STATE(heap) do { \
262 (heap)->dbg_step_type = DUK_STEP_TYPE_NONE; \
263 (heap)->dbg_step_thread = NULL; \
264 (heap)->dbg_step_csindex = 0; \
265 (heap)->dbg_step_startline = 0; \
266 } while (0)
267 #define DUK_HEAP_SET_PAUSED(heap) do { \
268 (heap)->dbg_paused = 1; \
269 (heap)->dbg_state_dirty = 1; \
270 DUK_HEAP_CLEAR_STEP_STATE((heap)); \
271 } while (0)
272 #define DUK_HEAP_CLEAR_PAUSED(heap) do { \
273 (heap)->dbg_paused = 0; \
274 (heap)->dbg_state_dirty = 1; \
275 DUK_HEAP_CLEAR_STEP_STATE((heap)); \
276 } while (0)
277 #endif /* DUK_USE_DEBUGGER_SUPPORT */
278
279 /*
280 * String cache should ideally be at duk_hthread level, but that would
281 * cause string finalization to slow down relative to the number of
282 * threads; string finalization must check the string cache for "weak"
283 * references to the string being finalized to avoid dead pointers.
284 *
285 * Thus, string caches are now at the heap level now.
286 */
287
288 struct duk_strcache {
289 duk_hstring *h;
290 duk_uint32_t bidx;
291 duk_uint32_t cidx;
292 };
293
294 /*
295 * Longjmp state, contains the information needed to perform a longjmp.
296 * Longjmp related values are written to value1, value2, and iserror.
297 */
298
299 struct duk_ljstate {
300 duk_jmpbuf *jmpbuf_ptr; /* current setjmp() catchpoint */
301 duk_small_uint_t type; /* longjmp type */
302 duk_bool_t iserror; /* isError flag for yield */
303 duk_tval value1; /* 1st related value (type specific) */
304 duk_tval value2; /* 2nd related value (type specific) */
305 };
306
307 /*
308 * Stringtable entry for fixed size stringtable
309 */
310
311 struct duk_strtab_entry {
312 #if defined(DUK_USE_HEAPPTR16)
313 /* A 16-bit listlen makes sense with 16-bit heap pointers: there
314 * won't be space for 64k strings anyway.
315 */
316 duk_uint16_t listlen; /* if 0, 'str16' used, if > 0, 'strlist16' used */
317 union {
318 duk_uint16_t strlist16;
319 duk_uint16_t str16;
320 } u;
321 #else
322 duk_size_t listlen; /* if 0, 'str' used, if > 0, 'strlist' used */
323 union {
324 duk_hstring **strlist;
325 duk_hstring *str;
326 } u;
327 #endif
328 };
329
330 /*
331 * Main heap structure
332 */
333
334 struct duk_heap {
335 duk_small_uint_t flags;
336
337 /* Allocator functions. */
338 duk_alloc_function alloc_func;
339 duk_realloc_function realloc_func;
340 duk_free_function free_func;
341
342 /* Heap udata, used for allocator functions but also for other heap
343 * level callbacks like pointer compression, etc.
344 */
345 void *heap_udata;
346
347 /* Precomputed pointers when using 16-bit heap pointer packing. */
348 #if defined(DUK_USE_HEAPPTR16)
349 duk_uint16_t heapptr_null16;
350 duk_uint16_t heapptr_deleted16;
351 #endif
352
353 /* Fatal error handling, called e.g. when a longjmp() is needed but
354 * lj.jmpbuf_ptr is NULL. fatal_func must never return; it's not
355 * declared as "noreturn" because doing that for typedefs is a bit
356 * challenging portability-wise.
357 */
358 duk_fatal_function fatal_func;
359
360 /* allocated heap objects */
361 duk_heaphdr *heap_allocated;
362
363 /* work list for objects whose refcounts are zero but which have not been
364 * "finalized"; avoids recursive C calls when refcounts go to zero in a
365 * chain of objects.
366 */
367 #if defined(DUK_USE_REFERENCE_COUNTING)
368 duk_heaphdr *refzero_list;
369 duk_heaphdr *refzero_list_tail;
370 #endif
371
372 #if defined(DUK_USE_MARK_AND_SWEEP)
373 /* mark-and-sweep control */
374 #if defined(DUK_USE_VOLUNTARY_GC)
375 duk_int_t mark_and_sweep_trigger_counter;
376 #endif
377 duk_int_t mark_and_sweep_recursion_depth;
378
379 /* mark-and-sweep flags automatically active (used for critical sections) */
380 duk_small_uint_t mark_and_sweep_base_flags;
381
382 /* work list for objects to be finalized (by mark-and-sweep) */
383 duk_heaphdr *finalize_list;
384 #endif
385
386 /* longjmp state */
387 duk_ljstate lj;
388
389 /* marker for detecting internal "double faults", see duk_error_throw.c */
390 duk_bool_t handling_error;
391
392 /* heap thread, used internally and for finalization */
393 duk_hthread *heap_thread;
394
395 /* current thread */
396 duk_hthread *curr_thread; /* currently running thread */
397
398 /* heap level "stash" object (e.g., various reachability roots) */
399 duk_hobject *heap_object;
400
401 /* duk_handle_call / duk_handle_safe_call recursion depth limiting */
402 duk_int_t call_recursion_depth;
403 duk_int_t call_recursion_limit;
404
405 /* mix-in value for computing string hashes; should be reasonably unpredictable */
406 duk_uint32_t hash_seed;
407
408 /* rnd_state for duk_util_tinyrandom.c */
409 duk_uint32_t rnd_state;
410
411 /* For manual debugging: instruction count based on executor and
412 * interrupt counter book-keeping. Inspect debug logs to see how
413 * they match up.
414 */
415 #if defined(DUK_USE_INTERRUPT_COUNTER) && defined(DUK_USE_DEBUG)
416 duk_int_t inst_count_exec;
417 duk_int_t inst_count_interrupt;
418 #endif
419
420 /* debugger */
421
422 #if defined(DUK_USE_DEBUGGER_SUPPORT)
423 /* callbacks and udata; dbg_read_cb != NULL is used to indicate attached state */
424 duk_debug_read_function dbg_read_cb; /* required, NULL implies detached */
425 duk_debug_write_function dbg_write_cb; /* required */
426 duk_debug_peek_function dbg_peek_cb;
427 duk_debug_read_flush_function dbg_read_flush_cb;
428 duk_debug_write_flush_function dbg_write_flush_cb;
429 duk_debug_detached_function dbg_detached_cb;
430 void *dbg_udata;
431
432 /* debugger state, only relevant when attached */
433 duk_bool_t dbg_processing; /* currently processing messages or breakpoints: don't enter message processing recursively (e.g. no breakpoints when processing debugger eval) */
434 duk_bool_t dbg_paused; /* currently paused: talk with debug client until step/resume */
435 duk_bool_t dbg_state_dirty; /* resend state next time executor is about to run */
436 duk_bool_t dbg_force_restart; /* force executor restart to recheck breakpoints; used to handle function returns (see GH-303) */
437 duk_small_uint_t dbg_step_type; /* step type: none, step into, step over, step out */
438 duk_hthread *dbg_step_thread; /* borrowed; NULL if no step state (NULLed in unwind) */
439 duk_size_t dbg_step_csindex; /* callstack index */
440 duk_uint32_t dbg_step_startline; /* starting line number */
441 duk_breakpoint dbg_breakpoints[DUK_HEAP_MAX_BREAKPOINTS]; /* breakpoints: [0,breakpoint_count[ gc reachable */
442 duk_small_uint_t dbg_breakpoint_count;
443 duk_breakpoint *dbg_breakpoints_active[DUK_HEAP_MAX_BREAKPOINTS + 1]; /* currently active breakpoints: NULL term, borrowed pointers */
444 /* XXX: make active breakpoints actual copies instead of pointers? */
445
446 /* These are for rate limiting Status notifications and transport peeking. */
447 duk_uint32_t dbg_exec_counter; /* cumulative opcode execution count (overflows are OK) */
448 duk_uint32_t dbg_last_counter; /* value of dbg_exec_counter when we last did a Date-based check */
449 duk_double_t dbg_last_time; /* time when status/peek was last done (Date-based rate limit) */
450 #endif
451
452 /* string intern table (weak refs) */
453 #if defined(DUK_USE_STRTAB_PROBE)
454 #if defined(DUK_USE_HEAPPTR16)
455 duk_uint16_t *strtable16;
456 #else
457 duk_hstring **strtable;
458 #endif
459 duk_uint32_t st_size; /* alloc size in elements */
460 duk_uint32_t st_used; /* used elements (includes DELETED) */
461 #endif
462
463 /* XXX: static alloc is OK until separate chaining stringtable
464 * resizing is implemented.
465 */
466 #if defined(DUK_USE_STRTAB_CHAIN)
467 duk_strtab_entry strtable[DUK_STRTAB_CHAIN_SIZE];
468 #endif
469
470 /* string access cache (codepoint offset -> byte offset) for fast string
471 * character looping; 'weak' reference which needs special handling in GC.
472 */
473 duk_strcache strcache[DUK_HEAP_STRCACHE_SIZE];
474
475 /* built-in strings */
476 #if defined(DUK_USE_HEAPPTR16)
477 duk_uint16_t strs16[DUK_HEAP_NUM_STRINGS];
478 #else
479 duk_hstring *strs[DUK_HEAP_NUM_STRINGS];
480 #endif
481 };
482
483 /*
484 * Prototypes
485 */
486
487 DUK_INTERNAL_DECL
488 duk_heap *duk_heap_alloc(duk_alloc_function alloc_func,
489 duk_realloc_function realloc_func,
490 duk_free_function free_func,
491 void *heap_udata,
492 duk_fatal_function fatal_func);
493 DUK_INTERNAL_DECL void duk_heap_free(duk_heap *heap);
494 DUK_INTERNAL_DECL void duk_free_hobject_inner(duk_heap *heap, duk_hobject *h);
495 DUK_INTERNAL_DECL void duk_free_hbuffer_inner(duk_heap *heap, duk_hbuffer *h);
496 DUK_INTERNAL_DECL void duk_free_hstring_inner(duk_heap *heap, duk_hstring *h);
497 DUK_INTERNAL_DECL void duk_heap_free_heaphdr_raw(duk_heap *heap, duk_heaphdr *hdr);
498
499 DUK_INTERNAL_DECL void duk_heap_insert_into_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);
500 #if defined(DUK_USE_DOUBLE_LINKED_HEAP) && defined(DUK_USE_REFERENCE_COUNTING)
501 DUK_INTERNAL_DECL void duk_heap_remove_any_from_heap_allocated(duk_heap *heap, duk_heaphdr *hdr);
502 #endif
503 #if defined(DUK_USE_INTERRUPT_COUNTER)
504 DUK_INTERNAL_DECL void duk_heap_switch_thread(duk_heap *heap, duk_hthread *new_thr);
505 #endif
506
507 #if 0 /*unused*/
508 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_lookup(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);
509 #endif
510 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern(duk_heap *heap, const duk_uint8_t *str, duk_uint32_t blen);
511 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_checked(duk_hthread *thr, const duk_uint8_t *str, duk_uint32_t len);
512 #if 0 /*unused*/
513 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_lookup_u32(duk_heap *heap, duk_uint32_t val);
514 #endif
515 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_u32(duk_heap *heap, duk_uint32_t val);
516 DUK_INTERNAL_DECL duk_hstring *duk_heap_string_intern_u32_checked(duk_hthread *thr, duk_uint32_t val);
517 DUK_INTERNAL_DECL void duk_heap_string_remove(duk_heap *heap, duk_hstring *h);
518 #if defined(DUK_USE_MARK_AND_SWEEP) && defined(DUK_USE_MS_STRINGTABLE_RESIZE)
519 DUK_INTERNAL_DECL void duk_heap_force_strtab_resize(duk_heap *heap);
520 #endif
521 DUK_INTERNAL void duk_heap_free_strtab(duk_heap *heap);
522 #if defined(DUK_USE_DEBUG)
523 DUK_INTERNAL void duk_heap_dump_strtab(duk_heap *heap);
524 #endif
525
526
527 DUK_INTERNAL_DECL void duk_heap_strcache_string_remove(duk_heap *heap, duk_hstring *h);
528 DUK_INTERNAL_DECL duk_uint_fast32_t duk_heap_strcache_offset_char2byte(duk_hthread *thr, duk_hstring *h, duk_uint_fast32_t char_offset);
529
530 #if defined(DUK_USE_PROVIDE_DEFAULT_ALLOC_FUNCTIONS)
531 DUK_INTERNAL_DECL void *duk_default_alloc_function(void *udata, duk_size_t size);
532 DUK_INTERNAL_DECL void *duk_default_realloc_function(void *udata, void *ptr, duk_size_t newsize);
533 DUK_INTERNAL_DECL void duk_default_free_function(void *udata, void *ptr);
534 #endif
535
536 DUK_INTERNAL_DECL void *duk_heap_mem_alloc(duk_heap *heap, duk_size_t size);
537 DUK_INTERNAL_DECL void *duk_heap_mem_alloc_zeroed(duk_heap *heap, duk_size_t size);
538 DUK_INTERNAL_DECL void *duk_heap_mem_realloc(duk_heap *heap, void *ptr, duk_size_t newsize);
539 DUK_INTERNAL_DECL void *duk_heap_mem_realloc_indirect(duk_heap *heap, duk_mem_getptr cb, void *ud, duk_size_t newsize);
540 DUK_INTERNAL_DECL void duk_heap_mem_free(duk_heap *heap, void *ptr);
541
542 #ifdef DUK_USE_REFERENCE_COUNTING
543 #if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
544 DUK_INTERNAL_DECL void duk_tval_incref(duk_tval *tv);
545 #endif
546 #if 0 /* unused */
547 DUK_INTERNAL_DECL void duk_tval_incref_allownull(duk_tval *tv);
548 #endif
549 DUK_INTERNAL_DECL void duk_tval_decref(duk_hthread *thr, duk_tval *tv);
550 #if 0 /* unused */
551 DUK_INTERNAL_DECL void duk_tval_decref_allownull(duk_hthread *thr, duk_tval *tv);
552 #endif
553 #if !defined(DUK_USE_FAST_REFCOUNT_DEFAULT)
554 DUK_INTERNAL_DECL void duk_heaphdr_incref(duk_heaphdr *h);
555 #endif
556 #if 0 /* unused */
557 DUK_INTERNAL_DECL void duk_heaphdr_incref_allownull(duk_heaphdr *h);
558 #endif
559 DUK_INTERNAL_DECL void duk_heaphdr_decref(duk_hthread *thr, duk_heaphdr *h);
560 DUK_INTERNAL_DECL void duk_heaphdr_decref_allownull(duk_hthread *thr, duk_heaphdr *h);
561 DUK_INTERNAL_DECL void duk_heaphdr_refzero(duk_hthread *thr, duk_heaphdr *h);
562 DUK_INTERNAL_DECL void duk_heaphdr_refcount_finalize(duk_hthread *thr, duk_heaphdr *hdr);
563 #else
564 /* no refcounting */
565 #endif
566
567 #if defined(DUK_USE_MARK_AND_SWEEP)
568 DUK_INTERNAL_DECL duk_bool_t duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags);
569 #endif
570
571 DUK_INTERNAL_DECL duk_uint32_t duk_heap_hashstring(duk_heap *heap, const duk_uint8_t *str, duk_size_t len);
572
573 #endif /* DUK_HEAP_H_INCLUDED */