@@ -780,7 +780,7 @@ bool ParallelCompactData::summarize(SplitInfo& split_info,
780
780
return true ;
781
781
}
782
782
783
- HeapWord* ParallelCompactData::calc_new_pointer (HeapWord* addr, ParCompactionManager* cm) const {
783
+ HeapWord* ParallelCompactData::calc_new_pointer (HeapWord* addr, ParCompactionManager* cm, bool use_block_table ) const {
784
784
assert (addr != NULL , " Should detect NULL oop earlier" );
785
785
assert (ParallelScavengeHeap::heap ()->is_in (addr), " not in heap" );
786
786
assert (PSParallelCompact::mark_bitmap ()->is_marked (addr), " not marked" );
@@ -801,24 +801,39 @@ HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionMan
801
801
return result;
802
802
}
803
803
804
- // Otherwise, the new location is region->destination + block offset + the
805
- // number of live words in the Block that are (a) to the left of addr and (b)
806
- // due to objects that start in the Block.
804
+ // Otherwise, the new location is region->destination + #live words to left
805
+ // of addr in this region. Calculating #live words naively means walking the
806
+ // mark bitmap from the start of this region. Block table can be used to
807
+ // speed up this process, but it would incur some side-effect. In debug-only
808
+ // code (such as asserts), we prefer the slower but side-effect free version,
809
+ // to avoid side effects that would not occur for release code and could
810
+ // potentially affect future calculations.
811
+ if (use_block_table) {
812
+ // #live words = block offset + #live words in the Block that are
813
+ // (a) to the left of addr and (b) due to objects that start in the Block.
807
814
808
- // Fill in the block table if necessary. This is unsynchronized, so multiple
809
- // threads may fill the block table for a region (harmless, since it is
810
- // idempotent).
811
- if (!region_ptr->blocks_filled ()) {
812
- PSParallelCompact::fill_blocks (addr_to_region_idx (addr));
813
- region_ptr->set_blocks_filled ();
814
- }
815
+ // Fill in the block table if necessary. This is unsynchronized, so multiple
816
+ // threads may fill the block table for a region (harmless, since it is
817
+ // idempotent).
818
+ if (!region_ptr->blocks_filled ()) {
819
+ PSParallelCompact::fill_blocks (addr_to_region_idx (addr));
820
+ region_ptr->set_blocks_filled ();
821
+ }
822
+
823
+ HeapWord* const search_start = block_align_down (addr);
824
+ const size_t block_offset = addr_to_block_ptr (addr)->offset ();
815
825
816
- HeapWord* const search_start = block_align_down (addr);
817
- const size_t block_offset = addr_to_block_ptr (addr)->offset ();
826
+ const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap ();
827
+ const size_t live = bitmap->live_words_in_range (cm, search_start, oop (addr));
828
+ result += block_offset + live;
829
+ } else {
830
+ guarantee (trueInDebug, " Only in debug build" );
831
+
832
+ const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap ();
833
+ const size_t live = bitmap->live_words_in_range (cm, region_align_down (addr), oop (addr));
834
+ result += region_ptr->partial_obj_size () + live;
835
+ }
818
836
819
- const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap ();
820
- const size_t live = bitmap->live_words_in_range (cm, search_start, oop (addr));
821
- result += block_offset + live;
822
837
DEBUG_ONLY (PSParallelCompact::check_new_location (addr, result));
823
838
return result;
824
839
}
@@ -3281,7 +3296,7 @@ MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
3281
3296
assert (bitmap ()->obj_size (addr) == words, " bad size" );
3282
3297
3283
3298
_source = addr;
3284
- assert (PSParallelCompact::summary_data ().calc_new_pointer (source (), compaction_manager ()) ==
3299
+ assert (PSParallelCompact::summary_data ().calc_new_pointer (source (), compaction_manager (), false ) ==
3285
3300
destination (), " wrong destination" );
3286
3301
3287
3302
if (words > words_remaining ()) {
0 commit comments