lisp-take-1/gc/inc_external_refcount.c

87 lines
2 KiB
C

#include <assert.h>
#include <debug.h>
#include <value/struct.h>
#include "linked_list/remove.h"
#include "linked_list/append.h"
#include "dotout.h"
#include "flags.h"
#include "struct.h"
#include "inc_external_refcount.h"
struct value* gc_inc_external_refcount(
struct gc* this,
struct value* value)
{
ENTER;
if (value)
{
if (value->external_refcount == 0)
{
assert(value->internally_referenced.in_set == true);
assert(value->externally_referenced.in_set == false);
#ifdef DOTOUT_BUILD
if (this->flags->dotout)
{
gc_dotout(this, "gc_inc_external_refcount: before");
}
#endif
value->external_refcount++;
linked_list_remove(
/* linked list: */ &this->internally_referenced,
/* element: */ value,
/* link offset: */ offsetof(struct value, internally_referenced));
if (value->white.in_set)
{
linked_list_remove(
/* linked list: */ &this->white,
/* element: */ value,
/* link offset: */ offsetof(struct value, white));
}
// if it's in the grey set, that's not a problem
linked_list_append(
/* linked list: */ &this->externally_referenced,
/* element: */ value,
/* link offset: */ offsetof(struct value, externally_referenced));
#ifdef DOTOUT_BUILD
if (this->flags->dotout)
{
gc_dotout(this, "gc_inc_external_refcount: after");
}
#endif
assert(value->externally_referenced.in_set == true);
}
else
{
value->external_refcount++;
}
}
EXIT;
return value;
}