Use rb_darray_insert_without_gc for heap_pages darray

rb_darray_insert could trigger a GC, which would cause problems if it
freed pages while a new page was being inserted.

For example, the following script fails:

    GC.stress = true
    GC.auto_compact = :empty

    10.times do
      GC.verify_compaction_references(expand_heap: true, toward: :empty)
    end

It errors out with:

    'GC.verify_compaction_references': malloc: possible integer overflow (8*18446744073709551603) (ArgumentError)
This commit is contained in:
Peter Zhu 2024-12-24 15:30:48 -05:00
parent f9cd9a1b55
commit b8c4af24f9
Notes: git 2025-01-02 16:03:26 +00:00
2 changed files with 4 additions and 3 deletions

View File

@ -58,10 +58,11 @@
(*(ptr_to_ary))->meta.size++; \
} while (0)
#define rb_darray_insert(ptr_to_ary, idx, element) do { \
#define rb_darray_insert_without_gc(ptr_to_ary, idx, element) do { \
rb_darray_ensure_space((ptr_to_ary), \
sizeof(**(ptr_to_ary)), \
sizeof((*(ptr_to_ary))->data[0])); \
sizeof((*(ptr_to_ary))->data[0]), \
rb_darray_realloc_mul_add_without_gc); \
MEMMOVE( \
rb_darray_ref(*(ptr_to_ary), idx + 1), \
rb_darray_ref(*(ptr_to_ary), idx), \

View File

@ -1961,7 +1961,7 @@ heap_page_allocate(rb_objspace_t *objspace)
}
}
rb_darray_insert(&objspace->heap_pages.sorted, hi, page);
rb_darray_insert_without_gc(&objspace->heap_pages.sorted, hi, page);
if (heap_pages_lomem == 0 || heap_pages_lomem > start) heap_pages_lomem = start;
if (heap_pages_himem < end) heap_pages_himem = end;