79 lines
1.9 KiB
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;
|
|
}
|
|
|
|
|
|
|
|
|
|
|