#ifndef INCLUDED_GC_H #define INCLUDED_GC_H #include "memory.h" #include #include #include #define OBJECT_PROCESS_STACK_BLOCK_SIZE 64 struct ObjectProcessStackBlock { void *objs[OBJECT_PROCESS_STACK_BLOCK_SIZE]; }; typedef struct { size_t num_blocks; size_t num_objs; struct ObjectProcessStackBlock **blocks; } ObjectProcessStack; static ALWAYS_INLINE bool OBJECT_PROCESS_STACK_EMPTY_P(ObjectProcessStack *restrict stack) { return !stack->num_objs; } static ALWAYS_INLINE void init_object_process_stack(ObjectProcessStack *restrict stack) { stack->num_blocks = 0; stack->num_objs = 0; stack->blocks = NULL; } void free_object_process_stack(ObjectProcessStack *restrict stack); void object_process_stack_push_object(ObjectProcessStack *restrict stack, void *obj); void object_process_stack_push_held_objects(ObjectProcessStack *restrict stack, void *obj); void *object_process_stack_pop(ObjectProcessStack *restrict stack); extern bool lisp_doing_gc; extern struct timespec total_gc_time; extern size_t total_gc_count; typedef struct { size_t non_statics_kept; size_t objects_cleaned; struct timespec ellapsed_time; } LispGCStats; typedef uint8_t ObjectGCSet; extern ObjectGCSet GC_BLACK; extern ObjectGCSet GC_GREY; extern ObjectGCSet GC_WHITE; struct GCObjectList; typedef struct { unsigned int is_static : 1; ObjectGCSet set : 2; tss_t has_local_ref; struct GCObjectList *gc_node; } ObjectGCInfo; // the argument is a LispVal * void lisp_gc_register_object(void *val); void lisp_gc_register_static_object(void *val); void gc_move_to_set(void *val, ObjectGCSet new_set); // note that the argument is restrict! void lisp_gc_now(LispGCStats *restrict status); // Debug void debug_print_gc_stats(FILE *stream, const LispGCStats *stats); #endif