예제 #1
0
파일: trace.c 프로젝트: awaidmann/ponyc
void ponyint_mark_done(pony_ctx_t* ctx)
{
  ponyint_gc_markimmutable(ctx, ponyint_actor_gc(ctx->current));
  ponyint_gc_handlestack(ctx);
  ponyint_gc_sendacquire(ctx);
  ponyint_gc_sweep(ctx, ponyint_actor_gc(ctx->current));
  ponyint_gc_done(ponyint_actor_gc(ctx->current));
}
예제 #2
0
파일: gc.c 프로젝트: killerswan/ponyc
static void release_local_object(pony_ctx_t* ctx, void* p, pony_type_t* t,
  int mutability)
{
  size_t index = HASHMAP_UNKNOWN;
  gc_t* gc = ponyint_actor_gc(ctx->current);
  object_t* obj = ponyint_objectmap_getobject(&gc->local, p, &index);
  pony_assert(obj != NULL);

  if(obj->mark == gc->mark)
    return;

  // Implicitly release the owner.
  release_local_actor(gc);

  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);
}
예제 #3
0
파일: gc.c 프로젝트: killerswan/ponyc
static void send_local_object(pony_ctx_t* ctx, void* p, pony_type_t* t,
  int mutability)
{
  gc_t* gc = ponyint_actor_gc(ctx->current);
  object_t* obj = ponyint_objectmap_getorput(&gc->local, p, gc->mark);

  if(obj->mark == gc->mark)
    return;

  // Implicitly send the owner.
  send_local_actor(gc);

  // Inc, mark, and recurse if not immutable.
  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);
}
예제 #4
0
파일: gc.c 프로젝트: killerswan/ponyc
static void acq_or_rel_remote_object(pony_ctx_t* ctx, pony_actor_t* actor,
  void* p, pony_type_t* t, int mutability)
{
  gc_t* gc = ponyint_actor_gc(ctx->current);
  actorref_t* aref = ponyint_actormap_getorput(&ctx->acquire, actor, 0);
  object_t* obj = ponyint_actorref_getorput(aref, p, gc->mark);

  if(obj->mark == gc->mark)
    return;

  // Implicitly acquire/release the owner.
  acq_or_rel_remote_actor(ctx, actor);

  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);
}
예제 #5
0
파일: gc.c 프로젝트: killerswan/ponyc
void ponyint_gc_releaseactor(pony_ctx_t* ctx, pony_actor_t* actor)
{
  if(actor == ctx->current)
    release_local_actor(ponyint_actor_gc(ctx->current));
  else
    acq_or_rel_remote_actor(ctx, actor);
}
예제 #6
0
파일: gc.c 프로젝트: cyisfor/ponyc
static void recv_local_object(pony_ctx_t* ctx, void* p, pony_trace_fn f,
  bool immutable)
{
  // get the object
  gc_t* gc = ponyint_actor_gc(ctx->current);
  object_t* obj = ponyint_objectmap_getobject(&gc->local, p);
  assert(obj != NULL);

  if(obj->mark == gc->mark)
    return;

  // Implicitly receive the owner.
  recv_local_actor(gc);

  // Dec, mark and recurse. Mark as reachable from the actor, since a
  // release message for this object could arrive before a gc pass.
  obj->rc--;
  obj->mark = gc->mark;
  obj->reachable = true;

  if(immutable)
    obj->immutable = true;

  if(!obj->immutable)
    recurse(ctx, p, f);
}
예제 #7
0
파일: gc.c 프로젝트: cyisfor/ponyc
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);
}
예제 #8
0
파일: trace.c 프로젝트: enigma/ponyc
void pony_recv_done(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));

  DTRACE1(GC_RECV_END, (uintptr_t)ctx->scheduler);
}
예제 #9
0
파일: gc.c 프로젝트: cyisfor/ponyc
void ponyint_gc_createactor(pony_actor_t* current, pony_actor_t* actor)
{
  gc_t* gc = ponyint_actor_gc(current);
  actorref_t* aref = ponyint_actormap_getorput(&gc->foreign, actor, gc->mark);
  aref->rc = GC_INC_MORE;
  gc->delta = ponyint_deltamap_update(gc->delta, actor, aref->rc);
  ponyint_heap_used(ponyint_actor_heap(current), GC_ACTOR_HEAP_EQUIV);
}
예제 #10
0
파일: trace.c 프로젝트: enigma/ponyc
void pony_send_done(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_sendacquire(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));

  DTRACE1(GC_SEND_END, (uintptr_t)ctx->scheduler);
}
예제 #11
0
파일: gc.c 프로젝트: cyisfor/ponyc
void ponyint_gc_markactor(pony_ctx_t* ctx, pony_actor_t* actor)
{
  if(actor == ctx->current)
    return;

  gc_t* gc = ponyint_actor_gc(ctx->current);
  actorref_t* aref = ponyint_actormap_getactor(&gc->foreign, actor);
  mark_remote_actor(ctx, gc, aref);
}
예제 #12
0
파일: trace.c 프로젝트: awaidmann/ponyc
void pony_recv_done(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));

#ifdef USE_TELEMETRY
  ctx->time_in_recv_scan += (ponyint_cpu_tick() - ctx->tsc);
#endif
}
예제 #13
0
파일: gc.c 프로젝트: cyisfor/ponyc
void ponyint_gc_recvactor(pony_ctx_t* ctx, pony_actor_t* actor)
{
  gc_t* gc = ponyint_actor_gc(ctx->current);

  if(actor == ctx->current)
  {
    recv_local_actor(gc);
  } else {
    actorref_t* aref = ponyint_actormap_getorput(&gc->foreign, actor, gc->mark);
    recv_remote_actor(ctx, gc, aref);
  }
}
예제 #14
0
파일: gc.c 프로젝트: cyisfor/ponyc
static void send_remote_object(pony_ctx_t* ctx, pony_actor_t* actor,
  void* p, pony_trace_fn f, bool immutable)
{
  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 send the owner.
  send_remote_actor(ctx, gc, aref);

  // Mark the object.
  obj->mark = gc->mark;

  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 sending 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 - 1);
    obj->immutable = true;
    acquire_object(ctx, actor, p, true);

    immutable = false;
  } else if(obj->rc <= 1) {
    // 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((obj->rc > 0) || immutable || (f == NULL));

    // Add to the acquire message and decrement.
    if(immutable)
      obj->immutable = true;

    obj->rc += (GC_INC_MORE - 1);
    acquire_object(ctx, actor, p, obj->immutable);
  } else {
    // Decrement.
    obj->rc--;
  }

  if(!immutable)
    recurse(ctx, p, f);
}
예제 #15
0
파일: gc.c 프로젝트: killerswan/ponyc
static void send_remote_object(pony_ctx_t* ctx, pony_actor_t* actor,
  void* p, pony_type_t* t, int mutability)
{
  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 send the owner.
  send_remote_actor(ctx, gc, aref);

  // Mark the object.
  obj->mark = gc->mark;

  if((mutability == PONY_TRACE_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 sending 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 - 1);
    obj->immutable = true;
    acquire_object(ctx, actor, p, true);

    // Set the to PONY_TRACE_MUTABLE to force recursion.
    mutability = PONY_TRACE_MUTABLE;
  } else if(obj->rc <= 1) {
    // If we haven't seen this object, it's an object that is reached from
    // another immutable object we received, or it's a pointer to an embedded
    // field received in an iso. Invent some references to this object and
    // acquire it.
    if(mutability == PONY_TRACE_IMMUTABLE)
      obj->immutable = true;

    // Add to the acquire message and decrement.
    obj->rc += (GC_INC_MORE - 1);
    acquire_object(ctx, actor, p, obj->immutable);
  } else {
    // Decrement.
    obj->rc--;
  }

  if(mutability == PONY_TRACE_MUTABLE)
    recurse(ctx, p, t->trace);
}
예제 #16
0
파일: gc.c 프로젝트: cyisfor/ponyc
static void send_local_object(pony_ctx_t* ctx, void* p, pony_trace_fn f,
  bool immutable)
{
  gc_t* gc = ponyint_actor_gc(ctx->current);
  object_t* obj = ponyint_objectmap_getorput(&gc->local, p, gc->mark);

  if(obj->mark == gc->mark)
    return;

  // Implicitly send the owner.
  send_local_actor(gc);

  // Inc, mark, and recurse if not immutable.
  obj->rc++;
  obj->mark = gc->mark;

  if(immutable)
    obj->immutable = true;

  if(!obj->immutable)
    recurse(ctx, p, f);
}
예제 #17
0
파일: gc.c 프로젝트: killerswan/ponyc
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);
}
예제 #18
0
파일: trace.c 프로젝트: enigma/ponyc
void pony_send_next(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));
}
예제 #19
0
파일: gc.c 프로젝트: cyisfor/ponyc
  ponyint_actormap_destroy(&ctx->acquire);
  memset(&ctx->acquire, 0, sizeof(actormap_t));
}

void ponyint_gc_sendrelease(pony_ctx_t* ctx, gc_t* gc)
{
  gc->delta = ponyint_actormap_sweep(ctx, &gc->foreign, gc->mark, gc->delta);
}

void ponyint_gc_register_final(pony_ctx_t* ctx, void* p, pony_final_fn final)
{
  if(!ctx->finalising)
  {
    // If we aren't finalising an actor, register the finaliser.
    gc_t* gc = ponyint_actor_gc(ctx->current);
    ponyint_objectmap_register_final(&gc->local, p, final, gc->mark);
    gc->finalisers++;
  } else {
    // Otherwise, put the finaliser on the gc stack.
    recurse(ctx, p, final);
  }
}

void ponyint_gc_final(pony_ctx_t* ctx, gc_t* gc)
{
  if(gc->finalisers == 0)
    return;

  // Set the finalising flag.
  ctx->finalising = true;
예제 #20
0
파일: trace.c 프로젝트: awaidmann/ponyc
void pony_acquire_done(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_sendacquire(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));
}
예제 #21
0
파일: trace.c 프로젝트: awaidmann/ponyc
void pony_release_done(pony_ctx_t* ctx)
{
  ponyint_gc_handlestack(ctx);
  ponyint_gc_sendrelease_manual(ctx);
  ponyint_gc_done(ponyint_actor_gc(ctx->current));
}