summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authortarui <tarui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-24 15:57:16 +0000
committertarui <tarui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-06-24 15:57:16 +0000
commit606d2d354d78e431a07e4cbcd6c3794fb7191615 (patch)
tree4a32b176ed8340eb31f0e5aa65a996c4486f587f /gc.c
parent13f1fbc09a0984ad7779d5819785597f20241d19 (diff)
* gc.c (typedef struct rb_objspace): Change members for monitor objects.
* gc.c (gc_marks_test): Check all WriteBarrier Errors and track them in obj-tree. * gc.c (rgengc_check_shady): Ditto. * gc.c (gc_marks): Move 2 funtion calls to gc_marks_test for test initialize. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@41607 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c125
1 files changed, 75 insertions, 50 deletions
diff --git a/gc.c b/gc.c
index 4aa9766e19..28e431d9f3 100644
--- a/gc.c
+++ b/gc.c
@@ -385,7 +385,8 @@ typedef struct rb_objspace {
/* for check mode */
VALUE parent_object;
- VALUE interesting_object;
+ unsigned int monitor_level;
+ st_table *monitored_object_table;
int need_major_gc;
size_t remembered_shady_object_count;
@@ -481,6 +482,8 @@ VALUE *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
#define initial_heap_min_slots initial_params.initial_heap_min_slots
#define initial_free_min initial_params.initial_free_min
#define initial_growth_factor initial_params.initial_growth_factor
+#define monitor_level objspace->rgengc.monitor_level
+#define monitored_object_table objspace->rgengc.monitored_object_table
#define is_lazy_sweeping(objspace) ((objspace)->heap.sweep_slots != 0)
@@ -3001,38 +3004,12 @@ rgengc_check_shady(rb_objspace_t *objspace, VALUE obj)
{
#if USE_RGENGC
#if RGENGC_CHECK_MODE >= 2
- VALUE parent = objspace->rgengc.parent_object;
-
- if (objspace->rgengc.interesting_object == obj) {
- /* output interesting parent->child references */
- if (FIXNUM_P(parent)) {
- fprintf(stderr, "rgengc_check_shady: !!! %p (%s) is pointed at line %d\n",
- (void *)obj, obj_type_name(obj), FIX2INT(parent));
- }
- else {
- fprintf(stderr, "rgengc_check_shady: !!! %p (%s) is pointed by %p (%s)\n",
- (void *)obj, obj_type_name(obj), (void *)parent, obj_type_name(parent));
- }
- }
-
-#if RGENGC_CHECK_MODE >= 3
- /* output all parent->child references */
- if (objspace->rgengc.interesting_object) {
- if (FIXNUM_P(parent)) {
- fprintf(stderr, "rgengc_check_shady: [line %d] -> %p (%s)\n",
- FIX2INT(parent), (void *)obj, obj_type_name(obj));
- }
- else {
- fprintf(stderr, "rgengc_check_shady: %p (%s) -> %p (%s)\n",
- (void *)parent, obj_type_name(parent), (void *)obj, obj_type_name(obj));
- }
- }
-#endif /* RGENGC_CHECK_MODE >= 3 */
-
- if (objspace->rgengc.have_saved_bitmaps) {
- /* check WB sanity */
#define SAVED_OLD(x) MARKED_IN_BITMAP(GET_HEAP_SLOT(x)->saved_oldgen_bits, (x))
#define SAVED_REM(x) MARKED_IN_BITMAP(GET_HEAP_SLOT(x)->saved_rememberset_bits, (x))
+ VALUE parent = objspace->rgengc.parent_object;
+
+ if (objspace->rgengc.have_saved_bitmaps && !monitor_level) {
+ /* check WB sanity */
if (!SAVED_OLD(obj) && /* obj is young object (newly created or shady) */
(!FIXNUM_P(parent) && SAVED_OLD(parent)) && /* parent was old */
!SAVED_REM(parent) && /* parent was not remembered */
@@ -3040,12 +3017,51 @@ rgengc_check_shady(rb_objspace_t *objspace, VALUE obj)
fprintf(stderr, "rgengc_check_shady: !!! WB miss: %p (%s) -> %p (%s)\n",
(void *)parent, obj_type_name(parent),
(void *)obj, obj_type_name(obj));
- rb_bug("!!!");
- objspace->rgengc.interesting_object = obj;
+ if(!st_lookup(monitored_object_table, (st_data_t)obj, NULL)) {
+ st_insert(monitored_object_table, (st_data_t)obj, 1);
+ }
+ }
+ } else if (monitor_level) {
+ st_data_t v;
+ if (st_lookup(monitored_object_table, (st_data_t)obj, &v)) {
+ if (v == monitor_level) {
+ if (FIXNUM_P(parent)) {
+ fprintf(stderr, "rgengc_check_shady: %14s [line %d] -> %p (%s) %d\n",
+ "",FIX2INT(parent), (void *)obj, obj_type_name(obj),monitor_level);
+ }
+ else {
+ if (st_lookup(monitored_object_table, (st_data_t)parent, &v)) {
+ if(parent == obj) {
+ /* skip self reference infomation */
+ }
+ else
+ fprintf(stderr, "rgengc_check_shady: %14u %p (%-8s) -> %p (%-8s) %d\n",(unsigned int)v,
+ (void *)parent, obj_type_name(parent), (void *)obj, obj_type_name(obj),monitor_level);
+ } else {
+ char const *marker = NULL;
+ if (SAVED_REM(parent)) {
+ if (SAVED_OLD(parent))
+ marker = "REMEMBERED OLD";
+ else
+ marker = "REMEMBERED";
+ } else {
+ if (SAVED_OLD(parent))
+ marker = "!!!!!!!!!!!!! NO REMEMBERED OLD !!!!!!!!!!!!! ";
+ else {
+ marker = "NO PROMOTED";
+ st_insert(monitored_object_table, (st_data_t)parent, v+1);
+ }
+ }
+ fprintf(stderr, "rgengc_check_shady: %-14s %p (%-8s) -> %p (%-8s) %d\n",
+ marker,
+ (void *)parent, obj_type_name(parent), (void *)obj, obj_type_name(obj),monitor_level);
+ }
+ }
+ }
}
+ }
#undef SAVED_OLD
#undef SAVED_REM
- }
#endif /* RGENGC_CHECK_MODE >= 2 */
if (objspace->rgengc.parent_object_is_promoted &&
@@ -3601,16 +3617,26 @@ gc_load_bitmaps(rb_objspace_t *objspace)
static void
gc_marks_test(rb_objspace_t *objspace)
{
- bits_t *exported_bitmaps = gc_export_bitmaps(objspace);
+ bits_t *exported_bitmaps;
size_t i;
size_t stored_oldgen, stored_shady;
-
/*
* Now, we have 2 types bitmaps:
* saved_bitmap: before minor marking
* exported_bitmap: after minor marking
*/
+
+ if(!monitored_object_table)
+ monitored_object_table = st_init_numtable();
+ gc_save_bitmaps(objspace);
+
+ rgengc_report(1, objspace, "gc_marks_test: minor gc\n");
+ {
+ gc_marks_body(objspace, TRUE);
+ }
+ exported_bitmaps = gc_export_bitmaps(objspace);
+
rgengc_report(1, objspace, "gc_marks_test: test-full-gc\n");
/* run major (full) gc with temporary mark/rememberset */
@@ -3634,23 +3660,24 @@ gc_marks_test(rb_objspace_t *objspace)
if (MARKED_IN_BITMAP(major_mark_bits, p) && /* should be lived */
!MARKED_IN_BITMAP(minor_mark_bits, p)) { /* not marked -> BUG! */
fprintf(stderr, "gc_marks_test: %p (%s) is living, but not marked && not promoted.\n", p, obj_type_name((VALUE)p));
- objspace->rgengc.interesting_object = (VALUE)p;
+ st_insert(monitored_object_table, (st_data_t)p, 1);
}
p++;
}
}
- if (objspace->rgengc.interesting_object) {
- fprintf(stderr, "!!! restart major gc\n");
- gc_load_bitmaps(objspace);
- gc_marks_body(objspace, FALSE);
-
- fprintf(stderr, "!!! restart minor gc\n");
- gc_load_bitmaps(objspace);
- gc_marks_body(objspace, TRUE);
-
- rb_bug("gc_marks_test (again): %p (%s) is living, but not marked && not promoted.\n",
- (void *)objspace->rgengc.interesting_object, obj_type_name((VALUE)objspace->rgengc.interesting_object));
+ if (monitored_object_table->num_entries) {
+ if (RGENGC_CHECK_MODE >= 3) {
+ st_index_t old_num;
+ do {
+ old_num = monitored_object_table->num_entries;
+ monitor_level ++;
+ fprintf(stderr, "!!!! restart major gc for get more information !!!!\n");
+ gc_load_bitmaps(objspace);
+ gc_marks_body(objspace, FALSE);
+ } while (old_num != monitored_object_table->num_entries);
+ }
+ rb_bug("WriteBarrier Error\n");
}
else {
gc_restore_exported_bitmaps(objspace, exported_bitmaps);
@@ -3684,8 +3711,6 @@ gc_marks(rb_objspace_t *objspace, int minor_gc)
}
else { /* minor GC */
#if RGENGC_CHECK_MODE >= 2
- gc_save_bitmaps(objspace);
- gc_marks_body(objspace, TRUE);
gc_marks_test(objspace);
#else
gc_marks_body(objspace, TRUE);