Path: blob/master/src/hotspot/share/gc/parallel/psParallelCompact.cpp
41149 views
/*1* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "classfile/classLoaderDataGraph.hpp"26#include "classfile/javaClasses.inline.hpp"27#include "classfile/stringTable.hpp"28#include "classfile/symbolTable.hpp"29#include "classfile/systemDictionary.hpp"30#include "code/codeCache.hpp"31#include "compiler/oopMap.hpp"32#include "gc/parallel/parallelArguments.hpp"33#include "gc/parallel/parallelScavengeHeap.inline.hpp"34#include "gc/parallel/parMarkBitMap.inline.hpp"35#include "gc/parallel/psAdaptiveSizePolicy.hpp"36#include "gc/parallel/psCompactionManager.inline.hpp"37#include "gc/parallel/psOldGen.hpp"38#include "gc/parallel/psParallelCompact.inline.hpp"39#include "gc/parallel/psPromotionManager.inline.hpp"40#include "gc/parallel/psRootType.hpp"41#include "gc/parallel/psScavenge.hpp"42#include "gc/parallel/psYoungGen.hpp"43#include "gc/shared/gcCause.hpp"44#include "gc/shared/gcHeapSummary.hpp"45#include "gc/shared/gcId.hpp"46#include "gc/shared/gcLocker.hpp"47#include "gc/shared/gcTimer.hpp"48#include "gc/shared/gcTrace.hpp"49#include "gc/shared/gcTraceTime.inline.hpp"50#include "gc/shared/isGCActiveMark.hpp"51#include "gc/shared/oopStorage.inline.hpp"52#include "gc/shared/oopStorageSet.inline.hpp"53#include "gc/shared/oopStorageSetParState.inline.hpp"54#include "gc/shared/referencePolicy.hpp"55#include "gc/shared/referenceProcessor.hpp"56#include "gc/shared/referenceProcessorPhaseTimes.hpp"57#include "gc/shared/spaceDecorator.inline.hpp"58#include "gc/shared/taskTerminator.hpp"59#include "gc/shared/weakProcessor.inline.hpp"60#include "gc/shared/workerPolicy.hpp"61#include "gc/shared/workgroup.hpp"62#include "logging/log.hpp"63#include "memory/iterator.inline.hpp"64#include "memory/metaspaceUtils.hpp"65#include "memory/resourceArea.hpp"66#include "memory/universe.hpp"67#include "oops/access.inline.hpp"68#include "oops/instanceClassLoaderKlass.inline.hpp"69#include "oops/instanceKlass.inline.hpp"70#include "oops/instanceMirrorKlass.inline.hpp"71#include "oops/methodData.hpp"72#include "oops/objArrayKlass.inline.hpp"73#include "oops/oop.inline.hpp"74#include "runtime/atomic.hpp"75#include "runtime/handles.inline.hpp"76#include "runtime/java.hpp"77#include "runtime/safepoint.hpp"78#include "runtime/vmThread.hpp"79#include "services/memTracker.hpp"80#include "services/memoryService.hpp"81#include "utilities/align.hpp"82#include "utilities/debug.hpp"83#include "utilities/events.hpp"84#include "utilities/formatBuffer.hpp"85#include "utilities/macros.hpp"86#include "utilities/stack.inline.hpp"87#if INCLUDE_JVMCI88#include "jvmci/jvmci.hpp"89#endif9091#include <math.h>9293// All sizes are in HeapWords.94const size_t ParallelCompactData::Log2RegionSize = 16; // 64K words95const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize;96const size_t ParallelCompactData::RegionSizeBytes =97RegionSize << LogHeapWordSize;98const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1;99const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1;100const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask;101102const size_t ParallelCompactData::Log2BlockSize = 7; // 128 words103const size_t ParallelCompactData::BlockSize = (size_t)1 << Log2BlockSize;104const size_t ParallelCompactData::BlockSizeBytes =105BlockSize << LogHeapWordSize;106const size_t ParallelCompactData::BlockSizeOffsetMask = BlockSize - 1;107const size_t ParallelCompactData::BlockAddrOffsetMask = BlockSizeBytes - 1;108const size_t ParallelCompactData::BlockAddrMask = ~BlockAddrOffsetMask;109110const size_t ParallelCompactData::BlocksPerRegion = RegionSize / BlockSize;111const size_t ParallelCompactData::Log2BlocksPerRegion =112Log2RegionSize - Log2BlockSize;113114const ParallelCompactData::RegionData::region_sz_t115ParallelCompactData::RegionData::dc_shift = 27;116117const ParallelCompactData::RegionData::region_sz_t118ParallelCompactData::RegionData::dc_mask = ~0U << dc_shift;119120const ParallelCompactData::RegionData::region_sz_t121ParallelCompactData::RegionData::dc_one = 0x1U << dc_shift;122123const ParallelCompactData::RegionData::region_sz_t124ParallelCompactData::RegionData::los_mask = ~dc_mask;125126const ParallelCompactData::RegionData::region_sz_t127ParallelCompactData::RegionData::dc_claimed = 0x8U << dc_shift;128129const ParallelCompactData::RegionData::region_sz_t130ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift;131132SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id];133134SpanSubjectToDiscoveryClosure PSParallelCompact::_span_based_discoverer;135ReferenceProcessor* PSParallelCompact::_ref_processor = NULL;136137double PSParallelCompact::_dwl_mean;138double PSParallelCompact::_dwl_std_dev;139double PSParallelCompact::_dwl_first_term;140double PSParallelCompact::_dwl_adjustment;141#ifdef ASSERT142bool PSParallelCompact::_dwl_initialized = false;143#endif // #ifdef ASSERT144145void SplitInfo::record(size_t src_region_idx, size_t partial_obj_size,146HeapWord* destination)147{148assert(src_region_idx != 0, "invalid src_region_idx");149assert(partial_obj_size != 0, "invalid partial_obj_size argument");150assert(destination != NULL, "invalid destination argument");151152_src_region_idx = src_region_idx;153_partial_obj_size = partial_obj_size;154_destination = destination;155156// These fields may not be updated below, so make sure they're clear.157assert(_dest_region_addr == NULL, "should have been cleared");158assert(_first_src_addr == NULL, "should have been cleared");159160// Determine the number of destination regions for the partial object.161HeapWord* const last_word = destination + partial_obj_size - 1;162const ParallelCompactData& sd = PSParallelCompact::summary_data();163HeapWord* const beg_region_addr = sd.region_align_down(destination);164HeapWord* const end_region_addr = sd.region_align_down(last_word);165166if (beg_region_addr == end_region_addr) {167// One destination region.168_destination_count = 1;169if (end_region_addr == destination) {170// The destination falls on a region boundary, thus the first word of the171// partial object will be the first word copied to the destination region.172_dest_region_addr = end_region_addr;173_first_src_addr = sd.region_to_addr(src_region_idx);174}175} else {176// Two destination regions. When copied, the partial object will cross a177// destination region boundary, so a word somewhere within the partial178// object will be the first word copied to the second destination region.179_destination_count = 2;180_dest_region_addr = end_region_addr;181const size_t ofs = pointer_delta(end_region_addr, destination);182assert(ofs < _partial_obj_size, "sanity");183_first_src_addr = sd.region_to_addr(src_region_idx) + ofs;184}185}186187void SplitInfo::clear()188{189_src_region_idx = 0;190_partial_obj_size = 0;191_destination = NULL;192_destination_count = 0;193_dest_region_addr = NULL;194_first_src_addr = NULL;195assert(!is_valid(), "sanity");196}197198#ifdef ASSERT199void SplitInfo::verify_clear()200{201assert(_src_region_idx == 0, "not clear");202assert(_partial_obj_size == 0, "not clear");203assert(_destination == NULL, "not clear");204assert(_destination_count == 0, "not clear");205assert(_dest_region_addr == NULL, "not clear");206assert(_first_src_addr == NULL, "not clear");207}208#endif // #ifdef ASSERT209210211void PSParallelCompact::print_on_error(outputStream* st) {212_mark_bitmap.print_on_error(st);213}214215#ifndef PRODUCT216const char* PSParallelCompact::space_names[] = {217"old ", "eden", "from", "to "218};219220void PSParallelCompact::print_region_ranges() {221if (!log_develop_is_enabled(Trace, gc, compaction)) {222return;223}224Log(gc, compaction) log;225ResourceMark rm;226LogStream ls(log.trace());227Universe::print_on(&ls);228log.trace("space bottom top end new_top");229log.trace("------ ---------- ---------- ---------- ----------");230231for (unsigned int id = 0; id < last_space_id; ++id) {232const MutableSpace* space = _space_info[id].space();233log.trace("%u %s "234SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " "235SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10) " ",236id, space_names[id],237summary_data().addr_to_region_idx(space->bottom()),238summary_data().addr_to_region_idx(space->top()),239summary_data().addr_to_region_idx(space->end()),240summary_data().addr_to_region_idx(_space_info[id].new_top()));241}242}243244void245print_generic_summary_region(size_t i, const ParallelCompactData::RegionData* c)246{247#define REGION_IDX_FORMAT SIZE_FORMAT_W(7)248#define REGION_DATA_FORMAT SIZE_FORMAT_W(5)249250ParallelCompactData& sd = PSParallelCompact::summary_data();251size_t dci = c->destination() ? sd.addr_to_region_idx(c->destination()) : 0;252log_develop_trace(gc, compaction)(253REGION_IDX_FORMAT " " PTR_FORMAT " "254REGION_IDX_FORMAT " " PTR_FORMAT " "255REGION_DATA_FORMAT " " REGION_DATA_FORMAT " "256REGION_DATA_FORMAT " " REGION_IDX_FORMAT " %d",257i, p2i(c->data_location()), dci, p2i(c->destination()),258c->partial_obj_size(), c->live_obj_size(),259c->data_size(), c->source_region(), c->destination_count());260261#undef REGION_IDX_FORMAT262#undef REGION_DATA_FORMAT263}264265void266print_generic_summary_data(ParallelCompactData& summary_data,267HeapWord* const beg_addr,268HeapWord* const end_addr)269{270size_t total_words = 0;271size_t i = summary_data.addr_to_region_idx(beg_addr);272const size_t last = summary_data.addr_to_region_idx(end_addr);273HeapWord* pdest = 0;274275while (i < last) {276ParallelCompactData::RegionData* c = summary_data.region(i);277if (c->data_size() != 0 || c->destination() != pdest) {278print_generic_summary_region(i, c);279total_words += c->data_size();280pdest = c->destination();281}282++i;283}284285log_develop_trace(gc, compaction)("summary_data_bytes=" SIZE_FORMAT, total_words * HeapWordSize);286}287288void289PSParallelCompact::print_generic_summary_data(ParallelCompactData& summary_data,290HeapWord* const beg_addr,291HeapWord* const end_addr) {292::print_generic_summary_data(summary_data,beg_addr, end_addr);293}294295void296print_generic_summary_data(ParallelCompactData& summary_data,297SpaceInfo* space_info)298{299if (!log_develop_is_enabled(Trace, gc, compaction)) {300return;301}302303for (unsigned int id = 0; id < PSParallelCompact::last_space_id; ++id) {304const MutableSpace* space = space_info[id].space();305print_generic_summary_data(summary_data, space->bottom(),306MAX2(space->top(), space_info[id].new_top()));307}308}309310void311print_initial_summary_data(ParallelCompactData& summary_data,312const MutableSpace* space) {313if (space->top() == space->bottom()) {314return;315}316317const size_t region_size = ParallelCompactData::RegionSize;318typedef ParallelCompactData::RegionData RegionData;319HeapWord* const top_aligned_up = summary_data.region_align_up(space->top());320const size_t end_region = summary_data.addr_to_region_idx(top_aligned_up);321const RegionData* c = summary_data.region(end_region - 1);322HeapWord* end_addr = c->destination() + c->data_size();323const size_t live_in_space = pointer_delta(end_addr, space->bottom());324325// Print (and count) the full regions at the beginning of the space.326size_t full_region_count = 0;327size_t i = summary_data.addr_to_region_idx(space->bottom());328while (i < end_region && summary_data.region(i)->data_size() == region_size) {329ParallelCompactData::RegionData* c = summary_data.region(i);330log_develop_trace(gc, compaction)(331SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",332i, p2i(c->destination()),333c->partial_obj_size(), c->live_obj_size(),334c->data_size(), c->source_region(), c->destination_count());335++full_region_count;336++i;337}338339size_t live_to_right = live_in_space - full_region_count * region_size;340341double max_reclaimed_ratio = 0.0;342size_t max_reclaimed_ratio_region = 0;343size_t max_dead_to_right = 0;344size_t max_live_to_right = 0;345346// Print the 'reclaimed ratio' for regions while there is something live in347// the region or to the right of it. The remaining regions are empty (and348// uninteresting), and computing the ratio will result in division by 0.349while (i < end_region && live_to_right > 0) {350c = summary_data.region(i);351HeapWord* const region_addr = summary_data.region_to_addr(i);352const size_t used_to_right = pointer_delta(space->top(), region_addr);353const size_t dead_to_right = used_to_right - live_to_right;354const double reclaimed_ratio = double(dead_to_right) / live_to_right;355356if (reclaimed_ratio > max_reclaimed_ratio) {357max_reclaimed_ratio = reclaimed_ratio;358max_reclaimed_ratio_region = i;359max_dead_to_right = dead_to_right;360max_live_to_right = live_to_right;361}362363ParallelCompactData::RegionData* c = summary_data.region(i);364log_develop_trace(gc, compaction)(365SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d"366"%12.10f " SIZE_FORMAT_W(10) " " SIZE_FORMAT_W(10),367i, p2i(c->destination()),368c->partial_obj_size(), c->live_obj_size(),369c->data_size(), c->source_region(), c->destination_count(),370reclaimed_ratio, dead_to_right, live_to_right);371372373live_to_right -= c->data_size();374++i;375}376377// Any remaining regions are empty. Print one more if there is one.378if (i < end_region) {379ParallelCompactData::RegionData* c = summary_data.region(i);380log_develop_trace(gc, compaction)(381SIZE_FORMAT_W(5) " " PTR_FORMAT " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " " SIZE_FORMAT_W(5) " %d",382i, p2i(c->destination()),383c->partial_obj_size(), c->live_obj_size(),384c->data_size(), c->source_region(), c->destination_count());385}386387log_develop_trace(gc, compaction)("max: " SIZE_FORMAT_W(4) " d2r=" SIZE_FORMAT_W(10) " l2r=" SIZE_FORMAT_W(10) " max_ratio=%14.12f",388max_reclaimed_ratio_region, max_dead_to_right, max_live_to_right, max_reclaimed_ratio);389}390391void392print_initial_summary_data(ParallelCompactData& summary_data,393SpaceInfo* space_info) {394if (!log_develop_is_enabled(Trace, gc, compaction)) {395return;396}397398unsigned int id = PSParallelCompact::old_space_id;399const MutableSpace* space;400do {401space = space_info[id].space();402print_initial_summary_data(summary_data, space);403} while (++id < PSParallelCompact::eden_space_id);404405do {406space = space_info[id].space();407print_generic_summary_data(summary_data, space->bottom(), space->top());408} while (++id < PSParallelCompact::last_space_id);409}410#endif // #ifndef PRODUCT411412ParallelCompactData::ParallelCompactData() :413_region_start(NULL),414DEBUG_ONLY(_region_end(NULL) COMMA)415_region_vspace(NULL),416_reserved_byte_size(0),417_region_data(NULL),418_region_count(0),419_block_vspace(NULL),420_block_data(NULL),421_block_count(0) {}422423bool ParallelCompactData::initialize(MemRegion covered_region)424{425_region_start = covered_region.start();426const size_t region_size = covered_region.word_size();427DEBUG_ONLY(_region_end = _region_start + region_size;)428429assert(region_align_down(_region_start) == _region_start,430"region start not aligned");431assert((region_size & RegionSizeOffsetMask) == 0,432"region size not a multiple of RegionSize");433434bool result = initialize_region_data(region_size) && initialize_block_data();435return result;436}437438PSVirtualSpace*439ParallelCompactData::create_vspace(size_t count, size_t element_size)440{441const size_t raw_bytes = count * element_size;442const size_t page_sz = os::page_size_for_region_aligned(raw_bytes, 10);443const size_t granularity = os::vm_allocation_granularity();444_reserved_byte_size = align_up(raw_bytes, MAX2(page_sz, granularity));445446const size_t rs_align = page_sz == (size_t) os::vm_page_size() ? 0 :447MAX2(page_sz, granularity);448ReservedSpace rs(_reserved_byte_size, rs_align, page_sz);449os::trace_page_sizes("Parallel Compact Data", raw_bytes, raw_bytes, page_sz, rs.base(),450rs.size());451452MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);453454PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);455if (vspace != 0) {456if (vspace->expand_by(_reserved_byte_size)) {457return vspace;458}459delete vspace;460// Release memory reserved in the space.461rs.release();462}463464return 0;465}466467bool ParallelCompactData::initialize_region_data(size_t region_size)468{469const size_t count = (region_size + RegionSizeOffsetMask) >> Log2RegionSize;470_region_vspace = create_vspace(count, sizeof(RegionData));471if (_region_vspace != 0) {472_region_data = (RegionData*)_region_vspace->reserved_low_addr();473_region_count = count;474return true;475}476return false;477}478479bool ParallelCompactData::initialize_block_data()480{481assert(_region_count != 0, "region data must be initialized first");482const size_t count = _region_count << Log2BlocksPerRegion;483_block_vspace = create_vspace(count, sizeof(BlockData));484if (_block_vspace != 0) {485_block_data = (BlockData*)_block_vspace->reserved_low_addr();486_block_count = count;487return true;488}489return false;490}491492void ParallelCompactData::clear()493{494memset(_region_data, 0, _region_vspace->committed_size());495memset(_block_data, 0, _block_vspace->committed_size());496}497498void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) {499assert(beg_region <= _region_count, "beg_region out of range");500assert(end_region <= _region_count, "end_region out of range");501assert(RegionSize % BlockSize == 0, "RegionSize not a multiple of BlockSize");502503const size_t region_cnt = end_region - beg_region;504memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData));505506const size_t beg_block = beg_region * BlocksPerRegion;507const size_t block_cnt = region_cnt * BlocksPerRegion;508memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData));509}510511HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const512{513const RegionData* cur_cp = region(region_idx);514const RegionData* const end_cp = region(region_count() - 1);515516HeapWord* result = region_to_addr(region_idx);517if (cur_cp < end_cp) {518do {519result += cur_cp->partial_obj_size();520} while (cur_cp->partial_obj_size() == RegionSize && ++cur_cp < end_cp);521}522return result;523}524525void ParallelCompactData::add_obj(HeapWord* addr, size_t len)526{527const size_t obj_ofs = pointer_delta(addr, _region_start);528const size_t beg_region = obj_ofs >> Log2RegionSize;529// end_region is inclusive530const size_t end_region = (obj_ofs + len - 1) >> Log2RegionSize;531532if (beg_region == end_region) {533// All in one region.534_region_data[beg_region].add_live_obj(len);535return;536}537538// First region.539const size_t beg_ofs = region_offset(addr);540_region_data[beg_region].add_live_obj(RegionSize - beg_ofs);541542// Middle regions--completely spanned by this object.543for (size_t region = beg_region + 1; region < end_region; ++region) {544_region_data[region].set_partial_obj_size(RegionSize);545_region_data[region].set_partial_obj_addr(addr);546}547548// Last region.549const size_t end_ofs = region_offset(addr + len - 1);550_region_data[end_region].set_partial_obj_size(end_ofs + 1);551_region_data[end_region].set_partial_obj_addr(addr);552}553554void555ParallelCompactData::summarize_dense_prefix(HeapWord* beg, HeapWord* end)556{557assert(is_region_aligned(beg), "not RegionSize aligned");558assert(is_region_aligned(end), "not RegionSize aligned");559560size_t cur_region = addr_to_region_idx(beg);561const size_t end_region = addr_to_region_idx(end);562HeapWord* addr = beg;563while (cur_region < end_region) {564_region_data[cur_region].set_destination(addr);565_region_data[cur_region].set_destination_count(0);566_region_data[cur_region].set_source_region(cur_region);567_region_data[cur_region].set_data_location(addr);568569// Update live_obj_size so the region appears completely full.570size_t live_size = RegionSize - _region_data[cur_region].partial_obj_size();571_region_data[cur_region].set_live_obj_size(live_size);572573++cur_region;574addr += RegionSize;575}576}577578// Find the point at which a space can be split and, if necessary, record the579// split point.580//581// If the current src region (which overflowed the destination space) doesn't582// have a partial object, the split point is at the beginning of the current src583// region (an "easy" split, no extra bookkeeping required).584//585// If the current src region has a partial object, the split point is in the586// region where that partial object starts (call it the split_region). If587// split_region has a partial object, then the split point is just after that588// partial object (a "hard" split where we have to record the split data and589// zero the partial_obj_size field). With a "hard" split, we know that the590// partial_obj ends within split_region because the partial object that caused591// the overflow starts in split_region. If split_region doesn't have a partial592// obj, then the split is at the beginning of split_region (another "easy"593// split).594HeapWord*595ParallelCompactData::summarize_split_space(size_t src_region,596SplitInfo& split_info,597HeapWord* destination,598HeapWord* target_end,599HeapWord** target_next)600{601assert(destination <= target_end, "sanity");602assert(destination + _region_data[src_region].data_size() > target_end,603"region should not fit into target space");604assert(is_region_aligned(target_end), "sanity");605606size_t split_region = src_region;607HeapWord* split_destination = destination;608size_t partial_obj_size = _region_data[src_region].partial_obj_size();609610if (destination + partial_obj_size > target_end) {611// The split point is just after the partial object (if any) in the612// src_region that contains the start of the object that overflowed the613// destination space.614//615// Find the start of the "overflow" object and set split_region to the616// region containing it.617HeapWord* const overflow_obj = _region_data[src_region].partial_obj_addr();618split_region = addr_to_region_idx(overflow_obj);619620// Clear the source_region field of all destination regions whose first word621// came from data after the split point (a non-null source_region field622// implies a region must be filled).623//624// An alternative to the simple loop below: clear during post_compact(),625// which uses memcpy instead of individual stores, and is easy to626// parallelize. (The downside is that it clears the entire RegionData627// object as opposed to just one field.)628//629// post_compact() would have to clear the summary data up to the highest630// address that was written during the summary phase, which would be631//632// max(top, max(new_top, clear_top))633//634// where clear_top is a new field in SpaceInfo. Would have to set clear_top635// to target_end.636const RegionData* const sr = region(split_region);637const size_t beg_idx =638addr_to_region_idx(region_align_up(sr->destination() +639sr->partial_obj_size()));640const size_t end_idx = addr_to_region_idx(target_end);641642log_develop_trace(gc, compaction)("split: clearing source_region field in [" SIZE_FORMAT ", " SIZE_FORMAT ")", beg_idx, end_idx);643for (size_t idx = beg_idx; idx < end_idx; ++idx) {644_region_data[idx].set_source_region(0);645}646647// Set split_destination and partial_obj_size to reflect the split region.648split_destination = sr->destination();649partial_obj_size = sr->partial_obj_size();650}651652// The split is recorded only if a partial object extends onto the region.653if (partial_obj_size != 0) {654_region_data[split_region].set_partial_obj_size(0);655split_info.record(split_region, partial_obj_size, split_destination);656}657658// Setup the continuation addresses.659*target_next = split_destination + partial_obj_size;660HeapWord* const source_next = region_to_addr(split_region) + partial_obj_size;661662if (log_develop_is_enabled(Trace, gc, compaction)) {663const char * split_type = partial_obj_size == 0 ? "easy" : "hard";664log_develop_trace(gc, compaction)("%s split: src=" PTR_FORMAT " src_c=" SIZE_FORMAT " pos=" SIZE_FORMAT,665split_type, p2i(source_next), split_region, partial_obj_size);666log_develop_trace(gc, compaction)("%s split: dst=" PTR_FORMAT " dst_c=" SIZE_FORMAT " tn=" PTR_FORMAT,667split_type, p2i(split_destination),668addr_to_region_idx(split_destination),669p2i(*target_next));670671if (partial_obj_size != 0) {672HeapWord* const po_beg = split_info.destination();673HeapWord* const po_end = po_beg + split_info.partial_obj_size();674log_develop_trace(gc, compaction)("%s split: po_beg=" PTR_FORMAT " " SIZE_FORMAT " po_end=" PTR_FORMAT " " SIZE_FORMAT,675split_type,676p2i(po_beg), addr_to_region_idx(po_beg),677p2i(po_end), addr_to_region_idx(po_end));678}679}680681return source_next;682}683684bool ParallelCompactData::summarize(SplitInfo& split_info,685HeapWord* source_beg, HeapWord* source_end,686HeapWord** source_next,687HeapWord* target_beg, HeapWord* target_end,688HeapWord** target_next)689{690HeapWord* const source_next_val = source_next == NULL ? NULL : *source_next;691log_develop_trace(gc, compaction)(692"sb=" PTR_FORMAT " se=" PTR_FORMAT " sn=" PTR_FORMAT693"tb=" PTR_FORMAT " te=" PTR_FORMAT " tn=" PTR_FORMAT,694p2i(source_beg), p2i(source_end), p2i(source_next_val),695p2i(target_beg), p2i(target_end), p2i(*target_next));696697size_t cur_region = addr_to_region_idx(source_beg);698const size_t end_region = addr_to_region_idx(region_align_up(source_end));699700HeapWord *dest_addr = target_beg;701while (cur_region < end_region) {702// The destination must be set even if the region has no data.703_region_data[cur_region].set_destination(dest_addr);704705size_t words = _region_data[cur_region].data_size();706if (words > 0) {707// If cur_region does not fit entirely into the target space, find a point708// at which the source space can be 'split' so that part is copied to the709// target space and the rest is copied elsewhere.710if (dest_addr + words > target_end) {711assert(source_next != NULL, "source_next is NULL when splitting");712*source_next = summarize_split_space(cur_region, split_info, dest_addr,713target_end, target_next);714return false;715}716717// Compute the destination_count for cur_region, and if necessary, update718// source_region for a destination region. The source_region field is719// updated if cur_region is the first (left-most) region to be copied to a720// destination region.721//722// The destination_count calculation is a bit subtle. A region that has723// data that compacts into itself does not count itself as a destination.724// This maintains the invariant that a zero count means the region is725// available and can be claimed and then filled.726uint destination_count = 0;727if (split_info.is_split(cur_region)) {728// The current region has been split: the partial object will be copied729// to one destination space and the remaining data will be copied to730// another destination space. Adjust the initial destination_count and,731// if necessary, set the source_region field if the partial object will732// cross a destination region boundary.733destination_count = split_info.destination_count();734if (destination_count == 2) {735size_t dest_idx = addr_to_region_idx(split_info.dest_region_addr());736_region_data[dest_idx].set_source_region(cur_region);737}738}739740HeapWord* const last_addr = dest_addr + words - 1;741const size_t dest_region_1 = addr_to_region_idx(dest_addr);742const size_t dest_region_2 = addr_to_region_idx(last_addr);743744// Initially assume that the destination regions will be the same and745// adjust the value below if necessary. Under this assumption, if746// cur_region == dest_region_2, then cur_region will be compacted747// completely into itself.748destination_count += cur_region == dest_region_2 ? 0 : 1;749if (dest_region_1 != dest_region_2) {750// Destination regions differ; adjust destination_count.751destination_count += 1;752// Data from cur_region will be copied to the start of dest_region_2.753_region_data[dest_region_2].set_source_region(cur_region);754} else if (is_region_aligned(dest_addr)) {755// Data from cur_region will be copied to the start of the destination756// region.757_region_data[dest_region_1].set_source_region(cur_region);758}759760_region_data[cur_region].set_destination_count(destination_count);761_region_data[cur_region].set_data_location(region_to_addr(cur_region));762dest_addr += words;763}764765++cur_region;766}767768*target_next = dest_addr;769return true;770}771772HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr, ParCompactionManager* cm) const {773assert(addr != NULL, "Should detect NULL oop earlier");774assert(ParallelScavengeHeap::heap()->is_in(addr), "not in heap");775assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");776777// Region covering the object.778RegionData* const region_ptr = addr_to_region_ptr(addr);779HeapWord* result = region_ptr->destination();780781// If the entire Region is live, the new location is region->destination + the782// offset of the object within in the Region.783784// Run some performance tests to determine if this special case pays off. It785// is worth it for pointers into the dense prefix. If the optimization to786// avoid pointer updates in regions that only point to the dense prefix is787// ever implemented, this should be revisited.788if (region_ptr->data_size() == RegionSize) {789result += region_offset(addr);790return result;791}792793// Otherwise, the new location is region->destination + block offset + the794// number of live words in the Block that are (a) to the left of addr and (b)795// due to objects that start in the Block.796797// Fill in the block table if necessary. This is unsynchronized, so multiple798// threads may fill the block table for a region (harmless, since it is799// idempotent).800if (!region_ptr->blocks_filled()) {801PSParallelCompact::fill_blocks(addr_to_region_idx(addr));802region_ptr->set_blocks_filled();803}804805HeapWord* const search_start = block_align_down(addr);806const size_t block_offset = addr_to_block_ptr(addr)->offset();807808const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();809const size_t live = bitmap->live_words_in_range(cm, search_start, cast_to_oop(addr));810result += block_offset + live;811DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));812return result;813}814815#ifdef ASSERT816void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)817{818const size_t* const beg = (const size_t*)vspace->committed_low_addr();819const size_t* const end = (const size_t*)vspace->committed_high_addr();820for (const size_t* p = beg; p < end; ++p) {821assert(*p == 0, "not zero");822}823}824825void ParallelCompactData::verify_clear()826{827verify_clear(_region_vspace);828verify_clear(_block_vspace);829}830#endif // #ifdef ASSERT831832STWGCTimer PSParallelCompact::_gc_timer;833ParallelOldTracer PSParallelCompact::_gc_tracer;834elapsedTimer PSParallelCompact::_accumulated_time;835unsigned int PSParallelCompact::_total_invocations = 0;836unsigned int PSParallelCompact::_maximum_compaction_gc_num = 0;837CollectorCounters* PSParallelCompact::_counters = NULL;838ParMarkBitMap PSParallelCompact::_mark_bitmap;839ParallelCompactData PSParallelCompact::_summary_data;840841PSParallelCompact::IsAliveClosure PSParallelCompact::_is_alive_closure;842843bool PSParallelCompact::IsAliveClosure::do_object_b(oop p) { return mark_bitmap()->is_marked(p); }844845class PCReferenceProcessor: public ReferenceProcessor {846public:847PCReferenceProcessor(848BoolObjectClosure* is_subject_to_discovery,849BoolObjectClosure* is_alive_non_header) :850ReferenceProcessor(is_subject_to_discovery,851ParallelGCThreads, // mt processing degree852true, // mt discovery853ParallelGCThreads, // mt discovery degree854true, // atomic_discovery855is_alive_non_header) {856}857858template<typename T> bool discover(oop obj, ReferenceType type) {859T* referent_addr = (T*) java_lang_ref_Reference::referent_addr_raw(obj);860T heap_oop = RawAccess<>::oop_load(referent_addr);861oop referent = CompressedOops::decode_not_null(heap_oop);862return PSParallelCompact::mark_bitmap()->is_unmarked(referent)863&& ReferenceProcessor::discover_reference(obj, type);864}865virtual bool discover_reference(oop obj, ReferenceType type) {866if (UseCompressedOops) {867return discover<narrowOop>(obj, type);868} else {869return discover<oop>(obj, type);870}871}872};873874void PSParallelCompact::post_initialize() {875ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();876_span_based_discoverer.set_span(heap->reserved_region());877_ref_processor =878new PCReferenceProcessor(&_span_based_discoverer,879&_is_alive_closure); // non-header is alive closure880881_counters = new CollectorCounters("Parallel full collection pauses", 1);882883// Initialize static fields in ParCompactionManager.884ParCompactionManager::initialize(mark_bitmap());885}886887bool PSParallelCompact::initialize() {888ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();889MemRegion mr = heap->reserved_region();890891// Was the old gen get allocated successfully?892if (!heap->old_gen()->is_allocated()) {893return false;894}895896initialize_space_info();897initialize_dead_wood_limiter();898899if (!_mark_bitmap.initialize(mr)) {900vm_shutdown_during_initialization(901err_msg("Unable to allocate " SIZE_FORMAT "KB bitmaps for parallel "902"garbage collection for the requested " SIZE_FORMAT "KB heap.",903_mark_bitmap.reserved_byte_size()/K, mr.byte_size()/K));904return false;905}906907if (!_summary_data.initialize(mr)) {908vm_shutdown_during_initialization(909err_msg("Unable to allocate " SIZE_FORMAT "KB card tables for parallel "910"garbage collection for the requested " SIZE_FORMAT "KB heap.",911_summary_data.reserved_byte_size()/K, mr.byte_size()/K));912return false;913}914915return true;916}917918void PSParallelCompact::initialize_space_info()919{920memset(&_space_info, 0, sizeof(_space_info));921922ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();923PSYoungGen* young_gen = heap->young_gen();924925_space_info[old_space_id].set_space(heap->old_gen()->object_space());926_space_info[eden_space_id].set_space(young_gen->eden_space());927_space_info[from_space_id].set_space(young_gen->from_space());928_space_info[to_space_id].set_space(young_gen->to_space());929930_space_info[old_space_id].set_start_array(heap->old_gen()->start_array());931}932933void PSParallelCompact::initialize_dead_wood_limiter()934{935const size_t max = 100;936_dwl_mean = double(MIN2(ParallelOldDeadWoodLimiterMean, max)) / 100.0;937_dwl_std_dev = double(MIN2(ParallelOldDeadWoodLimiterStdDev, max)) / 100.0;938_dwl_first_term = 1.0 / (sqrt(2.0 * M_PI) * _dwl_std_dev);939DEBUG_ONLY(_dwl_initialized = true;)940_dwl_adjustment = normal_distribution(1.0);941}942943void944PSParallelCompact::clear_data_covering_space(SpaceId id)945{946// At this point, top is the value before GC, new_top() is the value that will947// be set at the end of GC. The marking bitmap is cleared to top; nothing948// should be marked above top. The summary data is cleared to the larger of949// top & new_top.950MutableSpace* const space = _space_info[id].space();951HeapWord* const bot = space->bottom();952HeapWord* const top = space->top();953HeapWord* const max_top = MAX2(top, _space_info[id].new_top());954955const idx_t beg_bit = _mark_bitmap.addr_to_bit(bot);956const idx_t end_bit = _mark_bitmap.align_range_end(_mark_bitmap.addr_to_bit(top));957_mark_bitmap.clear_range(beg_bit, end_bit);958959const size_t beg_region = _summary_data.addr_to_region_idx(bot);960const size_t end_region =961_summary_data.addr_to_region_idx(_summary_data.region_align_up(max_top));962_summary_data.clear_range(beg_region, end_region);963964// Clear the data used to 'split' regions.965SplitInfo& split_info = _space_info[id].split_info();966if (split_info.is_valid()) {967split_info.clear();968}969DEBUG_ONLY(split_info.verify_clear();)970}971972void PSParallelCompact::pre_compact()973{974// Update the from & to space pointers in space_info, since they are swapped975// at each young gen gc. Do the update unconditionally (even though a976// promotion failure does not swap spaces) because an unknown number of young977// collections will have swapped the spaces an unknown number of times.978GCTraceTime(Debug, gc, phases) tm("Pre Compact", &_gc_timer);979ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();980_space_info[from_space_id].set_space(heap->young_gen()->from_space());981_space_info[to_space_id].set_space(heap->young_gen()->to_space());982983// Increment the invocation count984heap->increment_total_collections(true);985986// We need to track unique mark sweep invocations as well.987_total_invocations++;988989heap->print_heap_before_gc();990heap->trace_heap_before_gc(&_gc_tracer);991992// Fill in TLABs993heap->ensure_parsability(true); // retire TLABs994995if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {996Universe::verify("Before GC");997}998999// Verify object start arrays1000if (VerifyObjectStartArray &&1001VerifyBeforeGC) {1002heap->old_gen()->verify_object_start_array();1003}10041005DEBUG_ONLY(mark_bitmap()->verify_clear();)1006DEBUG_ONLY(summary_data().verify_clear();)10071008ParCompactionManager::reset_all_bitmap_query_caches();1009}10101011void PSParallelCompact::post_compact()1012{1013GCTraceTime(Info, gc, phases) tm("Post Compact", &_gc_timer);1014ParCompactionManager::remove_all_shadow_regions();10151016for (unsigned int id = old_space_id; id < last_space_id; ++id) {1017// Clear the marking bitmap, summary data and split info.1018clear_data_covering_space(SpaceId(id));1019// Update top(). Must be done after clearing the bitmap and summary data.1020_space_info[id].publish_new_top();1021}10221023MutableSpace* const eden_space = _space_info[eden_space_id].space();1024MutableSpace* const from_space = _space_info[from_space_id].space();1025MutableSpace* const to_space = _space_info[to_space_id].space();10261027ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();1028bool eden_empty = eden_space->is_empty();10291030// Update heap occupancy information which is used as input to the soft ref1031// clearing policy at the next gc.1032Universe::heap()->update_capacity_and_used_at_gc();10331034bool young_gen_empty = eden_empty && from_space->is_empty() &&1035to_space->is_empty();10361037PSCardTable* ct = heap->card_table();1038MemRegion old_mr = heap->old_gen()->reserved();1039if (young_gen_empty) {1040ct->clear(MemRegion(old_mr.start(), old_mr.end()));1041} else {1042ct->invalidate(MemRegion(old_mr.start(), old_mr.end()));1043}10441045// Delete metaspaces for unloaded class loaders and clean up loader_data graph1046ClassLoaderDataGraph::purge(/*at_safepoint*/true);1047DEBUG_ONLY(MetaspaceUtils::verify();)10481049heap->prune_scavengable_nmethods();10501051#if COMPILER2_OR_JVMCI1052DerivedPointerTable::update_pointers();1053#endif10541055if (ZapUnusedHeapArea) {1056heap->gen_mangle_unused_area();1057}10581059// Signal that we have completed a visit to all live objects.1060Universe::heap()->record_whole_heap_examined_timestamp();1061}10621063HeapWord*1064PSParallelCompact::compute_dense_prefix_via_density(const SpaceId id,1065bool maximum_compaction)1066{1067const size_t region_size = ParallelCompactData::RegionSize;1068const ParallelCompactData& sd = summary_data();10691070const MutableSpace* const space = _space_info[id].space();1071HeapWord* const top_aligned_up = sd.region_align_up(space->top());1072const RegionData* const beg_cp = sd.addr_to_region_ptr(space->bottom());1073const RegionData* const end_cp = sd.addr_to_region_ptr(top_aligned_up);10741075// Skip full regions at the beginning of the space--they are necessarily part1076// of the dense prefix.1077size_t full_count = 0;1078const RegionData* cp;1079for (cp = beg_cp; cp < end_cp && cp->data_size() == region_size; ++cp) {1080++full_count;1081}10821083assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");1084const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;1085const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval;1086if (maximum_compaction || cp == end_cp || interval_ended) {1087_maximum_compaction_gc_num = total_invocations();1088return sd.region_to_addr(cp);1089}10901091HeapWord* const new_top = _space_info[id].new_top();1092const size_t space_live = pointer_delta(new_top, space->bottom());1093const size_t space_used = space->used_in_words();1094const size_t space_capacity = space->capacity_in_words();10951096const double cur_density = double(space_live) / space_capacity;1097const double deadwood_density =1098(1.0 - cur_density) * (1.0 - cur_density) * cur_density * cur_density;1099const size_t deadwood_goal = size_t(space_capacity * deadwood_density);11001101log_develop_debug(gc, compaction)(1102"cur_dens=%5.3f dw_dens=%5.3f dw_goal=" SIZE_FORMAT,1103cur_density, deadwood_density, deadwood_goal);1104log_develop_debug(gc, compaction)(1105"space_live=" SIZE_FORMAT " space_used=" SIZE_FORMAT " "1106"space_cap=" SIZE_FORMAT,1107space_live, space_used,1108space_capacity);11091110// XXX - Use binary search?1111HeapWord* dense_prefix = sd.region_to_addr(cp);1112const RegionData* full_cp = cp;1113const RegionData* const top_cp = sd.addr_to_region_ptr(space->top() - 1);1114while (cp < end_cp) {1115HeapWord* region_destination = cp->destination();1116const size_t cur_deadwood = pointer_delta(dense_prefix, region_destination);11171118log_develop_trace(gc, compaction)(1119"c#=" SIZE_FORMAT_W(4) " dst=" PTR_FORMAT " "1120"dp=" PTR_FORMAT " cdw=" SIZE_FORMAT_W(8),1121sd.region(cp), p2i(region_destination),1122p2i(dense_prefix), cur_deadwood);11231124if (cur_deadwood >= deadwood_goal) {1125// Found the region that has the correct amount of deadwood to the left.1126// This typically occurs after crossing a fairly sparse set of regions, so1127// iterate backwards over those sparse regions, looking for the region1128// that has the lowest density of live objects 'to the right.'1129size_t space_to_left = sd.region(cp) * region_size;1130size_t live_to_left = space_to_left - cur_deadwood;1131size_t space_to_right = space_capacity - space_to_left;1132size_t live_to_right = space_live - live_to_left;1133double density_to_right = double(live_to_right) / space_to_right;1134while (cp > full_cp) {1135--cp;1136const size_t prev_region_live_to_right = live_to_right -1137cp->data_size();1138const size_t prev_region_space_to_right = space_to_right + region_size;1139double prev_region_density_to_right =1140double(prev_region_live_to_right) / prev_region_space_to_right;1141if (density_to_right <= prev_region_density_to_right) {1142return dense_prefix;1143}11441145log_develop_trace(gc, compaction)(1146"backing up from c=" SIZE_FORMAT_W(4) " d2r=%10.8f "1147"pc_d2r=%10.8f",1148sd.region(cp), density_to_right,1149prev_region_density_to_right);11501151dense_prefix -= region_size;1152live_to_right = prev_region_live_to_right;1153space_to_right = prev_region_space_to_right;1154density_to_right = prev_region_density_to_right;1155}1156return dense_prefix;1157}11581159dense_prefix += region_size;1160++cp;1161}11621163return dense_prefix;1164}11651166#ifndef PRODUCT1167void PSParallelCompact::print_dense_prefix_stats(const char* const algorithm,1168const SpaceId id,1169const bool maximum_compaction,1170HeapWord* const addr)1171{1172const size_t region_idx = summary_data().addr_to_region_idx(addr);1173RegionData* const cp = summary_data().region(region_idx);1174const MutableSpace* const space = _space_info[id].space();1175HeapWord* const new_top = _space_info[id].new_top();11761177const size_t space_live = pointer_delta(new_top, space->bottom());1178const size_t dead_to_left = pointer_delta(addr, cp->destination());1179const size_t space_cap = space->capacity_in_words();1180const double dead_to_left_pct = double(dead_to_left) / space_cap;1181const size_t live_to_right = new_top - cp->destination();1182const size_t dead_to_right = space->top() - addr - live_to_right;11831184log_develop_debug(gc, compaction)(1185"%s=" PTR_FORMAT " dpc=" SIZE_FORMAT_W(5) " "1186"spl=" SIZE_FORMAT " "1187"d2l=" SIZE_FORMAT " d2l%%=%6.4f "1188"d2r=" SIZE_FORMAT " l2r=" SIZE_FORMAT " "1189"ratio=%10.8f",1190algorithm, p2i(addr), region_idx,1191space_live,1192dead_to_left, dead_to_left_pct,1193dead_to_right, live_to_right,1194double(dead_to_right) / live_to_right);1195}1196#endif // #ifndef PRODUCT11971198// Return a fraction indicating how much of the generation can be treated as1199// "dead wood" (i.e., not reclaimed). The function uses a normal distribution1200// based on the density of live objects in the generation to determine a limit,1201// which is then adjusted so the return value is min_percent when the density is1202// 1.1203//1204// The following table shows some return values for a different values of the1205// standard deviation (ParallelOldDeadWoodLimiterStdDev); the mean is 0.5 and1206// min_percent is 1.1207//1208// fraction allowed as dead wood1209// -----------------------------------------------------------------1210// density std_dev=70 std_dev=75 std_dev=80 std_dev=85 std_dev=90 std_dev=951211// ------- ---------- ---------- ---------- ---------- ---------- ----------1212// 0.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.010000001213// 0.05000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.019749411214// 0.10000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.028692721215// 0.15000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.036760661216// 0.20000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.043889751217// 0.25000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.050023131218// 0.30000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.055111321219// 0.35000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.059112891220// 0.40000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.061995001221// 0.45000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.063733861222// 0.50000 0.13832410 0.11599237 0.09847664 0.08456518 0.07338887 0.064315101223// 0.55000 0.13687208 0.11481163 0.09750361 0.08375387 0.07270534 0.063733861224// 0.60000 0.13253818 0.11128511 0.09459590 0.08132834 0.07066107 0.061995001225// 0.65000 0.12538832 0.10545958 0.08978741 0.07731366 0.06727491 0.059112891226// 0.70000 0.11553050 0.09741183 0.08313394 0.07175114 0.06257797 0.055111321227// 0.75000 0.10311208 0.08724696 0.07471205 0.06469760 0.05661313 0.050023131228// 0.80000 0.08831616 0.07509618 0.06461766 0.05622444 0.04943437 0.043889751229// 0.85000 0.07135702 0.06111390 0.05296419 0.04641639 0.04110601 0.036760661230// 0.90000 0.05247504 0.04547452 0.03988045 0.03537016 0.03170171 0.028692721231// 0.95000 0.03193096 0.02836880 0.02550828 0.02319280 0.02130337 0.019749411232// 1.00000 0.01000000 0.01000000 0.01000000 0.01000000 0.01000000 0.0100000012331234double PSParallelCompact::dead_wood_limiter(double density, size_t min_percent)1235{1236assert(_dwl_initialized, "uninitialized");12371238// The raw limit is the value of the normal distribution at x = density.1239const double raw_limit = normal_distribution(density);12401241// Adjust the raw limit so it becomes the minimum when the density is 1.1242//1243// First subtract the adjustment value (which is simply the precomputed value1244// normal_distribution(1.0)); this yields a value of 0 when the density is 1.1245// Then add the minimum value, so the minimum is returned when the density is1246// 1. Finally, prevent negative values, which occur when the mean is not 0.5.1247const double min = double(min_percent) / 100.0;1248const double limit = raw_limit - _dwl_adjustment + min;1249return MAX2(limit, 0.0);1250}12511252ParallelCompactData::RegionData*1253PSParallelCompact::first_dead_space_region(const RegionData* beg,1254const RegionData* end)1255{1256const size_t region_size = ParallelCompactData::RegionSize;1257ParallelCompactData& sd = summary_data();1258size_t left = sd.region(beg);1259size_t right = end > beg ? sd.region(end) - 1 : left;12601261// Binary search.1262while (left < right) {1263// Equivalent to (left + right) / 2, but does not overflow.1264const size_t middle = left + (right - left) / 2;1265RegionData* const middle_ptr = sd.region(middle);1266HeapWord* const dest = middle_ptr->destination();1267HeapWord* const addr = sd.region_to_addr(middle);1268assert(dest != NULL, "sanity");1269assert(dest <= addr, "must move left");12701271if (middle > left && dest < addr) {1272right = middle - 1;1273} else if (middle < right && middle_ptr->data_size() == region_size) {1274left = middle + 1;1275} else {1276return middle_ptr;1277}1278}1279return sd.region(left);1280}12811282ParallelCompactData::RegionData*1283PSParallelCompact::dead_wood_limit_region(const RegionData* beg,1284const RegionData* end,1285size_t dead_words)1286{1287ParallelCompactData& sd = summary_data();1288size_t left = sd.region(beg);1289size_t right = end > beg ? sd.region(end) - 1 : left;12901291// Binary search.1292while (left < right) {1293// Equivalent to (left + right) / 2, but does not overflow.1294const size_t middle = left + (right - left) / 2;1295RegionData* const middle_ptr = sd.region(middle);1296HeapWord* const dest = middle_ptr->destination();1297HeapWord* const addr = sd.region_to_addr(middle);1298assert(dest != NULL, "sanity");1299assert(dest <= addr, "must move left");13001301const size_t dead_to_left = pointer_delta(addr, dest);1302if (middle > left && dead_to_left > dead_words) {1303right = middle - 1;1304} else if (middle < right && dead_to_left < dead_words) {1305left = middle + 1;1306} else {1307return middle_ptr;1308}1309}1310return sd.region(left);1311}13121313// The result is valid during the summary phase, after the initial summarization1314// of each space into itself, and before final summarization.1315inline double1316PSParallelCompact::reclaimed_ratio(const RegionData* const cp,1317HeapWord* const bottom,1318HeapWord* const top,1319HeapWord* const new_top)1320{1321ParallelCompactData& sd = summary_data();13221323assert(cp != NULL, "sanity");1324assert(bottom != NULL, "sanity");1325assert(top != NULL, "sanity");1326assert(new_top != NULL, "sanity");1327assert(top >= new_top, "summary data problem?");1328assert(new_top > bottom, "space is empty; should not be here");1329assert(new_top >= cp->destination(), "sanity");1330assert(top >= sd.region_to_addr(cp), "sanity");13311332HeapWord* const destination = cp->destination();1333const size_t dense_prefix_live = pointer_delta(destination, bottom);1334const size_t compacted_region_live = pointer_delta(new_top, destination);1335const size_t compacted_region_used = pointer_delta(top,1336sd.region_to_addr(cp));1337const size_t reclaimable = compacted_region_used - compacted_region_live;13381339const double divisor = dense_prefix_live + 1.25 * compacted_region_live;1340return double(reclaimable) / divisor;1341}13421343// Return the address of the end of the dense prefix, a.k.a. the start of the1344// compacted region. The address is always on a region boundary.1345//1346// Completely full regions at the left are skipped, since no compaction can1347// occur in those regions. Then the maximum amount of dead wood to allow is1348// computed, based on the density (amount live / capacity) of the generation;1349// the region with approximately that amount of dead space to the left is1350// identified as the limit region. Regions between the last completely full1351// region and the limit region are scanned and the one that has the best1352// (maximum) reclaimed_ratio() is selected.1353HeapWord*1354PSParallelCompact::compute_dense_prefix(const SpaceId id,1355bool maximum_compaction)1356{1357const size_t region_size = ParallelCompactData::RegionSize;1358const ParallelCompactData& sd = summary_data();13591360const MutableSpace* const space = _space_info[id].space();1361HeapWord* const top = space->top();1362HeapWord* const top_aligned_up = sd.region_align_up(top);1363HeapWord* const new_top = _space_info[id].new_top();1364HeapWord* const new_top_aligned_up = sd.region_align_up(new_top);1365HeapWord* const bottom = space->bottom();1366const RegionData* const beg_cp = sd.addr_to_region_ptr(bottom);1367const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);1368const RegionData* const new_top_cp =1369sd.addr_to_region_ptr(new_top_aligned_up);13701371// Skip full regions at the beginning of the space--they are necessarily part1372// of the dense prefix.1373const RegionData* const full_cp = first_dead_space_region(beg_cp, new_top_cp);1374assert(full_cp->destination() == sd.region_to_addr(full_cp) ||1375space->is_empty(), "no dead space allowed to the left");1376assert(full_cp->data_size() < region_size || full_cp == new_top_cp - 1,1377"region must have dead space");13781379// The gc number is saved whenever a maximum compaction is done, and used to1380// determine when the maximum compaction interval has expired. This avoids1381// successive max compactions for different reasons.1382assert(total_invocations() >= _maximum_compaction_gc_num, "sanity");1383const size_t gcs_since_max = total_invocations() - _maximum_compaction_gc_num;1384const bool interval_ended = gcs_since_max > HeapMaximumCompactionInterval ||1385total_invocations() == HeapFirstMaximumCompactionCount;1386if (maximum_compaction || full_cp == top_cp || interval_ended) {1387_maximum_compaction_gc_num = total_invocations();1388return sd.region_to_addr(full_cp);1389}13901391const size_t space_live = pointer_delta(new_top, bottom);1392const size_t space_used = space->used_in_words();1393const size_t space_capacity = space->capacity_in_words();13941395const double density = double(space_live) / double(space_capacity);1396const size_t min_percent_free = MarkSweepDeadRatio;1397const double limiter = dead_wood_limiter(density, min_percent_free);1398const size_t dead_wood_max = space_used - space_live;1399const size_t dead_wood_limit = MIN2(size_t(space_capacity * limiter),1400dead_wood_max);14011402log_develop_debug(gc, compaction)(1403"space_live=" SIZE_FORMAT " space_used=" SIZE_FORMAT " "1404"space_cap=" SIZE_FORMAT,1405space_live, space_used,1406space_capacity);1407log_develop_debug(gc, compaction)(1408"dead_wood_limiter(%6.4f, " SIZE_FORMAT ")=%6.4f "1409"dead_wood_max=" SIZE_FORMAT " dead_wood_limit=" SIZE_FORMAT,1410density, min_percent_free, limiter,1411dead_wood_max, dead_wood_limit);14121413// Locate the region with the desired amount of dead space to the left.1414const RegionData* const limit_cp =1415dead_wood_limit_region(full_cp, top_cp, dead_wood_limit);14161417// Scan from the first region with dead space to the limit region and find the1418// one with the best (largest) reclaimed ratio.1419double best_ratio = 0.0;1420const RegionData* best_cp = full_cp;1421for (const RegionData* cp = full_cp; cp < limit_cp; ++cp) {1422double tmp_ratio = reclaimed_ratio(cp, bottom, top, new_top);1423if (tmp_ratio > best_ratio) {1424best_cp = cp;1425best_ratio = tmp_ratio;1426}1427}14281429return sd.region_to_addr(best_cp);1430}14311432void PSParallelCompact::summarize_spaces_quick()1433{1434for (unsigned int i = 0; i < last_space_id; ++i) {1435const MutableSpace* space = _space_info[i].space();1436HeapWord** nta = _space_info[i].new_top_addr();1437bool result = _summary_data.summarize(_space_info[i].split_info(),1438space->bottom(), space->top(), NULL,1439space->bottom(), space->end(), nta);1440assert(result, "space must fit into itself");1441_space_info[i].set_dense_prefix(space->bottom());1442}1443}14441445void PSParallelCompact::fill_dense_prefix_end(SpaceId id)1446{1447HeapWord* const dense_prefix_end = dense_prefix(id);1448const RegionData* region = _summary_data.addr_to_region_ptr(dense_prefix_end);1449const idx_t dense_prefix_bit = _mark_bitmap.addr_to_bit(dense_prefix_end);1450if (dead_space_crosses_boundary(region, dense_prefix_bit)) {1451// Only enough dead space is filled so that any remaining dead space to the1452// left is larger than the minimum filler object. (The remainder is filled1453// during the copy/update phase.)1454//1455// The size of the dead space to the right of the boundary is not a1456// concern, since compaction will be able to use whatever space is1457// available.1458//1459// Here '||' is the boundary, 'x' represents a don't care bit and a box1460// surrounds the space to be filled with an object.1461//1462// In the 32-bit VM, each bit represents two 32-bit words:1463// +---+1464// a) beg_bits: ... x x x | 0 | || 0 x x ...1465// end_bits: ... x x x | 0 | || 0 x x ...1466// +---+1467//1468// In the 64-bit VM, each bit represents one 64-bit word:1469// +------------+1470// b) beg_bits: ... x x x | 0 || 0 | x x ...1471// end_bits: ... x x 1 | 0 || 0 | x x ...1472// +------------+1473// +-------+1474// c) beg_bits: ... x x | 0 0 | || 0 x x ...1475// end_bits: ... x 1 | 0 0 | || 0 x x ...1476// +-------+1477// +-----------+1478// d) beg_bits: ... x | 0 0 0 | || 0 x x ...1479// end_bits: ... 1 | 0 0 0 | || 0 x x ...1480// +-----------+1481// +-------+1482// e) beg_bits: ... 0 0 | 0 0 | || 0 x x ...1483// end_bits: ... 0 0 | 0 0 | || 0 x x ...1484// +-------+14851486// Initially assume case a, c or e will apply.1487size_t obj_len = CollectedHeap::min_fill_size();1488HeapWord* obj_beg = dense_prefix_end - obj_len;14891490#ifdef _LP641491if (MinObjAlignment > 1) { // object alignment > heap word size1492// Cases a, c or e.1493} else if (_mark_bitmap.is_obj_end(dense_prefix_bit - 2)) {1494// Case b above.1495obj_beg = dense_prefix_end - 1;1496} else if (!_mark_bitmap.is_obj_end(dense_prefix_bit - 3) &&1497_mark_bitmap.is_obj_end(dense_prefix_bit - 4)) {1498// Case d above.1499obj_beg = dense_prefix_end - 3;1500obj_len = 3;1501}1502#endif // #ifdef _LP6415031504CollectedHeap::fill_with_object(obj_beg, obj_len);1505_mark_bitmap.mark_obj(obj_beg, obj_len);1506_summary_data.add_obj(obj_beg, obj_len);1507assert(start_array(id) != NULL, "sanity");1508start_array(id)->allocate_block(obj_beg);1509}1510}15111512void1513PSParallelCompact::summarize_space(SpaceId id, bool maximum_compaction)1514{1515assert(id < last_space_id, "id out of range");1516assert(_space_info[id].dense_prefix() == _space_info[id].space()->bottom(),1517"should have been reset in summarize_spaces_quick()");15181519const MutableSpace* space = _space_info[id].space();1520if (_space_info[id].new_top() != space->bottom()) {1521HeapWord* dense_prefix_end = compute_dense_prefix(id, maximum_compaction);1522_space_info[id].set_dense_prefix(dense_prefix_end);15231524#ifndef PRODUCT1525if (log_is_enabled(Debug, gc, compaction)) {1526print_dense_prefix_stats("ratio", id, maximum_compaction,1527dense_prefix_end);1528HeapWord* addr = compute_dense_prefix_via_density(id, maximum_compaction);1529print_dense_prefix_stats("density", id, maximum_compaction, addr);1530}1531#endif // #ifndef PRODUCT15321533// Recompute the summary data, taking into account the dense prefix. If1534// every last byte will be reclaimed, then the existing summary data which1535// compacts everything can be left in place.1536if (!maximum_compaction && dense_prefix_end != space->bottom()) {1537// If dead space crosses the dense prefix boundary, it is (at least1538// partially) filled with a dummy object, marked live and added to the1539// summary data. This simplifies the copy/update phase and must be done1540// before the final locations of objects are determined, to prevent1541// leaving a fragment of dead space that is too small to fill.1542fill_dense_prefix_end(id);15431544// Compute the destination of each Region, and thus each object.1545_summary_data.summarize_dense_prefix(space->bottom(), dense_prefix_end);1546_summary_data.summarize(_space_info[id].split_info(),1547dense_prefix_end, space->top(), NULL,1548dense_prefix_end, space->end(),1549_space_info[id].new_top_addr());1550}1551}15521553if (log_develop_is_enabled(Trace, gc, compaction)) {1554const size_t region_size = ParallelCompactData::RegionSize;1555HeapWord* const dense_prefix_end = _space_info[id].dense_prefix();1556const size_t dp_region = _summary_data.addr_to_region_idx(dense_prefix_end);1557const size_t dp_words = pointer_delta(dense_prefix_end, space->bottom());1558HeapWord* const new_top = _space_info[id].new_top();1559const HeapWord* nt_aligned_up = _summary_data.region_align_up(new_top);1560const size_t cr_words = pointer_delta(nt_aligned_up, dense_prefix_end);1561log_develop_trace(gc, compaction)(1562"id=%d cap=" SIZE_FORMAT " dp=" PTR_FORMAT " "1563"dp_region=" SIZE_FORMAT " " "dp_count=" SIZE_FORMAT " "1564"cr_count=" SIZE_FORMAT " " "nt=" PTR_FORMAT,1565id, space->capacity_in_words(), p2i(dense_prefix_end),1566dp_region, dp_words / region_size,1567cr_words / region_size, p2i(new_top));1568}1569}15701571#ifndef PRODUCT1572void PSParallelCompact::summary_phase_msg(SpaceId dst_space_id,1573HeapWord* dst_beg, HeapWord* dst_end,1574SpaceId src_space_id,1575HeapWord* src_beg, HeapWord* src_end)1576{1577log_develop_trace(gc, compaction)(1578"Summarizing %d [%s] into %d [%s]: "1579"src=" PTR_FORMAT "-" PTR_FORMAT " "1580SIZE_FORMAT "-" SIZE_FORMAT " "1581"dst=" PTR_FORMAT "-" PTR_FORMAT " "1582SIZE_FORMAT "-" SIZE_FORMAT,1583src_space_id, space_names[src_space_id],1584dst_space_id, space_names[dst_space_id],1585p2i(src_beg), p2i(src_end),1586_summary_data.addr_to_region_idx(src_beg),1587_summary_data.addr_to_region_idx(src_end),1588p2i(dst_beg), p2i(dst_end),1589_summary_data.addr_to_region_idx(dst_beg),1590_summary_data.addr_to_region_idx(dst_end));1591}1592#endif // #ifndef PRODUCT15931594void PSParallelCompact::summary_phase(ParCompactionManager* cm,1595bool maximum_compaction)1596{1597GCTraceTime(Info, gc, phases) tm("Summary Phase", &_gc_timer);15981599// Quick summarization of each space into itself, to see how much is live.1600summarize_spaces_quick();16011602log_develop_trace(gc, compaction)("summary phase: after summarizing each space to self");1603NOT_PRODUCT(print_region_ranges());1604NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));16051606// The amount of live data that will end up in old space (assuming it fits).1607size_t old_space_total_live = 0;1608for (unsigned int id = old_space_id; id < last_space_id; ++id) {1609old_space_total_live += pointer_delta(_space_info[id].new_top(),1610_space_info[id].space()->bottom());1611}16121613MutableSpace* const old_space = _space_info[old_space_id].space();1614const size_t old_capacity = old_space->capacity_in_words();1615if (old_space_total_live > old_capacity) {1616// XXX - should also try to expand1617maximum_compaction = true;1618}16191620// Old generations.1621summarize_space(old_space_id, maximum_compaction);16221623// Summarize the remaining spaces in the young gen. The initial target space1624// is the old gen. If a space does not fit entirely into the target, then the1625// remainder is compacted into the space itself and that space becomes the new1626// target.1627SpaceId dst_space_id = old_space_id;1628HeapWord* dst_space_end = old_space->end();1629HeapWord** new_top_addr = _space_info[dst_space_id].new_top_addr();1630for (unsigned int id = eden_space_id; id < last_space_id; ++id) {1631const MutableSpace* space = _space_info[id].space();1632const size_t live = pointer_delta(_space_info[id].new_top(),1633space->bottom());1634const size_t available = pointer_delta(dst_space_end, *new_top_addr);16351636NOT_PRODUCT(summary_phase_msg(dst_space_id, *new_top_addr, dst_space_end,1637SpaceId(id), space->bottom(), space->top());)1638if (live > 0 && live <= available) {1639// All the live data will fit.1640bool done = _summary_data.summarize(_space_info[id].split_info(),1641space->bottom(), space->top(),1642NULL,1643*new_top_addr, dst_space_end,1644new_top_addr);1645assert(done, "space must fit into old gen");16461647// Reset the new_top value for the space.1648_space_info[id].set_new_top(space->bottom());1649} else if (live > 0) {1650// Attempt to fit part of the source space into the target space.1651HeapWord* next_src_addr = NULL;1652bool done = _summary_data.summarize(_space_info[id].split_info(),1653space->bottom(), space->top(),1654&next_src_addr,1655*new_top_addr, dst_space_end,1656new_top_addr);1657assert(!done, "space should not fit into old gen");1658assert(next_src_addr != NULL, "sanity");16591660// The source space becomes the new target, so the remainder is compacted1661// within the space itself.1662dst_space_id = SpaceId(id);1663dst_space_end = space->end();1664new_top_addr = _space_info[id].new_top_addr();1665NOT_PRODUCT(summary_phase_msg(dst_space_id,1666space->bottom(), dst_space_end,1667SpaceId(id), next_src_addr, space->top());)1668done = _summary_data.summarize(_space_info[id].split_info(),1669next_src_addr, space->top(),1670NULL,1671space->bottom(), dst_space_end,1672new_top_addr);1673assert(done, "space must fit when compacted into itself");1674assert(*new_top_addr <= space->top(), "usage should not grow");1675}1676}16771678log_develop_trace(gc, compaction)("Summary_phase: after final summarization");1679NOT_PRODUCT(print_region_ranges());1680NOT_PRODUCT(print_initial_summary_data(_summary_data, _space_info));1681}16821683// This method should contain all heap-specific policy for invoking a full1684// collection. invoke_no_policy() will only attempt to compact the heap; it1685// will do nothing further. If we need to bail out for policy reasons, scavenge1686// before full gc, or any other specialized behavior, it needs to be added here.1687//1688// Note that this method should only be called from the vm_thread while at a1689// safepoint.1690//1691// Note that the all_soft_refs_clear flag in the soft ref policy1692// may be true because this method can be called without intervening1693// activity. For example when the heap space is tight and full measure1694// are being taken to free space.1695void PSParallelCompact::invoke(bool maximum_heap_compaction) {1696assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint");1697assert(Thread::current() == (Thread*)VMThread::vm_thread(),1698"should be in vm thread");16991700ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();1701GCCause::Cause gc_cause = heap->gc_cause();1702assert(!heap->is_gc_active(), "not reentrant");17031704PSAdaptiveSizePolicy* policy = heap->size_policy();1705IsGCActiveMark mark;17061707if (ScavengeBeforeFullGC) {1708PSScavenge::invoke_no_policy();1709}17101711const bool clear_all_soft_refs =1712heap->soft_ref_policy()->should_clear_all_soft_refs();17131714PSParallelCompact::invoke_no_policy(clear_all_soft_refs ||1715maximum_heap_compaction);1716}17171718// This method contains no policy. You should probably1719// be calling invoke() instead.1720bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {1721assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint");1722assert(ref_processor() != NULL, "Sanity");17231724if (GCLocker::check_active_before_gc()) {1725return false;1726}17271728ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();17291730GCIdMark gc_id_mark;1731_gc_timer.register_gc_start();1732_gc_tracer.report_gc_start(heap->gc_cause(), _gc_timer.gc_start());17331734TimeStamp marking_start;1735TimeStamp compaction_start;1736TimeStamp collection_exit;17371738GCCause::Cause gc_cause = heap->gc_cause();1739PSYoungGen* young_gen = heap->young_gen();1740PSOldGen* old_gen = heap->old_gen();1741PSAdaptiveSizePolicy* size_policy = heap->size_policy();17421743// The scope of casr should end after code that can change1744// SoftRefPolicy::_should_clear_all_soft_refs.1745ClearedAllSoftRefs casr(maximum_heap_compaction,1746heap->soft_ref_policy());17471748if (ZapUnusedHeapArea) {1749// Save information needed to minimize mangling1750heap->record_gen_tops_before_GC();1751}17521753// Make sure data structures are sane, make the heap parsable, and do other1754// miscellaneous bookkeeping.1755pre_compact();17561757const PreGenGCValues pre_gc_values = heap->get_pre_gc_values();17581759// Get the compaction manager reserved for the VM thread.1760ParCompactionManager* const vmthread_cm = ParCompactionManager::get_vmthread_cm();17611762{1763const uint active_workers =1764WorkerPolicy::calc_active_workers(ParallelScavengeHeap::heap()->workers().total_workers(),1765ParallelScavengeHeap::heap()->workers().active_workers(),1766Threads::number_of_non_daemon_threads());1767ParallelScavengeHeap::heap()->workers().update_active_workers(active_workers);17681769GCTraceCPUTime tcpu;1770GCTraceTime(Info, gc) tm("Pause Full", NULL, gc_cause, true);17711772heap->pre_full_gc_dump(&_gc_timer);17731774TraceCollectorStats tcs(counters());1775TraceMemoryManagerStats tms(heap->old_gc_manager(), gc_cause);17761777if (log_is_enabled(Debug, gc, heap, exit)) {1778accumulated_time()->start();1779}17801781// Let the size policy know we're starting1782size_policy->major_collection_begin();17831784#if COMPILER2_OR_JVMCI1785DerivedPointerTable::clear();1786#endif17871788ref_processor()->enable_discovery();1789ref_processor()->setup_policy(maximum_heap_compaction);17901791bool marked_for_unloading = false;17921793marking_start.update();1794marking_phase(vmthread_cm, maximum_heap_compaction, &_gc_tracer);17951796bool max_on_system_gc = UseMaximumCompactionOnSystemGC1797&& GCCause::is_user_requested_gc(gc_cause);1798summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);17991800#if COMPILER2_OR_JVMCI1801assert(DerivedPointerTable::is_active(), "Sanity");1802DerivedPointerTable::set_active(false);1803#endif18041805// adjust_roots() updates Universe::_intArrayKlassObj which is1806// needed by the compaction for filling holes in the dense prefix.1807adjust_roots();18081809compaction_start.update();1810compact();18111812ParCompactionManager::verify_all_region_stack_empty();18131814// Reset the mark bitmap, summary data, and do other bookkeeping. Must be1815// done before resizing.1816post_compact();18171818// Let the size policy know we're done1819size_policy->major_collection_end(old_gen->used_in_bytes(), gc_cause);18201821if (UseAdaptiveSizePolicy) {1822log_debug(gc, ergo)("AdaptiveSizeStart: collection: %d ", heap->total_collections());1823log_trace(gc, ergo)("old_gen_capacity: " SIZE_FORMAT " young_gen_capacity: " SIZE_FORMAT,1824old_gen->capacity_in_bytes(), young_gen->capacity_in_bytes());18251826// Don't check if the size_policy is ready here. Let1827// the size_policy check that internally.1828if (UseAdaptiveGenerationSizePolicyAtMajorCollection &&1829AdaptiveSizePolicy::should_update_promo_stats(gc_cause)) {1830// Swap the survivor spaces if from_space is empty. The1831// resize_young_gen() called below is normally used after1832// a successful young GC and swapping of survivor spaces;1833// otherwise, it will fail to resize the young gen with1834// the current implementation.1835if (young_gen->from_space()->is_empty()) {1836young_gen->from_space()->clear(SpaceDecorator::Mangle);1837young_gen->swap_spaces();1838}18391840// Calculate optimal free space amounts1841assert(young_gen->max_gen_size() >1842young_gen->from_space()->capacity_in_bytes() +1843young_gen->to_space()->capacity_in_bytes(),1844"Sizes of space in young gen are out-of-bounds");18451846size_t young_live = young_gen->used_in_bytes();1847size_t eden_live = young_gen->eden_space()->used_in_bytes();1848size_t old_live = old_gen->used_in_bytes();1849size_t cur_eden = young_gen->eden_space()->capacity_in_bytes();1850size_t max_old_gen_size = old_gen->max_gen_size();1851size_t max_eden_size = young_gen->max_gen_size() -1852young_gen->from_space()->capacity_in_bytes() -1853young_gen->to_space()->capacity_in_bytes();18541855// Used for diagnostics1856size_policy->clear_generation_free_space_flags();18571858size_policy->compute_generations_free_space(young_live,1859eden_live,1860old_live,1861cur_eden,1862max_old_gen_size,1863max_eden_size,1864true /* full gc*/);18651866size_policy->check_gc_overhead_limit(eden_live,1867max_old_gen_size,1868max_eden_size,1869true /* full gc*/,1870gc_cause,1871heap->soft_ref_policy());18721873size_policy->decay_supplemental_growth(true /* full gc*/);18741875heap->resize_old_gen(1876size_policy->calculated_old_free_size_in_bytes());18771878heap->resize_young_gen(size_policy->calculated_eden_size_in_bytes(),1879size_policy->calculated_survivor_size_in_bytes());1880}18811882log_debug(gc, ergo)("AdaptiveSizeStop: collection: %d ", heap->total_collections());1883}18841885if (UsePerfData) {1886PSGCAdaptivePolicyCounters* const counters = heap->gc_policy_counters();1887counters->update_counters();1888counters->update_old_capacity(old_gen->capacity_in_bytes());1889counters->update_young_capacity(young_gen->capacity_in_bytes());1890}18911892heap->resize_all_tlabs();18931894// Resize the metaspace capacity after a collection1895MetaspaceGC::compute_new_size();18961897if (log_is_enabled(Debug, gc, heap, exit)) {1898accumulated_time()->stop();1899}19001901heap->print_heap_change(pre_gc_values);19021903// Track memory usage and detect low memory1904MemoryService::track_memory_usage();1905heap->update_counters();19061907heap->post_full_gc_dump(&_gc_timer);1908}19091910if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {1911Universe::verify("After GC");1912}19131914// Re-verify object start arrays1915if (VerifyObjectStartArray &&1916VerifyAfterGC) {1917old_gen->verify_object_start_array();1918}19191920if (ZapUnusedHeapArea) {1921old_gen->object_space()->check_mangled_unused_area_complete();1922}19231924NOT_PRODUCT(ref_processor()->verify_no_references_recorded());19251926collection_exit.update();19271928heap->print_heap_after_gc();1929heap->trace_heap_after_gc(&_gc_tracer);19301931log_debug(gc, task, time)("VM-Thread " JLONG_FORMAT " " JLONG_FORMAT " " JLONG_FORMAT,1932marking_start.ticks(), compaction_start.ticks(),1933collection_exit.ticks());19341935AdaptiveSizePolicyOutput::print(size_policy, heap->total_collections());19361937_gc_timer.register_gc_end();19381939_gc_tracer.report_dense_prefix(dense_prefix(old_space_id));1940_gc_tracer.report_gc_end(_gc_timer.gc_end(), _gc_timer.time_partitions());19411942return true;1943}19441945class PCAddThreadRootsMarkingTaskClosure : public ThreadClosure {1946private:1947uint _worker_id;19481949public:1950PCAddThreadRootsMarkingTaskClosure(uint worker_id) : _worker_id(worker_id) { }1951void do_thread(Thread* thread) {1952assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");19531954ResourceMark rm;19551956ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(_worker_id);19571958PCMarkAndPushClosure mark_and_push_closure(cm);1959MarkingCodeBlobClosure mark_and_push_in_blobs(&mark_and_push_closure, !CodeBlobToOopClosure::FixRelocations);19601961thread->oops_do(&mark_and_push_closure, &mark_and_push_in_blobs);19621963// Do the real work1964cm->follow_marking_stacks();1965}1966};19671968static void mark_from_roots_work(ParallelRootType::Value root_type, uint worker_id) {1969assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");19701971ParCompactionManager* cm =1972ParCompactionManager::gc_thread_compaction_manager(worker_id);1973PCMarkAndPushClosure mark_and_push_closure(cm);19741975switch (root_type) {1976case ParallelRootType::class_loader_data:1977{1978CLDToOopClosure cld_closure(&mark_and_push_closure, ClassLoaderData::_claim_strong);1979ClassLoaderDataGraph::always_strong_cld_do(&cld_closure);1980}1981break;19821983case ParallelRootType::code_cache:1984// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.1985//ScavengableNMethods::scavengable_nmethods_do(CodeBlobToOopClosure(&mark_and_push_closure));1986break;19871988case ParallelRootType::sentinel:1989DEBUG_ONLY(default:) // DEBUG_ONLY hack will create compile error on release builds (-Wswitch) and runtime check on debug builds1990fatal("Bad enumeration value: %u", root_type);1991break;1992}19931994// Do the real work1995cm->follow_marking_stacks();1996}19971998void steal_marking_work(TaskTerminator& terminator, uint worker_id) {1999assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");20002001ParCompactionManager* cm =2002ParCompactionManager::gc_thread_compaction_manager(worker_id);20032004oop obj = NULL;2005ObjArrayTask task;2006do {2007while (ParCompactionManager::steal_objarray(worker_id, task)) {2008cm->follow_array((objArrayOop)task.obj(), task.index());2009cm->follow_marking_stacks();2010}2011while (ParCompactionManager::steal(worker_id, obj)) {2012cm->follow_contents(obj);2013cm->follow_marking_stacks();2014}2015} while (!terminator.offer_termination());2016}20172018class MarkFromRootsTask : public AbstractGangTask {2019StrongRootsScope _strong_roots_scope; // needed for Threads::possibly_parallel_threads_do2020OopStorageSetStrongParState<false /* concurrent */, false /* is_const */> _oop_storage_set_par_state;2021SequentialSubTasksDone _subtasks;2022TaskTerminator _terminator;2023uint _active_workers;20242025public:2026MarkFromRootsTask(uint active_workers) :2027AbstractGangTask("MarkFromRootsTask"),2028_strong_roots_scope(active_workers),2029_subtasks(ParallelRootType::sentinel),2030_terminator(active_workers, ParCompactionManager::oop_task_queues()),2031_active_workers(active_workers) {2032}20332034virtual void work(uint worker_id) {2035for (uint task = 0; _subtasks.try_claim_task(task); /*empty*/ ) {2036mark_from_roots_work(static_cast<ParallelRootType::Value>(task), worker_id);2037}20382039PCAddThreadRootsMarkingTaskClosure closure(worker_id);2040Threads::possibly_parallel_threads_do(true /*parallel */, &closure);20412042// Mark from OopStorages2043{2044ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);2045PCMarkAndPushClosure closure(cm);2046_oop_storage_set_par_state.oops_do(&closure);2047// Do the real work2048cm->follow_marking_stacks();2049}20502051if (_active_workers > 1) {2052steal_marking_work(_terminator, worker_id);2053}2054}2055};20562057class ParallelCompactRefProcProxyTask : public RefProcProxyTask {2058TaskTerminator _terminator;20592060public:2061ParallelCompactRefProcProxyTask(uint max_workers)2062: RefProcProxyTask("ParallelCompactRefProcProxyTask", max_workers),2063_terminator(_max_workers, ParCompactionManager::oop_task_queues()) {}20642065void work(uint worker_id) override {2066assert(worker_id < _max_workers, "sanity");2067ParCompactionManager* cm = (_tm == RefProcThreadModel::Single) ? ParCompactionManager::get_vmthread_cm() : ParCompactionManager::gc_thread_compaction_manager(worker_id);2068PCMarkAndPushClosure keep_alive(cm);2069ParCompactionManager::FollowStackClosure complete_gc(cm, (_tm == RefProcThreadModel::Single) ? nullptr : &_terminator, worker_id);2070_rp_task->rp_work(worker_id, PSParallelCompact::is_alive_closure(), &keep_alive, &complete_gc);2071}20722073void prepare_run_task_hook() override {2074_terminator.reset_for_reuse(_queue_count);2075}2076};20772078void PSParallelCompact::marking_phase(ParCompactionManager* cm,2079bool maximum_heap_compaction,2080ParallelOldTracer *gc_tracer) {2081// Recursively traverse all live objects and mark them2082GCTraceTime(Info, gc, phases) tm("Marking Phase", &_gc_timer);20832084uint active_gc_threads = ParallelScavengeHeap::heap()->workers().active_workers();20852086// Need new claim bits before marking starts.2087ClassLoaderDataGraph::clear_claimed_marks();20882089{2090GCTraceTime(Debug, gc, phases) tm("Par Mark", &_gc_timer);20912092MarkFromRootsTask task(active_gc_threads);2093ParallelScavengeHeap::heap()->workers().run_task(&task);2094}20952096// Process reference objects found during marking2097{2098GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer);20992100ReferenceProcessorStats stats;2101ReferenceProcessorPhaseTimes pt(&_gc_timer, ref_processor()->max_num_queues());21022103ref_processor()->set_active_mt_degree(active_gc_threads);2104ParallelCompactRefProcProxyTask task(ref_processor()->max_num_queues());2105stats = ref_processor()->process_discovered_references(task, pt);21062107gc_tracer->report_gc_reference_stats(stats);2108pt.print_all_references();2109}21102111// This is the point where the entire marking should have completed.2112ParCompactionManager::verify_all_marking_stack_empty();21132114{2115GCTraceTime(Debug, gc, phases) tm("Weak Processing", &_gc_timer);2116WeakProcessor::weak_oops_do(is_alive_closure(), &do_nothing_cl);2117}21182119{2120GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer);21212122// Follow system dictionary roots and unload classes.2123bool purged_class = SystemDictionary::do_unloading(&_gc_timer);21242125// Unload nmethods.2126CodeCache::do_unloading(is_alive_closure(), purged_class);21272128// Prune dead klasses from subklass/sibling/implementor lists.2129Klass::clean_weak_klass_links(purged_class);21302131// Clean JVMCI metadata handles.2132JVMCI_ONLY(JVMCI::do_unloading(purged_class));2133}21342135_gc_tracer.report_object_count_after_gc(is_alive_closure());2136}21372138#ifdef ASSERT2139void PCAdjustPointerClosure::verify_cm(ParCompactionManager* cm) {2140assert(cm != NULL, "associate ParCompactionManage should not be NULL");2141auto vmthread_cm = ParCompactionManager::get_vmthread_cm();2142if (Thread::current()->is_VM_thread()) {2143assert(cm == vmthread_cm, "VM threads should use ParCompactionManager from get_vmthread_cm()");2144} else {2145assert(Thread::current()->is_GC_task_thread(), "Must be a GC thread");2146assert(cm != vmthread_cm, "GC threads should use ParCompactionManager from gc_thread_compaction_manager()");2147}2148}2149#endif21502151class PSAdjustTask final : public AbstractGangTask {2152SubTasksDone _sub_tasks;2153WeakProcessor::Task _weak_proc_task;2154OopStorageSetStrongParState<false, false> _oop_storage_iter;2155uint _nworkers;21562157enum PSAdjustSubTask {2158PSAdjustSubTask_code_cache,2159PSAdjustSubTask_old_ref_process,2160PSAdjustSubTask_young_ref_process,21612162PSAdjustSubTask_num_elements2163};21642165public:2166PSAdjustTask(uint nworkers) :2167AbstractGangTask("PSAdjust task"),2168_sub_tasks(PSAdjustSubTask_num_elements),2169_weak_proc_task(nworkers),2170_nworkers(nworkers) {2171// Need new claim bits when tracing through and adjusting pointers.2172ClassLoaderDataGraph::clear_claimed_marks();2173if (nworkers > 1) {2174Threads::change_thread_claim_token();2175}2176}21772178~PSAdjustTask() {2179Threads::assert_all_threads_claimed();2180}21812182void work(uint worker_id) {2183ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);2184PCAdjustPointerClosure adjust(cm);2185{2186ResourceMark rm;2187Threads::possibly_parallel_oops_do(_nworkers > 1, &adjust, nullptr);2188}2189_oop_storage_iter.oops_do(&adjust);2190{2191CLDToOopClosure cld_closure(&adjust, ClassLoaderData::_claim_strong);2192ClassLoaderDataGraph::cld_do(&cld_closure);2193}2194{2195AlwaysTrueClosure always_alive;2196_weak_proc_task.work(worker_id, &always_alive, &adjust);2197}2198if (_sub_tasks.try_claim_task(PSAdjustSubTask_code_cache)) {2199CodeBlobToOopClosure adjust_code(&adjust, CodeBlobToOopClosure::FixRelocations);2200CodeCache::blobs_do(&adjust_code);2201}2202if (_sub_tasks.try_claim_task(PSAdjustSubTask_old_ref_process)) {2203PSParallelCompact::ref_processor()->weak_oops_do(&adjust);2204}2205if (_sub_tasks.try_claim_task(PSAdjustSubTask_young_ref_process)) {2206// Roots were visited so references into the young gen in roots2207// may have been scanned. Process them also.2208// Should the reference processor have a span that excludes2209// young gen objects?2210PSScavenge::reference_processor()->weak_oops_do(&adjust);2211}2212_sub_tasks.all_tasks_claimed();2213}2214};22152216void PSParallelCompact::adjust_roots() {2217// Adjust the pointers to reflect the new locations2218GCTraceTime(Info, gc, phases) tm("Adjust Roots", &_gc_timer);2219uint nworkers = ParallelScavengeHeap::heap()->workers().active_workers();2220PSAdjustTask task(nworkers);2221ParallelScavengeHeap::heap()->workers().run_task(&task);2222}22232224// Helper class to print 8 region numbers per line and then print the total at the end.2225class FillableRegionLogger : public StackObj {2226private:2227Log(gc, compaction) log;2228static const int LineLength = 8;2229size_t _regions[LineLength];2230int _next_index;2231bool _enabled;2232size_t _total_regions;2233public:2234FillableRegionLogger() : _next_index(0), _enabled(log_develop_is_enabled(Trace, gc, compaction)), _total_regions(0) { }2235~FillableRegionLogger() {2236log.trace(SIZE_FORMAT " initially fillable regions", _total_regions);2237}22382239void print_line() {2240if (!_enabled || _next_index == 0) {2241return;2242}2243FormatBuffer<> line("Fillable: ");2244for (int i = 0; i < _next_index; i++) {2245line.append(" " SIZE_FORMAT_W(7), _regions[i]);2246}2247log.trace("%s", line.buffer());2248_next_index = 0;2249}22502251void handle(size_t region) {2252if (!_enabled) {2253return;2254}2255_regions[_next_index++] = region;2256if (_next_index == LineLength) {2257print_line();2258}2259_total_regions++;2260}2261};22622263void PSParallelCompact::prepare_region_draining_tasks(uint parallel_gc_threads)2264{2265GCTraceTime(Trace, gc, phases) tm("Drain Task Setup", &_gc_timer);22662267// Find the threads that are active2268uint worker_id = 0;22692270// Find all regions that are available (can be filled immediately) and2271// distribute them to the thread stacks. The iteration is done in reverse2272// order (high to low) so the regions will be removed in ascending order.22732274const ParallelCompactData& sd = PSParallelCompact::summary_data();22752276// id + 1 is used to test termination so unsigned can2277// be used with an old_space_id == 0.2278FillableRegionLogger region_logger;2279for (unsigned int id = to_space_id; id + 1 > old_space_id; --id) {2280SpaceInfo* const space_info = _space_info + id;2281MutableSpace* const space = space_info->space();2282HeapWord* const new_top = space_info->new_top();22832284const size_t beg_region = sd.addr_to_region_idx(space_info->dense_prefix());2285const size_t end_region =2286sd.addr_to_region_idx(sd.region_align_up(new_top));22872288for (size_t cur = end_region - 1; cur + 1 > beg_region; --cur) {2289if (sd.region(cur)->claim_unsafe()) {2290ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);2291bool result = sd.region(cur)->mark_normal();2292assert(result, "Must succeed at this point.");2293cm->region_stack()->push(cur);2294region_logger.handle(cur);2295// Assign regions to tasks in round-robin fashion.2296if (++worker_id == parallel_gc_threads) {2297worker_id = 0;2298}2299}2300}2301region_logger.print_line();2302}2303}23042305class TaskQueue : StackObj {2306volatile uint _counter;2307uint _size;2308uint _insert_index;2309PSParallelCompact::UpdateDensePrefixTask* _backing_array;2310public:2311explicit TaskQueue(uint size) : _counter(0), _size(size), _insert_index(0), _backing_array(NULL) {2312_backing_array = NEW_C_HEAP_ARRAY(PSParallelCompact::UpdateDensePrefixTask, _size, mtGC);2313}2314~TaskQueue() {2315assert(_counter >= _insert_index, "not all queue elements were claimed");2316FREE_C_HEAP_ARRAY(T, _backing_array);2317}23182319void push(const PSParallelCompact::UpdateDensePrefixTask& value) {2320assert(_insert_index < _size, "too small backing array");2321_backing_array[_insert_index++] = value;2322}23232324bool try_claim(PSParallelCompact::UpdateDensePrefixTask& reference) {2325uint claimed = Atomic::fetch_and_add(&_counter, 1u);2326if (claimed < _insert_index) {2327reference = _backing_array[claimed];2328return true;2329} else {2330return false;2331}2332}2333};23342335#define PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING 423362337void PSParallelCompact::enqueue_dense_prefix_tasks(TaskQueue& task_queue,2338uint parallel_gc_threads) {2339GCTraceTime(Trace, gc, phases) tm("Dense Prefix Task Setup", &_gc_timer);23402341ParallelCompactData& sd = PSParallelCompact::summary_data();23422343// Iterate over all the spaces adding tasks for updating2344// regions in the dense prefix. Assume that 1 gc thread2345// will work on opening the gaps and the remaining gc threads2346// will work on the dense prefix.2347unsigned int space_id;2348for (space_id = old_space_id; space_id < last_space_id; ++ space_id) {2349HeapWord* const dense_prefix_end = _space_info[space_id].dense_prefix();2350const MutableSpace* const space = _space_info[space_id].space();23512352if (dense_prefix_end == space->bottom()) {2353// There is no dense prefix for this space.2354continue;2355}23562357// The dense prefix is before this region.2358size_t region_index_end_dense_prefix =2359sd.addr_to_region_idx(dense_prefix_end);2360RegionData* const dense_prefix_cp =2361sd.region(region_index_end_dense_prefix);2362assert(dense_prefix_end == space->end() ||2363dense_prefix_cp->available() ||2364dense_prefix_cp->claimed(),2365"The region after the dense prefix should always be ready to fill");23662367size_t region_index_start = sd.addr_to_region_idx(space->bottom());23682369// Is there dense prefix work?2370size_t total_dense_prefix_regions =2371region_index_end_dense_prefix - region_index_start;2372// How many regions of the dense prefix should be given to2373// each thread?2374if (total_dense_prefix_regions > 0) {2375uint tasks_for_dense_prefix = 1;2376if (total_dense_prefix_regions <=2377(parallel_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)) {2378// Don't over partition. This assumes that2379// PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING is a small integer value2380// so there are not many regions to process.2381tasks_for_dense_prefix = parallel_gc_threads;2382} else {2383// Over partition2384tasks_for_dense_prefix = parallel_gc_threads *2385PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING;2386}2387size_t regions_per_thread = total_dense_prefix_regions /2388tasks_for_dense_prefix;2389// Give each thread at least 1 region.2390if (regions_per_thread == 0) {2391regions_per_thread = 1;2392}23932394for (uint k = 0; k < tasks_for_dense_prefix; k++) {2395if (region_index_start >= region_index_end_dense_prefix) {2396break;2397}2398// region_index_end is not processed2399size_t region_index_end = MIN2(region_index_start + regions_per_thread,2400region_index_end_dense_prefix);2401task_queue.push(UpdateDensePrefixTask(SpaceId(space_id),2402region_index_start,2403region_index_end));2404region_index_start = region_index_end;2405}2406}2407// This gets any part of the dense prefix that did not2408// fit evenly.2409if (region_index_start < region_index_end_dense_prefix) {2410task_queue.push(UpdateDensePrefixTask(SpaceId(space_id),2411region_index_start,2412region_index_end_dense_prefix));2413}2414}2415}24162417#ifdef ASSERT2418// Write a histogram of the number of times the block table was filled for a2419// region.2420void PSParallelCompact::write_block_fill_histogram()2421{2422if (!log_develop_is_enabled(Trace, gc, compaction)) {2423return;2424}24252426Log(gc, compaction) log;2427ResourceMark rm;2428LogStream ls(log.trace());2429outputStream* out = &ls;24302431typedef ParallelCompactData::RegionData rd_t;2432ParallelCompactData& sd = summary_data();24332434for (unsigned int id = old_space_id; id < last_space_id; ++id) {2435MutableSpace* const spc = _space_info[id].space();2436if (spc->bottom() != spc->top()) {2437const rd_t* const beg = sd.addr_to_region_ptr(spc->bottom());2438HeapWord* const top_aligned_up = sd.region_align_up(spc->top());2439const rd_t* const end = sd.addr_to_region_ptr(top_aligned_up);24402441size_t histo[5] = { 0, 0, 0, 0, 0 };2442const size_t histo_len = sizeof(histo) / sizeof(size_t);2443const size_t region_cnt = pointer_delta(end, beg, sizeof(rd_t));24442445for (const rd_t* cur = beg; cur < end; ++cur) {2446++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)];2447}2448out->print("Block fill histogram: %u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);2449for (size_t i = 0; i < histo_len; ++i) {2450out->print(" " SIZE_FORMAT_W(5) " %5.1f%%",2451histo[i], 100.0 * histo[i] / region_cnt);2452}2453out->cr();2454}2455}2456}2457#endif // #ifdef ASSERT24582459static void compaction_with_stealing_work(TaskTerminator* terminator, uint worker_id) {2460assert(ParallelScavengeHeap::heap()->is_gc_active(), "called outside gc");24612462ParCompactionManager* cm =2463ParCompactionManager::gc_thread_compaction_manager(worker_id);24642465// Drain the stacks that have been preloaded with regions2466// that are ready to fill.24672468cm->drain_region_stacks();24692470guarantee(cm->region_stack()->is_empty(), "Not empty");24712472size_t region_index = 0;24732474while (true) {2475if (ParCompactionManager::steal(worker_id, region_index)) {2476PSParallelCompact::fill_and_update_region(cm, region_index);2477cm->drain_region_stacks();2478} else if (PSParallelCompact::steal_unavailable_region(cm, region_index)) {2479// Fill and update an unavailable region with the help of a shadow region2480PSParallelCompact::fill_and_update_shadow_region(cm, region_index);2481cm->drain_region_stacks();2482} else {2483if (terminator->offer_termination()) {2484break;2485}2486// Go around again.2487}2488}2489}24902491class UpdateDensePrefixAndCompactionTask: public AbstractGangTask {2492TaskQueue& _tq;2493TaskTerminator _terminator;2494uint _active_workers;24952496public:2497UpdateDensePrefixAndCompactionTask(TaskQueue& tq, uint active_workers) :2498AbstractGangTask("UpdateDensePrefixAndCompactionTask"),2499_tq(tq),2500_terminator(active_workers, ParCompactionManager::region_task_queues()),2501_active_workers(active_workers) {2502}2503virtual void work(uint worker_id) {2504ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(worker_id);25052506for (PSParallelCompact::UpdateDensePrefixTask task; _tq.try_claim(task); /* empty */) {2507PSParallelCompact::update_and_deadwood_in_dense_prefix(cm,2508task._space_id,2509task._region_index_start,2510task._region_index_end);2511}25122513// Once a thread has drained it's stack, it should try to steal regions from2514// other threads.2515compaction_with_stealing_work(&_terminator, worker_id);2516}2517};25182519void PSParallelCompact::compact() {2520GCTraceTime(Info, gc, phases) tm("Compaction Phase", &_gc_timer);25212522ParallelScavengeHeap* heap = ParallelScavengeHeap::heap();2523PSOldGen* old_gen = heap->old_gen();2524old_gen->start_array()->reset();2525uint active_gc_threads = ParallelScavengeHeap::heap()->workers().active_workers();25262527// for [0..last_space_id)2528// for [0..active_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING)2529// push2530// push2531//2532// max push count is thus: last_space_id * (active_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING + 1)2533TaskQueue task_queue(last_space_id * (active_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING + 1));2534initialize_shadow_regions(active_gc_threads);2535prepare_region_draining_tasks(active_gc_threads);2536enqueue_dense_prefix_tasks(task_queue, active_gc_threads);25372538{2539GCTraceTime(Trace, gc, phases) tm("Par Compact", &_gc_timer);25402541UpdateDensePrefixAndCompactionTask task(task_queue, active_gc_threads);2542ParallelScavengeHeap::heap()->workers().run_task(&task);25432544#ifdef ASSERT2545// Verify that all regions have been processed before the deferred updates.2546for (unsigned int id = old_space_id; id < last_space_id; ++id) {2547verify_complete(SpaceId(id));2548}2549#endif2550}25512552{2553GCTraceTime(Trace, gc, phases) tm("Deferred Updates", &_gc_timer);2554// Update the deferred objects, if any. In principle, any compaction2555// manager can be used. However, since the current thread is VM thread, we2556// use the rightful one to keep the verification logic happy.2557ParCompactionManager* cm = ParCompactionManager::get_vmthread_cm();2558for (unsigned int id = old_space_id; id < last_space_id; ++id) {2559update_deferred_objects(cm, SpaceId(id));2560}2561}25622563DEBUG_ONLY(write_block_fill_histogram());2564}25652566#ifdef ASSERT2567void PSParallelCompact::verify_complete(SpaceId space_id) {2568// All Regions between space bottom() to new_top() should be marked as filled2569// and all Regions between new_top() and top() should be available (i.e.,2570// should have been emptied).2571ParallelCompactData& sd = summary_data();2572SpaceInfo si = _space_info[space_id];2573HeapWord* new_top_addr = sd.region_align_up(si.new_top());2574HeapWord* old_top_addr = sd.region_align_up(si.space()->top());2575const size_t beg_region = sd.addr_to_region_idx(si.space()->bottom());2576const size_t new_top_region = sd.addr_to_region_idx(new_top_addr);2577const size_t old_top_region = sd.addr_to_region_idx(old_top_addr);25782579bool issued_a_warning = false;25802581size_t cur_region;2582for (cur_region = beg_region; cur_region < new_top_region; ++cur_region) {2583const RegionData* const c = sd.region(cur_region);2584if (!c->completed()) {2585log_warning(gc)("region " SIZE_FORMAT " not filled: destination_count=%u",2586cur_region, c->destination_count());2587issued_a_warning = true;2588}2589}25902591for (cur_region = new_top_region; cur_region < old_top_region; ++cur_region) {2592const RegionData* const c = sd.region(cur_region);2593if (!c->available()) {2594log_warning(gc)("region " SIZE_FORMAT " not empty: destination_count=%u",2595cur_region, c->destination_count());2596issued_a_warning = true;2597}2598}25992600if (issued_a_warning) {2601print_region_ranges();2602}2603}2604#endif // #ifdef ASSERT26052606inline void UpdateOnlyClosure::do_addr(HeapWord* addr) {2607_start_array->allocate_block(addr);2608compaction_manager()->update_contents(cast_to_oop(addr));2609}26102611// Update interior oops in the ranges of regions [beg_region, end_region).2612void2613PSParallelCompact::update_and_deadwood_in_dense_prefix(ParCompactionManager* cm,2614SpaceId space_id,2615size_t beg_region,2616size_t end_region) {2617ParallelCompactData& sd = summary_data();2618ParMarkBitMap* const mbm = mark_bitmap();26192620HeapWord* beg_addr = sd.region_to_addr(beg_region);2621HeapWord* const end_addr = sd.region_to_addr(end_region);2622assert(beg_region <= end_region, "bad region range");2623assert(end_addr <= dense_prefix(space_id), "not in the dense prefix");26242625#ifdef ASSERT2626// Claim the regions to avoid triggering an assert when they are marked as2627// filled.2628for (size_t claim_region = beg_region; claim_region < end_region; ++claim_region) {2629assert(sd.region(claim_region)->claim_unsafe(), "claim() failed");2630}2631#endif // #ifdef ASSERT26322633if (beg_addr != space(space_id)->bottom()) {2634// Find the first live object or block of dead space that *starts* in this2635// range of regions. If a partial object crosses onto the region, skip it;2636// it will be marked for 'deferred update' when the object head is2637// processed. If dead space crosses onto the region, it is also skipped; it2638// will be filled when the prior region is processed. If neither of those2639// apply, the first word in the region is the start of a live object or dead2640// space.2641assert(beg_addr > space(space_id)->bottom(), "sanity");2642const RegionData* const cp = sd.region(beg_region);2643if (cp->partial_obj_size() != 0) {2644beg_addr = sd.partial_obj_end(beg_region);2645} else if (dead_space_crosses_boundary(cp, mbm->addr_to_bit(beg_addr))) {2646beg_addr = mbm->find_obj_beg(beg_addr, end_addr);2647}2648}26492650if (beg_addr < end_addr) {2651// A live object or block of dead space starts in this range of Regions.2652HeapWord* const dense_prefix_end = dense_prefix(space_id);26532654// Create closures and iterate.2655UpdateOnlyClosure update_closure(mbm, cm, space_id);2656FillClosure fill_closure(cm, space_id);2657ParMarkBitMap::IterationStatus status;2658status = mbm->iterate(&update_closure, &fill_closure, beg_addr, end_addr,2659dense_prefix_end);2660if (status == ParMarkBitMap::incomplete) {2661update_closure.do_addr(update_closure.source());2662}2663}26642665// Mark the regions as filled.2666RegionData* const beg_cp = sd.region(beg_region);2667RegionData* const end_cp = sd.region(end_region);2668for (RegionData* cp = beg_cp; cp < end_cp; ++cp) {2669cp->set_completed();2670}2671}26722673// Return the SpaceId for the space containing addr. If addr is not in the2674// heap, last_space_id is returned. In debug mode it expects the address to be2675// in the heap and asserts such.2676PSParallelCompact::SpaceId PSParallelCompact::space_id(HeapWord* addr) {2677assert(ParallelScavengeHeap::heap()->is_in_reserved(addr), "addr not in the heap");26782679for (unsigned int id = old_space_id; id < last_space_id; ++id) {2680if (_space_info[id].space()->contains(addr)) {2681return SpaceId(id);2682}2683}26842685assert(false, "no space contains the addr");2686return last_space_id;2687}26882689void PSParallelCompact::update_deferred_objects(ParCompactionManager* cm,2690SpaceId id) {2691assert(id < last_space_id, "bad space id");26922693ParallelCompactData& sd = summary_data();2694const SpaceInfo* const space_info = _space_info + id;2695ObjectStartArray* const start_array = space_info->start_array();26962697const MutableSpace* const space = space_info->space();2698assert(space_info->dense_prefix() >= space->bottom(), "dense_prefix not set");2699HeapWord* const beg_addr = space_info->dense_prefix();2700HeapWord* const end_addr = sd.region_align_up(space_info->new_top());27012702const RegionData* const beg_region = sd.addr_to_region_ptr(beg_addr);2703const RegionData* const end_region = sd.addr_to_region_ptr(end_addr);2704const RegionData* cur_region;2705for (cur_region = beg_region; cur_region < end_region; ++cur_region) {2706HeapWord* const addr = cur_region->deferred_obj_addr();2707if (addr != NULL) {2708if (start_array != NULL) {2709start_array->allocate_block(addr);2710}2711cm->update_contents(cast_to_oop(addr));2712assert(oopDesc::is_oop_or_null(cast_to_oop(addr)), "Expected an oop or NULL at " PTR_FORMAT, p2i(cast_to_oop(addr)));2713}2714}2715}27162717// Skip over count live words starting from beg, and return the address of the2718// next live word. Unless marked, the word corresponding to beg is assumed to2719// be dead. Callers must either ensure beg does not correspond to the middle of2720// an object, or account for those live words in some other way. Callers must2721// also ensure that there are enough live words in the range [beg, end) to skip.2722HeapWord*2723PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_t count)2724{2725assert(count > 0, "sanity");27262727ParMarkBitMap* m = mark_bitmap();2728idx_t bits_to_skip = m->words_to_bits(count);2729idx_t cur_beg = m->addr_to_bit(beg);2730const idx_t search_end = m->align_range_end(m->addr_to_bit(end));27312732do {2733cur_beg = m->find_obj_beg(cur_beg, search_end);2734idx_t cur_end = m->find_obj_end(cur_beg, search_end);2735const size_t obj_bits = cur_end - cur_beg + 1;2736if (obj_bits > bits_to_skip) {2737return m->bit_to_addr(cur_beg + bits_to_skip);2738}2739bits_to_skip -= obj_bits;2740cur_beg = cur_end + 1;2741} while (bits_to_skip > 0);27422743// Skipping the desired number of words landed just past the end of an object.2744// Find the start of the next object.2745cur_beg = m->find_obj_beg(cur_beg, search_end);2746assert(cur_beg < m->addr_to_bit(end), "not enough live words to skip");2747return m->bit_to_addr(cur_beg);2748}27492750HeapWord* PSParallelCompact::first_src_addr(HeapWord* const dest_addr,2751SpaceId src_space_id,2752size_t src_region_idx)2753{2754assert(summary_data().is_region_aligned(dest_addr), "not aligned");27552756const SplitInfo& split_info = _space_info[src_space_id].split_info();2757if (split_info.dest_region_addr() == dest_addr) {2758// The partial object ending at the split point contains the first word to2759// be copied to dest_addr.2760return split_info.first_src_addr();2761}27622763const ParallelCompactData& sd = summary_data();2764ParMarkBitMap* const bitmap = mark_bitmap();2765const size_t RegionSize = ParallelCompactData::RegionSize;27662767assert(sd.is_region_aligned(dest_addr), "not aligned");2768const RegionData* const src_region_ptr = sd.region(src_region_idx);2769const size_t partial_obj_size = src_region_ptr->partial_obj_size();2770HeapWord* const src_region_destination = src_region_ptr->destination();27712772assert(dest_addr >= src_region_destination, "wrong src region");2773assert(src_region_ptr->data_size() > 0, "src region cannot be empty");27742775HeapWord* const src_region_beg = sd.region_to_addr(src_region_idx);2776HeapWord* const src_region_end = src_region_beg + RegionSize;27772778HeapWord* addr = src_region_beg;2779if (dest_addr == src_region_destination) {2780// Return the first live word in the source region.2781if (partial_obj_size == 0) {2782addr = bitmap->find_obj_beg(addr, src_region_end);2783assert(addr < src_region_end, "no objects start in src region");2784}2785return addr;2786}27872788// Must skip some live data.2789size_t words_to_skip = dest_addr - src_region_destination;2790assert(src_region_ptr->data_size() > words_to_skip, "wrong src region");27912792if (partial_obj_size >= words_to_skip) {2793// All the live words to skip are part of the partial object.2794addr += words_to_skip;2795if (partial_obj_size == words_to_skip) {2796// Find the first live word past the partial object.2797addr = bitmap->find_obj_beg(addr, src_region_end);2798assert(addr < src_region_end, "wrong src region");2799}2800return addr;2801}28022803// Skip over the partial object (if any).2804if (partial_obj_size != 0) {2805words_to_skip -= partial_obj_size;2806addr += partial_obj_size;2807}28082809// Skip over live words due to objects that start in the region.2810addr = skip_live_words(addr, src_region_end, words_to_skip);2811assert(addr < src_region_end, "wrong src region");2812return addr;2813}28142815void PSParallelCompact::decrement_destination_counts(ParCompactionManager* cm,2816SpaceId src_space_id,2817size_t beg_region,2818HeapWord* end_addr)2819{2820ParallelCompactData& sd = summary_data();28212822#ifdef ASSERT2823MutableSpace* const src_space = _space_info[src_space_id].space();2824HeapWord* const beg_addr = sd.region_to_addr(beg_region);2825assert(src_space->contains(beg_addr) || beg_addr == src_space->end(),2826"src_space_id does not match beg_addr");2827assert(src_space->contains(end_addr) || end_addr == src_space->end(),2828"src_space_id does not match end_addr");2829#endif // #ifdef ASSERT28302831RegionData* const beg = sd.region(beg_region);2832RegionData* const end = sd.addr_to_region_ptr(sd.region_align_up(end_addr));28332834// Regions up to new_top() are enqueued if they become available.2835HeapWord* const new_top = _space_info[src_space_id].new_top();2836RegionData* const enqueue_end =2837sd.addr_to_region_ptr(sd.region_align_up(new_top));28382839for (RegionData* cur = beg; cur < end; ++cur) {2840assert(cur->data_size() > 0, "region must have live data");2841cur->decrement_destination_count();2842if (cur < enqueue_end && cur->available() && cur->claim()) {2843if (cur->mark_normal()) {2844cm->push_region(sd.region(cur));2845} else if (cur->mark_copied()) {2846// Try to copy the content of the shadow region back to its corresponding2847// heap region if the shadow region is filled. Otherwise, the GC thread2848// fills the shadow region will copy the data back (see2849// MoveAndUpdateShadowClosure::complete_region).2850copy_back(sd.region_to_addr(cur->shadow_region()), sd.region_to_addr(cur));2851ParCompactionManager::push_shadow_region_mt_safe(cur->shadow_region());2852cur->set_completed();2853}2854}2855}2856}28572858size_t PSParallelCompact::next_src_region(MoveAndUpdateClosure& closure,2859SpaceId& src_space_id,2860HeapWord*& src_space_top,2861HeapWord* end_addr)2862{2863typedef ParallelCompactData::RegionData RegionData;28642865ParallelCompactData& sd = PSParallelCompact::summary_data();2866const size_t region_size = ParallelCompactData::RegionSize;28672868size_t src_region_idx = 0;28692870// Skip empty regions (if any) up to the top of the space.2871HeapWord* const src_aligned_up = sd.region_align_up(end_addr);2872RegionData* src_region_ptr = sd.addr_to_region_ptr(src_aligned_up);2873HeapWord* const top_aligned_up = sd.region_align_up(src_space_top);2874const RegionData* const top_region_ptr =2875sd.addr_to_region_ptr(top_aligned_up);2876while (src_region_ptr < top_region_ptr && src_region_ptr->data_size() == 0) {2877++src_region_ptr;2878}28792880if (src_region_ptr < top_region_ptr) {2881// The next source region is in the current space. Update src_region_idx2882// and the source address to match src_region_ptr.2883src_region_idx = sd.region(src_region_ptr);2884HeapWord* const src_region_addr = sd.region_to_addr(src_region_idx);2885if (src_region_addr > closure.source()) {2886closure.set_source(src_region_addr);2887}2888return src_region_idx;2889}28902891// Switch to a new source space and find the first non-empty region.2892unsigned int space_id = src_space_id + 1;2893assert(space_id < last_space_id, "not enough spaces");28942895HeapWord* const destination = closure.destination();28962897do {2898MutableSpace* space = _space_info[space_id].space();2899HeapWord* const bottom = space->bottom();2900const RegionData* const bottom_cp = sd.addr_to_region_ptr(bottom);29012902// Iterate over the spaces that do not compact into themselves.2903if (bottom_cp->destination() != bottom) {2904HeapWord* const top_aligned_up = sd.region_align_up(space->top());2905const RegionData* const top_cp = sd.addr_to_region_ptr(top_aligned_up);29062907for (const RegionData* src_cp = bottom_cp; src_cp < top_cp; ++src_cp) {2908if (src_cp->live_obj_size() > 0) {2909// Found it.2910assert(src_cp->destination() == destination,2911"first live obj in the space must match the destination");2912assert(src_cp->partial_obj_size() == 0,2913"a space cannot begin with a partial obj");29142915src_space_id = SpaceId(space_id);2916src_space_top = space->top();2917const size_t src_region_idx = sd.region(src_cp);2918closure.set_source(sd.region_to_addr(src_region_idx));2919return src_region_idx;2920} else {2921assert(src_cp->data_size() == 0, "sanity");2922}2923}2924}2925} while (++space_id < last_space_id);29262927assert(false, "no source region was found");2928return 0;2929}29302931void PSParallelCompact::fill_region(ParCompactionManager* cm, MoveAndUpdateClosure& closure, size_t region_idx)2932{2933typedef ParMarkBitMap::IterationStatus IterationStatus;2934ParMarkBitMap* const bitmap = mark_bitmap();2935ParallelCompactData& sd = summary_data();2936RegionData* const region_ptr = sd.region(region_idx);29372938// Get the source region and related info.2939size_t src_region_idx = region_ptr->source_region();2940SpaceId src_space_id = space_id(sd.region_to_addr(src_region_idx));2941HeapWord* src_space_top = _space_info[src_space_id].space()->top();2942HeapWord* dest_addr = sd.region_to_addr(region_idx);29432944closure.set_source(first_src_addr(dest_addr, src_space_id, src_region_idx));29452946// Adjust src_region_idx to prepare for decrementing destination counts (the2947// destination count is not decremented when a region is copied to itself).2948if (src_region_idx == region_idx) {2949src_region_idx += 1;2950}29512952if (bitmap->is_unmarked(closure.source())) {2953// The first source word is in the middle of an object; copy the remainder2954// of the object or as much as will fit. The fact that pointer updates were2955// deferred will be noted when the object header is processed.2956HeapWord* const old_src_addr = closure.source();2957closure.copy_partial_obj();2958if (closure.is_full()) {2959decrement_destination_counts(cm, src_space_id, src_region_idx,2960closure.source());2961region_ptr->set_deferred_obj_addr(NULL);2962closure.complete_region(cm, dest_addr, region_ptr);2963return;2964}29652966HeapWord* const end_addr = sd.region_align_down(closure.source());2967if (sd.region_align_down(old_src_addr) != end_addr) {2968// The partial object was copied from more than one source region.2969decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);29702971// Move to the next source region, possibly switching spaces as well. All2972// args except end_addr may be modified.2973src_region_idx = next_src_region(closure, src_space_id, src_space_top,2974end_addr);2975}2976}29772978do {2979HeapWord* const cur_addr = closure.source();2980HeapWord* const end_addr = MIN2(sd.region_align_up(cur_addr + 1),2981src_space_top);2982IterationStatus status = bitmap->iterate(&closure, cur_addr, end_addr);29832984if (status == ParMarkBitMap::incomplete) {2985// The last obj that starts in the source region does not end in the2986// region.2987assert(closure.source() < end_addr, "sanity");2988HeapWord* const obj_beg = closure.source();2989HeapWord* const range_end = MIN2(obj_beg + closure.words_remaining(),2990src_space_top);2991HeapWord* const obj_end = bitmap->find_obj_end(obj_beg, range_end);2992if (obj_end < range_end) {2993// The end was found; the entire object will fit.2994status = closure.do_addr(obj_beg, bitmap->obj_size(obj_beg, obj_end));2995assert(status != ParMarkBitMap::would_overflow, "sanity");2996} else {2997// The end was not found; the object will not fit.2998assert(range_end < src_space_top, "obj cannot cross space boundary");2999status = ParMarkBitMap::would_overflow;3000}3001}30023003if (status == ParMarkBitMap::would_overflow) {3004// The last object did not fit. Note that interior oop updates were3005// deferred, then copy enough of the object to fill the region.3006region_ptr->set_deferred_obj_addr(closure.destination());3007status = closure.copy_until_full(); // copies from closure.source()30083009decrement_destination_counts(cm, src_space_id, src_region_idx,3010closure.source());3011closure.complete_region(cm, dest_addr, region_ptr);3012return;3013}30143015if (status == ParMarkBitMap::full) {3016decrement_destination_counts(cm, src_space_id, src_region_idx,3017closure.source());3018region_ptr->set_deferred_obj_addr(NULL);3019closure.complete_region(cm, dest_addr, region_ptr);3020return;3021}30223023decrement_destination_counts(cm, src_space_id, src_region_idx, end_addr);30243025// Move to the next source region, possibly switching spaces as well. All3026// args except end_addr may be modified.3027src_region_idx = next_src_region(closure, src_space_id, src_space_top,3028end_addr);3029} while (true);3030}30313032void PSParallelCompact::fill_and_update_region(ParCompactionManager* cm, size_t region_idx)3033{3034MoveAndUpdateClosure cl(mark_bitmap(), cm, region_idx);3035fill_region(cm, cl, region_idx);3036}30373038void PSParallelCompact::fill_and_update_shadow_region(ParCompactionManager* cm, size_t region_idx)3039{3040// Get a shadow region first3041ParallelCompactData& sd = summary_data();3042RegionData* const region_ptr = sd.region(region_idx);3043size_t shadow_region = ParCompactionManager::pop_shadow_region_mt_safe(region_ptr);3044// The InvalidShadow return value indicates the corresponding heap region is available,3045// so use MoveAndUpdateClosure to fill the normal region. Otherwise, use3046// MoveAndUpdateShadowClosure to fill the acquired shadow region.3047if (shadow_region == ParCompactionManager::InvalidShadow) {3048MoveAndUpdateClosure cl(mark_bitmap(), cm, region_idx);3049region_ptr->shadow_to_normal();3050return fill_region(cm, cl, region_idx);3051} else {3052MoveAndUpdateShadowClosure cl(mark_bitmap(), cm, region_idx, shadow_region);3053return fill_region(cm, cl, region_idx);3054}3055}30563057void PSParallelCompact::copy_back(HeapWord *shadow_addr, HeapWord *region_addr)3058{3059Copy::aligned_conjoint_words(shadow_addr, region_addr, _summary_data.RegionSize);3060}30613062bool PSParallelCompact::steal_unavailable_region(ParCompactionManager* cm, size_t ®ion_idx)3063{3064size_t next = cm->next_shadow_region();3065ParallelCompactData& sd = summary_data();3066size_t old_new_top = sd.addr_to_region_idx(_space_info[old_space_id].new_top());3067uint active_gc_threads = ParallelScavengeHeap::heap()->workers().active_workers();30683069while (next < old_new_top) {3070if (sd.region(next)->mark_shadow()) {3071region_idx = next;3072return true;3073}3074next = cm->move_next_shadow_region_by(active_gc_threads);3075}30763077return false;3078}30793080// The shadow region is an optimization to address region dependencies in full GC. The basic3081// idea is making more regions available by temporally storing their live objects in empty3082// shadow regions to resolve dependencies between them and the destination regions. Therefore,3083// GC threads need not wait destination regions to be available before processing sources.3084//3085// A typical workflow would be:3086// After draining its own stack and failing to steal from others, a GC worker would pick an3087// unavailable region (destination count > 0) and get a shadow region. Then the worker fills3088// the shadow region by copying live objects from source regions of the unavailable one. Once3089// the unavailable region becomes available, the data in the shadow region will be copied back.3090// Shadow regions are empty regions in the to-space and regions between top and end of other spaces.3091//3092// For more details, please refer to ยง4.2 of the VEE'19 paper:3093// Haoyu Li, Mingyu Wu, Binyu Zang, and Haibo Chen. 2019. ScissorGC: scalable and efficient3094// compaction for Java full garbage collection. In Proceedings of the 15th ACM SIGPLAN/SIGOPS3095// International Conference on Virtual Execution Environments (VEE 2019). ACM, New York, NY, USA,3096// 108-121. DOI: https://doi.org/10.1145/3313808.33138203097void PSParallelCompact::initialize_shadow_regions(uint parallel_gc_threads)3098{3099const ParallelCompactData& sd = PSParallelCompact::summary_data();31003101for (unsigned int id = old_space_id; id < last_space_id; ++id) {3102SpaceInfo* const space_info = _space_info + id;3103MutableSpace* const space = space_info->space();31043105const size_t beg_region =3106sd.addr_to_region_idx(sd.region_align_up(MAX2(space_info->new_top(), space->top())));3107const size_t end_region =3108sd.addr_to_region_idx(sd.region_align_down(space->end()));31093110for (size_t cur = beg_region; cur < end_region; ++cur) {3111ParCompactionManager::push_shadow_region(cur);3112}3113}31143115size_t beg_region = sd.addr_to_region_idx(_space_info[old_space_id].dense_prefix());3116for (uint i = 0; i < parallel_gc_threads; i++) {3117ParCompactionManager *cm = ParCompactionManager::gc_thread_compaction_manager(i);3118cm->set_next_shadow_region(beg_region + i);3119}3120}31213122void PSParallelCompact::fill_blocks(size_t region_idx)3123{3124// Fill in the block table elements for the specified region. Each block3125// table element holds the number of live words in the region that are to the3126// left of the first object that starts in the block. Thus only blocks in3127// which an object starts need to be filled.3128//3129// The algorithm scans the section of the bitmap that corresponds to the3130// region, keeping a running total of the live words. When an object start is3131// found, if it's the first to start in the block that contains it, the3132// current total is written to the block table element.3133const size_t Log2BlockSize = ParallelCompactData::Log2BlockSize;3134const size_t Log2RegionSize = ParallelCompactData::Log2RegionSize;3135const size_t RegionSize = ParallelCompactData::RegionSize;31363137ParallelCompactData& sd = summary_data();3138const size_t partial_obj_size = sd.region(region_idx)->partial_obj_size();3139if (partial_obj_size >= RegionSize) {3140return; // No objects start in this region.3141}31423143// Ensure the first loop iteration decides that the block has changed.3144size_t cur_block = sd.block_count();31453146const ParMarkBitMap* const bitmap = mark_bitmap();31473148const size_t Log2BitsPerBlock = Log2BlockSize - LogMinObjAlignment;3149assert((size_t)1 << Log2BitsPerBlock ==3150bitmap->words_to_bits(ParallelCompactData::BlockSize), "sanity");31513152size_t beg_bit = bitmap->words_to_bits(region_idx << Log2RegionSize);3153const size_t range_end = beg_bit + bitmap->words_to_bits(RegionSize);3154size_t live_bits = bitmap->words_to_bits(partial_obj_size);3155beg_bit = bitmap->find_obj_beg(beg_bit + live_bits, range_end);3156while (beg_bit < range_end) {3157const size_t new_block = beg_bit >> Log2BitsPerBlock;3158if (new_block != cur_block) {3159cur_block = new_block;3160sd.block(cur_block)->set_offset(bitmap->bits_to_words(live_bits));3161}31623163const size_t end_bit = bitmap->find_obj_end(beg_bit, range_end);3164if (end_bit < range_end - 1) {3165live_bits += end_bit - beg_bit + 1;3166beg_bit = bitmap->find_obj_beg(end_bit + 1, range_end);3167} else {3168return;3169}3170}3171}31723173ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()3174{3175if (source() != copy_destination()) {3176DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)3177Copy::aligned_conjoint_words(source(), copy_destination(), words_remaining());3178}3179update_state(words_remaining());3180assert(is_full(), "sanity");3181return ParMarkBitMap::full;3182}31833184void MoveAndUpdateClosure::copy_partial_obj()3185{3186size_t words = words_remaining();31873188HeapWord* const range_end = MIN2(source() + words, bitmap()->region_end());3189HeapWord* const end_addr = bitmap()->find_obj_end(source(), range_end);3190if (end_addr < range_end) {3191words = bitmap()->obj_size(source(), end_addr);3192}31933194// This test is necessary; if omitted, the pointer updates to a partial object3195// that crosses the dense prefix boundary could be overwritten.3196if (source() != copy_destination()) {3197DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)3198Copy::aligned_conjoint_words(source(), copy_destination(), words);3199}3200update_state(words);3201}32023203void MoveAndUpdateClosure::complete_region(ParCompactionManager *cm, HeapWord *dest_addr,3204PSParallelCompact::RegionData *region_ptr) {3205assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::NormalRegion, "Region should be finished");3206region_ptr->set_completed();3207}32083209ParMarkBitMapClosure::IterationStatus3210MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) {3211assert(destination() != NULL, "sanity");3212assert(bitmap()->obj_size(addr) == words, "bad size");32133214_source = addr;3215assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) ==3216destination(), "wrong destination");32173218if (words > words_remaining()) {3219return ParMarkBitMap::would_overflow;3220}32213222// The start_array must be updated even if the object is not moving.3223if (_start_array != NULL) {3224_start_array->allocate_block(destination());3225}32263227if (copy_destination() != source()) {3228DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());)3229Copy::aligned_conjoint_words(source(), copy_destination(), words);3230}32313232oop moved_oop = cast_to_oop(copy_destination());3233compaction_manager()->update_contents(moved_oop);3234assert(oopDesc::is_oop_or_null(moved_oop), "Expected an oop or NULL at " PTR_FORMAT, p2i(moved_oop));32353236update_state(words);3237assert(copy_destination() == cast_from_oop<HeapWord*>(moved_oop) + moved_oop->size(), "sanity");3238return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete;3239}32403241void MoveAndUpdateShadowClosure::complete_region(ParCompactionManager *cm, HeapWord *dest_addr,3242PSParallelCompact::RegionData *region_ptr) {3243assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::ShadowRegion, "Region should be shadow");3244// Record the shadow region index3245region_ptr->set_shadow_region(_shadow);3246// Mark the shadow region as filled to indicate the data is ready to be3247// copied back3248region_ptr->mark_filled();3249// Try to copy the content of the shadow region back to its corresponding3250// heap region if available; the GC thread that decreases the destination3251// count to zero will do the copying otherwise (see3252// PSParallelCompact::decrement_destination_counts).3253if (((region_ptr->available() && region_ptr->claim()) || region_ptr->claimed()) && region_ptr->mark_copied()) {3254region_ptr->set_completed();3255PSParallelCompact::copy_back(PSParallelCompact::summary_data().region_to_addr(_shadow), dest_addr);3256ParCompactionManager::push_shadow_region_mt_safe(_shadow);3257}3258}32593260UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm,3261ParCompactionManager* cm,3262PSParallelCompact::SpaceId space_id) :3263ParMarkBitMapClosure(mbm, cm),3264_space_id(space_id),3265_start_array(PSParallelCompact::start_array(space_id))3266{3267}32683269// Updates the references in the object to their new values.3270ParMarkBitMapClosure::IterationStatus3271UpdateOnlyClosure::do_addr(HeapWord* addr, size_t words) {3272do_addr(addr);3273return ParMarkBitMap::incomplete;3274}32753276FillClosure::FillClosure(ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) :3277ParMarkBitMapClosure(PSParallelCompact::mark_bitmap(), cm),3278_start_array(PSParallelCompact::start_array(space_id))3279{3280assert(space_id == PSParallelCompact::old_space_id,3281"cannot use FillClosure in the young gen");3282}32833284ParMarkBitMapClosure::IterationStatus3285FillClosure::do_addr(HeapWord* addr, size_t size) {3286CollectedHeap::fill_with_objects(addr, size);3287HeapWord* const end = addr + size;3288do {3289_start_array->allocate_block(addr);3290addr += cast_to_oop(addr)->size();3291} while (addr < end);3292return ParMarkBitMap::incomplete;3293}329432953296