From 8f14785f10988095a95ff1ac56ba215e8017d4e4 Mon Sep 17 00:00:00 2001 From: dearblue Date: Sun, 4 Feb 2024 21:55:54 +0900 Subject: [PATCH] Stop pseudo flexible array in `mrb_heap_page` For reference, the flexible array was introduced by commit 3ab2f9371e60039936356afaee9f509d782259fd (#2997). Subsequently changed for compatibility with C++ by commit 24939723d77291152298acc2fb6415b3d1fe2c24 (#5596). --- src/gc.c | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/src/gc.c b/src/gc.c index a39d4e47f..b5abd76a6 100644 --- a/src/gc.c +++ b/src/gc.c @@ -153,8 +153,7 @@ typedef struct mrb_heap_page { struct mrb_heap_page *next; struct mrb_heap_page *free_next; mrb_bool old:1; - /* Flexible array members are not C++ compatible */ - /* void* objects[]; */ + RVALUE objects[MRB_HEAP_PAGE_SIZE]; } mrb_heap_page; #define GC_STEP_SIZE 1024 @@ -181,12 +180,6 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK); #define other_white_part(s) ((s)->current_white_part ^ GC_WHITES) #define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE) -/* We have removed `objects[]` from `mrb_heap_page` since it was not C++ - * compatible. Using array index to get pointer after structure instead. */ - -/* #define objects(p) ((RVALUE*)p->objects) */ -#define objects(p) ((RVALUE*)&p[1]) - mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb); MRB_API void* @@ -279,7 +272,7 @@ heap_p(mrb_gc *gc, struct RBasic *object) while (page) { RVALUE *p; - p = objects(page); + p = page->objects; if (&p[0].as.basic <= object && object <= &p[MRB_HEAP_PAGE_SIZE - 1].as.basic) { return TRUE; } @@ -299,11 +292,11 @@ mrb_object_dead_p(mrb_state *mrb, struct RBasic *object) static void add_heap(mrb_state *mrb, mrb_gc *gc) { - mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page) + MRB_HEAP_PAGE_SIZE * sizeof(RVALUE)); + mrb_heap_page *page = (mrb_heap_page*)mrb_calloc(mrb, 1, sizeof(mrb_heap_page)); RVALUE *p, *e; struct RBasic *prev = NULL; - for (p = objects(page), e=p+MRB_HEAP_PAGE_SIZE; pobjects, e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt = MRB_TT_FREE; p->as.free.next = prev; prev = &p->as.basic; @@ -357,7 +350,7 @@ free_heap(mrb_state *mrb, mrb_gc *gc) while (page) { tmp = page; page = page->next; - for (p = objects(tmp), e=p+MRB_HEAP_PAGE_SIZE; pobjects, e=p+MRB_HEAP_PAGE_SIZE; pas.free.tt != MRB_TT_FREE) obj_free(mrb, &p->as.basic, TRUE); } @@ -1079,7 +1072,7 @@ incremental_sweep_phase(mrb_state *mrb, mrb_gc *gc, size_t limit) size_t tried_sweep = 0; while (page && (tried_sweep < limit)) { - RVALUE *p = objects(page); + RVALUE *p = page->objects; RVALUE *e = p + MRB_HEAP_PAGE_SIZE; size_t freed = 0; mrb_bool dead_slot = TRUE; @@ -1539,7 +1532,7 @@ gc_each_objects(mrb_state *mrb, mrb_gc *gc, mrb_each_object_callback *callback, while (page != NULL) { RVALUE *p; - p = objects(page); + p = page->objects; for (int i=0; i < MRB_HEAP_PAGE_SIZE; i++) { if ((*callback)(mrb, &p[i].as.basic, data) == MRB_EACH_OBJ_BREAK) return;