#include #include #include #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; }