// Return true if oop represents an object that is "visible" // to the java world. static inline bool visible_oop(oop o) { // the sentinel for deleted handles isn't visible if (o == JNIHandles::deleted_handle()) { return false; } // instance if (o->is_instance()) { // instance objects are visible if (o->klass() != SystemDictionary::Class_klass()) { return true; } if (java_lang_Class::is_primitive(o)) { return true; } // java.lang.Classes are visible Klass* k = java_lang_Class::as_Klass(o); if (k->is_klass()) { // if it's a class for an object, an object array, or // primitive (type) array then it's visible. if (k->is_instance_klass()) { return true; } if (k->is_objArray_klass()) { return true; } if (k->is_typeArray_klass()) { return true; } } return false; } // object arrays are visible if they aren't system object arrays if (o->is_objArray()) { return true; } // type arrays are visible if (o->is_typeArray()) { return true; } // everything else (Method*s, ...) aren't visible return false; }; // end of visible_oop()
void HeapRegion::verify(VerifyOption vo, bool* failures) const { G1CollectedHeap* g1 = G1CollectedHeap::heap(); *failures = false; HeapWord* p = bottom(); HeapWord* prev_p = NULL; VerifyLiveClosure vl_cl(g1, vo); bool is_humongous = isHumongous(); bool do_bot_verify = !is_young(); size_t object_num = 0; while (p < top()) { oop obj = oop(p); size_t obj_size = obj->size(); object_num += 1; if (is_humongous != g1->isHumongous(obj_size)) { gclog_or_tty->print_cr("obj "PTR_FORMAT" is of %shumongous size (" SIZE_FORMAT" words) in a %shumongous region", p, g1->isHumongous(obj_size) ? "" : "non-", obj_size, is_humongous ? "" : "non-"); *failures = true; return; } // If it returns false, verify_for_object() will output the // appropriate messasge. if (do_bot_verify && !_offsets.verify_for_object(p, obj_size)) { *failures = true; return; } if (!g1->is_obj_dead_cond(obj, this, vo)) { if (obj->is_oop()) { Klass* klass = obj->klass(); if (!klass->is_metaspace_object()) { gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " "not metadata", klass, (void *)obj); *failures = true; return; } else if (!klass->is_klass()) { gclog_or_tty->print_cr("klass "PTR_FORMAT" of object "PTR_FORMAT" " "not a klass", klass, (void *)obj); *failures = true; return; } else { vl_cl.set_containing_obj(obj); obj->oop_iterate_no_header(&vl_cl); if (vl_cl.failures()) { *failures = true; } if (G1MaxVerifyFailures >= 0 && vl_cl.n_failures() >= G1MaxVerifyFailures) { return; } } } else { gclog_or_tty->print_cr(PTR_FORMAT" no an oop", (void *)obj); *failures = true; return; } } prev_p = p; p += obj_size; } if (p != top()) { gclog_or_tty->print_cr("end of last object "PTR_FORMAT" " "does not match top "PTR_FORMAT, p, top()); *failures = true; return; } HeapWord* the_end = end(); assert(p == top(), "it should still hold"); // Do some extra BOT consistency checking for addresses in the // range [top, end). BOT look-ups in this range should yield // top. No point in doing that if top == end (there's nothing there). if (p < the_end) { // Look up top HeapWord* addr_1 = p; HeapWord* b_start_1 = _offsets.block_start_const(addr_1); if (b_start_1 != p) { gclog_or_tty->print_cr("BOT look up for top: "PTR_FORMAT" " " yielded "PTR_FORMAT", expecting "PTR_FORMAT, addr_1, b_start_1, p); *failures = true; return; } // Look up top + 1 HeapWord* addr_2 = p + 1; if (addr_2 < the_end) { HeapWord* b_start_2 = _offsets.block_start_const(addr_2); if (b_start_2 != p) { gclog_or_tty->print_cr("BOT look up for top + 1: "PTR_FORMAT" " " yielded "PTR_FORMAT", expecting "PTR_FORMAT, addr_2, b_start_2, p); *failures = true; return; } } // Look up an address between top and end size_t diff = pointer_delta(the_end, p) / 2; HeapWord* addr_3 = p + diff; if (addr_3 < the_end) { HeapWord* b_start_3 = _offsets.block_start_const(addr_3); if (b_start_3 != p) { gclog_or_tty->print_cr("BOT look up for top + diff: "PTR_FORMAT" " " yielded "PTR_FORMAT", expecting "PTR_FORMAT, addr_3, b_start_3, p); *failures = true; return; } } // Loook up end - 1 HeapWord* addr_4 = the_end - 1; HeapWord* b_start_4 = _offsets.block_start_const(addr_4); if (b_start_4 != p) { gclog_or_tty->print_cr("BOT look up for end - 1: "PTR_FORMAT" " " yielded "PTR_FORMAT", expecting "PTR_FORMAT, addr_4, b_start_4, p); *failures = true; return; } } if (is_humongous && object_num > 1) { gclog_or_tty->print_cr("region ["PTR_FORMAT","PTR_FORMAT"] is humongous " "but has "SIZE_FORMAT", objects", bottom(), end(), object_num); *failures = true; return; } verify_strong_code_roots(vo, failures); }