Fix (I hope) reference counting and garbage collecting
This commit is contained in:
59
src/lisp.h
59
src/lisp.h
@ -41,7 +41,9 @@ extern struct _TypeNameEntry LISP_TYPE_NAMES[N_LISP_TYPES];
|
||||
|
||||
#define LISP_OBJECT_HEADER \
|
||||
LispType type; \
|
||||
ptrdiff_t ref_count;
|
||||
void *gc_root; \
|
||||
ptrdiff_t ref_count; \
|
||||
bool finalizing;
|
||||
|
||||
typedef struct {
|
||||
LISP_OBJECT_HEADER;
|
||||
@ -270,7 +272,7 @@ inline static bool NUMBERP(LispVal *v) {
|
||||
{ \
|
||||
LispHashtable *__hashtable_foreach_table = (LispHashtable *) table; \
|
||||
for (size_t __hashtable_foreach_i = 0; \
|
||||
__hashtable_foreach_i < __hashtable_foreach_table->count; \
|
||||
__hashtable_foreach_i < __hashtable_foreach_table->table_size; \
|
||||
++__hashtable_foreach_i) { \
|
||||
struct HashtableBucket *__hashtable_foreach_cur = \
|
||||
__hashtable_foreach_table->data[__hashtable_foreach_i]; \
|
||||
@ -292,43 +294,21 @@ inline static bool NUMBERP(LispVal *v) {
|
||||
// #############################
|
||||
// # Allocation and references #
|
||||
// #############################
|
||||
|
||||
#define GC_EVERY_N_BYTES 1024 * 80
|
||||
void *lisp_malloc(size_t size);
|
||||
void *lisp_realloc(void *old_ptr, size_t size);
|
||||
#define lisp_free free
|
||||
|
||||
inline static void *lisp_ref(void *val) {
|
||||
if (!STATICP(val)) {
|
||||
++((LispVal *) val)->ref_count;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
inline static void *lisp_float_ref(void *val) {
|
||||
if (LISPVAL(val)->ref_count > 0) {
|
||||
--LISPVAL(val)->ref_count;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
void _internal_lisp_delete_object(LispVal *val);
|
||||
inline static void *lisp_unref(void *val) {
|
||||
if (STATICP(val)) {
|
||||
return val;
|
||||
} else if (LISPVAL(val)->ref_count > 1) {
|
||||
--LISPVAL(val)->ref_count;
|
||||
return val;
|
||||
} else {
|
||||
_internal_lisp_delete_object(val);
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
void *lisp_ref(void *val);
|
||||
void *lisp_float_ref(void *val);
|
||||
void garbage_collect();
|
||||
void *lisp_unref(void *val);
|
||||
#define UNREF_INPLACE(variable) \
|
||||
{ \
|
||||
variable = lisp_unref(variable); \
|
||||
}
|
||||
inline static void lisp_unref_double_ptr(void **val) {
|
||||
lisp_unref(*val);
|
||||
}
|
||||
void lisp_unref_double_ptr(void **val);
|
||||
#define IGNORE_REF(val) (lisp_unref(lisp_ref(val)))
|
||||
|
||||
// ################
|
||||
@ -481,10 +461,22 @@ extern LispVal *Qargument_error;
|
||||
Fthrow(Qtype_error, Qnil); \
|
||||
}
|
||||
|
||||
struct StaticReference {
|
||||
struct StaticReference *next;
|
||||
LispVal *obj;
|
||||
};
|
||||
|
||||
extern struct StaticReference *static_references;
|
||||
|
||||
void add_static_reference(LispVal *obj);
|
||||
|
||||
extern LispVal *Vobarray;
|
||||
|
||||
#define REGISTER_SYMBOL(sym) \
|
||||
Fputhash(Vobarray, LISPVAL(((LispSymbol *) Q##sym)->name), Q##sym)
|
||||
#define REGISTER_SYMBOL(sym) \
|
||||
{ \
|
||||
Fputhash(Vobarray, LISPVAL(((LispSymbol *) Q##sym)->name), Q##sym); \
|
||||
add_static_reference(Q##sym); \
|
||||
}
|
||||
#define REGISTER_STATIC_FUNCTION(obj, args, docstr) \
|
||||
((LispFunction *) (obj))->doc = STATIC_STRING(docstr); \
|
||||
{ \
|
||||
@ -492,6 +484,7 @@ extern LispVal *Vobarray;
|
||||
lisp_ref(src); \
|
||||
set_function_args((LispFunction *) (obj), Fread(src)); \
|
||||
lisp_unref(src); \
|
||||
add_static_reference(obj); \
|
||||
}
|
||||
#define REGISTER_FUNCTION(fn, args, docstr) \
|
||||
REGISTER_SYMBOL(fn); \
|
||||
|
Reference in New Issue
Block a user