Mercurial > hg > truffle
comparison src/share/vm/memory/cardTableModRefBS.cpp @ 628:7bb995fbd3c0
Merge
author | trims |
---|---|
date | Thu, 12 Mar 2009 18:16:36 -0700 |
parents | 0fbdb4381b99 4f360ec815ba |
children | ff004bcd2596 |
comparison
equal
deleted
inserted
replaced
580:ce2272390558 | 628:7bb995fbd3c0 |
---|---|
215 jbyte* const new_end = byte_after(new_region.last()); | 215 jbyte* const new_end = byte_after(new_region.last()); |
216 HeapWord* new_end_aligned = | 216 HeapWord* new_end_aligned = |
217 (HeapWord*) align_size_up((uintptr_t)new_end, _page_size); | 217 (HeapWord*) align_size_up((uintptr_t)new_end, _page_size); |
218 assert(new_end_aligned >= (HeapWord*) new_end, | 218 assert(new_end_aligned >= (HeapWord*) new_end, |
219 "align up, but less"); | 219 "align up, but less"); |
220 // Check the other regions (excludes "ind") to ensure that | |
221 // the new_end_aligned does not intrude onto the committed | |
222 // space of another region. | |
220 int ri = 0; | 223 int ri = 0; |
221 for (ri = 0; ri < _cur_covered_regions; ri++) { | 224 for (ri = 0; ri < _cur_covered_regions; ri++) { |
222 if (ri != ind) { | 225 if (ri != ind) { |
223 if (_committed[ri].contains(new_end_aligned)) { | 226 if (_committed[ri].contains(new_end_aligned)) { |
224 assert((new_end_aligned >= _committed[ri].start()) && | 227 // The prior check included in the assert |
225 (_committed[ri].start() > _committed[ind].start()), | 228 // (new_end_aligned >= _committed[ri].start()) |
229 // is redundant with the "contains" test. | |
230 // Any region containing the new end | |
231 // should start at or beyond the region found (ind) | |
232 // for the new end (committed regions are not expected to | |
233 // be proper subsets of other committed regions). | |
234 assert(_committed[ri].start() >= _committed[ind].start(), | |
226 "New end of committed region is inconsistent"); | 235 "New end of committed region is inconsistent"); |
227 new_end_aligned = _committed[ri].start(); | 236 new_end_aligned = _committed[ri].start(); |
228 assert(new_end_aligned > _committed[ind].start(), | 237 // new_end_aligned can be equal to the start of its |
238 // committed region (i.e., of "ind") if a second | |
239 // region following "ind" also start at the same location | |
240 // as "ind". | |
241 assert(new_end_aligned >= _committed[ind].start(), | |
229 "New end of committed region is before start"); | 242 "New end of committed region is before start"); |
230 debug_only(collided = true;) | 243 debug_only(collided = true;) |
231 // Should only collide with 1 region | 244 // Should only collide with 1 region |
232 break; | 245 break; |
233 } | 246 } |
341 | 354 |
342 void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { | 355 void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) { |
343 inline_write_ref_field(field, newVal); | 356 inline_write_ref_field(field, newVal); |
344 } | 357 } |
345 | 358 |
359 /* | |
360 Claimed and deferred bits are used together in G1 during the evacuation | |
361 pause. These bits can have the following state transitions: | |
362 1. The claimed bit can be put over any other card state. Except that | |
363 the "dirty -> dirty and claimed" transition is checked for in | |
364 G1 code and is not used. | |
365 2. Deferred bit can be set only if the previous state of the card | |
366 was either clean or claimed. mark_card_deferred() is wait-free. | |
367 We do not care if the operation is be successful because if | |
368 it does not it will only result in duplicate entry in the update | |
369 buffer because of the "cache-miss". So it's not worth spinning. | |
370 */ | |
371 | |
346 | 372 |
347 bool CardTableModRefBS::claim_card(size_t card_index) { | 373 bool CardTableModRefBS::claim_card(size_t card_index) { |
348 jbyte val = _byte_map[card_index]; | 374 jbyte val = _byte_map[card_index]; |
349 if (val != claimed_card_val()) { | 375 assert(val != dirty_card_val(), "Shouldn't claim a dirty card"); |
350 jbyte res = Atomic::cmpxchg((jbyte) claimed_card_val(), &_byte_map[card_index], val); | 376 while (val == clean_card_val() || |
351 if (res == val) | 377 (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) { |
378 jbyte new_val = val; | |
379 if (val == clean_card_val()) { | |
380 new_val = (jbyte)claimed_card_val(); | |
381 } else { | |
382 new_val = val | (jbyte)claimed_card_val(); | |
383 } | |
384 jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val); | |
385 if (res == val) { | |
352 return true; | 386 return true; |
353 else return false; | 387 } |
388 val = res; | |
354 } | 389 } |
355 return false; | 390 return false; |
356 } | 391 } |
392 | |
393 bool CardTableModRefBS::mark_card_deferred(size_t card_index) { | |
394 jbyte val = _byte_map[card_index]; | |
395 // It's already processed | |
396 if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) { | |
397 return false; | |
398 } | |
399 // Cached bit can be installed either on a clean card or on a claimed card. | |
400 jbyte new_val = val; | |
401 if (val == clean_card_val()) { | |
402 new_val = (jbyte)deferred_card_val(); | |
403 } else { | |
404 if (val & claimed_card_val()) { | |
405 new_val = val | (jbyte)deferred_card_val(); | |
406 } | |
407 } | |
408 if (new_val != val) { | |
409 Atomic::cmpxchg(new_val, &_byte_map[card_index], val); | |
410 } | |
411 return true; | |
412 } | |
413 | |
357 | 414 |
358 void CardTableModRefBS::non_clean_card_iterate(Space* sp, | 415 void CardTableModRefBS::non_clean_card_iterate(Space* sp, |
359 MemRegion mr, | 416 MemRegion mr, |
360 DirtyCardToOopClosure* dcto_cl, | 417 DirtyCardToOopClosure* dcto_cl, |
361 MemRegionClosure* cl, | 418 MemRegionClosure* cl, |