gc.c (mrb_obj_alloc): remove free_next,free_prev from heap pages

It used to be maintain heap pages with allocatable objects (free_heaps)
but we can save two words (16 bytes) per page by scanning live heap pages.
This commit is contained in:
Yukihiro "Matz" Matsumoto
2023-06-26 23:56:45 +09:00
parent 695ad6ea95
commit 38b9a25e83
2 changed files with 10 additions and 41 deletions
-3
View File
@@ -45,8 +45,6 @@ typedef struct mrb_heap_page {
struct RBasic *freelist;
struct mrb_heap_page *prev;
struct mrb_heap_page *next;
struct mrb_heap_page *free_next;
struct mrb_heap_page *free_prev;
mrb_bool old:1;
/* Flexible array members area a C99 feature, not C++ compatible */
/* void* objects[]; */
@@ -59,7 +57,6 @@ typedef struct mrb_heap_page {
typedef struct mrb_gc {
mrb_heap_page *heaps; /* heaps for GC */
mrb_heap_page *sweeps; /* page where sweep starts */
mrb_heap_page *free_heaps;
struct RBasic *gray_list; /* list of gray objects to be traversed incrementally */
struct RBasic *atomic_gray_list; /* list of objects to be traversed atomically */
size_t live; /* count of live objects */
+10 -38
View File
@@ -309,29 +309,6 @@ unlink_heap_page(mrb_gc *gc, mrb_heap_page *page)
page->next = NULL;
}
static void
link_free_heap_page(mrb_gc *gc, mrb_heap_page *page)
{
page->free_next = gc->free_heaps;
if (gc->free_heaps) {
gc->free_heaps->free_prev = page;
}
gc->free_heaps = page;
}
static void
unlink_free_heap_page(mrb_gc *gc, mrb_heap_page *page)
{
if (page->free_prev)
page->free_prev->free_next = page->free_next;
if (page->free_next)
page->free_next->free_prev = page->free_prev;
if (gc->free_heaps == page)
gc->free_heaps = page->free_next;
page->free_prev = NULL;
page->free_next = NULL;
}
static void
add_heap(mrb_state *mrb, mrb_gc *gc)
{
@@ -347,7 +324,6 @@ add_heap(mrb_state *mrb, mrb_gc *gc)
page->freelist = prev;
link_heap_page(gc, page);
link_free_heap_page(gc, page);
}
#define DEFAULT_GC_INTERVAL_RATIO 200
@@ -368,7 +344,6 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc)
gc->current_white_part = GC_WHITE_A;
gc->heaps = NULL;
gc->free_heaps = NULL;
add_heap(mrb, gc);
gc->interval_ratio = DEFAULT_GC_INTERVAL_RATIO;
gc->step_ratio = DEFAULT_GC_STEP_RATIO;
@@ -497,7 +472,6 @@ mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
MRB_API struct RBasic*
mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
{
struct RBasic *p;
static const RVALUE RVALUE_zero = { { { NULL, NULL, MRB_TT_FALSE } } };
mrb_gc *gc = &mrb->gc;
@@ -534,15 +508,18 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls)
if (gc->threshold < gc->live) {
mrb_incremental_gc(mrb);
}
if (gc->free_heaps == NULL) {
add_heap(mrb, gc);
}
p = gc->free_heaps->freelist;
gc->free_heaps->freelist = ((struct free_obj*)p)->next;
if (gc->free_heaps->freelist == NULL) {
unlink_free_heap_page(gc, gc->free_heaps);
mrb_heap_page *page = gc->heaps;
struct RBasic *p = NULL;
while (page->freelist == NULL) {
page = page->next;
if (page == NULL) {
add_heap(mrb, gc);
page = gc->heaps;
}
}
p = page->freelist;
page->freelist = ((struct free_obj*)p)->next;
gc->live++;
gc_protect(mrb, gc, p);
@@ -1109,7 +1086,6 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
RVALUE *e = p + MRB_HEAP_PAGE_SIZE;
size_t freed = 0;
mrb_bool dead_slot = TRUE;
mrb_bool full = (page->freelist == NULL);
if (is_minor_gc(gc) && page->old) {
/* skip a slot which doesn't contain any young object */
@@ -1143,14 +1119,10 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit)
mrb_heap_page *next = page->next;
unlink_heap_page(gc, page);
unlink_free_heap_page(gc, page);
mrb_free(mrb, page);
page = next;
}
else {
if (full && freed > 0) {
link_free_heap_page(gc, page);
}
if (page->freelist == NULL && is_minor_gc(gc))
page->old = TRUE;
else