Skip to content

Commit 36c6bbc

Browse files
Merge pull request #27 from ruby/forward-port-from-ruby-master
Forward port from GH-13115 from ruby/ruby
2 parents 220af8c + a2eaa7f commit 36c6bbc

File tree

2 files changed

+32
-9
lines changed

2 files changed

+32
-9
lines changed

gc/mmtk/Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gc/mmtk/mmtk.c

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,9 @@ rb_mmtk_update_obj_id_tables(void)
366366
struct objspace *objspace = rb_gc_get_objspace();
367367

368368
st_foreach(objspace->obj_to_id_tbl, rb_mmtk_update_obj_id_tables_obj_to_id_i, 0);
369-
st_foreach(objspace->id_to_obj_tbl, rb_mmtk_update_obj_id_tables_id_to_obj_i, 0);
369+
if (objspace->id_to_obj_tbl) {
370+
st_foreach(objspace->id_to_obj_tbl, rb_mmtk_update_obj_id_tables_id_to_obj_i, 0);
371+
}
370372
}
371373

372374
static int
@@ -1091,7 +1093,7 @@ static const struct st_hash_type object_id_hash_type = {
10911093
static void
10921094
objspace_obj_id_init(struct objspace *objspace)
10931095
{
1094-
objspace->id_to_obj_tbl = st_init_table(&object_id_hash_type);
1096+
objspace->id_to_obj_tbl = NULL;
10951097
objspace->obj_to_id_tbl = st_init_numtable();
10961098
objspace->next_object_id = OBJ_ID_INITIAL;
10971099
}
@@ -1119,30 +1121,51 @@ rb_gc_impl_object_id(void *objspace_ptr, VALUE obj)
11191121
objspace->next_object_id += OBJ_ID_INCREMENT;
11201122

11211123
st_insert(objspace->obj_to_id_tbl, (st_data_t)obj, (st_data_t)id);
1122-
st_insert(objspace->id_to_obj_tbl, (st_data_t)id, (st_data_t)obj);
1124+
if (RB_UNLIKELY(objspace->id_to_obj_tbl)) {
1125+
st_insert(objspace->id_to_obj_tbl, (st_data_t)id, (st_data_t)obj);
1126+
}
11231127
FL_SET(obj, FL_SEEN_OBJ_ID);
11241128
}
11251129
rb_gc_vm_unlock(lev);
11261130

11271131
return id;
11281132
}
11291133

1134+
static int
1135+
build_id_to_obj_i(st_data_t key, st_data_t value, st_data_t data)
1136+
{
1137+
st_table *id_to_obj_tbl = (st_table *)data;
1138+
st_insert(id_to_obj_tbl, value, key);
1139+
return ST_CONTINUE;
1140+
}
1141+
11301142
VALUE
11311143
rb_gc_impl_object_id_to_ref(void *objspace_ptr, VALUE object_id)
11321144
{
11331145
struct objspace *objspace = objspace_ptr;
11341146

1147+
1148+
unsigned int lev = rb_gc_vm_lock();
1149+
1150+
if (!objspace->id_to_obj_tbl) {
1151+
objspace->id_to_obj_tbl = st_init_table_with_size(&object_id_hash_type, st_table_size(objspace->obj_to_id_tbl));
1152+
st_foreach(objspace->obj_to_id_tbl, build_id_to_obj_i, (st_data_t)objspace->id_to_obj_tbl);
1153+
}
1154+
11351155
VALUE obj;
1136-
if (st_lookup(objspace->id_to_obj_tbl, object_id, &obj) &&
1137-
!rb_gc_impl_garbage_object_p(objspace, obj)) {
1156+
bool found = st_lookup(objspace->id_to_obj_tbl, object_id, &obj) && !rb_gc_impl_garbage_object_p(objspace, obj);
1157+
1158+
rb_gc_vm_unlock(lev);
1159+
1160+
if (found) {
11381161
return obj;
11391162
}
11401163

11411164
if (rb_funcall(object_id, rb_intern(">="), 1, ULL2NUM(objspace->next_object_id))) {
1142-
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not id value", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1165+
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is not an id value", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
11431166
}
11441167
else {
1145-
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is recycled object", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
1168+
rb_raise(rb_eRangeError, "%+"PRIsVALUE" is a recycled object", rb_funcall(object_id, rb_intern("to_s"), 1, INT2FIX(10)));
11461169
}
11471170
}
11481171

0 commit comments

Comments
 (0)