Skip to content

Commit 3b86dfb

Browse files
committed
Add rb_gc_impl_object_id_move
1 parent 26e6d9f commit 3b86dfb

File tree

4 files changed

+65
-34
lines changed

4 files changed

+65
-34
lines changed

gc.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ typedef struct gc_function_map {
665665
// Object ID
666666
VALUE (*object_id)(void *objspace_ptr, VALUE obj);
667667
VALUE (*object_id_to_ref)(void *objspace_ptr, VALUE object_id);
668+
st_data_t (*object_id_move)(void *objspace_ptr, VALUE dest, VALUE src);
668669
// Forking
669670
void (*before_fork)(void *objspace_ptr);
670671
void (*after_fork)(void *objspace_ptr, rb_pid_t pid);
@@ -842,6 +843,7 @@ ruby_modular_gc_init(void)
842843
// Object ID
843844
load_modular_gc_func(object_id);
844845
load_modular_gc_func(object_id_to_ref);
846+
load_modular_gc_func(object_id_move);
845847
// Forking
846848
load_modular_gc_func(before_fork);
847849
load_modular_gc_func(after_fork);
@@ -966,7 +968,6 @@ rb_objspace_alloc(void)
966968

967969
void *objspace = rb_gc_impl_objspace_alloc();
968970
ruby_current_vm_ptr->gc.objspace = objspace;
969-
970971
rb_gc_impl_objspace_init(objspace);
971972
rb_gc_impl_stress_set(objspace, initial_stress);
972973

@@ -2662,24 +2663,13 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
26622663
void
26632664
rb_gc_ractor_moved(VALUE dest, VALUE src)
26642665
{
2666+
void *objspace = rb_gc_get_objspace();
26652667
st_data_t id = 0;
26662668
if (UNLIKELY(FL_TEST_RAW(src, FL_SEEN_OBJ_ID))) {
2667-
/* If the source object's object_id has been seen, we need to update
2668-
* the object to object id mapping. */
2669-
rb_objspace_t *objspace = rb_gc_get_objspace();
2670-
2671-
unsigned int lev = rb_gc_vm_lock();
2672-
st_data_t key = (st_data_t)src;
2673-
if (!st_delete(objspace->obj_to_id_tbl, &key, &id)) {
2674-
rb_bug("gc_move: object ID seen, but not in mapping table: %s", rb_obj_info(src));
2675-
}
2676-
st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
2677-
st_insert(objspace->id_to_obj_tbl, id, (st_data_t)dest);
2678-
FL_UNSET_RAW(src, FL_SEEN_OBJ_ID);
2679-
rb_gc_vm_unlock(lev);
2669+
id = rb_gc_impl_object_id_move(objspace, dest, src);
26802670
}
26812671

2682-
rb_gc_obj_free(rb_gc_get_objspace(), src);
2672+
rb_gc_obj_free(objspace, src);
26832673
MEMZERO((void *)src, char, rb_gc_obj_slot_size(src));
26842674
RBASIC(src)->flags = T_OBJECT | FL_FREEZE; // Avoid mutations using bind_call, etc.
26852675
if (id) {

gc/default/default.c

Lines changed: 39 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,25 +1564,6 @@ rb_gc_impl_garbage_object_p(void *objspace_ptr, VALUE ptr)
15641564
!RVALUE_MARKED(objspace, ptr);
15651565
}
15661566

1567-
VALUE
1568-
rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
1569-
{
1570-
rb_objspace_t *objspace = objspace_ptr;
1571-
1572-
VALUE obj;
1573-
if (st_lookup(objspace->id_to_obj_tbl, object_id, &obj) &&
1574-
!rb_gc_impl_garbage_object_p(objspace, obj)) {
1575-
return obj;
1576-
}
1577-
1578-
if (rb_funcall(object_id, rb_intern(">="), 1, ULL2NUM(objspace->next_object_id))) {
1579-
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1580-
}
1581-
else {
1582-
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is recycled object", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1583-
}
1584-
}
1585-
15861567
VALUE
15871568
rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
15881569
{
@@ -1614,6 +1595,45 @@ rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
16141595
return id;
16151596
}
16161597

1598+
VALUE
1599+
rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
1600+
{
1601+
rb_objspace_t *objspace = objspace_ptr;
1602+
1603+
VALUE obj;
1604+
if (st_lookup(objspace->id_to_obj_tbl, object_id, &obj) &&
1605+
!rb_gc_impl_garbage_object_p(objspace, obj)) {
1606+
return obj;
1607+
}
1608+
1609+
if (rb_funcall(object_id, rb_intern(">="), 1, ULL2NUM(objspace->next_object_id))) {
1610+
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1611+
}
1612+
else {
1613+
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is recycled object", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1614+
}
1615+
}
1616+
1617+
st_data_t
1618+
rb_gc_impl_object_id_move(void *objspace_ptr, VALUE dest, VALUE src)
1619+
{
1620+
/* If the source object's object_id has been seen, we need to update
1621+
* the object to object id mapping. */
1622+
st_data_t id = 0;
1623+
rb_objspace_t *objspace = objspace_ptr;
1624+
1625+
unsigned int lev = rb_gc_vm_lock();
1626+
st_data_t key = (st_data_t)src;
1627+
if (!st_delete(objspace->obj_to_id_tbl, &key, &id)) {
1628+
rb_bug("gc_move: object ID seen, but not in mapping table: %s", rb_obj_info(src));
1629+
}
1630+
st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
1631+
st_insert(objspace->id_to_obj_tbl, id, (st_data_t)dest);
1632+
FL_UNSET_RAW(src, FL_SEEN_OBJ_ID);
1633+
rb_gc_vm_unlock(lev);
1634+
return id;
1635+
}
1636+
16171637
static void free_stack_chunks(mark_stack_t *);
16181638
static void mark_stack_free_cache(mark_stack_t *);
16191639
static void heap_page_free(rb_objspace_t *objspace, struct heap_page *page);

gc/gc_impl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ GC_IMPL_FN void rb_gc_impl_shutdown_call_finalizer(void *objspace_ptr);
103103
// Object ID
104104
GC_IMPL_FN VALUE rb_gc_impl_object_id(void *objspace_ptr, VALUE obj);
105105
GC_IMPL_FN VALUE rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id);
106+
GC_IMPL_FN VALUE rb_gc_impl_object_id_move(void *objspace_ptr, VALUE dest, VALUE src);
106107
// Forking
107108
GC_IMPL_FN void rb_gc_impl_before_fork(void *objspace_ptr);
108109
GC_IMPL_FN void rb_gc_impl_after_fork(void *objspace_ptr, rb_pid_t pid);

gc/mmtk/mmtk.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,26 @@ rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
11551155
}
11561156
}
11571157

1158+
st_data_t
1159+
rb_gc_impl_object_id_move(void *objspace_ptr, VALUE dest, VALUE src)
1160+
{
1161+
/* If the source object's object_id has been seen, we need to update
1162+
* the object to object id mapping. */
1163+
st_data_t id = 0;
1164+
struct objspace *objspace = objspace_ptr;
1165+
1166+
unsigned int lev = rb_gc_vm_lock();
1167+
st_data_t key = (st_data_t)src;
1168+
if (!st_delete(objspace->obj_to_id_tbl, &key, &id)) {
1169+
rb_bug("gc_move: object ID seen, but not in mapping table: %s", rb_obj_info(src));
1170+
}
1171+
st_insert(objspace->obj_to_id_tbl, (st_data_t)dest, id);
1172+
st_insert(objspace->id_to_obj_tbl, id, (st_data_t)dest);
1173+
FL_UNSET_RAW(src, FL_SEEN_OBJ_ID);
1174+
rb_gc_vm_unlock(lev);
1175+
return id;
1176+
}
1177+
11581178
// Forking
11591179

11601180
void

0 commit comments

Comments
 (0)