Skip to content

Commit

Permalink
8245025: MoveAndUpdateClosure::do_addr calls function with side-effec…
Browse files Browse the repository at this point in the history
…ts in an assert

Reviewed-by: tschatzl, kbarrett
  • Loading branch information
albertnetymk committed Mar 15, 2021
1 parent 46d78f0 commit 771b146
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 18 deletions.
49 changes: 32 additions & 17 deletions src/hotspot/share/gc/parallel/psParallelCompact.cpp
Expand Up @@ -780,7 +780,7 @@ bool ParallelCompactData::summarize(SplitInfo& split_info,
return true;
}

HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) const {
HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm, bool use_block_table) const {
assert(addr != NULL, "Should detect NULL oop earlier");
assert(ParallelScavengeHeap::heap()->is_in(addr), "not in heap");
assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
Expand All @@ -801,24 +801,39 @@ HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionMan
return result;
}

// Otherwise, the new location is region->destination + block offset + the
// number of live words in the Block that are (a) to the left of addr and (b)
// due to objects that start in the Block.
// Otherwise, the new location is region->destination + #live words to left
// of addr in this region. Calculating #live words naively means walking the
// mark bitmap from the start of this region. Block table can be used to
// speed up this process, but it would incur some side-effect. In debug-only
// code (such as asserts), we prefer the slower but side-effect free version,
// to avoid side effects that would not occur for release code and could
// potentially affect future calculations.
if (use_block_table) {
// #live words = block offset + #live words in the Block that are
// (a) to the left of addr and (b) due to objects that start in the Block.

// Fill in the block table if necessary. This is unsynchronized, so multiple
// threads may fill the block table for a region (harmless, since it is
// idempotent).
if (!region_ptr->blocks_filled()) {
PSParallelCompact::fill_blocks(addr_to_region_idx(addr));
region_ptr->set_blocks_filled();
}
// Fill in the block table if necessary. This is unsynchronized, so multiple
// threads may fill the block table for a region (harmless, since it is
// idempotent).
if (!region_ptr->blocks_filled()) {
PSParallelCompact::fill_blocks(addr_to_region_idx(addr));
region_ptr->set_blocks_filled();
}

HeapWord* const search_start = block_align_down(addr);
const size_t block_offset = addr_to_block_ptr(addr)->offset();

HeapWord* const search_start = block_align_down(addr);
const size_t block_offset = addr_to_block_ptr(addr)->offset();
const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
const size_t live = bitmap->live_words_in_range(cm, search_start, oop(addr));
result += block_offset + live;
} else {
guarantee(trueInDebug, "Only in debug build");

const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
const size_t live = bitmap->live_words_in_range(cm, region_align_down(addr), oop(addr));
result += region_ptr->partial_obj_size() + live;
}

const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
const size_t live = bitmap->live_words_in_range(cm, search_start, oop(addr));
result += block_offset + live;
DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
return result;
}
Expand Down Expand Up @@ -3281,7 +3296,7 @@ MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {
assert(bitmap()->obj_size(addr) == words, "bad size");

_source = addr;
assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) ==
assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager(), false) ==
destination(), "wrong destination");

if (words > words_remaining()) {
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/gc/parallel/psParallelCompact.hpp
Expand Up @@ -480,7 +480,9 @@ class ParallelCompactData
HeapWord* partial_obj_end(size_t region_idx) const;

// Return the location of the object after compaction.
HeapWord* calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) const;
HeapWord* calc_new_pointer(HeapWord* addr,
ParCompactionManager* cm,
bool use_block_table = true) const;

HeapWord* calc_new_pointer(oop p, ParCompactionManager* cm) const {
return calc_new_pointer(cast_from_oop<HeapWord*>(p), cm);
Expand Down

0 comments on commit 771b146

Please sign in to comment.