hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx)
{
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
typedef ParMarkBitMap::IterationStatus IterationStatus;
const size_t RegionSize = ParallelCompactData::RegionSize;
ParMarkBitMap* const bitmap = mark_bitmap();
ParallelCompactData& sd = summary_data();
RegionData* const region_ptr = sd.region(region_idx);
// Get the items needed to construct the closure.
HeapWord* dest_addr = sd.region_to_addr(region_idx);
SpaceId dest_space_id = space_id(dest_addr);
ObjectStartArray* start_array = _space_info[dest_space_id].start_array();
HeapWord* new_top = _space_info[dest_space_id].new_top();
assert(dest_addr < new_top, "sanity");
const size_t words = MIN2(pointer_delta(new_top, dest_addr), RegionSize);
// Get the source region and related info.
size_t src_region_idx = region_ptr->source_region();
SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx));
HeapWord* src_space_top = _space_info[src_space_id].space()->top();
{- -------------------------------------------
(1)
---------------------------------------- -}
MoveAndUpdateClosure closure(bitmap, cm, start_array, dest_addr, words);
closure.set_source(first_src_addr(dest_addr, src_space_id, src_region_idx));
{- -------------------------------------------
(1)
---------------------------------------- -}
// Adjust src_region_idx to prepare for decrementing destination counts (the
// destination count is not decremented when a region is copied to itself).
if (src_region_idx == region_idx) {
src_region_idx += 1;
}
{- -------------------------------------------
(1)
---------------------------------------- -}
if (bitmap->is_unmarked(closure.source())) {
// The first source word is in the middle of an object; copy the remainder
// of the object or as much as will fit. The fact that pointer updates were
// deferred will be noted when the object header is processed.
HeapWord* const old_src_addr = closure.source();
closure.copy_partial_obj();
if (closure.is_full()) {
decrement_destination_counts(cm, src_space_id, src_region_idx,
closure.source());
region_ptr->set_deferred_obj_addr(NULL);
region_ptr->set_completed();
return;
}
HeapWord* const end_addr = sd.region_align_down(closure.source());
if (sd.region_align_down(old_src_addr) != end_addr) {
// The partial object was copied from more than one source region.
decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);
// Move to the next source region, possibly switching spaces as well. All
// args except end_addr may be modified.
src_region_idx = next_src_region(closure, src_space_id, src_space_top,
end_addr);
}
}
{- -------------------------------------------
(1)
---------------------------------------- -}
do {
HeapWord* const cur_addr = closure.source();
HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1),
src_space_top);
IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);
if (status == ParMarkBitMap::incomplete) {
// The last obj that starts in the source region does not end in the
// region.
assert(closure.source() < end_addr, "sanity");
HeapWord* const obj_beg = closure.source();
HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),
src_space_top);
HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end);
if (obj_end < range_end) {
// The end was found; the entire object will fit.
status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end));
assert(status != ParMarkBitMap::would_overflow, "sanity");
} else {
// The end was not found; the object will not fit.
assert(range_end < src_space_top, "obj cannot cross space boundary");
status = ParMarkBitMap::would_overflow;
}
}
if (status == ParMarkBitMap::would_overflow) {
// The last object did not fit. Note that interior oop updates were
// deferred, then copy enough of the object to fill the region.
region_ptr->set_deferred_obj_addr(closure.destination());
status = closure.copy_until_full(); // copies from closure.source()
decrement_destination_counts(cm, src_space_id, src_region_idx,
closure.source());
region_ptr->set_completed();
return;
}
if (status == ParMarkBitMap::full) {
decrement_destination_counts(cm, src_space_id, src_region_idx,
closure.source());
region_ptr->set_deferred_obj_addr(NULL);
region_ptr->set_completed();
return;
}
decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);
// Move to the next source region, possibly switching spaces as well. All
// args except end_addr may be modified.
src_region_idx = next_src_region(closure, src_space_id, src_space_top,
end_addr);
} while (true);
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.