lisp-take-1/gc/dec_external_refcount.c

79 lines
1.9 KiB
C

#include <assert.h>
#include <debug.h>
#include <value/struct.h>
#include "linked_list/append.h"
#include "linked_list/remove.h"
#include "dotout.h"
#include "flags.h"
#include "struct.h"
#include "dec_external_refcount.h"
void gc_dec_external_refcount(
struct gc* this,
struct value* value)
{
ENTER;
if (value)
{
assert(value->external_refcount > 0);
if (value->external_refcount > 1)
{
value->external_refcount--;
}
else if (value->external_refcount == 1)
{
assert(value->externally_referenced.in_set == true);
assert(value->internally_referenced.in_set == false);
assert(value->white.in_set == false);
assert(value->reaped.in_set == false);
#ifdef DOTOUT_BUILD
if (this->flags->dotout)
{
gc_dotout(this, "gc_dec_external_refcount: before");
}
#endif
value->external_refcount--;
linked_list_remove(
/* linked list: */ &this->externally_referenced,
/* element: */ value,
/* link offset: */ offsetof(struct value, externally_referenced));
// it might be in the grey set, but that's okay.
linked_list_append(
/* linked list: */ &this->internally_referenced,
/* element: */ value,
/* link offset: */ offsetof(struct value, internally_referenced));
#ifdef DOTOUT_BUILD
if (this->flags->dotout)
{
gc_dotout(this, "gc_dec_external_refcount: after");
}
#endif
assert(value->internally_referenced.in_set);
}
else
{
NOPE;
}
}
EXIT;
}