Skip to content

Commit 23a2c00

Browse files
committed
WIP
1 parent b96d8be commit 23a2c00

5 files changed

Lines changed: 64 additions & 28 deletions

File tree

gc.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4145,6 +4145,18 @@ rb_gc_update_vm_references(void *objspace)
41454145
#endif
41464146
}
41474147

4148+
void
4149+
rb_gc_update_moved_object(void *objspace, VALUE dest, VALUE src)
4150+
{
4151+
if (RB_TYPE_P(dest, T_IMEMO)) {
4152+
return;
4153+
}
4154+
4155+
if (FL_TEST_RAW(dest, RUBY_FL_ADDRESS_SEEN)) {
4156+
rb_obj_set_stable_address(dest, src);
4157+
}
4158+
}
4159+
41484160
void
41494161
rb_gc_update_object_references(void *objspace, VALUE obj)
41504162
{

gc/default/default.c

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5453,25 +5453,22 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, VALUE src)
54535453
GC_ASSERT(gc_is_moveable_obj(objspace, src));
54545454

54555455
rb_heap_t *dest_pool = gc_compact_destination_pool(objspace, heap, src);
5456+
uint32_t orig_shape = 0;
5457+
uint32_t new_shape = 0;
54565458

54575459
if (gc_compact_heap_cursors_met_p(dest_pool)) {
54585460
return dest_pool != heap;
54595461
}
54605462

5461-
uint32_t orig_shape, new_shape;
5462-
VALUE dest = rb_gc_impl_location(objspace, src);
5463-
5464-
if (RB_TYPE_P(src, T_IMEMO)) {
5465-
new_shape = orig_shape = 0;
5466-
}
5467-
else {
5468-
new_shape = orig_shape = rb_gc_get_shape(src);
5469-
}
5470-
54715463
if (RB_TYPE_P(src, T_OBJECT)) {
5464+
orig_shape = rb_gc_get_shape(src);
5465+
54725466
if (dest_pool != heap) {
54735467
new_shape = rb_gc_rebuild_shape(src, dest_pool - heaps);
5474-
dest_pool = heap;
5468+
5469+
if (new_shape == 0) {
5470+
dest_pool = heap;
5471+
}
54755472
}
54765473
}
54775474

@@ -5500,19 +5497,13 @@ gc_compact_move(rb_objspace_t *objspace, rb_heap_t *heap, VALUE src)
55005497
}
55015498
}
55025499

5503-
if (FL_TEST_RAW(dest, RUBY_FL_ADDRESS_SEEN) && !rb_shape_has_old_address(new_shape)) {
5504-
DURING_GC_COULD_MALLOC_REGION_START();
5505-
{
5506-
new_shape = rb_shape_transition_old_address(new_shape);
5507-
rb_obj_field_set(dest, new_shape, 0, src);
5500+
if (orig_shape != 0) {
5501+
if (new_shape != 0) {
5502+
VALUE dest = rb_gc_impl_location(objspace, src);
5503+
rb_gc_set_shape(dest, new_shape);
55085504
}
5509-
DURING_GC_COULD_MALLOC_REGION_END();
5510-
}
5511-
5512-
if (new_shape != orig_shape) {
5513-
rb_gc_set_shape(dest, new_shape);
5505+
RMOVED(src)->original_shape_id = orig_shape;
55145506
}
5515-
RMOVED(src)->original_shape_id = orig_shape;
55165507

55175508
return true;
55185509
}
@@ -7031,9 +7022,11 @@ gc_ref_update(void *vstart, void *vend, size_t stride, rb_objspace_t *objspace,
70317022
asan_unpoisoning_object(v) {
70327023
switch (BUILTIN_TYPE(v)) {
70337024
case T_NONE:
7034-
case T_MOVED:
70357025
case T_ZOMBIE:
70367026
break;
7027+
case T_MOVED:
7028+
rb_gc_update_moved_object(objspace, rb_gc_location(v), v);
7029+
break;
70377030
default:
70387031
if (RVALUE_WB_UNPROTECTED(objspace, v)) {
70397032
page->flags.has_uncollectible_wb_unprotected_objects = TRUE;

gc/gc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ MODULAR_GC_FN size_t rb_gc_obj_optimal_size(VALUE obj);
7575
MODULAR_GC_FN void rb_gc_mark_children(void *objspace, VALUE obj);
7676
MODULAR_GC_FN void rb_gc_vm_weak_table_foreach(vm_table_foreach_callback_func callback, vm_table_update_callback_func update_callback, void *data, bool weak_only, enum rb_gc_vm_weak_tables table);
7777
MODULAR_GC_FN void rb_gc_update_object_references(void *objspace, VALUE obj);
78+
MODULAR_GC_FN void rb_gc_update_moved_object(void *objspace, VALUE dest, VALUE src);
7879
MODULAR_GC_FN void rb_gc_update_vm_references(void *objspace);
7980
MODULAR_GC_FN void rb_gc_event_hook(VALUE obj, rb_event_flag_t event);
8081
MODULAR_GC_FN void *rb_gc_get_objspace(void);

internal/variable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ VALUE rb_obj_field_get(VALUE obj, shape_id_t target_shape_id);
5555
void rb_ivar_set_internal(VALUE obj, ID id, VALUE val);
5656
void rb_obj_field_set(VALUE obj, shape_id_t target_shape_id, ID field_name, VALUE val);
5757
st_index_t rb_obj_stable_address(VALUE obj);
58+
void rb_obj_set_stable_address(VALUE obj, VALUE old_address);
5859

5960
RUBY_SYMBOL_EXPORT_BEGIN
6061
/* variable.c (export) */

variable.c

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4789,14 +4789,43 @@ rb_obj_stable_address(VALUE obj)
47894789
RUBY_ASSERT(FL_ABLE(obj));
47904790
RUBY_ASSERT(!RB_TYPE_P(obj, T_IMEMO));
47914791

4792-
if (!FL_TEST_RAW(obj, RUBY_FL_ADDRESS_SEEN)) {
4792+
if (FL_TEST_RAW(obj, RUBY_FL_ADDRESS_SEEN)) {
4793+
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
4794+
if (UNLIKELY(rb_shape_has_old_address(shape_id))) {
4795+
VALUE old_address = rb_obj_field_get(obj, rb_shape_old_address(shape_id));
4796+
#if SIZEOF_LONG == SIZEOF_VOIDP
4797+
return (st_index_t)NUM2LONG(old_address);
4798+
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
4799+
return (st_index_t)NUM2LL(old_address);
4800+
#else
4801+
#error "Unexpected VALUE size"
4802+
#endif
4803+
}
4804+
}
4805+
else {
47934806
FL_SET_RAW(obj, RUBY_FL_ADDRESS_SEEN);
47944807
}
47954808

4809+
return (st_index_t)obj;
4810+
}
4811+
4812+
void
4813+
rb_obj_set_stable_address(VALUE obj, VALUE old_address)
4814+
{
4815+
RUBY_ASSERT(FL_ABLE(obj));
4816+
RUBY_ASSERT(!RB_TYPE_P(obj, T_IMEMO));
4817+
RUBY_ASSERT(FL_TEST_RAW(obj, RUBY_FL_ADDRESS_SEEN));
4818+
47964819
shape_id_t shape_id = RBASIC_SHAPE_ID(obj);
4797-
if (rb_shape_has_old_address(shape_id)) {
4798-
return (st_index_t)rb_obj_field_get(obj, rb_shape_old_address(shape_id));
4799-
}
48004820

4801-
return (st_index_t)obj;
4821+
if (!rb_shape_has_old_address(shape_id)) {
4822+
#if SIZEOF_LONG == SIZEOF_VOIDP
4823+
old_address = LONG2NUM(old_address);
4824+
#elif SIZEOF_LONG_LONG == SIZEOF_VOIDP
4825+
old_address = LL2NUM(old_address);
4826+
#else
4827+
#error "Unexpected VALUE size"
4828+
#endif
4829+
rb_obj_field_set(obj, rb_shape_transition_old_address(shape_id), 0, old_address);
4830+
}
48024831
}

0 commit comments

Comments
 (0)