mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Disable GC during rb_objspace_reachable_object_p
Try to fix CI breakage by [Feature #15974].
This commit is contained in:
parent
9f1d67a68f
commit
d0cd0866d8
1 changed files with 54 additions and 33 deletions
87
gc.c
87
gc.c
|
@ -2954,39 +2954,7 @@ should_be_finalizable(VALUE obj)
|
||||||
rb_check_frozen(obj);
|
rb_check_frozen(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct reachable_object_data {
|
static int rb_objspace_reachable_object_p(VALUE obj, VALUE root);
|
||||||
VALUE obj;
|
|
||||||
VALUE set;
|
|
||||||
bool found;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void
|
|
||||||
reachable_object_callback(VALUE child, void *dp)
|
|
||||||
{
|
|
||||||
struct reachable_object_data *data = dp;
|
|
||||||
if (child == data->obj)
|
|
||||||
data->found = true;
|
|
||||||
|
|
||||||
if (data->found)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Maintain a set of objects already searched, so that we don't follow a cycle
|
|
||||||
if (rb_hash_lookup2(data->set, child, Qfalse))
|
|
||||||
return;
|
|
||||||
rb_hash_aset(data->set, child, Qtrue);
|
|
||||||
|
|
||||||
rb_objspace_reachable_objects_from(child, reachable_object_callback, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
rb_objspace_reachable_object_p(VALUE obj, VALUE root)
|
|
||||||
{
|
|
||||||
struct reachable_object_data data = {obj, rb_ident_hash_new()};
|
|
||||||
rb_obj_hide(data.set);
|
|
||||||
rb_objspace_reachable_objects_from(root, reachable_object_callback, &data);
|
|
||||||
rb_hash_clear(data.set);
|
|
||||||
return data.found;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
@ -9369,6 +9337,59 @@ rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE,
|
||||||
POP_MARK_FUNC_DATA();
|
POP_MARK_FUNC_DATA();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct reachable_object_data {
|
||||||
|
VALUE obj;
|
||||||
|
VALUE set;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
reachable_object_callback(VALUE child, void *dp)
|
||||||
|
{
|
||||||
|
struct reachable_object_data *data = dp;
|
||||||
|
if (child == data->obj) {
|
||||||
|
rb_throw_obj(data->set, Qtrue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Maintain a set of objects already searched, so that we don't follow a cycle
|
||||||
|
if (rb_hash_lookup2(data->set, child, Qfalse))
|
||||||
|
return;
|
||||||
|
rb_hash_aset(data->set, child, Qtrue);
|
||||||
|
|
||||||
|
rb_objspace_reachable_objects_from(child, reachable_object_callback, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
call_reachable_object(RB_BLOCK_CALL_FUNC_ARGLIST(set, arg))
|
||||||
|
{
|
||||||
|
struct reachable_object_data *data = (void *)arg;
|
||||||
|
VALUE obj = data->set;
|
||||||
|
data->set = rb_obj_hide(set);
|
||||||
|
gc_mark_children(&rb_objspace, obj);
|
||||||
|
rb_hash_clear(set);
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
rb_objspace_reachable_object_p(VALUE obj, VALUE root)
|
||||||
|
{
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
int reachable = FALSE;
|
||||||
|
if (is_markable_object(objspace, obj)) {
|
||||||
|
struct reachable_object_data data = {obj, root};
|
||||||
|
struct mark_func_data_struct mfd = {&data, reachable_object_callback};
|
||||||
|
int prev_dont_gc = dont_gc;
|
||||||
|
enum ruby_tag_type state;
|
||||||
|
|
||||||
|
dont_gc = TRUE;
|
||||||
|
PUSH_MARK_FUNC_DATA(&mfd);
|
||||||
|
reachable = RTEST(rb_catch_protect(rb_ident_hash_new(), call_reachable_object, (VALUE)&data, &state));
|
||||||
|
POP_MARK_FUNC_DATA();
|
||||||
|
dont_gc = prev_dont_gc;
|
||||||
|
if (state) EC_JUMP_TAG(GET_EC(), state);
|
||||||
|
}
|
||||||
|
return reachable;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------ Extended allocator ------------------------
|
------------------------ Extended allocator ------------------------
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue