@@ -236,7 +236,7 @@ inline bool CDSHeapVerifier::do_entry(oop& orig_obj, HeapShared::CachedOopInfo&
236
236
ls.print (" Value: " );
237
237
orig_obj->print_on (&ls);
238
238
ls.print_cr (" --- trace begin ---" );
239
- trace_to_root (orig_obj, NULL , &value);
239
+ trace_to_root (&ls, orig_obj, NULL , &value);
240
240
ls.print_cr (" --- trace end ---" );
241
241
ls.cr ();
242
242
_problems ++;
@@ -248,54 +248,62 @@ inline bool CDSHeapVerifier::do_entry(oop& orig_obj, HeapShared::CachedOopInfo&
248
248
class CDSHeapVerifier ::TraceFields : public FieldClosure {
249
249
oop _orig_obj;
250
250
oop _orig_field;
251
- LogStream* _ls ;
251
+ outputStream* _st ;
252
252
253
253
public:
254
- TraceFields (oop orig_obj, oop orig_field, LogStream* ls )
255
- : _orig_obj(orig_obj), _orig_field(orig_field), _ls(ls ) {}
254
+ TraceFields (oop orig_obj, oop orig_field, outputStream* st )
255
+ : _orig_obj(orig_obj), _orig_field(orig_field), _st(st ) {}
256
256
257
257
void do_field (fieldDescriptor* fd) {
258
258
if (fd->field_type () == T_OBJECT || fd->field_type () == T_ARRAY) {
259
259
oop obj_field = _orig_obj->obj_field (fd->offset ());
260
260
if (obj_field == _orig_field) {
261
- _ls ->print (" ::%s (offset = %d)" , fd->name ()->as_C_string (), fd->offset ());
261
+ _st ->print (" ::%s (offset = %d)" , fd->name ()->as_C_string (), fd->offset ());
262
262
}
263
263
}
264
264
}
265
265
};
266
266
267
- // Hint: to exercise this function, uncomment out one of the ADD_EXCL lines above.
268
- int CDSHeapVerifier::trace_to_root (oop orig_obj, oop orig_field, HeapShared::CachedOopInfo* p) {
267
+ // Call this function (from gdb, etc) if you want to know why an object is archived.
268
+ void CDSHeapVerifier::trace_to_root (outputStream* st, oop orig_obj) {
269
+ HeapShared::CachedOopInfo* info = HeapShared::archived_object_cache ()->get (orig_obj);
270
+ if (info != NULL ) {
271
+ trace_to_root (st, orig_obj, NULL , info);
272
+ } else {
273
+ st->print_cr (" Not an archived object??" );
274
+ }
275
+ }
276
+
277
+ int CDSHeapVerifier::trace_to_root (outputStream* st, oop orig_obj, oop orig_field, HeapShared::CachedOopInfo* info) {
269
278
int level = 0 ;
270
- LogStream ls (Log (cds, heap)::warning ());
271
- if (p->_referrer != NULL ) {
272
- HeapShared::CachedOopInfo* ref = HeapShared::archived_object_cache ()->get (p->_referrer );
279
+ if (info->_referrer != NULL ) {
280
+ HeapShared::CachedOopInfo* ref = HeapShared::archived_object_cache ()->get (info->_referrer );
273
281
assert (ref != NULL , " sanity" );
274
- level = trace_to_root (p ->_referrer , orig_obj, ref) + 1 ;
282
+ level = trace_to_root (st, info ->_referrer , orig_obj, ref) + 1 ;
275
283
} else if (java_lang_String::is_instance (orig_obj)) {
276
- ls. print_cr (" [%2d] (shared string table)" , level++);
284
+ st-> print_cr (" [%2d] (shared string table)" , level++);
277
285
}
278
286
Klass* k = orig_obj->klass ();
279
287
ResourceMark rm;
280
- ls. print (" [%2d] " , level);
281
- orig_obj->print_address_on (&ls );
282
- ls. print (" %s" , k->internal_name ());
288
+ st-> print (" [%2d] " , level);
289
+ orig_obj->print_address_on (st );
290
+ st-> print (" %s" , k->internal_name ());
283
291
if (orig_field != NULL ) {
284
292
if (k->is_instance_klass ()) {
285
- TraceFields clo (orig_obj, orig_field, &ls); ;
293
+ TraceFields clo (orig_obj, orig_field, st) ;
286
294
InstanceKlass::cast (k)->do_nonstatic_fields (&clo);
287
295
} else {
288
296
assert (orig_obj->is_objArray (), " must be" );
289
297
objArrayOop array = (objArrayOop)orig_obj;
290
298
for (int i = 0 ; i < array->length (); i++) {
291
299
if (array->obj_at (i) == orig_field) {
292
- ls. print (" @[%d]" , i);
300
+ st-> print (" @[%d]" , i);
293
301
break ;
294
302
}
295
303
}
296
304
}
297
305
}
298
- ls. cr ();
306
+ st-> cr ();
299
307
300
308
return level;
301
309
}
0 commit comments