Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130#ifndef ANT_GC_OBJECTS_H#define ANT_GC_OBJECTS_H
#include "types.h"#include "object.h"
#include <time.h>#ifdef ANT_WASM_EMBED#include "wasm_embed.h"#endif
static constexpr int GC_ARRAY_STORAGE_CLASSES = 9;static constexpr uint8_t ANT_GC_DEAD = 0xFF;
typedef struct { ant_value_t *head[GC_ARRAY_STORAGE_CLASSES]; uint32_t count[GC_ARRAY_STORAGE_CLASSES]; uint32_t taken[GC_ARRAY_STORAGE_CLASSES];} gc_array_storage_cache_t;
typedef struct gc_vm_seg { struct gc_vm_seg *prev; uintptr_t lo, hi; uintptr_t fp; uint32_t jit_depth; int entry_vm_fp;} gc_vm_seg_t;
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;
static inline uint64_t gc_now_ns(void) {#ifdef ANT_WASM_EMBED return (uint64_t)(ant_wasm_now_ms() * 1000000.0);#else struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); return (uint64_t)ts.tv_sec * 1000000000ULL + (uint64_t)ts.tv_nsec;#endif}
#if defined(__aarch64__)#define GC_VM_SEG_SAVED_REGS_BYTES 144u#elif defined(__x86_64__)#define GC_VM_SEG_SAVED_REGS_BYTES 40u#else#define GC_VM_SEG_SAVED_REGS_BYTES 0u#endif
static constexpr uint32_t GC_CARD_SHIFT = 7;static constexpr uint32_t GC_CARD_SLOTS = 1u << GC_CARD_SHIFT;static constexpr uint32_t GC_CARD_MIN_CAP = 1024;
struct gc_card_table { uint32_t ncards; bool all_dirty; uint64_t bits[];};
static inline gc_card_table_t *gc_cards_of(const ant_object_t *arr) { ant_object_sidecar_t *sidecar = ant_object_sidecar(arr); return sidecar ? sidecar->gc_cards : NULL;}
static inline bool gc_card_is_set(const gc_card_table_t *cards, uint32_t card) { return (cards->bits[card / 64u] & (UINT64_C(1) << (card % 64u))) != 0;}
static inline void gc_card_set(gc_card_table_t *cards, uint32_t card) { cards->bits[card / 64u] |= UINT64_C(1) << (card % 64u);}
void gc_remember_element(ant_t *js, ant_object_t *arr, uint32_t idx);void gc_cards_mark_all(ant_object_t *arr);
static inline __attribute__((always_inline)) uintptr_t gc_native_sp(void) { uintptr_t sp;#if defined(__aarch64__) __asm__ volatile("mov %0, sp" : "=r"(sp));#elif defined(__x86_64__) __asm__ volatile("mov %%rsp, %0" : "=r"(sp));#else volatile char marker; sp = (uintptr_t)▮#endif return sp;}
typedef void (*gc_extra_roots_fn)(ant_t *js);
uint64_t gc_get_epoch(ant_t *js);uint64_t gc_objects_run(ant_t *js, gc_extra_roots_fn extra_roots);
uint32_t gc_array_storage_fit(uint32_t cap);bool gc_obj_is_marked(ant_t *js, const ant_object_t *obj);
void gc_mark_str(ant_t *js, ant_value_t v);void gc_mark_value(ant_t *js, ant_value_t v);void gc_mark_closure(ant_t *js, sv_closure_t *c);void gc_mark_coroutine(ant_t *js, coroutine_t *coro);void gc_mark_upvalue_cells(ant_t *js, sv_upvalue_t *const *cells, uint32_t count);void gc_mark_arguments_cells(ant_t *js, ant_value_t obj);void gc_mark_conservative_range(ant_t *js, const void *ptr, size_t size);
void gc_objects_run_minor(ant_t *js);void gc_object_free(ant_t *js, ant_object_t *obj);void gc_pin_existing_objects(ant_t *js);
ant_value_t *gc_array_storage_alloc(ant_t *js, uint32_t cap);ant_value_t *gc_array_storage_grow(ant_t *js, ant_value_t *data, uint32_t old_cap, uint32_t new_cap);
void gc_array_storage_release(ant_t *js, ant_value_t *data, uint32_t cap);size_t gc_array_storage_cached_bytes(ant_t *js);
void gc_array_storage_trim(ant_t *js);void gc_array_storage_cache_destroy(ant_t *js);void gc_closures_destroy(ant_t *js);
struct ant_promise_state *gc_promise_state_alloc(ant_t *js);
void gc_root_pending_promise(ant_t *js, ant_object_t *obj);void gc_unroot_pending_promise(ant_t *js, ant_object_t *obj);
#endif