comparison src/share/vm/memory/blockOffsetTable.cpp @ 1716:be3f9c242c9d

6948538: CMS: BOT walkers can fall into object allocation and initialization cracks Summary: GC workers now recognize an intermediate transient state of blocks which are allocated but have not yet completed initialization. blk_start() calls do not attempt to determine the size of a block in the transient state, rather waiting for the block to become initialized so that it is safe to query its size. Audited and ensured the order of initialization of object fields (klass, free bit and size) to respect block state transition protocol. Also included some new assertion checking code enabled in debug mode. Reviewed-by: chrisphi, johnc, poonam
author ysr
date Mon, 16 Aug 2010 15:58:42 -0700
parents c18cbe5936b8
children f95d63e2154a
comparison
equal deleted inserted replaced
1713:7fcd5f39bd7a 1716:be3f9c242c9d
1 /* 1 /*
2 * Copyright (c) 2000, 2006, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
101 ////////////////////////////////////////////////////////////////////// 101 //////////////////////////////////////////////////////////////////////
102 // BlockOffsetArray 102 // BlockOffsetArray
103 ////////////////////////////////////////////////////////////////////// 103 //////////////////////////////////////////////////////////////////////
104 104
105 BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array, 105 BlockOffsetArray::BlockOffsetArray(BlockOffsetSharedArray* array,
106 MemRegion mr, bool init_to_zero) : 106 MemRegion mr, bool init_to_zero_) :
107 BlockOffsetTable(mr.start(), mr.end()), 107 BlockOffsetTable(mr.start(), mr.end()),
108 _array(array), 108 _array(array)
109 _init_to_zero(init_to_zero)
110 { 109 {
111 assert(_bottom <= _end, "arguments out of order"); 110 assert(_bottom <= _end, "arguments out of order");
112 if (!_init_to_zero) { 111 set_init_to_zero(init_to_zero_);
112 if (!init_to_zero_) {
113 // initialize cards to point back to mr.start() 113 // initialize cards to point back to mr.start()
114 set_remainder_to_point_to_start(mr.start() + N_words, mr.end()); 114 set_remainder_to_point_to_start(mr.start() + N_words, mr.end());
115 _array->set_offset_array(0, 0); // set first card to 0 115 _array->set_offset_array(0, 0); // set first card to 0
116 } 116 }
117 } 117 }
119 119
120 // The arguments follow the normal convention of denoting 120 // The arguments follow the normal convention of denoting
121 // a right-open interval: [start, end) 121 // a right-open interval: [start, end)
122 void 122 void
123 BlockOffsetArray:: 123 BlockOffsetArray::
124 set_remainder_to_point_to_start(HeapWord* start, HeapWord* end) { 124 set_remainder_to_point_to_start(HeapWord* start, HeapWord* end, bool reducing) {
125 125
126 check_reducing_assertion(reducing);
126 if (start >= end) { 127 if (start >= end) {
127 // The start address is equal to the end address (or to 128 // The start address is equal to the end address (or to
128 // the right of the end address) so there are not cards 129 // the right of the end address) so there are not cards
129 // that need to be updated.. 130 // that need to be updated..
130 return; 131 return;
165 // 166 //
166 size_t start_card = _array->index_for(start); 167 size_t start_card = _array->index_for(start);
167 size_t end_card = _array->index_for(end-1); 168 size_t end_card = _array->index_for(end-1);
168 assert(start ==_array->address_for_index(start_card), "Precondition"); 169 assert(start ==_array->address_for_index(start_card), "Precondition");
169 assert(end ==_array->address_for_index(end_card)+N_words, "Precondition"); 170 assert(end ==_array->address_for_index(end_card)+N_words, "Precondition");
170 set_remainder_to_point_to_start_incl(start_card, end_card); // closed interval 171 set_remainder_to_point_to_start_incl(start_card, end_card, reducing); // closed interval
171 } 172 }
172 173
173 174
174 // Unlike the normal convention in this code, the argument here denotes 175 // Unlike the normal convention in this code, the argument here denotes
175 // a closed, inclusive interval: [start_card, end_card], cf set_remainder_to_point_to_start() 176 // a closed, inclusive interval: [start_card, end_card], cf set_remainder_to_point_to_start()
176 // above. 177 // above.
177 void 178 void
178 BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card) { 179 BlockOffsetArray::set_remainder_to_point_to_start_incl(size_t start_card, size_t end_card, bool reducing) {
180
181 check_reducing_assertion(reducing);
179 if (start_card > end_card) { 182 if (start_card > end_card) {
180 return; 183 return;
181 } 184 }
182 assert(start_card > _array->index_for(_bottom), "Cannot be first card"); 185 assert(start_card > _array->index_for(_bottom), "Cannot be first card");
183 assert(_array->offset_array(start_card-1) <= N_words, 186 assert(_array->offset_array(start_card-1) <= N_words,
189 // so that the reach ends in this region and not at the start 192 // so that the reach ends in this region and not at the start
190 // of the next. 193 // of the next.
191 size_t reach = start_card - 1 + (power_to_cards_back(i+1) - 1); 194 size_t reach = start_card - 1 + (power_to_cards_back(i+1) - 1);
192 offset = N_words + i; 195 offset = N_words + i;
193 if (reach >= end_card) { 196 if (reach >= end_card) {
194 _array->set_offset_array(start_card_for_region, end_card, offset); 197 _array->set_offset_array(start_card_for_region, end_card, offset, reducing);
195 start_card_for_region = reach + 1; 198 start_card_for_region = reach + 1;
196 break; 199 break;
197 } 200 }
198 _array->set_offset_array(start_card_for_region, reach, offset); 201 _array->set_offset_array(start_card_for_region, reach, offset, reducing);
199 start_card_for_region = reach + 1; 202 start_card_for_region = reach + 1;
200 } 203 }
201 assert(start_card_for_region > end_card, "Sanity check"); 204 assert(start_card_for_region > end_card, "Sanity check");
202 DEBUG_ONLY(check_all_cards(start_card, end_card);) 205 DEBUG_ONLY(check_all_cards(start_card, end_card);)
203 } 206 }
209 212
210 if (end_card < start_card) { 213 if (end_card < start_card) {
211 return; 214 return;
212 } 215 }
213 guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card"); 216 guarantee(_array->offset_array(start_card) == N_words, "Wrong value in second card");
217 u_char last_entry = N_words;
214 for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) { 218 for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
215 u_char entry = _array->offset_array(c); 219 u_char entry = _array->offset_array(c);
220 guarantee(entry >= last_entry, "Monotonicity");
216 if (c - start_card > power_to_cards_back(1)) { 221 if (c - start_card > power_to_cards_back(1)) {
217 guarantee(entry > N_words, "Should be in logarithmic region"); 222 guarantee(entry > N_words, "Should be in logarithmic region");
218 } 223 }
219 size_t backskip = entry_to_cards_back(entry); 224 size_t backskip = entry_to_cards_back(entry);
220 size_t landing_card = c - backskip; 225 size_t landing_card = c - backskip;
221 guarantee(landing_card >= (start_card - 1), "Inv"); 226 guarantee(landing_card >= (start_card - 1), "Inv");
222 if (landing_card >= start_card) { 227 if (landing_card >= start_card) {
223 guarantee(_array->offset_array(landing_card) <= entry, "monotonicity"); 228 guarantee(_array->offset_array(landing_card) <= entry, "Monotonicity");
224 } else { 229 } else {
225 guarantee(landing_card == start_card - 1, "Tautology"); 230 guarantee(landing_card == (start_card - 1), "Tautology");
231 // Note that N_words is the maximum offset value
226 guarantee(_array->offset_array(landing_card) <= N_words, "Offset value"); 232 guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
227 } 233 }
234 last_entry = entry; // remember for monotonicity test
228 } 235 }
229 } 236 }
230 237
231 238
232 void 239 void
241 // Action_single - udpate the BOT for an allocation. 248 // Action_single - udpate the BOT for an allocation.
242 // Action_verify - BOT verification. 249 // Action_verify - BOT verification.
243 void 250 void
244 BlockOffsetArray::do_block_internal(HeapWord* blk_start, 251 BlockOffsetArray::do_block_internal(HeapWord* blk_start,
245 HeapWord* blk_end, 252 HeapWord* blk_end,
246 Action action) { 253 Action action, bool reducing) {
247 assert(Universe::heap()->is_in_reserved(blk_start), 254 assert(Universe::heap()->is_in_reserved(blk_start),
248 "reference must be into the heap"); 255 "reference must be into the heap");
249 assert(Universe::heap()->is_in_reserved(blk_end-1), 256 assert(Universe::heap()->is_in_reserved(blk_end-1),
250 "limit must be within the heap"); 257 "limit must be within the heap");
251 // This is optimized to make the test fast, assuming we only rarely 258 // This is optimized to make the test fast, assuming we only rarely
273 assert(start_index <= end_index, "monotonicity of index_for()"); 280 assert(start_index <= end_index, "monotonicity of index_for()");
274 assert(boundary <= (HeapWord*)boundary_before_end, "tautology"); 281 assert(boundary <= (HeapWord*)boundary_before_end, "tautology");
275 switch (action) { 282 switch (action) {
276 case Action_mark: { 283 case Action_mark: {
277 if (init_to_zero()) { 284 if (init_to_zero()) {
278 _array->set_offset_array(start_index, boundary, blk_start); 285 _array->set_offset_array(start_index, boundary, blk_start, reducing);
279 break; 286 break;
280 } // Else fall through to the next case 287 } // Else fall through to the next case
281 } 288 }
282 case Action_single: { 289 case Action_single: {
283 _array->set_offset_array(start_index, boundary, blk_start); 290 _array->set_offset_array(start_index, boundary, blk_start, reducing);
284 // We have finished marking the "offset card". We need to now 291 // We have finished marking the "offset card". We need to now
285 // mark the subsequent cards that this blk spans. 292 // mark the subsequent cards that this blk spans.
286 if (start_index < end_index) { 293 if (start_index < end_index) {
287 HeapWord* rem_st = _array->address_for_index(start_index) + N_words; 294 HeapWord* rem_st = _array->address_for_index(start_index) + N_words;
288 HeapWord* rem_end = _array->address_for_index(end_index) + N_words; 295 HeapWord* rem_end = _array->address_for_index(end_index) + N_words;
289 set_remainder_to_point_to_start(rem_st, rem_end); 296 set_remainder_to_point_to_start(rem_st, rem_end, reducing);
290 } 297 }
291 break; 298 break;
292 } 299 }
293 case Action_check: { 300 case Action_check: {
294 _array->check_offset_array(start_index, boundary, blk_start); 301 _array->check_offset_array(start_index, boundary, blk_start);
393 HeapWord* end_addr = blk + blk_size; 400 HeapWord* end_addr = blk + blk_size;
394 401
395 // Indices for starts of prefix block and suffix block. 402 // Indices for starts of prefix block and suffix block.
396 size_t pref_index = _array->index_for(pref_addr); 403 size_t pref_index = _array->index_for(pref_addr);
397 if (_array->address_for_index(pref_index) != pref_addr) { 404 if (_array->address_for_index(pref_index) != pref_addr) {
398 // pref_addr deos not begin pref_index 405 // pref_addr does not begin pref_index
399 pref_index++; 406 pref_index++;
400 } 407 }
401 408
402 size_t suff_index = _array->index_for(suff_addr); 409 size_t suff_index = _array->index_for(suff_addr);
403 if (_array->address_for_index(suff_index) != suff_addr) { 410 if (_array->address_for_index(suff_index) != suff_addr) {
428 size_t num_suff_cards = end_index - suff_index; 435 size_t num_suff_cards = end_index - suff_index;
429 // Change the cards that need changing 436 // Change the cards that need changing
430 if (num_suff_cards > 0) { 437 if (num_suff_cards > 0) {
431 HeapWord* boundary = _array->address_for_index(suff_index); 438 HeapWord* boundary = _array->address_for_index(suff_index);
432 // Set the offset card for suffix block 439 // Set the offset card for suffix block
433 _array->set_offset_array(suff_index, boundary, suff_addr); 440 _array->set_offset_array(suff_index, boundary, suff_addr, true /* reducing */);
434 // Change any further cards that need changing in the suffix 441 // Change any further cards that need changing in the suffix
435 if (num_pref_cards > 0) { 442 if (num_pref_cards > 0) {
436 if (num_pref_cards >= num_suff_cards) { 443 if (num_pref_cards >= num_suff_cards) {
437 // Unilaterally fix all of the suffix cards: closed card 444 // Unilaterally fix all of the suffix cards: closed card
438 // index interval in args below. 445 // index interval in args below.
439 set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1); 446 set_remainder_to_point_to_start_incl(suff_index + 1, end_index - 1, true /* reducing */);
440 } else { 447 } else {
441 // Unilaterally fix the first (num_pref_cards - 1) following 448 // Unilaterally fix the first (num_pref_cards - 1) following
442 // the "offset card" in the suffix block. 449 // the "offset card" in the suffix block.
443 set_remainder_to_point_to_start_incl(suff_index + 1, 450 set_remainder_to_point_to_start_incl(suff_index + 1,
444 suff_index + num_pref_cards - 1); 451 suff_index + num_pref_cards - 1, true /* reducing */);
445 // Fix the appropriate cards in the remainder of the 452 // Fix the appropriate cards in the remainder of the
446 // suffix block -- these are the last num_pref_cards 453 // suffix block -- these are the last num_pref_cards
447 // cards in each power block of the "new" range plumbed 454 // cards in each power block of the "new" range plumbed
448 // from suff_addr. 455 // from suff_addr.
449 bool more = true; 456 bool more = true;
459 if (back_by > num_pref_cards) { 466 if (back_by > num_pref_cards) {
460 // Fill in the remainder of this "power block", if it 467 // Fill in the remainder of this "power block", if it
461 // is non-null. 468 // is non-null.
462 if (left_index <= right_index) { 469 if (left_index <= right_index) {
463 _array->set_offset_array(left_index, right_index, 470 _array->set_offset_array(left_index, right_index,
464 N_words + i - 1); 471 N_words + i - 1, true /* reducing */);
465 } else { 472 } else {
466 more = false; // we are done 473 more = false; // we are done
467 } 474 }
468 i++; 475 i++;
469 break; 476 break;
480 break; 487 break;
481 } 488 }
482 more = false; 489 more = false;
483 } 490 }
484 assert(left_index <= right_index, "Error"); 491 assert(left_index <= right_index, "Error");
485 _array->set_offset_array(left_index, right_index, N_words + i - 1); 492 _array->set_offset_array(left_index, right_index, N_words + i - 1, true /* reducing */);
486 i++; 493 i++;
487 } 494 }
488 } 495 }
489 } // else no more cards to fix in suffix 496 } // else no more cards to fix in suffix
490 } // else nothing needs to be done 497 } // else nothing needs to be done
499 // with the appropriate offset. 506 // with the appropriate offset.
500 // NOTE: this method does _not_ adjust _unallocated_block or 507 // NOTE: this method does _not_ adjust _unallocated_block or
501 // any cards subsequent to the first one. 508 // any cards subsequent to the first one.
502 void 509 void
503 BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start, 510 BlockOffsetArrayNonContigSpace::mark_block(HeapWord* blk_start,
504 HeapWord* blk_end) { 511 HeapWord* blk_end, bool reducing) {
505 do_block_internal(blk_start, blk_end, Action_mark); 512 do_block_internal(blk_start, blk_end, Action_mark, reducing);
506 } 513 }
507 514
508 HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe( 515 HeapWord* BlockOffsetArrayNonContigSpace::block_start_unsafe(
509 const void* addr) const { 516 const void* addr) const {
510 assert(_array->offset_array(0) == 0, "objects can't cross covered areas"); 517 assert(_array->offset_array(0) == 0, "objects can't cross covered areas");
511
512 assert(_bottom <= addr && addr < _end, 518 assert(_bottom <= addr && addr < _end,
513 "addr must be covered by this Array"); 519 "addr must be covered by this Array");
514 // Must read this exactly once because it can be modified by parallel 520 // Must read this exactly once because it can be modified by parallel
515 // allocation. 521 // allocation.
516 HeapWord* ub = _unallocated_block; 522 HeapWord* ub = _unallocated_block;
540 546
541 while (n <= addr) { 547 while (n <= addr) {
542 debug_only(HeapWord* last = q); // for debugging 548 debug_only(HeapWord* last = q); // for debugging
543 q = n; 549 q = n;
544 n += _sp->block_size(n); 550 n += _sp->block_size(n);
545 } 551 assert(n > q, err_msg("Looping at: " INTPTR_FORMAT, n));
546 assert(q <= addr, "wrong order for current and arg"); 552 }
547 assert(addr <= n, "wrong order for arg and next"); 553 assert(q <= addr, err_msg("wrong order for current (" INTPTR_FORMAT ") <= arg (" INTPTR_FORMAT ")", q, addr));
554 assert(addr <= n, err_msg("wrong order for arg (" INTPTR_FORMAT ") <= next (" INTPTR_FORMAT ")", addr, n));
548 return q; 555 return q;
549 } 556 }
550 557
551 HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful( 558 HeapWord* BlockOffsetArrayNonContigSpace::block_start_careful(
552 const void* addr) const { 559 const void* addr) const {
725 732
726 // _next_offset_index and _next_offset_threshold updated here. 733 // _next_offset_index and _next_offset_threshold updated here.
727 _next_offset_index = end_index + 1; 734 _next_offset_index = end_index + 1;
728 // Calculate _next_offset_threshold this way because end_index 735 // Calculate _next_offset_threshold this way because end_index
729 // may be the last valid index in the covered region. 736 // may be the last valid index in the covered region.
730 _next_offset_threshold = _array->address_for_index(end_index) + 737 _next_offset_threshold = _array->address_for_index(end_index) + N_words;
731 N_words; 738 assert(_next_offset_threshold >= blk_end, "Incorrect offset threshold");
732 assert(_next_offset_threshold >= blk_end, "Incorrent offset threshold");
733 739
734 #ifdef ASSERT 740 #ifdef ASSERT
735 // The offset can be 0 if the block starts on a boundary. That 741 // The offset can be 0 if the block starts on a boundary. That
736 // is checked by an assertion above. 742 // is checked by an assertion above.
737 size_t start_index = _array->index_for(blk_start); 743 size_t start_index = _array->index_for(blk_start);