summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-24 00:04:56 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-10-24 00:04:56 +0000
commit6c6dece7f192664986c3973ed15c994cc6af1696 (patch)
treee1f26eef14cd823a88e0a15b5cff5832d6fde9fd /gc.c
parente1d772c801b95a5b0c8ed898b48d7205faceb83c (diff)
* ext/objspace/objspace.c (ObjectSpace.reachable_objects_from):
internal object support. If given object `obj' has references to internal objects (such as T_NODE objects), then this method returns instances of `ObjectSpace::InternalObjectWrapper' instead of that internal objects. This instance contains a refereance to an internal object and you can check the type of internal object using `ObjectSpace::InternalObjectWrapper#type' method. Rdoc of `InternalObjectWrapper' is not prepared yet. * gc.c (rb_objspace_reachable_objects_from), gc.h: change an interface of 'rb_objspace_reachable_objects_from()' * gc.c, gc.h: add two APIs - rb_objspace_markable_object_p(obj): check markable or not. - rb_objspace_internal_object_p(obj): check internal or not. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37307 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c51
1 files changed, 19 insertions, 32 deletions
diff --git a/gc.c b/gc.c
index 2d21cada24..29b9cc7bde 100644
--- a/gc.c
+++ b/gc.c
@@ -275,8 +275,8 @@ typedef struct rb_objspace {
int gc_stress;
struct mark_func_data_struct {
- VALUE data;
- void (*mark_func)(struct rb_objspace *objspace, VALUE v);
+ void *data;
+ void (*mark_func)(VALUE v, void *data);
} *mark_func_data;
} rb_objspace_t;
@@ -1182,6 +1182,12 @@ internal_object_p(VALUE obj)
return 1;
}
+int
+rb_objspace_internal_object_p(VALUE obj)
+{
+ return internal_object_p(obj);
+}
+
static int
os_obj_of_i(void *vstart, void *vend, size_t stride, void *data)
{
@@ -2568,6 +2574,12 @@ markable_object_p(rb_objspace_t *objspace, VALUE ptr)
return 1;
}
+int
+rb_objspace_markable_object_p(VALUE obj)
+{
+ return markable_object_p(/* now it doesn't use &rb_objspace */ 0, obj);
+}
+
static void
gc_mark(rb_objspace_t *objspace, VALUE ptr)
{
@@ -2580,7 +2592,7 @@ gc_mark(rb_objspace_t *objspace, VALUE ptr)
push_mark_stack(&objspace->mark_stack, ptr);
}
else {
- objspace->mark_func_data->mark_func(objspace, ptr);
+ objspace->mark_func_data->mark_func(ptr, objspace->mark_func_data->data);
}
}
@@ -3303,43 +3315,18 @@ rb_gc_set_params(void)
}
}
-static void
-collect_refs(rb_objspace_t *objspace, VALUE obj)
-{
- if (markable_object_p(objspace, obj) && !internal_object_p(obj)) {
- st_insert((st_table *)objspace->mark_func_data->data, obj, Qtrue);
- }
-}
-
-static int
-collect_keys(st_data_t key, st_data_t value, st_data_t data)
-{
- VALUE ary = (VALUE)data;
- rb_ary_push(ary, (VALUE)key);
- return ST_CONTINUE;
-}
-
-VALUE
-rb_objspace_reachable_objects_from(VALUE obj)
+void
+rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data)
{
rb_objspace_t *objspace = &rb_objspace;
if (markable_object_p(objspace, obj)) {
- st_table *refs = st_init_numtable();
struct mark_func_data_struct mfd;
- VALUE ret = rb_ary_new();
- mfd.mark_func = collect_refs;
- mfd.data = (VALUE)refs;
+ mfd.mark_func = func;
+ mfd.data = data;
objspace->mark_func_data = &mfd;
-
gc_mark_children(objspace, obj);
-
objspace->mark_func_data = 0;
- st_foreach(refs, collect_keys, (st_data_t)ret);
- return ret;
- }
- else {
- return Qnil;
}
}