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