Skip to content

Commit f7b1830

Browse files
author
Thomas Schatzl
committed
8289538: Make G1BlockOffsetTablePart unaware of block sizes
Reviewed-by: ayang, iwalulya
1 parent 5564eff commit f7b1830

6 files changed

+78
-82
lines changed

src/hotspot/share/gc/g1/g1BlockOffsetTable.cpp

+4-2
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,10 @@ void G1BlockOffsetTablePart::set_remainder_to_point_to_start_incl(size_t start_c
134134
start_card_for_region = reach + 1;
135135
}
136136
assert(start_card_for_region > end_card, "Sanity check");
137-
DEBUG_ONLY(check_all_cards(start_card, end_card);)
137+
check_all_cards(start_card, end_card);
138138
}
139139

140+
#ifdef ASSERT
140141
// The card-interval [start_card, end_card] is a closed interval; this
141142
// is an expensive check -- use with care and only under protection of
142143
// suitable flag.
@@ -174,6 +175,7 @@ void G1BlockOffsetTablePart::check_all_cards(size_t start_card, size_t end_card)
174175
}
175176
}
176177
}
178+
#endif
177179

178180
//
179181
// cur_card_boundary
@@ -262,7 +264,7 @@ void G1BlockOffsetTablePart::verify() const {
262264
HeapWord* obj_end = card_address - entry;
263265
while (obj_end < card_address) {
264266
HeapWord* obj = obj_end;
265-
size_t obj_size = block_size(obj);
267+
size_t obj_size = _hr->block_size(obj);
266268
obj_end = obj + obj_size;
267269
guarantee(obj_end > obj && obj_end <= _hr->top(),
268270
"Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,

src/hotspot/share/gc/g1/g1BlockOffsetTable.hpp

+9-17
Original file line numberDiff line numberDiff line change
@@ -108,43 +108,43 @@ class G1BlockOffsetTable: public CHeapObj<mtGC> {
108108

109109
class G1BlockOffsetTablePart {
110110
friend class G1BlockOffsetTable;
111-
friend class HeapRegion;
112111
friend class VMStructs;
113112
private:
114113
// This is the global BlockOffsetTable.
115114
G1BlockOffsetTable* _bot;
116115

117-
// The region that owns this subregion.
116+
// The region that owns this part of the BOT.
118117
HeapRegion* _hr;
119118

120119
// Sets the entries corresponding to the cards starting at "start" and ending
121120
// at "end" to point back to the card before "start"; [start, end]
122121
void set_remainder_to_point_to_start_incl(size_t start, size_t end);
123122

124123
inline size_t block_size(const HeapWord* p) const;
125-
inline size_t block_size(const HeapWord* p, HeapWord* pb) const;
126124

127125
// Returns the address of a block whose start is at most "addr".
128126
inline HeapWord* block_at_or_preceding(const void* addr) const;
129127

130128
// Return the address of the beginning of the block that contains "addr".
131129
// "q" is a block boundary that is <= "addr"; "n" is the address of the
132130
// next block (or the end of the space.)
133-
// "pb" is the current value of the region's parsable_bottom.
134131
inline HeapWord* forward_to_block_containing_addr(HeapWord* q, HeapWord* n,
135132
const void* addr,
136133
HeapWord* pb) const;
137134

138135
// Update BOT entries corresponding to the mem range [blk_start, blk_end).
139136
void update_for_block_work(HeapWord* blk_start, HeapWord* blk_end);
140137

141-
void check_all_cards(size_t left_card, size_t right_card) const;
138+
void check_all_cards(size_t left_card, size_t right_card) const NOT_DEBUG_RETURN;
142139

143-
public:
144140
static HeapWord* align_up_by_card_size(HeapWord* const addr) {
145141
return align_up(addr, BOTConstants::card_size());
146142
}
147143

144+
void update_for_block(HeapWord* blk_start, size_t size) {
145+
update_for_block(blk_start, blk_start + size);
146+
}
147+
public:
148148
static bool is_crossing_card_boundary(HeapWord* const obj_start,
149149
HeapWord* const obj_end) {
150150
HeapWord* cur_card_boundary = align_up_by_card_size(obj_start);
@@ -157,24 +157,16 @@ class G1BlockOffsetTablePart {
157157

158158
void verify() const;
159159

160-
// Returns the address of the start of the block containing "addr", or
161-
// else "null" if it is covered by no block. (May have side effects,
162-
// namely updating of shared array entries that "point" too far
163-
// backwards. This can occur, for example, when lab allocation is used
164-
// in a space covered by the table.)
165-
// "pb" is the current value of the region's parsable_bottom.
166-
inline HeapWord* block_start(const void* addr, HeapWord* pb);
160+
// Returns the address of the start of the block reaching into the card containing
161+
// "addr".
162+
inline HeapWord* block_start_reaching_into_card(const void* addr) const;
167163

168164
void update_for_block(HeapWord* blk_start, HeapWord* blk_end) {
169165
if (is_crossing_card_boundary(blk_start, blk_end)) {
170166
update_for_block_work(blk_start, blk_end);
171167
}
172168
}
173169

174-
void update_for_block(HeapWord* blk_start, size_t size) {
175-
update_for_block(blk_start, blk_start + size);
176-
}
177-
178170
void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size);
179171

180172
void print_on(outputStream* out) PRODUCT_RETURN;

src/hotspot/share/gc/g1/g1BlockOffsetTable.inline.hpp

+25-59
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,32 @@
3232
#include "runtime/atomic.hpp"
3333
#include "oops/oop.inline.hpp"
3434

35-
inline HeapWord* G1BlockOffsetTablePart::block_start(const void* addr, HeapWord* const pb) {
35+
inline HeapWord* G1BlockOffsetTablePart::block_start_reaching_into_card(const void* addr) const {
3636
assert(addr >= _hr->bottom() && addr < _hr->top(), "invalid address");
37-
HeapWord* q = block_at_or_preceding(addr);
38-
HeapWord* n = q + block_size(q, pb);
39-
return forward_to_block_containing_addr(q, n, addr, pb);
37+
38+
#ifdef ASSERT
39+
if (!_hr->is_continues_humongous()) {
40+
// For non-ContinuesHumongous regions, the first obj always starts from bottom.
41+
u_char offset = _bot->offset_array(_bot->index_for(_hr->bottom()));
42+
assert(offset == 0, "Found offset %u instead of 0 for region %u %s",
43+
offset, _hr->hrm_index(), _hr->get_short_type_str());
44+
}
45+
#endif
46+
47+
size_t index = _bot->index_for(addr);
48+
49+
uint offset = _bot->offset_array(index);
50+
while (offset >= BOTConstants::card_size_in_words()) {
51+
// The excess of the offset from N_words indicates a power of Base
52+
// to go back by.
53+
size_t n_cards_back = BOTConstants::entry_to_cards_back(offset);
54+
index -= n_cards_back;
55+
offset = _bot->offset_array(index);
56+
}
57+
assert(offset < BOTConstants::card_size_in_words(), "offset too large");
58+
59+
HeapWord* q = _bot->address_for_index(index);
60+
return q - offset;
4061
}
4162

4263
u_char G1BlockOffsetTable::offset_array(size_t index) const {
@@ -95,59 +116,4 @@ inline HeapWord* G1BlockOffsetTable::address_for_index(size_t index) const {
95116
return result;
96117
}
97118

98-
inline size_t G1BlockOffsetTablePart::block_size(const HeapWord* p) const {
99-
return _hr->block_size(p);
100-
}
101-
102-
inline size_t G1BlockOffsetTablePart::block_size(const HeapWord* p, HeapWord* const pb) const {
103-
return _hr->block_size(p, pb);
104-
}
105-
106-
inline HeapWord* G1BlockOffsetTablePart::block_at_or_preceding(const void* addr) const {
107-
#ifdef ASSERT
108-
if (!_hr->is_continues_humongous()) {
109-
// For non-ContinuesHumongous regions, the first obj always starts from bottom.
110-
u_char offset = _bot->offset_array(_bot->index_for(_hr->bottom()));
111-
assert(offset == 0, "Found offset %u instead of 0 for region %u %s",
112-
offset, _hr->hrm_index(), _hr->get_short_type_str());
113-
}
114-
#endif
115-
116-
size_t index = _bot->index_for(addr);
117-
118-
uint offset = _bot->offset_array(index); // Extend u_char to uint.
119-
while (offset >= BOTConstants::card_size_in_words()) {
120-
// The excess of the offset from N_words indicates a power of Base
121-
// to go back by.
122-
size_t n_cards_back = BOTConstants::entry_to_cards_back(offset);
123-
index -= n_cards_back;
124-
offset = _bot->offset_array(index);
125-
}
126-
assert(offset < BOTConstants::card_size_in_words(), "offset too large");
127-
128-
HeapWord* q = _bot->address_for_index(index);
129-
return q - offset;
130-
}
131-
132-
inline HeapWord* G1BlockOffsetTablePart::forward_to_block_containing_addr(HeapWord* q, HeapWord* n,
133-
const void* addr,
134-
HeapWord* const pb) const {
135-
while (n <= addr) {
136-
// When addr is not covered by the block starting at q we need to
137-
// step forward until we find the correct block. With the BOT
138-
// being precise, we should never have to step through more than
139-
// a single card.
140-
assert(_bot->index_for(n) == _bot->index_for(addr),
141-
"BOT not precise. Index for n: " SIZE_FORMAT " must be equal to the index for addr: " SIZE_FORMAT,
142-
_bot->index_for(n), _bot->index_for(addr));
143-
q = n;
144-
assert(cast_to_oop(q)->klass_or_null() != nullptr,
145-
"start of block must be an initialized object");
146-
n += block_size(q, pb);
147-
}
148-
assert(q <= addr, "wrong order for q and addr");
149-
assert(addr < n, "wrong order for addr and n");
150-
return q;
151-
}
152-
153119
#endif // SHARE_GC_G1_G1BLOCKOFFSETTABLE_INLINE_HPP

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2346,7 +2346,7 @@ HeapWord* G1CollectedHeap::block_start(const void* addr) const {
23462346
if (addr >= hr->top()) {
23472347
return nullptr;
23482348
}
2349-
return hr->block_start(addr, hr->parsable_bottom_acquire());
2349+
return hr->block_start(addr);
23502350
}
23512351

23522352
bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const {

src/hotspot/share/gc/g1/heapRegion.hpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -144,10 +144,19 @@ class HeapRegion : public CHeapObj<mtGC> {
144144
// This version synchronizes with other calls to par_allocate_impl().
145145
inline HeapWord* par_allocate_impl(size_t min_word_size, size_t desired_word_size, size_t* actual_word_size);
146146

147+
// Return the address of the beginning of the block that contains "addr".
148+
// "q" is a block boundary that is <= "addr"; "n" is the address of the
149+
// next block (or the end of the HeapRegion.)
150+
inline HeapWord* forward_to_block_containing_addr(HeapWord* q, HeapWord* n,
151+
const void* addr,
152+
HeapWord* pb) const;
153+
147154
static bool obj_is_filler(oop obj);
148155

149156
public:
150-
HeapWord* block_start(const void* addr, HeapWord* const pb);
157+
// Returns the address of the block reaching into or starting at addr.
158+
HeapWord* block_start(const void* addr) const;
159+
HeapWord* block_start(const void* addr, HeapWord* const pb) const;
151160

152161
void object_iterate(ObjectClosure* blk);
153162

src/hotspot/share/gc/g1/heapRegion.inline.hpp

+29-2
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,35 @@ inline HeapWord* HeapRegion::par_allocate_impl(size_t min_word_size,
8282
} while (true);
8383
}
8484

85-
inline HeapWord* HeapRegion::block_start(const void* addr, HeapWord* const pb) {
86-
return _bot_part.block_start(addr, pb);
85+
inline HeapWord* HeapRegion::forward_to_block_containing_addr(HeapWord* q, HeapWord* n,
86+
const void* addr,
87+
HeapWord* pb) const {
88+
while (n <= addr) {
89+
// When addr is not covered by the block starting at q we need to
90+
// step forward until we find the correct block. With the BOT
91+
// being precise, we should never have to step through more than
92+
// a single card.
93+
assert(!G1BlockOffsetTablePart::is_crossing_card_boundary(n, (HeapWord*)addr), "must be");
94+
q = n;
95+
assert(cast_to_oop(q)->klass_or_null() != nullptr,
96+
"start of block must be an initialized object");
97+
n += block_size(q, pb);
98+
}
99+
assert(q <= addr, "wrong order for q and addr");
100+
assert(addr < n, "wrong order for addr and n");
101+
return q;
102+
}
103+
104+
inline HeapWord* HeapRegion::block_start(const void* addr) const {
105+
return block_start(addr, parsable_bottom_acquire());
106+
}
107+
108+
inline HeapWord* HeapRegion::block_start(const void* addr, HeapWord* const pb) const {
109+
HeapWord* q = _bot_part.block_start_reaching_into_card(addr);
110+
// The returned address is the block that reaches into the card of addr. Walk
111+
// the heap to get to the block reaching into addr.
112+
HeapWord* n = q + block_size(q, pb);
113+
return forward_to_block_containing_addr(q, n, addr, pb);
87114
}
88115

89116
inline bool HeapRegion::obj_in_unparsable_area(oop obj, HeapWord* const pb) {

0 commit comments

Comments
 (0)