Path: blob/master/runtime/gc_vlhgc/CompactGroupManager.hpp
5986 views
1/*******************************************************************************2* Copyright (c) 1991, 2014 IBM Corp. and others3*4* This program and the accompanying materials are made available under5* the terms of the Eclipse Public License 2.0 which accompanies this6* distribution and is available at https://www.eclipse.org/legal/epl-2.0/7* or the Apache License, Version 2.0 which accompanies this distribution and8* is available at https://www.apache.org/licenses/LICENSE-2.0.9*10* This Source Code may also be made available under the following11* Secondary Licenses when the conditions for such availability set12* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU13* General Public License, version 2 with the GNU Classpath14* Exception [1] and GNU General Public License, version 2 with the15* OpenJDK Assembly Exception [2].16*17* [1] https://www.gnu.org/software/classpath/license.html18* [2] http://openjdk.java.net/legal/assembly-exception.html19*20* 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-exception21*******************************************************************************/2223/**24* @file25* @ingroup GC_Modron_Tarok26*/2728#if !defined(COMPACTGROUPMANAGER_HPP_)29#define COMPACTGROUPMANAGER_HPP_3031#include "j9.h"32#include "j9cfg.h"3334#include "AllocationContextTarok.hpp"35#include "BaseNonVirtual.hpp"36#include "GCExtensions.hpp"37#include "GlobalAllocationManagerTarok.hpp"38#include "HeapRegionDescriptorVLHGC.hpp"394041class MM_CompactGroupManager : public MM_BaseNonVirtual42{43/* Data Members */44public:45protected:46private:4748/* Methods */49public:50/**51* Computes the 0-indexed compact group index for the receiver52* @param env[in] The thread53* @param age region age to compute compact group number for54* @param migrationDestination The context to consider for compact group number55* @return A 0-indexed value which can be used to look up the compact group if it were owned by migrationDestination56*/57MMINLINE static UDATA getCompactGroupNumberForAge(MM_EnvironmentVLHGC *env, UDATA age, MM_AllocationContextTarok *migrationDestination)58{59UDATA maxAge = MM_GCExtensions::getExtensions(env)->tarokRegionMaxAge;60Assert_MM_true(age <= maxAge);61UDATA contextNumber = migrationDestination->getAllocationContextNumber();62return (contextNumber * (maxAge + 1)) + age;63}6465/**66* Computes the 0-indexed compact group index for the receiver67* @param env[in] The thread68* @param region Region to compute the compact group number for.69* @param migrationDestination The context to consider for compact group number instead of the owning context of the given region70* @return A 0-indexed value which can be used to look up the region's compact group if it were owned by migrationDestination71*/72MMINLINE static UDATA getCompactGroupNumberInContext(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region, MM_AllocationContextTarok *migrationDestination)73{74return getCompactGroupNumberForAge(env, region->getLogicalAge(), migrationDestination);75}7677/**78* Computes the 0-indexed compact group index for the receiver79* @param env[in] The thread80* @param region Region to compute the compact group number for.81* @return A 0-indexed value which can be used to look up the regions compact group82*/83MMINLINE static UDATA getCompactGroupNumber(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)84{85return getCompactGroupNumberInContext(env, region, region->_allocateData._owningContext);86}8788/**89* Calculate the maximum index that can be returned for a compact group.90* @param env GC thread.91* @return a 0-indexed value which represents the maximum that can be returned as a compact group (duration of the system).92*/93MMINLINE static UDATA getCompactGroupMaxCount(MM_EnvironmentVLHGC *env)94{95MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);9697UDATA managedContextCount = MM_GlobalAllocationManagerTarok::calculateIdealManagedContextCount(extensions);98return (extensions->tarokRegionMaxAge + 1) * managedContextCount;99}100101/**102* Derive the allocation context number from the compact group number.103* @param env GC thread.104* @param compactGroupNumber the compact group number serving as the base.105* @return the allocation context number which comprises part of the compact group number.106*/107MMINLINE static UDATA getAllocationContextNumberFromGroup(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)108{109MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);110return compactGroupNumber / (extensions->tarokRegionMaxAge + 1);111}112113/**114* Derive the region age from the compact group number.115* @param env GC thread.116* @param compactGroupNumber the compact group number serving as the base.117* @return the region age which comprises part of the compact group number.118*/119MMINLINE static UDATA getRegionAgeFromGroup(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)120{121MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);122return compactGroupNumber % (extensions->tarokRegionMaxAge + 1);123}124125/**126* Calculate Logical age for region based on Allocation age127*128* Each next ages interval growth exponentially (specified-based)129* To avoid exponent/logarithm operations and as far as maximum logical age is a small constant (order of tens)130* it is safe to do calculation incrementally.131* Also it is easy to control possible overflow at each step of calculation and explicitly limit amount of work132*133* AgesIntervalSize(n+1) = AgesIntervalSize(n) * exponentBase;134* ThresholdForAge(n+1) = ThresholdForAge(n) + AgesIntervalSize(n+1);135*136* @param env current thread environment137* @param allocationAge for region138* @return calculated logical region age139*/140MMINLINE static UDATA calculateLogicalAgeForRegion(MM_EnvironmentVLHGC *env, U_64 allocationAge)141{142MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);143144U_64 unit = (U_64)extensions->tarokAllocationAgeUnit;145double exponentBase = extensions->tarokAllocationAgeExponentBase;146147Assert_MM_true(unit > 0);148Assert_MM_true(allocationAge <= extensions->tarokMaximumAgeInBytes);149150UDATA logicalAge = 0;151bool tooLarge = false;152153U_64 threshold = unit;154155while (!tooLarge && (threshold <= allocationAge)) {156unit = (U_64)(unit * exponentBase);157U_64 nextThreshold = threshold + unit;158159tooLarge = (nextThreshold < threshold) /* overflow */160|| (logicalAge >= extensions->tarokRegionMaxAge); /* maximum logical age reached */161162if (tooLarge) {163logicalAge = extensions->tarokRegionMaxAge;164} else {165threshold = nextThreshold;166logicalAge += 1;167}168}169170return logicalAge;171}172173/**174* Calculate initial value for maximum allocation age in bytes based on maximumLogicalAge175* @param env current thread environment176* @param maximumLogicalAge maximum logical age allocation age calculated for177*/178MMINLINE static U_64 calculateMaximumAllocationAge(MM_EnvironmentVLHGC *env, UDATA maximumLogicalAge)179{180MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);181U_64 unit = (U_64)extensions->tarokAllocationAgeUnit;182double exponentBase = extensions->tarokAllocationAgeExponentBase;183Assert_MM_true(unit > 0);184Assert_MM_true(maximumLogicalAge > 0);185UDATA logicalAge = 1;186bool tooLarge = false;187U_64 allocationAge = unit;188189while (!tooLarge && (logicalAge < maximumLogicalAge)) {190unit = (U_64)(unit * exponentBase);191U_64 nextThreshold = allocationAge + unit;192193tooLarge = (nextThreshold < allocationAge); /* overflow */194195if (tooLarge) {196allocationAge = U_64_MAX;197} else {198allocationAge = nextThreshold;199logicalAge += 1;200}201}202203return allocationAge;204}205206/**207* Check is given region is a member of Nursery Collection Set208* Eden region is mandatory part of Nursery Collection Set regardless it's age209* non-Eden region is part of Nursery Collection Set if it's age is lower or equal of nursery threshold210* @param env[in] The thread211* @param region given region212* @return true if region is a member of Nursery Collection Set213*/214MMINLINE static bool isRegionInNursery(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)215{216MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);217bool result = false;218219if (extensions->tarokAllocationAgeEnabled) {220result = region->isEden() || (region->getAllocationAge() <= extensions->tarokMaximumNurseryAgeInBytes);221} else {222result = region->isEden() || (region->getLogicalAge() <= extensions->tarokNurseryMaxAge._valueSpecified);223}224225return result;226}227228/**229* Check is given region is a DCSS candidate230* It is true if it is not a member of Nursery Collection Set and it's age has not reached maximum yet231* @param env[in] The thread232* @param region given region233* @return true if region is a DCSS candidate234*/235MMINLINE static bool isRegionDCSSCandidate(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)236{237MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);238bool result = false;239240if (extensions->tarokAllocationAgeEnabled) {241result = !isRegionInNursery(env, region) && (region->getAllocationAge() < extensions->tarokMaximumAgeInBytes);242} else {243result = !isRegionInNursery(env, region) && (region->getLogicalAge() < extensions->tarokRegionMaxAge);244}245246return result;247}248249/**250* Check is given Compact Group is a DCSS candidate251* It is true if it is not a member of Nursery Collection Set and it's age has not reached maximum yet252* @param env[in] The thread253* @param compactGroupNumber given compact group number254* @return true if region is a DCSS candidate255*/256MMINLINE static bool isCompactGroupDCSSCandidate(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)257{258MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);259bool result = false;260UDATA ageOfGroup = getRegionAgeFromGroup(env, compactGroupNumber);261262/*263* It is no special case for allocation-based aging system because264* tarokNurseryMaxAge and tarokRegionMaxAge were set at startup265*/266result = (ageOfGroup > extensions->tarokNurseryMaxAge._valueSpecified) && (ageOfGroup < extensions->tarokRegionMaxAge);267268return result;269}270271protected:272private:273MM_CompactGroupManager()274{275_typeId = __FUNCTION__;276}277278};279280#endif /* COMPACTGROUPMANAGER_HPP_ */281282283