#ifndef ANT_GC_H #define ANT_GC_H #include "internal.h" #include #include #define GC_MIN_TICK 1024 #define GC_NURSERY_THRESHOLD 32768 #define GC_FORCE_INTERVAL_MS 50 #define GC_MAJOR_EVERY_N_MINOR 8 #define GC_OBJ_TYPE_MASK (JS_TPFLG(T_OBJ) \ | JS_TPFLG(T_ARR) \ | JS_TPFLG(T_PROMISE) \ | JS_TPFLG(T_GENERATOR)) typedef struct gc_func_mark_profile { bool enabled; uint64_t collections; uint64_t func_visits; uint64_t child_edges; uint64_t const_slots; uint64_t time_ns; } gc_func_mark_profile_t; void gc_run(ant_t *js); void gc_run_minor(ant_t *js); void gc_maybe(ant_t *js); void gc_remember_add(ant_t *js, ant_object_t *obj); size_t gc_live_major_threshold(ant_t *js); size_t gc_pool_major_threshold(ant_t *js); void gc_func_mark_profile_enable(bool enabled); void gc_func_mark_profile_reset(void); extern bool gc_disabled; gc_func_mark_profile_t gc_func_mark_profile_get(void); static inline void gc_write_barrier(ant_t *js, ant_object_t *writer_obj, ant_value_t new_val) { if (writer_obj->generation != 1 || new_val <= NANBOX_PREFIX) return; uint8_t type = (new_val >> NANBOX_TYPE_SHIFT) & NANBOX_TYPE_MASK; if (type == T_FUNC) gc_remember_add(js, writer_obj); else if ((1u << type) & GC_OBJ_TYPE_MASK) { ant_object_t *ref = (ant_object_t *)(uintptr_t)(new_val & NANBOX_DATA_MASK); if (ref && ref->generation == 0) gc_remember_add(js, writer_obj); } } #endif