提交 1d1883f5 编写于 作者: J johnc

7194633: G1: Assertion and guarantee failures in block offset table

Summary: Add detailed error messages to assertions and guarantees in G1's block offset table.
Reviewed-by: ysr, brutisso
上级 cb64e966
...@@ -302,16 +302,28 @@ void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) con ...@@ -302,16 +302,28 @@ void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) con
for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) { for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
u_char entry = _array->offset_array(c); u_char entry = _array->offset_array(c);
if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) { if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
guarantee(entry > N_words, "Should be in logarithmic region"); guarantee(entry > N_words,
err_msg("Should be in logarithmic region - "
"entry: " UINT32_FORMAT ", "
"_array->offset_array(c): " UINT32_FORMAT ", "
"N_words: " UINT32_FORMAT,
entry, _array->offset_array(c), N_words));
} }
size_t backskip = BlockOffsetArray::entry_to_cards_back(entry); size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
size_t landing_card = c - backskip; size_t landing_card = c - backskip;
guarantee(landing_card >= (start_card - 1), "Inv"); guarantee(landing_card >= (start_card - 1), "Inv");
if (landing_card >= start_card) { if (landing_card >= start_card) {
guarantee(_array->offset_array(landing_card) <= entry, "monotonicity"); guarantee(_array->offset_array(landing_card) <= entry,
err_msg("Monotonicity - landing_card offset: " UINT32_FORMAT ", "
"entry: " UINT32_FORMAT,
_array->offset_array(landing_card), entry));
} else { } else {
guarantee(landing_card == start_card - 1, "Tautology"); guarantee(landing_card == start_card - 1, "Tautology");
guarantee(_array->offset_array(landing_card) <= N_words, "Offset value"); // Note that N_words is the maximum offset value
guarantee(_array->offset_array(landing_card) <= N_words,
err_msg("landing card offset: " UINT32_FORMAT ", "
"N_words: " UINT32_FORMAT,
_array->offset_array(landing_card), N_words));
} }
} }
} }
...@@ -541,12 +553,22 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_ ...@@ -541,12 +553,22 @@ void G1BlockOffsetArray::alloc_block_work2(HeapWord** threshold_, size_t* index_
blk_start == boundary) || blk_start == boundary) ||
(_array->offset_array(orig_index) > 0 && (_array->offset_array(orig_index) > 0 &&
_array->offset_array(orig_index) <= N_words), _array->offset_array(orig_index) <= N_words),
"offset array should have been set"); err_msg("offset array should have been set - "
"orig_index offset: " UINT32_FORMAT ", "
"blk_start: " PTR_FORMAT ", "
"boundary: " PTR_FORMAT,
_array->offset_array(orig_index),
blk_start, boundary));
for (size_t j = orig_index + 1; j <= end_index; j++) { for (size_t j = orig_index + 1; j <= end_index; j++) {
assert(_array->offset_array(j) > 0 && assert(_array->offset_array(j) > 0 &&
_array->offset_array(j) <= _array->offset_array(j) <=
(u_char) (N_words+BlockOffsetArray::N_powers-1), (u_char) (N_words+BlockOffsetArray::N_powers-1),
"offset array should have been set"); err_msg("offset array should have been set - "
UINT32_FORMAT " not > 0 OR "
UINT32_FORMAT " not <= " UINT32_FORMAT,
_array->offset_array(j),
_array->offset_array(j),
(u_char) (N_words+BlockOffsetArray::N_powers-1)));
} }
#endif #endif
} }
......
...@@ -78,7 +78,9 @@ public: ...@@ -78,7 +78,9 @@ public:
virtual void resize(size_t new_word_size) = 0; virtual void resize(size_t new_word_size) = 0;
virtual void set_bottom(HeapWord* new_bottom) { virtual void set_bottom(HeapWord* new_bottom) {
assert(new_bottom <= _end, "new_bottom > _end"); assert(new_bottom <= _end,
err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")",
new_bottom, _end));
_bottom = new_bottom; _bottom = new_bottom;
resize(pointer_delta(_end, _bottom)); resize(pointer_delta(_end, _bottom));
} }
...@@ -134,29 +136,42 @@ private: ...@@ -134,29 +136,42 @@ private:
VirtualSpace _vs; VirtualSpace _vs;
u_char* _offset_array; // byte array keeping backwards offsets u_char* _offset_array; // byte array keeping backwards offsets
void check_index(size_t index, const char* msg) const {
assert(index < _vs.committed_size(),
err_msg("%s - "
"index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
msg, index, _vs.committed_size()));
}
void check_offset(size_t offset, const char* msg) const {
assert(offset <= N_words,
err_msg("%s - "
"offset: " UINT32_FORMAT", N_words: " UINT32_FORMAT,
msg, offset, N_words));
}
// Bounds checking accessors: // Bounds checking accessors:
// For performance these have to devolve to array accesses in product builds. // For performance these have to devolve to array accesses in product builds.
u_char offset_array(size_t index) const { u_char offset_array(size_t index) const {
assert(index < _vs.committed_size(), "index out of range"); check_index(index, "index out of range");
return _offset_array[index]; return _offset_array[index];
} }
void set_offset_array(size_t index, u_char offset) { void set_offset_array(size_t index, u_char offset) {
assert(index < _vs.committed_size(), "index out of range"); check_index(index, "index out of range");
assert(offset <= N_words, "offset too large"); check_offset(offset, "offset too large");
_offset_array[index] = offset; _offset_array[index] = offset;
} }
void set_offset_array(size_t index, HeapWord* high, HeapWord* low) { void set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
assert(index < _vs.committed_size(), "index out of range"); check_index(index, "index out of range");
assert(high >= low, "addresses out of order"); assert(high >= low, "addresses out of order");
assert(pointer_delta(high, low) <= N_words, "offset too large"); check_offset(pointer_delta(high, low), "offset too large");
_offset_array[index] = (u_char) pointer_delta(high, low); _offset_array[index] = (u_char) pointer_delta(high, low);
} }
void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) { void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
assert(index_for(right - 1) < _vs.committed_size(), check_index(index_for(right - 1), "right address out of range");
"right address out of range");
assert(left < right, "Heap addresses out of order"); assert(left < right, "Heap addresses out of order");
size_t num_cards = pointer_delta(right, left) >> LogN_words; size_t num_cards = pointer_delta(right, left) >> LogN_words;
if (UseMemSetInBOT) { if (UseMemSetInBOT) {
...@@ -171,7 +186,7 @@ private: ...@@ -171,7 +186,7 @@ private:
} }
void set_offset_array(size_t left, size_t right, u_char offset) { void set_offset_array(size_t left, size_t right, u_char offset) {
assert(right < _vs.committed_size(), "right address out of range"); check_index(right, "right index out of range");
assert(left <= right, "indexes out of order"); assert(left <= right, "indexes out of order");
size_t num_cards = right - left + 1; size_t num_cards = right - left + 1;
if (UseMemSetInBOT) { if (UseMemSetInBOT) {
...@@ -186,11 +201,10 @@ private: ...@@ -186,11 +201,10 @@ private:
} }
void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const { void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
assert(index < _vs.committed_size(), "index out of range"); check_index(index, "index out of range");
assert(high >= low, "addresses out of order"); assert(high >= low, "addresses out of order");
assert(pointer_delta(high, low) <= N_words, "offset too large"); check_offset(pointer_delta(high, low), "offset too large");
assert(_offset_array[index] == pointer_delta(high, low), assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
"Wrong offset");
} }
bool is_card_boundary(HeapWord* p) const; bool is_card_boundary(HeapWord* p) const;
...@@ -481,7 +495,6 @@ class G1BlockOffsetArrayContigSpace: public G1BlockOffsetArray { ...@@ -481,7 +495,6 @@ class G1BlockOffsetArrayContigSpace: public G1BlockOffsetArray {
blk_start, blk_end); blk_start, blk_end);
} }
public: public:
G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr); G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);
......
...@@ -49,16 +49,17 @@ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const { ...@@ -49,16 +49,17 @@ inline size_t G1BlockOffsetSharedArray::index_for(const void* p) const {
char* pc = (char*)p; char* pc = (char*)p;
assert(pc >= (char*)_reserved.start() && assert(pc >= (char*)_reserved.start() &&
pc < (char*)_reserved.end(), pc < (char*)_reserved.end(),
"p not in range."); err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
p, (char*)_reserved.start(), (char*)_reserved.end()));
size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char)); size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char));
size_t result = delta >> LogN; size_t result = delta >> LogN;
assert(result < _vs.committed_size(), "bad index from address"); check_index(result, "bad index from address");
return result; return result;
} }
inline HeapWord* inline HeapWord*
G1BlockOffsetSharedArray::address_for_index(size_t index) const { G1BlockOffsetSharedArray::address_for_index(size_t index) const {
assert(index < _vs.committed_size(), "bad index"); check_index(index, "index out of range");
HeapWord* result = _reserved.start() + (index << LogN_words); HeapWord* result = _reserved.start() + (index << LogN_words);
assert(result >= _reserved.start() && result < _reserved.end(), assert(result >= _reserved.start() && result < _reserved.end(),
err_msg("bad address from index result " PTR_FORMAT err_msg("bad address from index result " PTR_FORMAT
......
...@@ -790,7 +790,9 @@ ALL_SINCE_SAVE_MARKS_CLOSURES(ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN) ...@@ -790,7 +790,9 @@ ALL_SINCE_SAVE_MARKS_CLOSURES(ContigSpace_OOP_SINCE_SAVE_MARKS_DEFN)
// Very general, slow implementation. // Very general, slow implementation.
HeapWord* ContiguousSpace::block_start_const(const void* p) const { HeapWord* ContiguousSpace::block_start_const(const void* p) const {
assert(MemRegion(bottom(), end()).contains(p), "p not in space"); assert(MemRegion(bottom(), end()).contains(p),
err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
p, bottom(), end()));
if (p >= top()) { if (p >= top()) {
return top(); return top();
} else { } else {
...@@ -800,19 +802,27 @@ HeapWord* ContiguousSpace::block_start_const(const void* p) const { ...@@ -800,19 +802,27 @@ HeapWord* ContiguousSpace::block_start_const(const void* p) const {
last = cur; last = cur;
cur += oop(cur)->size(); cur += oop(cur)->size();
} }
assert(oop(last)->is_oop(), "Should be an object start"); assert(oop(last)->is_oop(),
err_msg(PTR_FORMAT " should be an object start", last));
return last; return last;
} }
} }
size_t ContiguousSpace::block_size(const HeapWord* p) const { size_t ContiguousSpace::block_size(const HeapWord* p) const {
assert(MemRegion(bottom(), end()).contains(p), "p not in space"); assert(MemRegion(bottom(), end()).contains(p),
err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
p, bottom(), end()));
HeapWord* current_top = top(); HeapWord* current_top = top();
assert(p <= current_top, "p is not a block start"); assert(p <= current_top,
assert(p == current_top || oop(p)->is_oop(), "p is not a block start"); err_msg("p > current top - p: " PTR_FORMAT ", current top: " PTR_FORMAT,
if (p < current_top) p, current_top));
assert(p == current_top || oop(p)->is_oop(),
err_msg("p (" PTR_FORMAT ") is not a block start - "
"current_top: " PTR_FORMAT ", is_oop: %s",
p, current_top, BOOL_TO_STR(oop(p)->is_oop())));
if (p < current_top) {
return oop(p)->size(); return oop(p)->size();
else { } else {
assert(p == current_top, "just checking"); assert(p == current_top, "just checking");
return pointer_delta(end(), (HeapWord*) p); return pointer_delta(end(), (HeapWord*) p);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册