91 |
91 |
92 HeapRegion* loc_hr = hr(); |
92 HeapRegion* loc_hr = hr(); |
93 // If the test below fails, then this table was reused concurrently |
93 // If the test below fails, then this table was reused concurrently |
94 // with this operation. This is OK, since the old table was coarsened, |
94 // with this operation. This is OK, since the old table was coarsened, |
95 // and adding a bit to the new table is never incorrect. |
95 // and adding a bit to the new table is never incorrect. |
96 // If the table used to belong to a continues humongous region and is |
|
97 // now reused for the corresponding start humongous region, we need to |
|
98 // make sure that we detect this. Thus, we call is_in_reserved_raw() |
|
99 // instead of just is_in_reserved() here. |
|
100 if (loc_hr->is_in_reserved(from)) { |
96 if (loc_hr->is_in_reserved(from)) { |
101 size_t hw_offset = pointer_delta((HeapWord*)from, loc_hr->bottom()); |
97 CardIdx_t from_card = OtherRegionsTable::card_within_region(from, loc_hr); |
102 CardIdx_t from_card = (CardIdx_t) |
|
103 hw_offset >> (G1CardTable::card_shift - LogHeapWordSize); |
|
104 |
|
105 assert((size_t)from_card < HeapRegion::CardsPerRegion, |
|
106 "Must be in range."); |
|
107 add_card_work(from_card, par); |
98 add_card_work(from_card, par); |
108 } |
99 } |
109 } |
100 } |
110 |
101 |
111 public: |
102 public: |
341 "just checking"); |
332 "just checking"); |
342 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL, |
333 assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL, |
343 "just checking"); |
334 "just checking"); |
344 } |
335 } |
345 |
336 |
|
337 CardIdx_t OtherRegionsTable::card_within_region(OopOrNarrowOopStar within_region, HeapRegion* hr) { |
|
338 assert(hr->is_in_reserved(within_region), |
|
339 "HeapWord " PTR_FORMAT " is outside of region %u [" PTR_FORMAT ", " PTR_FORMAT ")", |
|
340 p2i(within_region), hr->hrm_index(), p2i(hr->bottom()), p2i(hr->end())); |
|
341 CardIdx_t result = (CardIdx_t)(pointer_delta((HeapWord*)within_region, hr->bottom()) >> (CardTable::card_shift - LogHeapWordSize)); |
|
342 return result; |
|
343 } |
|
344 |
346 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) { |
345 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, uint tid) { |
347 uint cur_hrm_ind = _hr->hrm_index(); |
346 uint cur_hrm_ind = _hr->hrm_index(); |
348 |
347 |
349 int from_card = (int)(uintptr_t(from) >> G1CardTable::card_shift); |
348 uintptr_t from_card = uintptr_t(from) >> CardTable::card_shift; |
350 |
349 |
351 if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) { |
350 if (G1FromCardCache::contains_or_replace(tid, cur_hrm_ind, from_card)) { |
352 assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from)); |
351 assert(contains_reference(from), "We just found " PTR_FORMAT " in the FromCardCache", p2i(from)); |
353 return; |
352 return; |
354 } |
353 } |
370 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); |
369 MutexLockerEx x(_m, Mutex::_no_safepoint_check_flag); |
371 // Confirm that it's really not there... |
370 // Confirm that it's really not there... |
372 prt = find_region_table(ind, from_hr); |
371 prt = find_region_table(ind, from_hr); |
373 if (prt == NULL) { |
372 if (prt == NULL) { |
374 |
373 |
375 uintptr_t from_hr_bot_card_index = |
374 CardIdx_t card_index = card_within_region(from, from_hr); |
376 uintptr_t(from_hr->bottom()) |
375 |
377 >> G1CardTable::card_shift; |
|
378 CardIdx_t card_index = from_card - from_hr_bot_card_index; |
|
379 assert((size_t)card_index < HeapRegion::CardsPerRegion, |
|
380 "Must be in range."); |
|
381 if (G1HRRSUseSparseTable && |
376 if (G1HRRSUseSparseTable && |
382 _sparse_table.add_card(from_hrm_ind, card_index)) { |
377 _sparse_table.add_card(from_hrm_ind, card_index)) { |
383 assert(contains_reference_locked(from), "We just added " PTR_FORMAT " to the Sparse table", p2i(from)); |
378 assert(contains_reference_locked(from), "We just added " PTR_FORMAT " to the Sparse table", p2i(from)); |
384 return; |
379 return; |
385 } |
380 } |
605 RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index(); |
600 RegionIdx_t hr_ind = (RegionIdx_t) hr->hrm_index(); |
606 // Is this region in the coarse map? |
601 // Is this region in the coarse map? |
607 if (_coarse_map.at(hr_ind)) return true; |
602 if (_coarse_map.at(hr_ind)) return true; |
608 |
603 |
609 PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, |
604 PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask, |
610 hr); |
605 hr); |
611 if (prt != NULL) { |
606 if (prt != NULL) { |
612 return prt->contains_reference(from); |
607 return prt->contains_reference(from); |
613 |
608 |
614 } else { |
609 } else { |
615 uintptr_t from_card = |
610 CardIdx_t card_index = card_within_region(from, hr); |
616 (uintptr_t(from) >> G1CardTable::card_shift); |
|
617 uintptr_t hr_bot_card_index = |
|
618 uintptr_t(hr->bottom()) >> G1CardTable::card_shift; |
|
619 assert(from_card >= hr_bot_card_index, "Inv"); |
|
620 CardIdx_t card_index = from_card - hr_bot_card_index; |
|
621 assert((size_t)card_index < HeapRegion::CardsPerRegion, |
|
622 "Must be in range."); |
|
623 return _sparse_table.contains_card(hr_ind, card_index); |
611 return _sparse_table.contains_card(hr_ind, card_index); |
624 } |
612 } |
625 } |
613 } |
626 |
614 |
627 void |
615 void |