52
53 if (TraceBlockOffsetTable) {
54 gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
55 gclog_or_tty->print_cr(" "
56 " rs.base(): " PTR_FORMAT
57 " rs.size(): " SIZE_FORMAT
58 " rs end(): " PTR_FORMAT,
59 p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
60 }
61 }
62
63 bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
64 assert(p >= _reserved.start(), "just checking");
65 size_t delta = pointer_delta(p, _reserved.start());
66 return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
67 }
68
69 #ifdef ASSERT
70 void G1BlockOffsetSharedArray::check_index(size_t index, const char* msg) const {
71 assert((index) < (_reserved.word_size() >> LogN_words),
72 err_msg("%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
73 msg, (index), (_reserved.word_size() >> LogN_words)));
74 assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
75 err_msg("Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
76 " (%u) is not in committed area.",
77 (index),
78 p2i(address_for_index_raw(index)),
79 G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index))));
80 }
81 #endif // ASSERT
82
83 //////////////////////////////////////////////////////////////////////
84 // G1BlockOffsetArray
85 //////////////////////////////////////////////////////////////////////
86
87 G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
88 MemRegion mr) :
89 G1BlockOffsetTable(mr.start(), mr.end()),
90 _unallocated_block(_bottom),
91 _array(array), _gsp(NULL) {
92 assert(_bottom <= _end, "arguments out of order");
93 }
94
95 void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
96 _gsp = sp;
97 }
98
99 // The arguments follow the normal convention of denoting
175 _array->set_offset_array(start_card_for_region, reach, offset);
176 start_card_for_region = reach + 1;
177 }
178 assert(start_card_for_region > end_card, "Sanity check");
179 DEBUG_ONLY(check_all_cards(start_card, end_card);)
180 }
181
182 // The card-interval [start_card, end_card] is a closed interval; this
183 // is an expensive check -- use with care and only under protection of
184 // suitable flag.
185 void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
186
187 if (end_card < start_card) {
188 return;
189 }
190 guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
191 for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
192 u_char entry = _array->offset_array(c);
193 if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
194 guarantee(entry > N_words,
195 err_msg("Should be in logarithmic region - "
196 "entry: %u, "
197 "_array->offset_array(c): %u, "
198 "N_words: %u",
199 (uint)entry, (uint)_array->offset_array(c), (uint)N_words));
200 }
201 size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
202 size_t landing_card = c - backskip;
203 guarantee(landing_card >= (start_card - 1), "Inv");
204 if (landing_card >= start_card) {
205 guarantee(_array->offset_array(landing_card) <= entry,
206 err_msg("Monotonicity - landing_card offset: %u, "
207 "entry: %u",
208 (uint)_array->offset_array(landing_card), (uint)entry));
209 } else {
210 guarantee(landing_card == start_card - 1, "Tautology");
211 // Note that N_words is the maximum offset value
212 guarantee(_array->offset_array(landing_card) <= N_words,
213 err_msg("landing card offset: %u, "
214 "N_words: %u",
215 (uint)_array->offset_array(landing_card), (uint)N_words));
216 }
217 }
218 }
219
220 HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
221 assert(_bottom <= addr && addr < _end,
222 "addr must be covered by this Array");
223 // Must read this exactly once because it can be modified by parallel
224 // allocation.
225 HeapWord* ub = _unallocated_block;
226 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
227 assert(ub < _end, "tautology (see above)");
228 return ub;
229 }
230 // Otherwise, find the block start using the table.
231 HeapWord* q = block_at_or_preceding(addr, false, 0);
232 return forward_to_block_containing_addr(q, addr);
233 }
234
235 // This duplicates a little code from the above: unavoidable.
254 HeapWord*
255 G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
256 HeapWord* n,
257 const void* addr) {
258 // We're not in the normal case. We need to handle an important subcase
259 // here: LAB allocation. An allocation previously recorded in the
260 // offset table was actually a lab allocation, and was divided into
261 // several objects subsequently. Fix this situation as we answer the
262 // query, by updating entries as we cross them.
263
264 // If the fist object's end q is at the card boundary. Start refining
265 // with the corresponding card (the value of the entry will be basically
266 // set to 0). If the object crosses the boundary -- start from the next card.
267 size_t n_index = _array->index_for(n);
268 size_t next_index = _array->index_for(n) + !_array->is_card_boundary(n);
269 // Calculate a consistent next boundary. If "n" is not at the boundary
270 // already, step to the boundary.
271 HeapWord* next_boundary = _array->address_for_index(n_index) +
272 (n_index == next_index ? 0 : N_words);
273 assert(next_boundary <= _array->_end,
274 err_msg("next_boundary is beyond the end of the covered region "
275 " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
276 p2i(next_boundary), p2i(_array->_end)));
277 if (addr >= gsp()->top()) return gsp()->top();
278 while (next_boundary < addr) {
279 while (n <= next_boundary) {
280 q = n;
281 oop obj = oop(q);
282 if (obj->klass_or_null() == NULL) return q;
283 n += block_size(q);
284 }
285 assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
286 // [q, n) is the block that crosses the boundary.
287 alloc_block_work2(&next_boundary, &next_index, q, n);
288 }
289 return forward_to_block_containing_addr_const(q, n, addr);
290 }
291
292 // Note that the committed size of the covered space may have changed,
293 // so the table size might also wish to change.
294 void G1BlockOffsetArray::resize(size_t new_word_size) {
295 HeapWord* new_end = _bottom + new_word_size;
296 _end = new_end; // update _end
348
349 index = end_index + 1;
350 // Calculate threshold_ this way because end_index
351 // may be the last valid index in the covered region.
352 threshold = _array->address_for_index(end_index) + N_words;
353 assert(threshold >= blk_end, "Incorrect offset threshold");
354
355 // index_ and threshold_ updated here.
356 *threshold_ = threshold;
357 *index_ = index;
358
359 #ifdef ASSERT
360 // The offset can be 0 if the block starts on a boundary. That
361 // is checked by an assertion above.
362 size_t start_index = _array->index_for(blk_start);
363 HeapWord* boundary = _array->address_for_index(start_index);
364 assert((_array->offset_array(orig_index) == 0 &&
365 blk_start == boundary) ||
366 (_array->offset_array(orig_index) > 0 &&
367 _array->offset_array(orig_index) <= N_words),
368 err_msg("offset array should have been set - "
369 "orig_index offset: %u, "
370 "blk_start: " PTR_FORMAT ", "
371 "boundary: " PTR_FORMAT,
372 (uint)_array->offset_array(orig_index),
373 p2i(blk_start), p2i(boundary)));
374 for (size_t j = orig_index + 1; j <= end_index; j++) {
375 assert(_array->offset_array(j) > 0 &&
376 _array->offset_array(j) <=
377 (u_char) (N_words+BlockOffsetArray::N_powers-1),
378 err_msg("offset array should have been set - "
379 "%u not > 0 OR %u not <= %u",
380 (uint) _array->offset_array(j),
381 (uint) _array->offset_array(j),
382 (uint) (N_words+BlockOffsetArray::N_powers-1)));
383 }
384 #endif
385 }
386
387 void G1BlockOffsetArray::verify() const {
388 assert(gsp()->bottom() < gsp()->top(), "Only non-empty regions should be verified.");
389 size_t start_card = _array->index_for(gsp()->bottom());
390 size_t end_card = _array->index_for(gsp()->top() - 1);
391
392 for (size_t current_card = start_card; current_card < end_card; current_card++) {
393 u_char entry = _array->offset_array(current_card);
394 if (entry < N_words) {
395 // The entry should point to an object before the current card. Verify that
396 // it is possible to walk from that object in to the current card by just
397 // iterating over the objects following it.
398 HeapWord* card_address = _array->address_for_index(current_card);
399 HeapWord* obj_end = card_address - entry;
400 while (obj_end < card_address) {
401 HeapWord* obj = obj_end;
402 size_t obj_size = block_size(obj);
403 obj_end = obj + obj_size;
404 guarantee(obj_end > obj && obj_end <= gsp()->top(),
405 err_msg("Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
406 p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top())));
407 }
408 } else {
409 // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
410 // We need to make sure that we are going backwards and that we don't pass the start of the
411 // corresponding heap region. But that is about all we can verify.
412 size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
413 guarantee(backskip >= 1, "Must be going back at least one card.");
414
415 size_t max_backskip = current_card - start_card;
416 guarantee(backskip <= max_backskip,
417 err_msg("Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
418 start_card, current_card, backskip));
419
420 HeapWord* backskip_address = _array->address_for_index(current_card - backskip);
421 guarantee(backskip_address >= gsp()->bottom(),
422 err_msg("Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
423 p2i(gsp()->bottom()), p2i(backskip_address)));
424 }
425 }
426 }
427
428 #ifndef PRODUCT
429 void
430 G1BlockOffsetArray::print_on(outputStream* out) {
431 size_t from_index = _array->index_for(_bottom);
432 size_t to_index = _array->index_for(_end);
433 out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
434 "cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
435 p2i(_bottom), p2i(_end), from_index, to_index);
436 for (size_t i = from_index; i < to_index; ++i) {
437 out->print_cr(" entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
438 i, p2i(_array->address_for_index(i)),
439 (uint) _array->offset_array(i));
440 }
441 }
442 #endif // !PRODUCT
443
|
52
53 if (TraceBlockOffsetTable) {
54 gclog_or_tty->print_cr("G1BlockOffsetSharedArray::G1BlockOffsetSharedArray: ");
55 gclog_or_tty->print_cr(" "
56 " rs.base(): " PTR_FORMAT
57 " rs.size(): " SIZE_FORMAT
58 " rs end(): " PTR_FORMAT,
59 p2i(bot_reserved.start()), bot_reserved.byte_size(), p2i(bot_reserved.end()));
60 }
61 }
62
63 bool G1BlockOffsetSharedArray::is_card_boundary(HeapWord* p) const {
64 assert(p >= _reserved.start(), "just checking");
65 size_t delta = pointer_delta(p, _reserved.start());
66 return (delta & right_n_bits(LogN_words)) == (size_t)NoBits;
67 }
68
69 #ifdef ASSERT
70 void G1BlockOffsetSharedArray::check_index(size_t index, const char* msg) const {
71 assert((index) < (_reserved.word_size() >> LogN_words),
72 "%s - index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
73 msg, (index), (_reserved.word_size() >> LogN_words));
74 assert(G1CollectedHeap::heap()->is_in_exact(address_for_index_raw(index)),
75 "Index " SIZE_FORMAT " corresponding to " PTR_FORMAT
76 " (%u) is not in committed area.",
77 (index),
78 p2i(address_for_index_raw(index)),
79 G1CollectedHeap::heap()->addr_to_region(address_for_index_raw(index)));
80 }
81 #endif // ASSERT
82
83 //////////////////////////////////////////////////////////////////////
84 // G1BlockOffsetArray
85 //////////////////////////////////////////////////////////////////////
86
87 G1BlockOffsetArray::G1BlockOffsetArray(G1BlockOffsetSharedArray* array,
88 MemRegion mr) :
89 G1BlockOffsetTable(mr.start(), mr.end()),
90 _unallocated_block(_bottom),
91 _array(array), _gsp(NULL) {
92 assert(_bottom <= _end, "arguments out of order");
93 }
94
95 void G1BlockOffsetArray::set_space(G1OffsetTableContigSpace* sp) {
96 _gsp = sp;
97 }
98
99 // The arguments follow the normal convention of denoting
175 _array->set_offset_array(start_card_for_region, reach, offset);
176 start_card_for_region = reach + 1;
177 }
178 assert(start_card_for_region > end_card, "Sanity check");
179 DEBUG_ONLY(check_all_cards(start_card, end_card);)
180 }
181
182 // The card-interval [start_card, end_card] is a closed interval; this
183 // is an expensive check -- use with care and only under protection of
184 // suitable flag.
185 void G1BlockOffsetArray::check_all_cards(size_t start_card, size_t end_card) const {
186
187 if (end_card < start_card) {
188 return;
189 }
190 guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
191 for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
192 u_char entry = _array->offset_array(c);
193 if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
194 guarantee(entry > N_words,
195 "Should be in logarithmic region - "
196 "entry: %u, "
197 "_array->offset_array(c): %u, "
198 "N_words: %u",
199 (uint)entry, (uint)_array->offset_array(c), (uint)N_words);
200 }
201 size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
202 size_t landing_card = c - backskip;
203 guarantee(landing_card >= (start_card - 1), "Inv");
204 if (landing_card >= start_card) {
205 guarantee(_array->offset_array(landing_card) <= entry,
206 "Monotonicity - landing_card offset: %u, "
207 "entry: %u",
208 (uint)_array->offset_array(landing_card), (uint)entry);
209 } else {
210 guarantee(landing_card == start_card - 1, "Tautology");
211 // Note that N_words is the maximum offset value
212 guarantee(_array->offset_array(landing_card) <= N_words,
213 "landing card offset: %u, "
214 "N_words: %u",
215 (uint)_array->offset_array(landing_card), (uint)N_words);
216 }
217 }
218 }
219
220 HeapWord* G1BlockOffsetArray::block_start_unsafe(const void* addr) {
221 assert(_bottom <= addr && addr < _end,
222 "addr must be covered by this Array");
223 // Must read this exactly once because it can be modified by parallel
224 // allocation.
225 HeapWord* ub = _unallocated_block;
226 if (BlockOffsetArrayUseUnallocatedBlock && addr >= ub) {
227 assert(ub < _end, "tautology (see above)");
228 return ub;
229 }
230 // Otherwise, find the block start using the table.
231 HeapWord* q = block_at_or_preceding(addr, false, 0);
232 return forward_to_block_containing_addr(q, addr);
233 }
234
235 // This duplicates a little code from the above: unavoidable.
254 HeapWord*
255 G1BlockOffsetArray::forward_to_block_containing_addr_slow(HeapWord* q,
256 HeapWord* n,
257 const void* addr) {
258 // We're not in the normal case. We need to handle an important subcase
259 // here: LAB allocation. An allocation previously recorded in the
260 // offset table was actually a lab allocation, and was divided into
261 // several objects subsequently. Fix this situation as we answer the
262 // query, by updating entries as we cross them.
263
264 // If the fist object's end q is at the card boundary. Start refining
265 // with the corresponding card (the value of the entry will be basically
266 // set to 0). If the object crosses the boundary -- start from the next card.
267 size_t n_index = _array->index_for(n);
268 size_t next_index = _array->index_for(n) + !_array->is_card_boundary(n);
269 // Calculate a consistent next boundary. If "n" is not at the boundary
270 // already, step to the boundary.
271 HeapWord* next_boundary = _array->address_for_index(n_index) +
272 (n_index == next_index ? 0 : N_words);
273 assert(next_boundary <= _array->_end,
274 "next_boundary is beyond the end of the covered region "
275 " next_boundary " PTR_FORMAT " _array->_end " PTR_FORMAT,
276 p2i(next_boundary), p2i(_array->_end));
277 if (addr >= gsp()->top()) return gsp()->top();
278 while (next_boundary < addr) {
279 while (n <= next_boundary) {
280 q = n;
281 oop obj = oop(q);
282 if (obj->klass_or_null() == NULL) return q;
283 n += block_size(q);
284 }
285 assert(q <= next_boundary && n > next_boundary, "Consequence of loop");
286 // [q, n) is the block that crosses the boundary.
287 alloc_block_work2(&next_boundary, &next_index, q, n);
288 }
289 return forward_to_block_containing_addr_const(q, n, addr);
290 }
291
292 // Note that the committed size of the covered space may have changed,
293 // so the table size might also wish to change.
294 void G1BlockOffsetArray::resize(size_t new_word_size) {
295 HeapWord* new_end = _bottom + new_word_size;
296 _end = new_end; // update _end
348
349 index = end_index + 1;
350 // Calculate threshold_ this way because end_index
351 // may be the last valid index in the covered region.
352 threshold = _array->address_for_index(end_index) + N_words;
353 assert(threshold >= blk_end, "Incorrect offset threshold");
354
355 // index_ and threshold_ updated here.
356 *threshold_ = threshold;
357 *index_ = index;
358
359 #ifdef ASSERT
360 // The offset can be 0 if the block starts on a boundary. That
361 // is checked by an assertion above.
362 size_t start_index = _array->index_for(blk_start);
363 HeapWord* boundary = _array->address_for_index(start_index);
364 assert((_array->offset_array(orig_index) == 0 &&
365 blk_start == boundary) ||
366 (_array->offset_array(orig_index) > 0 &&
367 _array->offset_array(orig_index) <= N_words),
368 "offset array should have been set - "
369 "orig_index offset: %u, "
370 "blk_start: " PTR_FORMAT ", "
371 "boundary: " PTR_FORMAT,
372 (uint)_array->offset_array(orig_index),
373 p2i(blk_start), p2i(boundary));
374 for (size_t j = orig_index + 1; j <= end_index; j++) {
375 assert(_array->offset_array(j) > 0 &&
376 _array->offset_array(j) <=
377 (u_char) (N_words+BlockOffsetArray::N_powers-1),
378 "offset array should have been set - "
379 "%u not > 0 OR %u not <= %u",
380 (uint) _array->offset_array(j),
381 (uint) _array->offset_array(j),
382 (uint) (N_words+BlockOffsetArray::N_powers-1));
383 }
384 #endif
385 }
386
387 void G1BlockOffsetArray::verify() const {
388 assert(gsp()->bottom() < gsp()->top(), "Only non-empty regions should be verified.");
389 size_t start_card = _array->index_for(gsp()->bottom());
390 size_t end_card = _array->index_for(gsp()->top() - 1);
391
392 for (size_t current_card = start_card; current_card < end_card; current_card++) {
393 u_char entry = _array->offset_array(current_card);
394 if (entry < N_words) {
395 // The entry should point to an object before the current card. Verify that
396 // it is possible to walk from that object in to the current card by just
397 // iterating over the objects following it.
398 HeapWord* card_address = _array->address_for_index(current_card);
399 HeapWord* obj_end = card_address - entry;
400 while (obj_end < card_address) {
401 HeapWord* obj = obj_end;
402 size_t obj_size = block_size(obj);
403 obj_end = obj + obj_size;
404 guarantee(obj_end > obj && obj_end <= gsp()->top(),
405 "Invalid object end. obj: " PTR_FORMAT " obj_size: " SIZE_FORMAT " obj_end: " PTR_FORMAT " top: " PTR_FORMAT,
406 p2i(obj), obj_size, p2i(obj_end), p2i(gsp()->top()));
407 }
408 } else {
409 // Because we refine the BOT based on which cards are dirty there is not much we can verify here.
410 // We need to make sure that we are going backwards and that we don't pass the start of the
411 // corresponding heap region. But that is about all we can verify.
412 size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
413 guarantee(backskip >= 1, "Must be going back at least one card.");
414
415 size_t max_backskip = current_card - start_card;
416 guarantee(backskip <= max_backskip,
417 "Going backwards beyond the start_card. start_card: " SIZE_FORMAT " current_card: " SIZE_FORMAT " backskip: " SIZE_FORMAT,
418 start_card, current_card, backskip);
419
420 HeapWord* backskip_address = _array->address_for_index(current_card - backskip);
421 guarantee(backskip_address >= gsp()->bottom(),
422 "Going backwards beyond bottom of the region: bottom: " PTR_FORMAT ", backskip_address: " PTR_FORMAT,
423 p2i(gsp()->bottom()), p2i(backskip_address));
424 }
425 }
426 }
427
428 #ifndef PRODUCT
429 void
430 G1BlockOffsetArray::print_on(outputStream* out) {
431 size_t from_index = _array->index_for(_bottom);
432 size_t to_index = _array->index_for(_end);
433 out->print_cr(">> BOT for area [" PTR_FORMAT "," PTR_FORMAT ") "
434 "cards [" SIZE_FORMAT "," SIZE_FORMAT ")",
435 p2i(_bottom), p2i(_end), from_index, to_index);
436 for (size_t i = from_index; i < to_index; ++i) {
437 out->print_cr(" entry " SIZE_FORMAT_W(8) " | " PTR_FORMAT " : %3u",
438 i, p2i(_array->address_for_index(i)),
439 (uint) _array->offset_array(i));
440 }
441 }
442 #endif // !PRODUCT
443
|