Path: blob/master/runtime/gc_vlhgc/CollectionSetDelegate.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122/**23* @file24* @ingroup GC_Modron_Tarok25*/2627#include "j9.h"28#include "j9cfg.h"29#include "j9comp.h"30#include "j9port.h"31#include "gcutils.h"32#include "ModronAssertions.h"3334#include "AllocationContextTarok.hpp"35#include "CollectionSetDelegate.hpp"36#include "CompactGroupManager.hpp"37#include "CompactGroupPersistentStats.hpp"38#include "CycleState.hpp"39#include "EnvironmentVLHGC.hpp"40#include "GlobalAllocationManagerTarok.hpp"41#include "MemorySubSpace.hpp"42#include "HeapMapWordIterator.hpp"43#include "HeapRegionDescriptorVLHGC.hpp"44#include "HeapRegionIteratorVLHGC.hpp"45#include "HeapRegionManager.hpp"46#include "HeapRegionManagerTarok.hpp"47#include "MarkMap.hpp"48#include "MemoryPool.hpp"49#include "RegionValidator.hpp"5051MM_CollectionSetDelegate::MM_CollectionSetDelegate(MM_EnvironmentBase *env, MM_HeapRegionManager *manager)52: MM_BaseNonVirtual()53, _extensions(MM_GCExtensions::getExtensions(env))54, _regionManager(manager)55, _setSelectionDataTable(NULL)56, _dynamicSelectionList(NULL)57{58_typeId = __FUNCTION__;59}6061bool62MM_CollectionSetDelegate::initialize(MM_EnvironmentVLHGC *env)63{64if(_extensions->tarokEnableDynamicCollectionSetSelection) {65UDATA setSelectionEntryCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);66UDATA tableAllocationSizeInBytes = sizeof(SetSelectionData) * setSelectionEntryCount;67_setSelectionDataTable = (SetSelectionData *)env->getForge()->allocate(tableAllocationSizeInBytes, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());68if(NULL == _setSelectionDataTable) {69goto error_no_memory;70}71memset((void *)_setSelectionDataTable, 0, tableAllocationSizeInBytes);72for(UDATA index = 0; index < setSelectionEntryCount; index++) {73_setSelectionDataTable[index]._compactGroup = index;74}7576/* Publish table for TGC purposes */77_extensions->tarokTgcSetSelectionDataTable = (void *)_setSelectionDataTable;7879_dynamicSelectionList = (SetSelectionData **)env->getForge()->allocate(sizeof(SetSelectionData *) * setSelectionEntryCount, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());80if(NULL == _dynamicSelectionList) {81goto error_no_memory;82}83}8485return true;8687error_no_memory:88return false;89}9091void92MM_CollectionSetDelegate::tearDown(MM_EnvironmentVLHGC *env)93{94if(NULL != _setSelectionDataTable) {95env->getForge()->free(_setSelectionDataTable);96_setSelectionDataTable = NULL;97}9899if(NULL != _dynamicSelectionList) {100env->getForge()->free(_dynamicSelectionList);101_dynamicSelectionList = NULL;102}103}104105/**106* Helper function used by J9_SORT to sort rate of return element lists.107*/108static int109compareRateOfReturnScoreFunc(const void *element1, const void *element2)110{111MM_CollectionSetDelegate::SetSelectionData *ror1 = *(MM_CollectionSetDelegate::SetSelectionData **)element1;112MM_CollectionSetDelegate::SetSelectionData *ror2 = *(MM_CollectionSetDelegate::SetSelectionData **)element2;113114/* We actually do the checks instead of simple math (w/ multiplier) to catch slight differences. Perhaps if we multiply by 1000 then the differences are115* so minor it doesn't matter?116*/117if(ror1->_rateOfReturn == ror2->_rateOfReturn) {118return 0;119} else if(ror1->_rateOfReturn < ror2->_rateOfReturn ) {120return 1;121} else {122return -1;123}124}125126/**127* Helper function used by J9_SORT to sort core sample element lists.128*/129static int130compareCoreSampleScoreFunc(const void *element1, const void *element2)131{132MM_CollectionSetDelegate::SetSelectionData *coreSample1 = *(MM_CollectionSetDelegate::SetSelectionData **)element1;133MM_CollectionSetDelegate::SetSelectionData *coreSample2 = *(MM_CollectionSetDelegate::SetSelectionData **)element2;134135if(coreSample1->_regionCount == coreSample2->_regionCount) {136return 0;137} else if(coreSample1->_regionCount < coreSample2->_regionCount) {138return 1;139} else {140return -1;141}142}143144UDATA145MM_CollectionSetDelegate::createNurseryCollectionSet(MM_EnvironmentVLHGC *env)146{147bool dynamicCollectionSet = _extensions->tarokEnableDynamicCollectionSetSelection;148Trc_MM_CollectionSetDelegate_createNurseryCollectionSet_Entry(env->getLanguageVMThread(), dynamicCollectionSet ? "true" : "false");149Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);150151UDATA nurseryRegionCount = 0;152153/* Calculate the core "required" collection set for the Partial GC, which constitutes all regions that are equal to154* or below the nursery age.155*/156GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);157MM_HeapRegionDescriptorVLHGC *region = NULL;158while (NULL != (region = regionIterator.nextRegion())) {159Assert_MM_true(MM_RegionValidator(region).validate(env));160Assert_MM_false(region->_markData._shouldMark);161Assert_MM_false(region->_reclaimData._shouldReclaim);162if (region->containsObjects()) {163bool regionHasCriticalRegions = (0 != region->_criticalRegionsInUse);164bool isSelectionForCopyForward = env->_cycleState->_shouldRunCopyForward;165166/* We allow eden regions, which have jniCritical, to be part of nursery collectionSet; those regions would be marked instead of copyforwarded. */167if (region->getRememberedSetCardList()->isAccurate() && (!isSelectionForCopyForward || !regionHasCriticalRegions || (regionHasCriticalRegions && region->isEden()))) {168169if(MM_CompactGroupManager::isRegionInNursery(env, region)) {170UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);171/* on collection phase, mark all non-overflowed regions and those that RSCL is not being rebuilt */172/* sweep/compact flags are set in ReclaimDelegate */173region->_markData._shouldMark = true;174region->_reclaimData._shouldReclaim = true;175region->_compactData._shouldCompact = false;176/* Collected regions are no longer target for defragmentation until next GMP */177region->_defragmentationTarget = false;178_extensions->compactGroupPersistentStats[compactGroup]._regionsInRegionCollectionSetForPGC += 1;179nurseryRegionCount += 1;180} else {181Assert_MM_true(!region->isEden());182}183184/* Add the region to appropriate dynamic collection set data age group (building up information for later use) */185if(dynamicCollectionSet) {186UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);187_setSelectionDataTable[compactGroup].addRegion(region);188}189} else {190Assert_MM_true(!region->isEden());191}192}193}194195Trc_MM_CollectionSetDelegate_createNurseryCollectionSet_Exit(env->getLanguageVMThread(), nurseryRegionCount);196return nurseryRegionCount;197}198199UDATA200MM_CollectionSetDelegate::selectRegionsForBudget(MM_EnvironmentVLHGC *env, UDATA ageGroupBudget, SetSelectionData *setSelectionData)201{202Trc_MM_CollectionSetDelegate_selectRegionsForBudget_Entry(env->getLanguageVMThread(), ageGroupBudget);203UDATA ageGroupBudgetRemaining = ageGroupBudget;204UDATA regionSize = _regionManager->getRegionSize();205206/* Walk the rate of return age group using a remainder skip-system to select the appropriate % of regions to collect (based on budget) */207UDATA regionSelectionIndex = 0;208UDATA regionSelectionIncrement = ageGroupBudget;209UDATA regionSelectionThreshold = setSelectionData->_regionCount;210MM_HeapRegionDescriptorVLHGC *regionSelectionPtr = setSelectionData->_regionList;211while((0 != ageGroupBudgetRemaining) && (NULL != regionSelectionPtr)) {212regionSelectionIndex += regionSelectionIncrement;213if(regionSelectionIndex >= regionSelectionThreshold) {214/* The region is to be selected as part of the dynamic set */215regionSelectionPtr->_markData._shouldMark = true;216regionSelectionPtr->_reclaimData._shouldReclaim = true;217regionSelectionPtr->_compactData._shouldCompact = false;218/* Collected regions are no longer target for defragmentation until the next GMP */219regionSelectionPtr->_defragmentationTarget = false;220ageGroupBudgetRemaining -= 1;221222UDATA tableIndex = _regionManager->mapDescriptorToRegionTableIndex(regionSelectionPtr);223UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, regionSelectionPtr);224UDATA freeMemory = regionSelectionPtr->getMemoryPool()->getFreeMemoryAndDarkMatterBytes();225_extensions->compactGroupPersistentStats[compactGroup]._regionsInRegionCollectionSetForPGC += 1;226227Trc_MM_CollectionSetDelegate_selectRegionsForBudget(env->getLanguageVMThread(), tableIndex, compactGroup, (100 * freeMemory)/regionSize, (UDATA) 0, (UDATA) 0);228}229regionSelectionIndex %= regionSelectionThreshold;230231regionSelectionPtr = regionSelectionPtr->getDynamicSelectionNext();232}233234Assert_MM_true(ageGroupBudgetRemaining <= ageGroupBudget);235Trc_MM_CollectionSetDelegate_selectRegionsForBudget_Exit(env->getLanguageVMThread(), ageGroupBudget - ageGroupBudgetRemaining);236return ageGroupBudgetRemaining;237}238239void240MM_CollectionSetDelegate::createRateOfReturnCollectionSet(MM_EnvironmentVLHGC *env, UDATA nurseryRegionCount)241{242/* Build and sort the rate of return list into budget consumption priority order */243UDATA sortListSize = 0;244UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);245246for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {247if (MM_CompactGroupManager::isCompactGroupDCSSCandidate(env, compactGroup)) {248SetSelectionData *tableEntry = &_setSelectionDataTable[compactGroup];249if ((0.0 != tableEntry->_rateOfReturn) && (0 != tableEntry->_regionCount)) {250_dynamicSelectionList[sortListSize] = tableEntry;251sortListSize += 1;252}253}254}255256J9_SORT(_dynamicSelectionList, sortListSize, sizeof(SetSelectionData *), compareRateOfReturnScoreFunc);257258/* Walk the ROR priority list and select regions based on remaining available budget */259UDATA regionBudget = 0;260if(0 != _extensions->tarokDynamicCollectionSetSelectionAbsoluteBudget) {261regionBudget = _extensions->tarokDynamicCollectionSetSelectionAbsoluteBudget;262} else {263regionBudget = (UDATA)(nurseryRegionCount * _extensions->tarokDynamicCollectionSetSelectionPercentageBudget);264}265266Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelectionBudget(267env->getLanguageVMThread(),268nurseryRegionCount,269regionBudget270);271272UDATA rorIndex = 0;273while((0 != regionBudget) && (rorIndex < sortListSize)) {274SetSelectionData *rorEntry = _dynamicSelectionList[rorIndex];275276/* Determine the budget available for collection in the current compact group */277UDATA compactGroupBudget = (UDATA)( ((double)regionBudget) * rorEntry->_rateOfReturn );278Assert_MM_true(compactGroupBudget <= regionBudget);279compactGroupBudget = OMR_MIN(compactGroupBudget, rorEntry->_regionCount);280281UDATA compactGroupBudgetRemaining = 0;282283if(compactGroupBudget > 0) {284/* The age group is participating in dynamic set selection */285rorEntry->_dynamicSelectionThisCycle = true;286287compactGroupBudgetRemaining = selectRegionsForBudget(env, compactGroupBudget, rorEntry);288}289290/* Deduct the age group budget used from the overall budget */291Assert_MM_true(compactGroupBudget >= compactGroupBudgetRemaining);292UDATA budgetConsumed = compactGroupBudget - compactGroupBudgetRemaining;293Assert_MM_true(regionBudget >= budgetConsumed);294regionBudget -= budgetConsumed;295296Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelection(297env->getLanguageVMThread(),298rorEntry->_compactGroup,299rorEntry->_regionCount,3001000.0 * rorEntry->_rateOfReturn,301compactGroupBudget,302budgetConsumed303);304305/* Move to the next ROR entry */306rorIndex += 1;307}308Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_dynamicRegionSelectionBudgetRemaining(309env->getLanguageVMThread(),310regionBudget311);312}313314void315MM_CollectionSetDelegate::createCoreSamplingCollectionSet(MM_EnvironmentVLHGC *env, UDATA nurseryRegionCount)316{317/* Collect and sort all regions into the core sample buckets so that we can find them quickly (this is an optimization) */318UDATA totalCoreSampleRegions = 0;319UDATA sortListSize = 0;320UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);321322for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {323if (MM_CompactGroupManager::isCompactGroupDCSSCandidate(env, compactGroup)) {324SetSelectionData *tableEntry = &_setSelectionDataTable[compactGroup];325if (!tableEntry->_dynamicSelectionThisCycle && (0 != tableEntry->_regionCount)) {326/* The region is a collection candidate and eligible for dynamic selection - count it as part of the total possible core sampling group */327totalCoreSampleRegions += tableEntry->_regionCount;328_dynamicSelectionList[sortListSize] = tableEntry;329sortListSize += 1;330}331}332}333334J9_SORT(_dynamicSelectionList, sortListSize, sizeof(SetSelectionData *), compareCoreSampleScoreFunc);335336/* Given a region budget, select regions for core sampling according to population and whether the age group has participated in other337* dynamically added activities.338*/339UDATA regionBudget = 0;340if(0 != _extensions->tarokCoreSamplingAbsoluteBudget) {341regionBudget = _extensions->tarokCoreSamplingAbsoluteBudget;342} else {343regionBudget = (UDATA)(nurseryRegionCount * _extensions->tarokCoreSamplingPercentageBudget);344}345346Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingBudget(347env->getLanguageVMThread(),348totalCoreSampleRegions,349regionBudget350);351352UDATA coreSampleIndex = 0;353while((regionBudget != 0) && (coreSampleIndex < sortListSize)) {354SetSelectionData *coreSample = _dynamicSelectionList[coreSampleIndex];355UDATA compactGroup = coreSample->_compactGroup;356357Assert_MM_true(!_setSelectionDataTable[compactGroup]._dynamicSelectionThisCycle);358359/* Determine the budget available for collection in the current compact group */360Assert_MM_true(totalCoreSampleRegions > 0);361UDATA compactGroupBudget = (UDATA) (((double)regionBudget) * ((double)coreSample->_regionCount) / ((double)totalCoreSampleRegions));362Assert_MM_true(compactGroupBudget <= regionBudget);363compactGroupBudget = OMR_MIN(compactGroupBudget, coreSample->_regionCount);364/* Want at least one region out of this */365compactGroupBudget = OMR_MAX(compactGroupBudget, 1);366367UDATA compactGroupBudgetRemaining = 0;368369if(compactGroupBudget > 0) {370compactGroupBudgetRemaining = selectRegionsForBudget(env, compactGroupBudget, coreSample);371}372373/* Deduct the compact group budget used from the overall budget */374Assert_MM_true(compactGroupBudget >= compactGroupBudgetRemaining);375UDATA budgetConsumed = compactGroupBudget - compactGroupBudgetRemaining;376Assert_MM_true(regionBudget >= budgetConsumed);377regionBudget -= budgetConsumed;378379Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingSelection(380env->getLanguageVMThread(),381compactGroup,382coreSample->_regionCount,383compactGroupBudget,384budgetConsumed385);386387coreSampleIndex += 1;388}389390Trc_MM_CollectionSetDelegate_createRegionCollectionSetForPartialGC_coreSamplingBudgetRemaining(391env->getLanguageVMThread(),392regionBudget393);394}395396397void398MM_CollectionSetDelegate::createRegionCollectionSetForPartialGC(MM_EnvironmentVLHGC *env)399{400Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);401402bool dynamicCollectionSet = _extensions->tarokEnableDynamicCollectionSetSelection;403404/* If dynamic collection sets are enabled, reset all related data structures that are used for selection */405if(dynamicCollectionSet) {406MM_CompactGroupPersistentStats *persistentStats = _extensions->compactGroupPersistentStats;407UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);408409for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {410Assert_MM_true(compactGroup == _setSelectionDataTable[compactGroup]._compactGroup);411_setSelectionDataTable[compactGroup]._regionCount = 0;412_setSelectionDataTable[compactGroup]._regionList = NULL;413/* cache the survival rate in this table since we sort based on rate of return (1-survival) */414/* survival rate can be more than 100% if the compact group is being used as a migration target due to NUMA proximity */415double survivalRate = OMR_MIN(1.0, persistentStats[compactGroup]._historicalSurvivalRate);416_setSelectionDataTable[compactGroup]._rateOfReturn = (1.0 - survivalRate);417_setSelectionDataTable[compactGroup]._dynamicSelectionThisCycle = false;418}419}420421UDATA nurseryRegionCount = createNurseryCollectionSet(env);422423424/* Add any non-nursery regions to the collection set as the rate-of-return and region budget dictates */425if(dynamicCollectionSet) {426createRateOfReturnCollectionSet(env, nurseryRegionCount);427createCoreSamplingCollectionSet(env, nurseryRegionCount);428429/* Clean up any linkage data that was computed during set selection but will potentially become stale over the course of the run */430431/* Reset base region counts and lists */432UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);433434for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {435_setSelectionDataTable[compactGroup]._regionCount = 0;436_setSelectionDataTable[compactGroup]._regionList = NULL;437}438439/* Clean list linkage between all regions (age group lists) */440GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);441MM_HeapRegionDescriptorVLHGC *region = NULL;442while (NULL != (region = regionIterator.nextRegion())) {443region->setDynamicSelectionNext(NULL);444}445}446}447448void449MM_CollectionSetDelegate::deleteRegionCollectionSetForPartialGC(MM_EnvironmentVLHGC *env)450{451Assert_MM_true(MM_CycleState::CT_PARTIAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);452453GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);454MM_HeapRegionDescriptorVLHGC *region = NULL;455while (NULL != (region = regionIterator.nextRegion())) {456/* there shouldn't be any regions that have some occupancy but not marked left if the increment is done */457Assert_MM_false(MM_HeapRegionDescriptor::ADDRESS_ORDERED == region->getRegionType());458Assert_MM_true(MM_RegionValidator(region).validate(env));459460region->_markData._shouldMark = false;461region->_reclaimData._shouldReclaim = false;462region->_markData._noEvacuation = false;463}464}465466void467MM_CollectionSetDelegate::createRegionCollectionSetForGlobalGC(MM_EnvironmentVLHGC *env)468{469Assert_MM_true(MM_CycleState::CT_GLOBAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);470471GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::MANAGED);472MM_HeapRegionDescriptorVLHGC *region = NULL;473while (NULL != (region = regionIterator.nextRegion())) {474Assert_MM_true(MM_RegionValidator(region).validate(env));475Assert_MM_false(region->_reclaimData._shouldReclaim);476if (region->containsObjects()) {477region->_reclaimData._shouldReclaim = true;478region->_compactData._shouldCompact = false;479}480}481}482483void484MM_CollectionSetDelegate::deleteRegionCollectionSetForGlobalGC(MM_EnvironmentVLHGC *env)485{486Assert_MM_true(MM_CycleState::CT_GLOBAL_GARBAGE_COLLECTION == env->_cycleState->_collectionType);487488GC_HeapRegionIteratorVLHGC regionIterator(_regionManager);489MM_HeapRegionDescriptorVLHGC *region = NULL;490while (NULL != (region = regionIterator.nextRegion())) {491/* there shouldn't be any regions that have some occupancy but not marked left */492Assert_MM_false(MM_HeapRegionDescriptor::ADDRESS_ORDERED == region->getRegionType());493Assert_MM_true(MM_RegionValidator(region).validate(env));494495region->_reclaimData._shouldReclaim = false;496}497}498499MM_HeapRegionDescriptorVLHGC*500MM_CollectionSetDelegate::getNextRegion(MM_HeapRegionDescriptorVLHGC* cursor)501{502MM_HeapRegionDescriptorVLHGC* result = cursor;503if (NULL != result) {504result = (MM_HeapRegionDescriptorVLHGC*)_regionManager->getNextTableRegion(result);505}506if (NULL == result) {507result = (MM_HeapRegionDescriptorVLHGC*)_regionManager->getFirstTableRegion();508}509Assert_MM_true(NULL != result);510return result;511}512513void514MM_CollectionSetDelegate::rateOfReturnCalculationBeforeSweep(MM_EnvironmentVLHGC *env)515{516if(_extensions->tarokEnableDynamicCollectionSetSelection) {517UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);518for (UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {519/* Clear the current trace reclaim rate table information as we'll be building a new set */520_setSelectionDataTable[compactGroup]._reclaimStats.reset();521}522523/* Walk and count all regions, and count any region that will be included in the sweep set (those in trace or those that require re-sweeping due to a GMP) */524GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::ALL);525MM_HeapRegionDescriptorVLHGC *region = NULL;526while (NULL != (region = regionIterator.nextRegion())) {527if(region->containsObjects()) {528SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, region)];529MM_MemoryPool *memoryPool = region->getMemoryPool();530531stats->_reclaimStats._regionCountBefore += 1;532if(!region->_sweepData._alreadySwept) {533stats->_reclaimStats._reclaimableRegionCountBefore += 1;534535stats->_reclaimStats._regionBytesFreeBefore += memoryPool->getActualFreeMemorySize();536stats->_reclaimStats._regionDarkMatterBefore += memoryPool->getDarkMatterBytes();537}538if(!region->getRememberedSetCardList()->isAccurate()) {539stats->_reclaimStats._regionCountOverflow += 1;540}541} else if(region->isArrayletLeaf()) {542MM_HeapRegionDescriptorVLHGC *parentRegion = (MM_HeapRegionDescriptorVLHGC *)_regionManager->regionDescriptorForAddress((void *)region->_allocateData.getSpine());543Assert_MM_true(parentRegion->containsObjects());544SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, parentRegion)];545546stats->_reclaimStats._regionCountBefore += 1;547stats->_reclaimStats._regionCountArrayletLeafBefore += 1;548549if(!parentRegion->_sweepData._alreadySwept) {550stats->_reclaimStats._reclaimableRegionCountBefore += 1;551stats->_reclaimStats._reclaimableRegionCountArrayletLeafBefore += 1;552}553if(!parentRegion->getRememberedSetCardList()->isAccurate()) {554stats->_reclaimStats._regionCountArrayletLeafOverflow += 1;555}556}557}558}559}560561void562MM_CollectionSetDelegate::rateOfReturnCalculationAfterSweep(MM_EnvironmentVLHGC *env)563{564if(_extensions->tarokEnableDynamicCollectionSetSelection) {565/* Walk and count all regions */566GC_HeapRegionIteratorVLHGC regionIterator(_regionManager, MM_HeapRegionDescriptor::ALL);567MM_HeapRegionDescriptorVLHGC *region = NULL;568while (NULL != (region = regionIterator.nextRegion())) {569if(region->containsObjects()) {570UDATA compactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);571SetSelectionData *stats = &_setSelectionDataTable[compactGroup];572MM_MemoryPool *memoryPool = region->getMemoryPool();573574stats->_reclaimStats._regionCountAfter += 1;575576if(!region->_sweepData._alreadySwept) {577stats->_reclaimStats._reclaimableRegionCountAfter += 1;578579stats->_reclaimStats._regionBytesFreeAfter += memoryPool->getActualFreeMemorySize();580stats->_reclaimStats._regionDarkMatterAfter += memoryPool->getDarkMatterBytes();581}582} else if(region->isArrayletLeaf()) {583MM_HeapRegionDescriptorVLHGC *parentRegion = (MM_HeapRegionDescriptorVLHGC *)_regionManager->regionDescriptorForAddress((void *)region->_allocateData.getSpine());584Assert_MM_true(parentRegion->containsObjects());585SetSelectionData *stats = &_setSelectionDataTable[MM_CompactGroupManager::getCompactGroupNumber(env, parentRegion)];586587stats->_reclaimStats._regionCountAfter += 1;588stats->_reclaimStats._regionCountArrayletLeafAfter += 1;589590if(!parentRegion->_sweepData._alreadySwept) {591stats->_reclaimStats._reclaimableRegionCountAfter += 1;592stats->_reclaimStats._reclaimableRegionCountArrayletLeafAfter += 1;593}594}595}596597/* We now have an expected change as a result of tracing and sweeping (parts of) the heap. Calculate the rate-of-return (ROR) on598* tracing for age groups where work was done.599* Use a weighted running average to calculate the ROR, where the weight is the % of regions in an age group that we are examining.600* NOTE: We leave the ROR for the last age group as 0.601*/602UDATA compactGroupCount = MM_CompactGroupManager::getCompactGroupMaxCount(env);603604for(UDATA compactGroup = 0; compactGroup < compactGroupCount; compactGroup++) {605if (MM_CompactGroupManager::getRegionAgeFromGroup(env, compactGroup) < _extensions->tarokRegionMaxAge) {606/* We set the compact group for each entry every time through a table. This is overkill, but allows us to be sure when examining a ROR element whether607* in fact it represents the compact group with think it does.608*/609SetSelectionData *stats = &_setSelectionDataTable[compactGroup];610stats->_compactGroup = compactGroup;611612if(0 == stats->_reclaimStats._reclaimableRegionCountBefore) {613Assert_MM_true(stats->_reclaimStats._regionCountBefore == stats->_reclaimStats._regionCountAfter);614} else {615Assert_MM_true(stats->_reclaimStats._regionCountBefore >= stats->_reclaimStats._reclaimableRegionCountBefore);616Assert_MM_true(stats->_reclaimStats._regionCountBefore >= stats->_reclaimStats._regionCountAfter);617Assert_MM_true(stats->_reclaimStats._reclaimableRegionCountBefore >= stats->_reclaimStats._reclaimableRegionCountAfter);618619UDATA bytesConsumedBefore =620(stats->_reclaimStats._reclaimableRegionCountBefore * _extensions->regionSize)621- stats->_reclaimStats._regionBytesFreeBefore622- stats->_reclaimStats._regionDarkMatterBefore;623stats->_reclaimStats._reclaimableBytesConsumedBefore = bytesConsumedBefore;624UDATA bytesConsumedAfter =625(stats->_reclaimStats._reclaimableRegionCountAfter * _extensions->regionSize)626- stats->_reclaimStats._regionBytesFreeAfter627- stats->_reclaimStats._regionDarkMatterAfter;628stats->_reclaimStats._reclaimableBytesConsumedAfter = bytesConsumedAfter;629}630}631}632}633}634635636