bool ponyint_gc_acquire(gc_t* gc, actorref_t* aref) { size_t rc = aref->rc; gc->rc += rc; objectmap_t* map = &aref->map; size_t i = HASHMAP_BEGIN; object_t* obj; while((obj = ponyint_objectmap_next(map, &i)) != NULL) { // Add to our RC. The object may not be in our object map, if it was // reached through another immutable reference. object_t* obj_local = ponyint_objectmap_getorput(&gc->local, obj->address, gc->mark); obj_local->rc += obj->rc; // Mark as immutable if necessary. if(obj->immutable) obj_local->immutable = true; } ponyint_actorref_free(aref); return rc > 0; }
bool ponyint_gc_release(gc_t* gc, actorref_t* aref) { size_t rc = aref->rc; assert(gc->rc >= rc); gc->rc -= rc; objectmap_t* map = &aref->map; size_t i = HASHMAP_BEGIN; object_t* obj; while((obj = ponyint_objectmap_next(map, &i)) != NULL) { void* p = obj->address; object_t* obj_local = ponyint_objectmap_getobject(&gc->local, p); assert(obj_local->rc >= obj->rc); obj_local->rc -= obj->rc; if(obj_local->rc == 0) { // The local rc for this object has dropped to zero. We keep track of // whether or not the object was reachable. If we go to 0 rc and it // wasn't reachable, we free it. If we receive the object in a message, // mark it as reachable again. if(!obj_local->reachable) { chunk_t* chunk = (chunk_t*)ponyint_pagemap_get(p); ponyint_heap_free(chunk, p); } } } ponyint_actorref_free(aref); return rc > 0; }
static void send_release(pony_ctx_t* ctx, actorref_t* aref) { if(aref == NULL) return; if(ponyint_actor_pendingdestroy(aref->actor) || ((aref->rc == 0) && (ponyint_objectmap_size(&aref->map) == 0)) ) { ponyint_actorref_free(aref); return; } pony_sendp(ctx, aref->actor, ACTORMSG_RELEASE, aref); }
bool ponyint_gc_release(gc_t* gc, actorref_t* aref) { size_t rc = aref->rc; pony_assert(gc->rc >= rc); gc->rc -= rc; objectmap_t* map = &aref->map; size_t i = HASHMAP_BEGIN; object_t* obj; size_t index = HASHMAP_UNKNOWN; while((obj = ponyint_objectmap_next(map, &i)) != NULL) { void* p = obj->address; object_t* obj_local = ponyint_objectmap_getobject(&gc->local, p, &index); pony_assert(obj_local->rc >= obj->rc); obj_local->rc -= obj->rc; } ponyint_actorref_free(aref); return rc > 0; }