Skip to content

Commit d3554d3

Browse files
committed
Fix GC compaction
1 parent 8946b0c commit d3554d3

File tree

2 files changed

+18
-21
lines changed

2 files changed

+18
-21
lines changed

gc.c

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,6 +2058,16 @@ remove_obj_from_freelist(rb_heap_t *heap, VALUE obj)
20582058
GC_ASSERT(prev == NULL);
20592059
heap->freelist = next;
20602060
}
2061+
2062+
if (p == GET_HEAP_PAGE(p)->freelist) {
2063+
GC_ASSERT(prev == NULL);
2064+
GET_HEAP_PAGE(p)->freelist = next;
2065+
}
2066+
2067+
if (p == GET_HEAP_PAGE(p)->freelist_tail) {
2068+
GC_ASSERT(next == NULL);
2069+
GET_HEAP_PAGE(p)->freelist_tail = prev;
2070+
}
20612071
}
20622072

20632073
static inline VALUE
@@ -4443,6 +4453,8 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_
44434453
RVALUE *p = pstart + i;
44444454
VALUE vp = (VALUE)p;
44454455

4456+
GC_ASSERT(!RVALUE_PAGE_MARKING(sweep_page, p) || sweep_page->flags.has_remembered_objects);
4457+
44464458
bitset = (~bits[BITMAP_INDEX(p)] >> BITMAP_OFFSET(p)) & 1;
44474459

44484460
asan_unpoison_object(vp, false);
@@ -4452,7 +4464,6 @@ gc_page_sweep(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *sweep_
44524464
gc_report(2, objspace, "page_sweep: free %p\n", (void *)p);
44534465
#if RGENGC_CHECK_MODE
44544466
if (!is_full_marking(objspace)) {
4455-
// if (RVALUE_OLD_P(vp)) rb_bug("page_sweep: %p - old while minor GC.", (void *)p);
44564467
if (RVALUE_OLD_P(vp)) rb_bug("page_sweep: old while minor GC: %s.", obj_info(p));
44574468
if (rgengc_remembered_sweep(objspace, vp)) rb_bug("page_sweep: %p - remembered.", (void *)p);
44584469
}
@@ -7843,6 +7854,7 @@ gc_is_moveable_obj(rb_objspace_t *objspace, VALUE obj)
78437854
case T_NIL:
78447855
case T_MOVED:
78457856
case T_ZOMBIE:
7857+
case T_GARBAGE:
78467858
return FALSE;
78477859
case T_SYMBOL:
78487860
if (DYNAMIC_SYM_P(obj) && (RSYMBOL(obj)->id & ~ID_SCOPE_MASK)) {
@@ -7925,6 +7937,8 @@ gc_move(rb_objspace_t *objspace, VALUE scan, VALUE free, struct RMoved * moved_l
79257937
st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
79267938
}
79277939

7940+
remove_obj_from_freelist(heap_eden, (VALUE)dest);
7941+
79287942
/* Move the object */
79297943
memcpy(dest, src, sizeof(RVALUE));
79307944
memset(src, 0, sizeof(RVALUE));
@@ -7978,12 +7992,12 @@ static void
79787992
advance_cursor(struct heap_cursor *free, struct heap_page **page_list)
79797993
{
79807994
if (free->slot == free->page->start + free->page->total_slots - 1) {
7981-
free->index--;
7995+
free->index++;
79827996
free->page = page_list[free->index];
79837997
free->slot = free->page->start;
79847998
}
79857999
else {
7986-
free->slot--;
8000+
free->slot++;
79878001
}
79888002
}
79898003

@@ -8027,7 +8041,7 @@ init_cursors(rb_objspace_t *objspace, struct heap_cursor *free, struct heap_curs
80278041
page = page_list[total_pages - 1];
80288042
scan->index = total_pages - 1;
80298043
scan->page = page;
8030-
scan->slot = page->start + page->total_slots * 2 - 2;
8044+
scan->slot = page->start + page->total_slots - 1;
80318045
scan->objspace = objspace;
80328046
}
80338047

@@ -8703,16 +8717,10 @@ gc_ref_update(void *vstart, void *vend, size_t stride, void * data)
87038717
{
87048718
rb_objspace_t * objspace;
87058719
struct heap_page *page;
8706-
short free_slots = 0;
87078720

87088721
VALUE v = (VALUE)vstart;
87098722
objspace = (rb_objspace_t *)data;
87108723
page = GET_HEAP_PAGE(v);
8711-
asan_unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
8712-
page->freelist = NULL;
8713-
asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
8714-
page->flags.has_uncollectible_shady_objects = FALSE;
8715-
page->flags.has_remembered_objects = FALSE;
87168724

87178725
/* For each object on the page */
87188726
for (; v != (VALUE)vend; v += stride) {
@@ -8722,11 +8730,7 @@ gc_ref_update(void *vstart, void *vend, size_t stride, void * data)
87228730

87238731
switch (BUILTIN_TYPE(v)) {
87248732
case T_NONE:
8725-
heap_page_add_freeobj(objspace, page, v);
8726-
free_slots++;
8727-
break;
87288733
case T_MOVED:
8729-
break;
87308734
case T_ZOMBIE:
87318735
break;
87328736
default:
@@ -8746,7 +8750,6 @@ gc_ref_update(void *vstart, void *vend, size_t stride, void * data)
87468750
}
87478751
}
87488752

8749-
page->free_slots = free_slots;
87508753
return 0;
87518754
}
87528755

test/ruby/test_gc_compact.rb

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ def find_object_in_recycled_slot(addresses)
3535
end
3636

3737
def test_complex_hash_keys
38-
skip
39-
4038
list_of_objects = big_list
4139
hash = list_of_objects.hash
4240
GC.verify_compaction_references(toward: :empty)
@@ -54,16 +52,12 @@ def walk_ast ast
5452
end
5553

5654
def test_ast_compacts
57-
skip
58-
5955
ast = RubyVM::AbstractSyntaxTree.parse_file __FILE__
6056
assert GC.compact
6157
walk_ast ast
6258
end
6359

6460
def test_compact_count
65-
skip
66-
6761
count = GC.stat(:compact_count)
6862
GC.compact
6963
assert_equal count + 1, GC.stat(:compact_count)

0 commit comments

Comments
 (0)