Skip to content

Commit ec8900e

Browse files
committed
rb_gc_impl_copy_finalizer: generate a new object id
Fix a regression introduced by: ruby#13155
1 parent a294427 commit ec8900e

File tree

4 files changed

+25
-4
lines changed

4 files changed

+25
-4
lines changed

gc/default/default.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2805,7 +2805,8 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
28052805

28062806
int lev = rb_gc_vm_lock();
28072807
if (RB_LIKELY(st_lookup(finalizer_table, obj, &data))) {
2808-
table = (VALUE)data;
2808+
table = rb_ary_dup((VALUE)data);
2809+
RARRAY_ASET(table, 0, rb_obj_id(dest));
28092810
st_insert(finalizer_table, dest, table);
28102811
FL_SET(dest, FL_FINALIZE);
28112812
}

gc/mmtk/mmtk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -985,7 +985,8 @@ rb_gc_impl_copy_finalizer(void *objspace_ptr, VALUE dest, VALUE obj)
985985

986986
int lev = rb_gc_vm_lock();
987987
if (RB_LIKELY(st_lookup(objspace->finalizer_table, obj, &data))) {
988-
table = (VALUE)data;
988+
table = rb_ary_dup((VALUE)data);
989+
RARRAY_ASET(table, 0, rb_obj_id(dest));
989990
st_insert(objspace->finalizer_table, dest, table);
990991
FL_SET(dest, FL_FINALIZE);
991992
}

object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,11 @@ init_copy(VALUE dest, VALUE obj)
409409
RBASIC(dest)->flags &= ~(T_MASK|FL_EXIVAR);
410410
// Copies the shape id from obj to dest
411411
RBASIC(dest)->flags |= RBASIC(obj)->flags & (T_MASK|FL_EXIVAR);
412-
rb_gc_copy_attributes(dest, obj);
413412
rb_copy_generic_ivar(dest, obj);
414413
if (RB_TYPE_P(obj, T_OBJECT)) {
415414
rb_obj_copy_ivar(dest, obj);
416415
}
416+
rb_gc_copy_attributes(dest, obj);
417417
}
418418

419419
static VALUE immutable_obj_clone(VALUE obj, VALUE kwfreeze);

test/ruby/test_objectspace.rb

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def test_count_objects
9494
end
9595

9696
def test_finalizer
97-
assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok :ok), [])
97+
assert_in_out_err(["-e", <<-END], "", %w(:ok :ok :ok), [])
9898
a = []
9999
ObjectSpace.define_finalizer(a) { p :ok }
100100
b = a.dup
@@ -137,6 +137,25 @@ class << fin
137137
}
138138
end
139139

140+
def test_finalizer_copy
141+
assert_in_out_err(["-e", <<~'RUBY'], "", %w(:ok), [])
142+
def fin
143+
ids = Set.new
144+
->(id) { puts "object_id (#{id}) reused" unless ids.add?(id) }
145+
end
146+
147+
OBJ = Object.new
148+
ObjectSpace.define_finalizer(OBJ, fin)
149+
OBJ.freeze
150+
151+
10.times do
152+
OBJ.clone
153+
end
154+
155+
p :ok
156+
RUBY
157+
end
158+
140159
def test_finalizer_with_super
141160
assert_in_out_err(["-e", <<-END], "", %w(:ok), [])
142161
class A

0 commit comments

Comments
 (0)