Skip to content

Commit

Permalink
Revert "Move heap ownership info from chunk to pagemap (#4368)"
Browse files Browse the repository at this point in the history
This reverts commit afb94f6.
  • Loading branch information
jemc committed Aug 1, 2023
1 parent a1a1446 commit 9a478e5
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 215 deletions.
10 changes: 5 additions & 5 deletions packages/builtin_test/_test.pony
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use @pony_alloc_final[Pointer[U8]](ctx: Pointer[None], size: USize)
use @pony_exitcode[None](code: I32)
use @pony_get_exitcode[I32]()
use @pony_triggergc[None](ctx: Pointer[None])
use @ponyint_pagemap_get_chunk[Pointer[None]](p: Pointer[None] tag)
use @ponyint_pagemap_get[Pointer[None]](p: Pointer[None] tag)

use "pony_test"
use "collections"
Expand Down Expand Up @@ -617,12 +617,12 @@ class \nodoc\ iso _TestStringTrimInPlace is UnitTest
space: USize = 0)
=>
let copy: String ref = orig.clone()
let pre_trim_pagemap = @ponyint_pagemap_get_chunk(copy.cpointer())
let pre_trim_pagemap = @ponyint_pagemap_get(copy.cpointer())
copy.trim_in_place(from, to)
h.assert_eq[String box](expected, copy)
h.assert_eq[USize](space, copy.space())
h.assert_eq[String box](expected, copy.clone()) // safe to clone
let post_trim_pagemap = @ponyint_pagemap_get_chunk(copy.cpointer())
let post_trim_pagemap = @ponyint_pagemap_get(copy.cpointer())
if copy.space() == 0 then
h.assert_eq[USize](0, post_trim_pagemap.usize())
else
Expand Down Expand Up @@ -1480,11 +1480,11 @@ class \nodoc\ iso _TestArrayTrimInPlace is UnitTest
space: USize = 0)
=>
let copy: Array[U8] ref = orig.clone()
let pre_trim_pagemap = @ponyint_pagemap_get_chunk(copy.cpointer())
let pre_trim_pagemap = @ponyint_pagemap_get(copy.cpointer())
copy.trim_in_place(from, to)
h.assert_eq[USize](space, copy.space())
h.assert_array_eq[U8](expected, copy)
let post_trim_pagemap = @ponyint_pagemap_get_chunk(copy.cpointer())
let post_trim_pagemap = @ponyint_pagemap_get(copy.cpointer())
if copy.space() == 0 then
h.assert_eq[USize](0, post_trim_pagemap.usize())
else
Expand Down
27 changes: 16 additions & 11 deletions src/libponyrt/gc/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,7 @@ static void acq_or_rel_remote_object(pony_ctx_t* ctx, pony_actor_t* actor,
void ponyint_gc_sendobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
int mutability)
{
pony_actor_t* actor = NULL;
chunk_t* chunk = ponyint_pagemap_get(p, &actor);
chunk_t* chunk = ponyint_pagemap_get(p);

// Don't gc memory that wasn't pony_allocated, but do recurse.
if(chunk == NULL)
Expand All @@ -493,6 +492,8 @@ void ponyint_gc_sendobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
return;
}

pony_actor_t* actor = ponyint_heap_owner(chunk);

if(actor == ctx->current)
send_local_object(ctx, p, t, mutability);
else
Expand All @@ -502,8 +503,7 @@ void ponyint_gc_sendobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
void ponyint_gc_recvobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
int mutability)
{
pony_actor_t* actor = NULL;
chunk_t* chunk = ponyint_pagemap_get(p, &actor);
chunk_t* chunk = ponyint_pagemap_get(p);

// Don't gc memory that wasn't pony_allocated, but do recurse.
if(chunk == NULL)
Expand All @@ -513,6 +513,8 @@ void ponyint_gc_recvobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
return;
}

pony_actor_t* actor = ponyint_heap_owner(chunk);

if(actor == ctx->current)
recv_local_object(ctx, p, t, mutability);
else
Expand All @@ -522,8 +524,7 @@ void ponyint_gc_recvobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
void ponyint_gc_markobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
int mutability)
{
pony_actor_t* actor = NULL;
chunk_t* chunk = ponyint_pagemap_get(p, &actor);
chunk_t* chunk = ponyint_pagemap_get(p);

// Don't gc memory that wasn't pony_allocated, but do recurse.
if(chunk == NULL)
Expand All @@ -533,6 +534,8 @@ void ponyint_gc_markobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
return;
}

pony_actor_t* actor = ponyint_heap_owner(chunk);

if(actor == ctx->current)
mark_local_object(ctx, chunk, p, t, mutability);
else
Expand All @@ -542,8 +545,7 @@ void ponyint_gc_markobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
void ponyint_gc_acquireobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
int mutability)
{
pony_actor_t* actor = NULL;
chunk_t* chunk = ponyint_pagemap_get(p, &actor);
chunk_t* chunk = ponyint_pagemap_get(p);

// Don't gc memory that wasn't pony_allocated, but do recurse.
if(chunk == NULL)
Expand All @@ -553,6 +555,8 @@ void ponyint_gc_acquireobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
return;
}

pony_actor_t* actor = ponyint_heap_owner(chunk);

if(actor == ctx->current)
acquire_local_object(ctx, p, t, mutability);
else
Expand All @@ -562,8 +566,7 @@ void ponyint_gc_acquireobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
void ponyint_gc_releaseobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
int mutability)
{
pony_actor_t* actor = NULL;
chunk_t* chunk = ponyint_pagemap_get(p, &actor);
chunk_t* chunk = ponyint_pagemap_get(p);

// Don't gc memory that wasn't pony_allocated, but do recurse.
if(chunk == NULL)
Expand All @@ -573,6 +576,8 @@ void ponyint_gc_releaseobject(pony_ctx_t* ctx, void* p, pony_type_t* t,
return;
}

pony_actor_t* actor = ponyint_heap_owner(chunk);

if(actor == ctx->current)
release_local_object(ctx, p, t, mutability);
else
Expand Down Expand Up @@ -660,7 +665,7 @@ void ponyint_gc_markimmutable(pony_ctx_t* ctx, gc_t* gc)
{
// Mark in our heap and recurse if it wasn't already marked.
void* p = obj->address;
chunk_t* chunk = ponyint_pagemap_get_chunk(p);
chunk_t* chunk = ponyint_pagemap_get(p);
mark_local_object(ctx, chunk, p, obj->type, PONY_TRACE_IMMUTABLE);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libponyrt/gc/objectmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ void ponyint_objectmap_sweep(objectmap_t* map)

if(obj->rc > 0)
{
chunk_t* chunk = ponyint_pagemap_get_chunk(p);
chunk_t* chunk = ponyint_pagemap_get(p);
ponyint_heap_mark_shallow(chunk, p);
} else {
ponyint_objectmap_clearindex(map, i);
Expand Down
31 changes: 24 additions & 7 deletions src/libponyrt/mem/heap.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

typedef struct chunk_t
{
// immutable
pony_actor_t* actor;

// used for pointer tagging
// bit 0 (lowest bit) for keeping track of chunk type (1 = small; 0 = large)
// bit 1 for keeping track of chunks to be cleared
Expand Down Expand Up @@ -235,9 +238,9 @@ static char* get_m(chunk_t* chunk)
return (char*)((uintptr_t)chunk->m & CHUNK_M_BITMASK);
}

static void large_pagemap(char* m, size_t size, chunk_t* chunk, pony_actor_t* actor)
static void large_pagemap(char* m, size_t size, chunk_t* chunk)
{
ponyint_pagemap_set_bulk(m, chunk, actor, size);
ponyint_pagemap_set_bulk(m, chunk, size);
}

static void maybe_clear_chunk(chunk_t* chunk)
Expand Down Expand Up @@ -323,7 +326,7 @@ static void destroy_small(small_chunk_t* chunk, uint32_t mark)
final_small(chunk, FORCE_ALL_FINALISERS);

char* m = get_m((chunk_t*)chunk);
ponyint_pagemap_set(m, NULL, NULL);
ponyint_pagemap_set(m, NULL);
POOL_FREE(block_t, m);
POOL_FREE(small_chunk_t, chunk);
}
Expand All @@ -337,7 +340,7 @@ static void destroy_large(large_chunk_t* chunk, uint32_t mark)
final_large(chunk, mark);

char* m = get_m((chunk_t*)chunk);
large_pagemap(m, chunk->size, NULL, NULL);
large_pagemap(m, chunk->size, NULL);

if(m != NULL)
ponyint_pool_free_size(chunk->size, m);
Expand Down Expand Up @@ -594,6 +597,7 @@ void* ponyint_heap_alloc_small(pony_actor_t* actor, heap_t* heap,
}
} else {
small_chunk_t* n = (small_chunk_t*) POOL_ALLOC(small_chunk_t);
n->base.actor = actor;
n->base.m = (char*) POOL_ALLOC(block_t);
set_small_chunk_size(n, sizeclass);
#ifdef USE_RUNTIMESTATS
Expand All @@ -613,7 +617,7 @@ void* ponyint_heap_alloc_small(pony_actor_t* actor, heap_t* heap,

set_chunk_needs_clearing((chunk_t*)n);

ponyint_pagemap_set(get_m((chunk_t*)n), (chunk_t*)n, actor);
ponyint_pagemap_set(get_m((chunk_t*)n), (chunk_t*)n);

heap->small_free[sizeclass] = n;
chunk = n;
Expand Down Expand Up @@ -644,6 +648,7 @@ void* ponyint_heap_alloc_large(pony_actor_t* actor, heap_t* heap, size_t size,
size = ponyint_pool_adjust_size(size);

large_chunk_t* chunk = (large_chunk_t*) POOL_ALLOC(large_chunk_t);
chunk->base.actor = actor;
chunk->size = size;
chunk->base.m = (char*) ponyint_pool_alloc_size(size);
#ifdef USE_RUNTIMESTATS
Expand All @@ -661,7 +666,7 @@ void* ponyint_heap_alloc_large(pony_actor_t* actor, heap_t* heap, size_t size,
// note if a finaliser needs to run or not
set_large_chunk_finaliser(chunk, (track_finalisers_mask & 1));

large_pagemap(get_m((chunk_t*)chunk), size, (chunk_t*)chunk, actor);
large_pagemap(get_m((chunk_t*)chunk), size, (chunk_t*)chunk);

chunk->next = heap->large;
heap->large = chunk;
Expand All @@ -680,7 +685,7 @@ void* ponyint_heap_realloc(pony_actor_t* actor, heap_t* heap, void* p,
actor->actorstats.heap_realloc_counter++;
#endif

chunk_t* chunk = ponyint_pagemap_get_chunk(p);
chunk_t* chunk = ponyint_pagemap_get(p);

// We can't realloc memory that wasn't pony_alloc'ed since we can't know how
// much to copy from the previous location.
Expand Down Expand Up @@ -903,6 +908,18 @@ void ponyint_heap_endgc(heap_t* heap
heap->next_gc = heap_initialgc;
}

pony_actor_t* ponyint_heap_owner(chunk_t* chunk)
{
// FIX: false sharing
// reading from something that will never be written
// but is on a cache line that will often be written
// called during tracing
// actual chunk only needed for GC tracing
// all other tracing only needs the owner
// so the owner needs the chunk and everyone else just needs the owner
return chunk->actor;
}

size_t ponyint_heap_size(chunk_t* chunk)
{
if(get_chunk_is_small_chunk(chunk))
Expand Down
2 changes: 2 additions & 0 deletions src/libponyrt/mem/heap.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ void ponyint_heap_endgc(heap_t* heap
);
#endif

pony_actor_t* ponyint_heap_owner(chunk_t* chunk);

size_t ponyint_heap_size(chunk_t* chunk);

#ifdef USE_RUNTIMESTATS
Expand Down
Loading

0 comments on commit 9a478e5

Please sign in to comment.