Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,8 @@ jobs:
os: ubuntu-24.04
configure: 'CC=clang-18 cflags=-fsanitize=address cppflags=-DUSE_MN_THREADS=0'
timeout: 60
# ubuntu-24.04-arm jobs don't start on ruby/ruby as of 2025-10-29
#- test_task: check
# os: ubuntu-24.04-arm
- test_task: check
os: ubuntu-26.04-arm
fail-fast: false

env: &make-env
Expand Down
20 changes: 11 additions & 9 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -6750,6 +6750,8 @@ rb_ary_count(int argc, VALUE *argv, VALUE ary)
return LONG2NUM(n);
}

VALUE rb_ident_set_new(void);

static VALUE
flatten(VALUE ary, int level)
{
Expand Down Expand Up @@ -6777,9 +6779,9 @@ flatten(VALUE ary, int level)
rb_ary_push(stack, LONG2NUM(i + 1));

if (level < 0) {
memo = rb_obj_hide(rb_ident_hash_new());
rb_hash_aset(memo, ary, Qtrue);
rb_hash_aset(memo, tmp, Qtrue);
memo = rb_obj_hide(rb_ident_set_new());
rb_set_add(memo, ary);
rb_set_add(memo, tmp);
}

ary = tmp;
Expand All @@ -6795,7 +6797,7 @@ flatten(VALUE ary, int level)
tmp = rb_check_array_type(elt);
if (RBASIC(result)->klass) {
if (RTEST(memo)) {
rb_hash_clear(memo);
rb_set_clear(memo);
}
rb_raise(rb_eRuntimeError, "flatten reentered");
}
Expand All @@ -6804,11 +6806,11 @@ flatten(VALUE ary, int level)
}
else {
if (memo) {
if (rb_hash_aref(memo, tmp) == Qtrue) {
rb_hash_clear(memo);
if (rb_set_lookup(memo, tmp)) {
rb_set_clear(memo);
rb_raise(rb_eArgError, "tried to flatten recursive array");
}
rb_hash_aset(memo, tmp, Qtrue);
rb_set_add(memo, tmp);
}
rb_ary_push(stack, ary);
rb_ary_push(stack, LONG2NUM(i));
Expand All @@ -6820,15 +6822,15 @@ flatten(VALUE ary, int level)
break;
}
if (memo) {
rb_hash_delete(memo, ary);
rb_set_delete(memo, ary);
}
tmp = rb_ary_pop(stack);
i = NUM2LONG(tmp);
ary = rb_ary_pop(stack);
}

if (memo) {
rb_hash_clear(memo);
rb_set_clear(memo);
}

RBASIC_SET_CLASS(result, rb_cArray);
Expand Down
13 changes: 10 additions & 3 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3699,10 +3699,17 @@ rb_gc_obj_optimal_size(VALUE obj)

case T_HASH:
{
if (RB_OBJ_FROZEN(obj) && RHASH_AR_TABLE_P(obj)) {
return sizeof(struct RHash) + offsetof(ar_table, pairs) + RHASH_AR_TABLE_BOUND(obj) * sizeof(ar_table_pair);
const size_t st_size = sizeof(struct RHash) + sizeof(st_table);
if (RHASH_ST_TABLE_P(obj)) {
return st_size;
}
return sizeof(struct RHash) + (RHASH_ST_TABLE_P(obj) ? sizeof(st_table) : sizeof(ar_table));

const size_t ar_size = sizeof(struct RHash) + offsetof(ar_table, pairs) + RHASH_AR_TABLE_BOUND(obj) * sizeof(ar_table_pair);
if (OBJ_FROZEN(obj) || ar_size > st_size) {
return ar_size;
}

return st_size;
}

default:
Expand Down
4 changes: 4 additions & 0 deletions gc/default/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -5925,6 +5925,7 @@ static void pinned_roots_mark(rb_objspace_t *objspace, rb_heap_t *heap);
static void
mark_roots(rb_objspace_t *objspace, const char **categoryp)
{
VALUE objspace_guard = (VALUE)objspace;
#define MARK_CHECKPOINT(category) do { \
if (categoryp) *categoryp = category; \
} while (0)
Expand Down Expand Up @@ -5955,6 +5956,9 @@ mark_roots(rb_objspace_t *objspace, const char **categoryp)

rb_gc_save_machine_context();
rb_gc_mark_roots(objspace, categoryp);
/* Keep this frame, including its saved registers, until root marking has
* scanned the machine stack. */
RB_GC_GUARD(objspace_guard);
gc_mark_set_parent_invalid(objspace);
}

Expand Down
Loading