8025564: gc/memory/UniThread/Linear1 times out during heap verification
Reviewed-by: stefank, tschatzl
This commit is contained in:
parent
98f413fa1f
commit
ff1498ba6b
@ -369,33 +369,44 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void G1BlockOffsetArray::verify() const {
|
||||||
G1BlockOffsetArray::verify_for_object(HeapWord* obj_start,
|
size_t start_card = _array->index_for(gsp()->bottom());
|
||||||
size_t word_size) const {
|
size_t end_card = _array->index_for(gsp()->top());
|
||||||
size_t first_card = _array->index_for(obj_start);
|
|
||||||
size_t last_card = _array->index_for(obj_start + word_size - 1);
|
for (size_t current_card = start_card; current_card < end_card; current_card++) {
|
||||||
if (!_array->is_card_boundary(obj_start)) {
|
u_char entry = _array->offset_array(current_card);
|
||||||
// If the object is not on a card boundary the BOT entry of the
|
if (entry < N_words) {
|
||||||
// first card should point to another object so we should not
|
// The entry should point to an object before the current card. Verify that
|
||||||
// check that one.
|
// it is possible to walk from that object in to the current card by just
|
||||||
first_card += 1;
|
// iterating over the objects following it.
|
||||||
}
|
HeapWord* card_address = _array->address_for_index(current_card);
|
||||||
for (size_t card = first_card; card <= last_card; card += 1) {
|
HeapWord* obj_end = card_address - entry;
|
||||||
HeapWord* card_addr = _array->address_for_index(card);
|
while (obj_end < card_address) {
|
||||||
HeapWord* block_start = block_start_const(card_addr);
|
HeapWord* obj = obj_end;
|
||||||
if (block_start != obj_start) {
|
size_t obj_size = block_size(obj);
|
||||||
gclog_or_tty->print_cr("block start: "PTR_FORMAT" is incorrect - "
|
obj_end = obj + obj_size;
|
||||||
"card index: "SIZE_FORMAT" "
|
guarantee(obj_end > obj && obj_end <= gsp()->top(),
|
||||||
"card addr: "PTR_FORMAT" BOT entry: %u "
|
err_msg("Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
|
||||||
"obj: "PTR_FORMAT" word size: "SIZE_FORMAT" "
|
p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top())));
|
||||||
"cards: ["SIZE_FORMAT","SIZE_FORMAT"]",
|
}
|
||||||
p2i(block_start), card, p2i(card_addr),
|
} else {
|
||||||
_array->offset_array(card),
|
// Because we refine the BOT based on which cards are dirty there is not much we can verify here.
|
||||||
p2i(obj_start), word_size, first_card, last_card);
|
// We need to make sure that we are going backwards and that we don't pass the start of the
|
||||||
return false;
|
// corresponding heap region. But that is about all we can verify.
|
||||||
|
size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
|
||||||
|
guarantee(backskip >= 1, "Must be going back at least one card.");
|
||||||
|
|
||||||
|
size_t max_backskip = current_card - start_card;
|
||||||
|
guarantee(backskip <= max_backskip,
|
||||||
|
err_msg("Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
|
||||||
|
start_card, current_card, backskip));
|
||||||
|
|
||||||
|
HeapWord* backskip_address = _array->address_for_index(current_card - backskip);
|
||||||
|
guarantee(backskip_address >= gsp()->bottom(),
|
||||||
|
err_msg("Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
|
||||||
|
p2i(gsp()->bottom()), p2i(backskip_address)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef PRODUCT
|
#ifndef PRODUCT
|
||||||
|
@ -304,14 +304,10 @@ public:
|
|||||||
virtual HeapWord* block_start_unsafe(const void* addr);
|
virtual HeapWord* block_start_unsafe(const void* addr);
|
||||||
virtual HeapWord* block_start_unsafe_const(const void* addr) const;
|
virtual HeapWord* block_start_unsafe_const(const void* addr) const;
|
||||||
|
|
||||||
// Used by region verification. Checks that the contents of the
|
|
||||||
// BOT reflect that there's a single object that spans the address
|
|
||||||
// range [obj_start, obj_start + word_size); returns true if this is
|
|
||||||
// the case, returns false if it's not.
|
|
||||||
bool verify_for_object(HeapWord* obj_start, size_t word_size) const;
|
|
||||||
|
|
||||||
void check_all_cards(size_t left_card, size_t right_card) const;
|
void check_all_cards(size_t left_card, size_t right_card) const;
|
||||||
|
|
||||||
|
void verify() const;
|
||||||
|
|
||||||
virtual void print_on(outputStream* out) PRODUCT_RETURN;
|
virtual void print_on(outputStream* out) PRODUCT_RETURN;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -861,7 +861,6 @@ void HeapRegion::verify(VerifyOption vo,
|
|||||||
HeapWord* prev_p = NULL;
|
HeapWord* prev_p = NULL;
|
||||||
VerifyLiveClosure vl_cl(g1, vo);
|
VerifyLiveClosure vl_cl(g1, vo);
|
||||||
bool is_humongous = isHumongous();
|
bool is_humongous = isHumongous();
|
||||||
bool do_bot_verify = !is_young();
|
|
||||||
size_t object_num = 0;
|
size_t object_num = 0;
|
||||||
while (p < top()) {
|
while (p < top()) {
|
||||||
oop obj = oop(p);
|
oop obj = oop(p);
|
||||||
@ -878,15 +877,6 @@ void HeapRegion::verify(VerifyOption vo,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If it returns false, verify_for_object() will output the
|
|
||||||
// appropriate message.
|
|
||||||
if (do_bot_verify &&
|
|
||||||
!g1->is_obj_dead(obj, this) &&
|
|
||||||
!_offsets.verify_for_object(p, obj_size)) {
|
|
||||||
*failures = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!g1->is_obj_dead_cond(obj, this, vo)) {
|
if (!g1->is_obj_dead_cond(obj, this, vo)) {
|
||||||
if (obj->is_oop()) {
|
if (obj->is_oop()) {
|
||||||
Klass* klass = obj->klass();
|
Klass* klass = obj->klass();
|
||||||
@ -924,6 +914,10 @@ void HeapRegion::verify(VerifyOption vo,
|
|||||||
p += obj_size;
|
p += obj_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_young() && !is_empty()) {
|
||||||
|
_offsets.verify();
|
||||||
|
}
|
||||||
|
|
||||||
if (p != top()) {
|
if (p != top()) {
|
||||||
gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
|
gclog_or_tty->print_cr("end of last object "PTR_FORMAT" "
|
||||||
"does not match top "PTR_FORMAT, p, top());
|
"does not match top "PTR_FORMAT, p, top());
|
||||||
|
Loading…
Reference in New Issue
Block a user