Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/ConfigurationRealtime.cpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2020 IBM Corp. and others
3
*
4
* This program and the accompanying materials are made available under
5
* the terms of the Eclipse Public License 2.0 which accompanies this
6
* 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 and
8
* is available at https://www.apache.org/licenses/LICENSE-2.0.
9
*
10
* This Source Code may also be made available under the following
11
* Secondary Licenses when the conditions for such availability set
12
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
13
* General Public License, version 2 with the GNU Classpath
14
* Exception [1] and GNU General Public License, version 2 with the
15
* OpenJDK Assembly Exception [2].
16
*
17
* [1] https://www.gnu.org/software/classpath/license.html
18
* [2] http://openjdk.java.net/legal/assembly-exception.html
19
*
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-exception
21
*******************************************************************************/
22
23
/**
24
* @file
25
* @ingroup GC_Modron_Metronome
26
*/
27
28
#include "omr.h"
29
#include "omrcfg.h"
30
31
#include "ConfigurationRealtime.hpp"
32
33
#include "EnvironmentRealtime.hpp"
34
#include "GlobalAllocationManagerRealtime.hpp"
35
#include "GCExtensionsBase.hpp"
36
#include "HeapVirtualMemory.hpp"
37
#include "HeapRegionDescriptorRealtime.hpp"
38
#include "HeapRegionManagerTarok.hpp"
39
#include "MemoryPoolSegregated.hpp"
40
#include "MemorySpace.hpp"
41
#include "MemorySubSpaceMetronome.hpp"
42
#include "PhysicalArenaRegionBased.hpp"
43
#include "PhysicalSubArenaRegionBased.hpp"
44
#include "RealtimeGC.hpp"
45
#include "RegionPoolSegregated.hpp"
46
#include "Scheduler.hpp"
47
#include "SizeClasses.hpp"
48
49
#define REALTIME_REGION_SIZE_BYTES 64 * 1024
50
51
/* Define realtime arraylet leaf size as the largest small size class we can have */
52
#define REALTIME_ARRAYLET_LEAF_SIZE_BYTES J9VMGC_SIZECLASSES_MAX_SMALL_SIZE_BYTES
53
54
#define J9GC_HASH_SALT_COUNT_METRONOME 1
55
56
class MM_MemoryPoolSegregated;
57
58
bool
59
MM_ConfigurationRealtime::initialize(MM_EnvironmentBase *env)
60
{
61
MM_GCExtensionsBase *extensions = env->getExtensions();
62
63
bool success = false;
64
if (MM_Configuration::initialize(env)) {
65
/*
66
* The split available lists are populated during sweep by GC threads,
67
* each worker inserts into its corresponding split list as it finishes sweeping a region,
68
* which also removes the contention when inserting to a global list.
69
* So the split count equals the number of gc threads.
70
* NOTE: The split available list mechanism assumes the worker IDs are in the range of [0, gcThreadCount-1].
71
* This is currently the case, as _statusTable in ParallelDispatcher also replies on worker IDs be in this range
72
* as it uses the worker ID as index into the status array. If worker IDs ever fall out of the above range,
73
* split available list would likely loose the performance advantage.
74
*/
75
extensions->splitAvailableListSplitAmount = extensions->gcThreadCount;
76
77
env->getOmrVM()->_sizeClasses = _delegate.getSegregatedSizeClasses(env);
78
if (NULL != env->getOmrVM()->_sizeClasses) {
79
extensions->setSegregatedHeap(true);
80
extensions->setMetronomeGC(true);
81
82
extensions->arrayletsPerRegion = extensions->regionSize / env->getOmrVM()->_arrayletLeafSize;
83
/* Excessive GC logic does not work with incremental Metronome. */
84
if (!extensions->excessiveGCEnabled._wasSpecified) {
85
extensions->excessiveGCEnabled._valueSpecified = false;
86
}
87
success = true;
88
}
89
}
90
return success;
91
}
92
93
void
94
MM_ConfigurationRealtime::tearDown(MM_EnvironmentBase* env)
95
{
96
MM_GCExtensionsBase* extensions = env->getExtensions();
97
98
if (NULL != extensions->defaultSizeClasses) {
99
extensions->defaultSizeClasses->kill(env);
100
extensions->defaultSizeClasses = NULL;
101
}
102
103
MM_Configuration::tearDown(env);
104
}
105
106
MM_Heap *
107
MM_ConfigurationRealtime::createHeapWithManager(MM_EnvironmentBase *env, uintptr_t heapBytesRequested, MM_HeapRegionManager *regionManager)
108
{
109
return MM_HeapVirtualMemory::newInstance(env, env->getExtensions()->heapAlignment, heapBytesRequested, regionManager);
110
}
111
112
MM_MemorySpace *
113
MM_ConfigurationRealtime::createDefaultMemorySpace(MM_EnvironmentBase *envBase, MM_Heap *heap, MM_InitializationParameters *parameters)
114
{
115
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
116
MM_GCExtensionsBase *extensions = env->getExtensions();
117
MM_MemoryPoolSegregated *memoryPool = NULL;
118
MM_MemorySubSpaceMetronome *memorySubSpaceMetronome = NULL;
119
MM_PhysicalSubArenaRegionBased *physicalSubArena = NULL;
120
MM_PhysicalArenaRegionBased *physicalArena = NULL;
121
MM_RegionPoolSegregated *regionPool = NULL;
122
123
if(NULL == (extensions->defaultSizeClasses = MM_SizeClasses::newInstance(env))) {
124
return NULL;
125
}
126
127
regionPool = MM_RegionPoolSegregated::newInstance(env, extensions->heapRegionManager);
128
if (NULL == regionPool) {
129
return NULL;
130
}
131
132
extensions->globalAllocationManager = MM_GlobalAllocationManagerRealtime::newInstance(env, regionPool);
133
if(NULL == extensions->globalAllocationManager) {
134
return NULL;
135
}
136
137
if(NULL == (memoryPool = MM_MemoryPoolSegregated::newInstance(env, regionPool, MINIMUM_FREE_CHUNK_SIZE, (MM_GlobalAllocationManagerSegregated*)extensions->globalAllocationManager))) {
138
return NULL;
139
}
140
141
if(NULL == (physicalSubArena = MM_PhysicalSubArenaRegionBased::newInstance(env, heap))) {
142
memoryPool->kill(env);
143
return NULL;
144
}
145
146
memorySubSpaceMetronome = MM_MemorySubSpaceMetronome::newInstance(env, physicalSubArena, memoryPool, true, parameters->_minimumSpaceSize, parameters->_initialOldSpaceSize, parameters->_maximumSpaceSize);
147
if(NULL == memorySubSpaceMetronome) {
148
return NULL;
149
}
150
151
if(NULL == (physicalArena = MM_PhysicalArenaRegionBased::newInstance(env, heap))) {
152
memorySubSpaceMetronome->kill(env);
153
return NULL;
154
}
155
156
return MM_MemorySpace::newInstance(env, heap, physicalArena, memorySubSpaceMetronome, parameters, MEMORY_SPACE_NAME_METRONOME, MEMORY_SPACE_DESCRIPTION_METRONOME);
157
}
158
159
160
MM_EnvironmentBase *
161
MM_ConfigurationRealtime::allocateNewEnvironment(MM_GCExtensionsBase *extensions, OMR_VMThread *omrVMThread)
162
{
163
return MM_EnvironmentRealtime::newInstance(extensions, omrVMThread);
164
}
165
166
J9Pool *
167
MM_ConfigurationRealtime::createEnvironmentPool(MM_EnvironmentBase *env)
168
{
169
OMRPORT_ACCESS_FROM_ENVIRONMENT(env);
170
171
uintptr_t numberOfElements = getConfigurationDelegate()->getInitialNumberOfPooledEnvironments(env);
172
/* number of elements, pool flags = 0, 0 selects default pool configuration (at least 1 element, puddle size rounded to OS page size) */
173
return pool_new(sizeof(MM_EnvironmentRealtime), numberOfElements, sizeof(U_64), 0, OMR_GET_CALLSITE(), OMRMEM_CATEGORY_MM, POOL_FOR_PORT(OMRPORTLIB));
174
}
175
176
bool
177
MM_ConfigurationRealtime::initializeEnvironment(MM_EnvironmentBase *envBase)
178
{
179
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
180
if (MM_Configuration::initializeEnvironment(env)) {
181
MM_GCExtensionsBase *extensions = env->getExtensions();
182
if (extensions->globalAllocationManager->acquireAllocationContext(env)) {
183
MM_MemoryPoolSegregated *memoryPool = (MM_MemoryPoolSegregated *)extensions->heap->getDefaultMemorySpace()->getDefaultMemorySubSpace()->getMemoryPool();
184
env->_allocationTracker = memoryPool->createAllocationTracker(env);
185
return (NULL != env->_allocationTracker);
186
}
187
}
188
189
return false;
190
}
191
192
void
193
MM_ConfigurationRealtime::defaultMemorySpaceAllocated(MM_GCExtensionsBase *extensions, void* defaultMemorySpace)
194
{
195
MM_Configuration::defaultMemorySpaceAllocated(extensions, defaultMemorySpace);
196
197
extensions->realtimeGC->getRealtimeDelegate()->defaultMemorySpaceAllocated(extensions, defaultMemorySpace);
198
}
199
200
MM_HeapRegionManager *
201
MM_ConfigurationRealtime::createHeapRegionManager(MM_EnvironmentBase *env)
202
{
203
MM_GCExtensionsBase *extensions = env->getExtensions();
204
uintptr_t descriptorSize = sizeof(MM_HeapRegionDescriptorRealtime) + sizeof(uintptr_t *) * extensions->arrayletsPerRegion;
205
206
MM_HeapRegionManagerTarok *heapRegionManager = MM_HeapRegionManagerTarok::newInstance(env, extensions->regionSize, descriptorSize, MM_HeapRegionDescriptorRealtime::initializer, MM_HeapRegionDescriptorRealtime::destructor);
207
return heapRegionManager;
208
}
209
210
MM_ParallelDispatcher *
211
MM_ConfigurationRealtime::createParallelDispatcher(MM_EnvironmentBase *env, omrsig_handler_fn handler, void* handler_arg, uintptr_t defaultOSStackSize)
212
{
213
return MM_Scheduler::newInstance(env, handler, handler_arg, defaultOSStackSize);
214
}
215
216
MM_Configuration *
217
MM_ConfigurationRealtime::newInstance(MM_EnvironmentBase *env)
218
{
219
MM_ConfigurationRealtime *configuration = (MM_ConfigurationRealtime *) env->getForge()->allocate(sizeof(MM_ConfigurationRealtime), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());
220
if (NULL != configuration) {
221
new(configuration) MM_ConfigurationRealtime(env);
222
if(!configuration->initialize(env)) {
223
configuration->kill(env);
224
configuration = NULL;
225
}
226
}
227
return configuration;
228
}
229
230
MM_GlobalCollector *
231
MM_ConfigurationRealtime::createGlobalCollector(MM_EnvironmentBase *env)
232
{
233
return MM_RealtimeGC::newInstance(env);
234
}
235
236