Path: blob/master/runtime/gc_glue_java/ConfigurationDelegate.hpp
5990 views
/*******************************************************************************1* Copyright (c) 2017, 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#ifndef CONFIGURATIONDELEGATE_HPP_23#define CONFIGURATIONDELEGATE_HPP_2425#include "j9.h"26#include "j9cfg.h"27#include "j9consts.h"28#include "j9nonbuilder.h"29#include "omrgcconsts.h"30#include "sizeclasses.h"3132#include "ClassLoaderManager.hpp"33#include "ConcurrentGC.hpp"34#include "EnvironmentBase.hpp"35#include "GCExtensions.hpp"36#include "GlobalAllocationManager.hpp"37#include "Heap.hpp"38#include "HeapRegionDescriptor.hpp"39#include "HeapRegionManager.hpp"40#include "ObjectAccessBarrier.hpp"41#include "ObjectAllocationInterface.hpp"42#include "StringTable.hpp"4344#include "OwnableSynchronizerObjectList.hpp"45#include "ReferenceObjectList.hpp"46#include "UnfinalizedObjectList.hpp"4748typedef struct MM_HeapRegionDescriptorStandardExtension {49uintptr_t _maxListIndex; /**< Max index for _*ObjectLists[index] */50MM_UnfinalizedObjectList *_unfinalizedObjectLists; /**< An array of lists of unfinalized objects in this region */51MM_OwnableSynchronizerObjectList *_ownableSynchronizerObjectLists; /**< An array of lists of ownable synchronizer objects in this region */52MM_ReferenceObjectList *_referenceObjectLists; /**< An array of lists of reference objects (i.e. weak/soft/phantom) in this region */53} MM_HeapRegionDescriptorStandardExtension;5455class MM_ConfigurationDelegate56{57/*58* Member data and types59*/60private:61static const uintptr_t _maximumDefaultNumberOfGCThreads = 64;62const MM_GCPolicy _gcPolicy;6364protected:65public:6667/*68* Member functions69*/70private:71protected:7273public:74bool75initialize(MM_EnvironmentBase* env, MM_GCWriteBarrierType writeBarrierType, MM_GCAllocationType allocationType)76{77/* sync J9 VM arraylet size with OMR VM */78OMR_VM* omrVM = env->getOmrVM();79J9JavaVM* javaVM = (J9JavaVM*)omrVM->_language_vm;80javaVM->arrayletLeafSize = omrVM->_arrayletLeafSize;81javaVM->arrayletLeafLogSize = omrVM->_arrayletLeafLogSize;8283/* set write barrier for J9 VM -- catch -Xgc:alwayscallwritebarrier first */84MM_GCExtensions* extensions = MM_GCExtensions::getExtensions(javaVM);85if (extensions->alwaysCallWriteBarrier) {86writeBarrierType = gc_modron_wrtbar_always;87}8889Assert_MM_true(gc_modron_wrtbar_illegal != writeBarrierType);90javaVM->gcWriteBarrierType = writeBarrierType;9192if (extensions->alwaysCallReadBarrier) {93/* AlwaysCallReadBarrier takes precedence over other read barrier types */94javaVM->gcReadBarrierType = gc_modron_readbar_always;95} else if (extensions->isScavengerEnabled() && extensions->isConcurrentScavengerEnabled()) {96javaVM->gcReadBarrierType = gc_modron_readbar_range_check;97} else if (extensions->isVLHGC() && extensions->isConcurrentCopyForwardEnabled()) {98javaVM->gcReadBarrierType = gc_modron_readbar_region_check;99} else {100javaVM->gcReadBarrierType = gc_modron_readbar_none;101}102103/* set allocation type for J9 VM */104javaVM->gcAllocationType = allocationType;105106if (!extensions->dynamicClassUnloadingSet) {107extensions->dynamicClassUnloading = MM_GCExtensions::DYNAMIC_CLASS_UNLOADING_ON_CLASS_LOADER_CHANGES;108}109110/* Enable string constant collection by default if we support class unloading */111extensions->collectStringConstants = true;112113/*114* note that these are the default thresholds but Realtime Configurations override these values, in their initialize methods115* (hence it is key for them to call their super initialize, first)116*/117#define DYNAMIC_CLASS_UNLOADING_THRESHOLD 6118#define DYNAMIC_CLASS_UNLOADING_KICKOFF_THRESHOLD 80000119120if (!extensions->dynamicClassUnloadingThresholdForced) {121extensions->dynamicClassUnloadingThreshold = DYNAMIC_CLASS_UNLOADING_THRESHOLD;122}123if (!extensions->dynamicClassUnloadingKickoffThresholdForced) {124extensions->dynamicClassUnloadingKickoffThreshold = DYNAMIC_CLASS_UNLOADING_KICKOFF_THRESHOLD;125}126return true;127}128129void130tearDown(MM_EnvironmentBase* env)131{132J9JavaVM* vm = (J9JavaVM*)env->getOmrVM()->_language_vm;133MM_GCExtensions* extensions = MM_GCExtensions::getExtensions(env);134135if (NULL != vm->identityHashData) {136env->getForge()->free(vm->identityHashData);137vm->identityHashData = NULL;138}139140if (NULL != extensions->classLoaderManager) {141extensions->classLoaderManager->kill(env);142extensions->classLoaderManager = NULL;143}144145if (NULL != extensions->stringTable) {146extensions->stringTable->kill(env);147extensions->stringTable = NULL;148}149}150151OMR_SizeClasses *getSegregatedSizeClasses(MM_EnvironmentBase* env)152{153J9JavaVM* javaVM = (J9JavaVM*)env->getOmrVM()->_language_vm;154return (OMR_SizeClasses*)(javaVM->realtimeSizeClasses);155}156157static MM_HeapRegionDescriptorStandardExtension *158getHeapRegionDescriptorStandardExtension(MM_EnvironmentBase* env, MM_HeapRegionDescriptor *region)159{160MM_HeapRegionDescriptorStandardExtension *regionExtension = NULL;161if (env->getExtensions()->isStandardGC()) {162regionExtension = (MM_HeapRegionDescriptorStandardExtension *)region->_heapRegionDescriptorExtension;163}164return regionExtension;165}166167bool168initializeHeapRegionDescriptorExtension(MM_EnvironmentBase* env, MM_HeapRegionDescriptor *region)169{170MM_GCExtensions* extensions = MM_GCExtensions::getExtensions(env);171172if (extensions->isStandardGC()) {173uintptr_t listCount = extensions->gcThreadCount;174uintptr_t allocSize = sizeof(MM_HeapRegionDescriptorStandardExtension) + (listCount * (sizeof(MM_UnfinalizedObjectList) + sizeof(MM_OwnableSynchronizerObjectList) + sizeof(MM_ReferenceObjectList)));175MM_HeapRegionDescriptorStandardExtension *regionExtension = (MM_HeapRegionDescriptorStandardExtension *)env->getForge()->allocate(allocSize, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());176if (NULL == regionExtension) {177return false;178}179180regionExtension->_maxListIndex = listCount;181regionExtension->_unfinalizedObjectLists = (MM_UnfinalizedObjectList *) ((uintptr_t)regionExtension + sizeof(MM_HeapRegionDescriptorStandardExtension));182regionExtension->_ownableSynchronizerObjectLists = (MM_OwnableSynchronizerObjectList *) (regionExtension->_unfinalizedObjectLists + listCount);183regionExtension->_referenceObjectLists = (MM_ReferenceObjectList *) (regionExtension->_ownableSynchronizerObjectLists + listCount);184185for (uintptr_t list = 0; list < listCount; list++) {186new(®ionExtension->_unfinalizedObjectLists[list]) MM_UnfinalizedObjectList();187regionExtension->_unfinalizedObjectLists[list].setNextList(extensions->unfinalizedObjectLists);188regionExtension->_unfinalizedObjectLists[list].setPreviousList(NULL);189if (NULL != extensions->unfinalizedObjectLists) {190extensions->unfinalizedObjectLists->setPreviousList(®ionExtension->_unfinalizedObjectLists[list]);191}192extensions->unfinalizedObjectLists = ®ionExtension->_unfinalizedObjectLists[list];193194new(®ionExtension->_ownableSynchronizerObjectLists[list]) MM_OwnableSynchronizerObjectList();195regionExtension->_ownableSynchronizerObjectLists[list].setNextList(extensions->getOwnableSynchronizerObjectLists());196regionExtension->_ownableSynchronizerObjectLists[list].setPreviousList(NULL);197if (NULL != extensions->getOwnableSynchronizerObjectLists()) {198extensions->getOwnableSynchronizerObjectLists()->setPreviousList(®ionExtension->_ownableSynchronizerObjectLists[list]);199}200extensions->setOwnableSynchronizerObjectLists(®ionExtension->_ownableSynchronizerObjectLists[list]);201202new(®ionExtension->_referenceObjectLists[list]) MM_ReferenceObjectList();203}204205region->_heapRegionDescriptorExtension = regionExtension;206}207208return true;209}210211void212teardownHeapRegionDescriptorExtension(MM_EnvironmentBase* env, MM_HeapRegionDescriptor *region)213{214if (env->getExtensions()->isStandardGC()) {215if (NULL != region->_heapRegionDescriptorExtension) {216env->getForge()->free(region->_heapRegionDescriptorExtension);217region->_heapRegionDescriptorExtension = NULL;218}219}220}221222bool223heapInitialized(MM_EnvironmentBase* env)224{225MM_Heap *heap = env->getExtensions()->getHeap();226MM_HeapRegionManager *heapRegionManager = heap->getHeapRegionManager();227228uintptr_t hashSaltCount = 0;229uintptr_t hashSaltPolicy = J9_IDENTITY_HASH_SALT_POLICY_NONE;230231switch (_gcPolicy) {232case gc_policy_optthruput:233case gc_policy_nogc:234case gc_policy_optavgpause:235case gc_policy_gencon:236hashSaltCount = 1;237hashSaltPolicy = J9_IDENTITY_HASH_SALT_POLICY_STANDARD;238break;239case gc_policy_metronome:240break;241case gc_policy_balanced:242hashSaltCount = heapRegionManager->getTableRegionCount();243hashSaltPolicy = J9_IDENTITY_HASH_SALT_POLICY_REGION;244break;245default:246Assert_MM_unreachable();247break;248}249250J9JavaVM* javaVM = (J9JavaVM*)env->getOmrVM()->_language_vm;251uintptr_t size = offsetof(J9IdentityHashData, hashSaltTable) + (sizeof(U_32) * hashSaltCount);252javaVM->identityHashData = (J9IdentityHashData*)env->getForge()->allocate(size, MM_AllocationCategory::FIXED, J9_GET_CALLSITE());253bool result = NULL != javaVM->identityHashData;254if (result) {255J9IdentityHashData* hashData = javaVM->identityHashData;256hashData->hashData1 = UDATA_MAX;257hashData->hashData2 = 0;258hashData->hashData3 = 0;259hashData->hashData4 = 0;260hashData->hashSaltPolicy = hashSaltPolicy;261switch (hashSaltPolicy) {262case J9_IDENTITY_HASH_SALT_POLICY_NONE:263break;264case J9_IDENTITY_HASH_SALT_POLICY_STANDARD:265javaVM->identityHashData->hashSaltTable[J9GC_HASH_SALT_NURSERY_INDEX] = (U_32)convertValueToHash(javaVM, 1421595292 ^ (U_32)(uintptr_t)javaVM);266break;267case J9_IDENTITY_HASH_SALT_POLICY_REGION:268for (uintptr_t index = 0; index < hashSaltCount; index++) {269javaVM->identityHashData->hashSaltTable[index] = (U_32)convertValueToHash(javaVM, 1421595292 ^ (U_32)(uintptr_t)heapRegionManager->physicalTableDescriptorForIndex(index));270}271hashData->hashData1 = (uintptr_t)heap->getHeapBase();272hashData->hashData2 = (uintptr_t)heap->getHeapTop();273hashData->hashData3 = heapRegionManager->getRegionShift();274hashData->hashData4 = hashSaltCount;275break;276default:277result = false;278break;279}280}281return result;282}283284uint32_t285getInitialNumberOfPooledEnvironments(MM_EnvironmentBase* env)286{287return 0;288}289290bool291environmentInitialized(MM_EnvironmentBase* env)292{293MM_GCExtensions* extensions = MM_GCExtensions::getExtensions(env);294J9VMThread* vmThread = (J9VMThread *)env->getLanguageVMThread();295OMR_VM *omrVM = env->getOmrVM();296297/* only assign this parent list if we are going to use it */298if (extensions->isStandardGC()) {299vmThread->gcRememberedSet.parentList = &extensions->rememberedSet;300}301302extensions->accessBarrier->initializeForNewThread(env);303304if ((extensions->isConcurrentMarkEnabled()) && (!extensions->usingSATBBarrier())) {305#if defined(OMR_GC_MODRON_CONCURRENT_MARK)306vmThread->cardTableVirtualStart = (U_8*)j9gc_incrementalUpdate_getCardTableVirtualStart(omrVM);307vmThread->cardTableShiftSize = j9gc_incrementalUpdate_getCardTableShiftValue(omrVM);308MM_ConcurrentGC *concurrentGC = (MM_ConcurrentGC *)extensions->getGlobalCollector();309if (!extensions->optimizeConcurrentWB || (CONCURRENT_OFF < concurrentGC->getConcurrentGCStats()->getExecutionMode())) {310vmThread->privateFlags |= J9_PRIVATE_FLAGS_CONCURRENT_MARK_ACTIVE;311}312#else313Assert_MM_unreachable();314#endif /* OMR_GC_MODRON_CONCURRENT_MARK */315} else if (extensions->isVLHGC()) {316#if defined(OMR_GC_VLHGC)317vmThread->cardTableVirtualStart = (U_8 *)j9gc_incrementalUpdate_getCardTableVirtualStart(omrVM);318vmThread->cardTableShiftSize = j9gc_incrementalUpdate_getCardTableShiftValue(omrVM);319#else320Assert_MM_unreachable();321#endif /* OMR_GC_VLHGC */322} else {323vmThread->cardTableVirtualStart = (U_8*)NULL;324vmThread->cardTableShiftSize = 0;325}326327if (extensions->fvtest_disableInlineAllocation) {328env->_objectAllocationInterface->disableCachedAllocations(env);329}330331return true;332}333334bool canCollectFragmentationStats(MM_EnvironmentBase *env)335{336J9JavaVM* javaVM = (J9JavaVM*)env->getOmrVM()->_language_vm;337/* processing estimate Fragmentation only is on non startup stage to avoid startup regression(fragmentation during startup is not meaningful for the estimation)338it is only for jit mode(for int mode javaVM->phase is always J9VM_PHASE_NOT_STARTUP) */339return (J9VM_PHASE_NOT_STARTUP == javaVM->phase);340}341342uintptr_t getMaxGCThreadCount(MM_EnvironmentBase* env)343{344return _maximumDefaultNumberOfGCThreads;345}346347MM_GCPolicy getGCPolicy() { return _gcPolicy; }348349/**350* Constructor.351*/352MM_ConfigurationDelegate(MM_GCPolicy gcPolicy)353: _gcPolicy(gcPolicy)354{}355};356357#endif /* CONFIGURATIONDELEGATE_HPP_ */358359360