summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authornari <nari@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-22 15:03:46 +0000
committernari <nari@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-11-22 15:03:46 +0000
commit66db637a9fc0e03b4b25e213e2e96ddf5b53597f (patch)
treea681b1b0624399c82d668ab3dac92e582025340a /gc.c
parent97ecab7b34aaf58f472254356afcd3d529e57401 (diff)
* gc.c (is_swept_object): extract from is_dead_object().
* gc.c (rb_gcdebug_print_obj_condition): add the function for debug. This function shows some conditions of given object (e.g., marked, in heap, swept). * gc.c (rb_gcdebug_sentinel): add the function for debug. This function allow check to inadvertently free up an object. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@37809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c62
1 files changed, 58 insertions, 4 deletions
diff --git a/gc.c b/gc.c
index d8a74c4df5..4ea10ffe41 100644
--- a/gc.c
+++ b/gc.c
@@ -1582,16 +1582,25 @@ is_id_value(rb_objspace_t *objspace, VALUE ptr)
}
static inline int
-is_dead_object(rb_objspace_t *objspace, VALUE ptr)
+is_swept_object(rb_objspace_t *objspace, VALUE ptr)
{
struct heaps_slot *slot = objspace->heap.sweep_slots;
- if (!is_lazy_sweeping(objspace) || MARKED_IN_BITMAP(GET_HEAP_BITMAP(ptr), ptr))
- return FALSE;
+
while (slot) {
if ((VALUE)slot->header->start <= ptr && ptr < (VALUE)(slot->header->end))
- return TRUE;
+ return FALSE;
slot = slot->next;
}
+ return TRUE;
+}
+
+static inline int
+is_dead_object(rb_objspace_t *objspace, VALUE ptr)
+{
+ if (!is_lazy_sweeping(objspace) || MARKED_IN_BITMAP(GET_HEAP_BITMAP(ptr), ptr))
+ return FALSE;
+ if (!is_swept_object(objspace, ptr))
+ return TRUE;
return FALSE;
}
@@ -4304,6 +4313,51 @@ gc_profile_disable(void)
return Qnil;
}
+#ifdef GC_DEBUG
+
+/*
+ ------------------------------ DEBUG ------------------------------
+*/
+
+void
+rb_gcdebug_print_obj_condition(VALUE obj)
+{
+ rb_objspace_t *objspace = &rb_objspace;
+
+ if (is_pointer_to_heap(objspace, (void *)obj)) {
+ fprintf(stderr, "pointer to heap?: true\n");
+ }
+ else {
+ fprintf(stderr, "pointer to heap?: false\n");
+ return;
+ }
+ fprintf(stderr, "marked?: %s\n",
+ MARKED_IN_BITMAP(GET_HEAP_BITMAP(obj), obj) ? "true" : "false");
+ if (is_lazy_sweeping(objspace)) {
+ fprintf(stderr, "lazy sweeping?: true\n");
+ fprintf(stderr, "swept?: %s\n",
+ is_swept_object(objspace, obj) ? "done" : "not yet");
+ }
+ else {
+ fprintf(stderr, "lazy sweeping?: false\n");
+ }
+}
+
+static VALUE
+gcdebug_sential(VALUE obj, VALUE name)
+{
+ fprintf(stderr, "WARNING: object %s(%p) is inadvertently collected\n", (char *)name, (void *)obj);
+ return Qnil;
+}
+
+void
+rb_gcdebug_sentinel(VALUE obj, const char *name)
+{
+ rb_define_final(obj, rb_proc_new(gcdebug_sential, (VALUE)name));
+}
+#endif /* GC_DEBUG */
+
+
/*
* Document-class: ObjectSpace
*