Path: blob/master/runtime/gc_realtime/ConfigurationRealtime.cpp
5985 views
/*******************************************************************************1* Copyright (c) 1991, 2020 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_Metronome25*/2627#include "omr.h"28#include "omrcfg.h"2930#include "ConfigurationRealtime.hpp"3132#include "EnvironmentRealtime.hpp"33#include "GlobalAllocationManagerRealtime.hpp"34#include "GCExtensionsBase.hpp"35#include "HeapVirtualMemory.hpp"36#include "HeapRegionDescriptorRealtime.hpp"37#include "HeapRegionManagerTarok.hpp"38#include "MemoryPoolSegregated.hpp"39#include "MemorySpace.hpp"40#include "MemorySubSpaceMetronome.hpp"41#include "PhysicalArenaRegionBased.hpp"42#include "PhysicalSubArenaRegionBased.hpp"43#include "RealtimeGC.hpp"44#include "RegionPoolSegregated.hpp"45#include "Scheduler.hpp"46#include "SizeClasses.hpp"4748#define REALTIME_REGION_SIZE_BYTES 64 * 10244950/* Define realtime arraylet leaf size as the largest small size class we can have */51#define REALTIME_ARRAYLET_LEAF_SIZE_BYTES J9VMGC_SIZECLASSES_MAX_SMALL_SIZE_BYTES5253#define J9GC_HASH_SALT_COUNT_METRONOME 15455class MM_MemoryPoolSegregated;5657bool58MM_ConfigurationRealtime::initialize(MM_EnvironmentBase *env)59{60MM_GCExtensionsBase *extensions = env->getExtensions();6162bool success = false;63if (MM_Configuration::initialize(env)) {64/*65* The split available lists are populated during sweep by GC threads,66* each worker inserts into its corresponding split list as it finishes sweeping a region,67* which also removes the contention when inserting to a global list.68* So the split count equals the number of gc threads.69* NOTE: The split available list mechanism assumes the worker IDs are in the range of [0, gcThreadCount-1].70* This is currently the case, as _statusTable in ParallelDispatcher also replies on worker IDs be in this range71* as it uses the worker ID as index into the status array. If worker IDs ever fall out of the above range,72* split available list would likely loose the performance advantage.73*/74extensions->splitAvailableListSplitAmount = extensions->gcThreadCount;7576env->getOmrVM()->_sizeClasses = _delegate.getSegregatedSizeClasses(env);77if (NULL != env->getOmrVM()->_sizeClasses) {78extensions->setSegregatedHeap(true);79extensions->setMetronomeGC(true);8081extensions->arrayletsPerRegion = extensions->regionSize / env->getOmrVM()->_arrayletLeafSize;82/* Excessive GC logic does not work with incremental Metronome. */83if (!extensions->excessiveGCEnabled._wasSpecified) {84extensions->excessiveGCEnabled._valueSpecified = false;85}86success = true;87}88}89return success;90}9192void93MM_ConfigurationRealtime::tearDown(MM_EnvironmentBase* env)94{95MM_GCExtensionsBase* extensions = env->getExtensions();9697if (NULL != extensions->defaultSizeClasses) {98extensions->defaultSizeClasses->kill(env);99extensions->defaultSizeClasses = NULL;100}101102MM_Configuration::tearDown(env);103}104105MM_Heap *106MM_ConfigurationRealtime::createHeapWithManager(MM_EnvironmentBase *env, uintptr_t heapBytesRequested, MM_HeapRegionManager *regionManager)107{108return MM_HeapVirtualMemory::newInstance(env, env->getExtensions()->heapAlignment, heapBytesRequested, regionManager);109}110111MM_MemorySpace *112MM_ConfigurationRealtime::createDefaultMemorySpace(MM_EnvironmentBase *envBase, MM_Heap *heap, MM_InitializationParameters *parameters)113{114MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);115MM_GCExtensionsBase *extensions = env->getExtensions();116MM_MemoryPoolSegregated *memoryPool = NULL;117MM_MemorySubSpaceMetronome *memorySubSpaceMetronome = NULL;118MM_PhysicalSubArenaRegionBased *physicalSubArena = NULL;119MM_PhysicalArenaRegionBased *physicalArena = NULL;120MM_RegionPoolSegregated *regionPool = NULL;121122if(NULL == (extensions->defaultSizeClasses = MM_SizeClasses::newInstance(env))) {123return NULL;124}125126regionPool = MM_RegionPoolSegregated::newInstance(env, extensions->heapRegionManager);127if (NULL == regionPool) {128return NULL;129}130131extensions->globalAllocationManager = MM_GlobalAllocationManagerRealtime::newInstance(env, regionPool);132if(NULL == extensions->globalAllocationManager) {133return NULL;134}135136if(NULL == (memoryPool = MM_MemoryPoolSegregated::newInstance(env, regionPool, MINIMUM_FREE_CHUNK_SIZE, (MM_GlobalAllocationManagerSegregated*)extensions->globalAllocationManager))) {137return NULL;138}139140if(NULL == (physicalSubArena = MM_PhysicalSubArenaRegionBased::newInstance(env, heap))) {141memoryPool->kill(env);142return NULL;143}144145memorySubSpaceMetronome = MM_MemorySubSpaceMetronome::newInstance(env, physicalSubArena, memoryPool, true, parameters->_minimumSpaceSize, parameters->_initialOldSpaceSize, parameters->_maximumSpaceSize);146if(NULL == memorySubSpaceMetronome) {147return NULL;148}149150if(NULL == (physicalArena = MM_PhysicalArenaRegionBased::newInstance(env, heap))) {151memorySubSpaceMetronome->kill(env);152return NULL;153}154155return MM_MemorySpace::newInstance(env, heap, physicalArena, memorySubSpaceMetronome, parameters, MEMORY_SPACE_NAME_METRONOME, MEMORY_SPACE_DESCRIPTION_METRONOME);156}157158159MM_EnvironmentBase *160MM_ConfigurationRealtime::allocateNewEnvironment(MM_GCExtensionsBase *extensions, OMR_VMThread *omrVMThread)161{162return MM_EnvironmentRealtime::newInstance(extensions, omrVMThread);163}164165J9Pool *166MM_ConfigurationRealtime::createEnvironmentPool(MM_EnvironmentBase *env)167{168OMRPORT_ACCESS_FROM_ENVIRONMENT(env);169170uintptr_t numberOfElements = getConfigurationDelegate()->getInitialNumberOfPooledEnvironments(env);171/* number of elements, pool flags = 0, 0 selects default pool configuration (at least 1 element, puddle size rounded to OS page size) */172return pool_new(sizeof(MM_EnvironmentRealtime), numberOfElements, sizeof(U_64), 0, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_MM, POOL_FOR_PORT(OMRPORTLIB));173}174175bool176MM_ConfigurationRealtime::initializeEnvironment(MM_EnvironmentBase *envBase)177{178MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);179if (MM_Configuration::initializeEnvironment(env)) {180MM_GCExtensionsBase *extensions = env->getExtensions();181if (extensions->globalAllocationManager->acquireAllocationContext(env)) {182MM_MemoryPoolSegregated *memoryPool = (MM_MemoryPoolSegregated *)extensions->heap->getDefaultMemorySpace()->getDefaultMemorySubSpace()->getMemoryPool();183env->_allocationTracker = memoryPool->createAllocationTracker(env);184return (NULL != env->_allocationTracker);185}186}187188return false;189}190191void192MM_ConfigurationRealtime::defaultMemorySpaceAllocated(MM_GCExtensionsBase *extensions, void* defaultMemorySpace)193{194MM_Configuration::defaultMemorySpaceAllocated(extensions, defaultMemorySpace);195196extensions->realtimeGC->getRealtimeDelegate()->defaultMemorySpaceAllocated(extensions, defaultMemorySpace);197}198199MM_HeapRegionManager *200MM_ConfigurationRealtime::createHeapRegionManager(MM_EnvironmentBase *env)201{202MM_GCExtensionsBase *extensions = env->getExtensions();203uintptr_t descriptorSize = sizeof(MM_HeapRegionDescriptorRealtime) + sizeof(uintptr_t *) * extensions->arrayletsPerRegion;204205MM_HeapRegionManagerTarok *heapRegionManager = MM_HeapRegionManagerTarok::newInstance(env, extensions->regionSize, descriptorSize, MM_HeapRegionDescriptorRealtime::initializer, MM_HeapRegionDescriptorRealtime::destructor);206return heapRegionManager;207}208209MM_ParallelDispatcher *210MM_ConfigurationRealtime::createParallelDispatcher(MM_EnvironmentBase *env, omrsig_handler_fn handler, void* handler_arg, uintptr_t defaultOSStackSize)211{212return MM_Scheduler::newInstance(env, handler, handler_arg, defaultOSStackSize);213}214215MM_Configuration *216MM_ConfigurationRealtime::newInstance(MM_EnvironmentBase *env)217{218MM_ConfigurationRealtime *configuration = (MM_ConfigurationRealtime *) env->getForge()->allocate(sizeof(MM_ConfigurationRealtime), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());219if (NULL != configuration) {220new(configuration) MM_ConfigurationRealtime(env);221if(!configuration->initialize(env)) {222configuration->kill(env);223configuration = NULL;224}225}226return configuration;227}228229MM_GlobalCollector *230MM_ConfigurationRealtime::createGlobalCollector(MM_EnvironmentBase *env)231{232return MM_RealtimeGC::newInstance(env);233}234235236