static void recv_remote_object(pony_ctx_t* ctx, pony_actor_t* actor, void* p, pony_trace_fn f, bool immutable, chunk_t* chunk) { gc_t* gc = ponyint_actor_gc(ctx->current); actorref_t* aref = ponyint_actormap_getorput(&gc->foreign, actor, gc->mark); object_t* obj = ponyint_actorref_getorput(aref, p, gc->mark); if(obj->mark == gc->mark) return; // Implicitly receive the owner. recv_remote_actor(ctx, gc, aref); // If this is our first reference, add to our heap used size. if(obj->rc == 0) ponyint_heap_used(ponyint_actor_heap(ctx->current), ponyint_heap_size(chunk)); // Inc, mark and recurse. obj->rc++; obj->mark = gc->mark; if(immutable) obj->immutable = true; if(!obj->immutable) recurse(ctx, p, f); }
static void mark_remote_object(pony_ctx_t* ctx, pony_actor_t* actor, void* p, pony_trace_fn f, bool immutable, chunk_t* chunk) { gc_t* gc = ponyint_actor_gc(ctx->current); actorref_t* aref = ponyint_actormap_getorput(&gc->foreign, actor, gc->mark); object_t* obj = ponyint_actorref_getorput(aref, p, gc->mark); if(obj->mark == gc->mark) return; // Implicitly mark the owner. mark_remote_actor(ctx, gc, aref); // Mark the object. obj->mark = gc->mark; // Add to heap used size. ponyint_heap_used(ponyint_actor_heap(ctx->current), ponyint_heap_size(chunk)); if(immutable && !obj->immutable && (obj->rc > 0)) { // If we received the object as not immutable (it's not marked as immutable // and it has an RC > 0), but we are now marking it as immutable, we need // to acquire it in order to inform the owner it is now immutable. But we // also need to continue tracing, to protect the contents until the owner // has received the acquire messages. obj->rc += GC_INC_MORE; obj->immutable = true; acquire_object(ctx, actor, p, true); immutable = false; } else if(obj->rc == 0) { // If we haven't seen this object, it's an object that is reached from // another immutable object we received. Invent some references to this // object and acquire it. This object should either be immutable or a tag. assert(immutable || (f == NULL)); if(immutable) obj->immutable = true; obj->rc += GC_INC_MORE; acquire_object(ctx, actor, p, obj->immutable); } if(!immutable) recurse(ctx, p, f); }
static void recv_remote_object(pony_ctx_t* ctx, pony_actor_t* actor, void* p, pony_type_t* t, int mutability, chunk_t* chunk) { gc_t* gc = ponyint_actor_gc(ctx->current); actorref_t* aref = ponyint_actormap_getorput(&gc->foreign, actor, gc->mark); object_t* obj = ponyint_actorref_getorput(aref, p, gc->mark); if(obj->mark == gc->mark) return; // Implicitly receive the owner. recv_remote_actor(ctx, gc, aref); if(obj->rc == 0) { // Increase apparent used memory to provoke GC. ponyint_heap_used(ponyint_actor_heap(ctx->current), ponyint_heap_size(chunk)); // Increase apparent used memory further if the object is immutable, to // account for memory that is reachable but not traced by this actor. if(mutability == PONY_TRACE_IMMUTABLE) ponyint_heap_used(ponyint_actor_heap(ctx->current), GC_IMMUT_HEAP_EQUIV); } // Inc, mark and recurse. obj->rc++; obj->mark = gc->mark; if(mutability == PONY_TRACE_OPAQUE) return; if(mutability == PONY_TRACE_IMMUTABLE) obj->immutable = true; if(!obj->immutable) recurse(ctx, p, t->trace); }