Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_vlhgc/CompactGroupManager.hpp
5986 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2014 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* 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
22
*******************************************************************************/
23
24
/**
25
* @file
26
* @ingroup GC_Modron_Tarok
27
*/
28
29
#if !defined(COMPACTGROUPMANAGER_HPP_)
30
#define COMPACTGROUPMANAGER_HPP_
31
32
#include "j9.h"
33
#include "j9cfg.h"
34
35
#include "AllocationContextTarok.hpp"
36
#include "BaseNonVirtual.hpp"
37
#include "GCExtensions.hpp"
38
#include "GlobalAllocationManagerTarok.hpp"
39
#include "HeapRegionDescriptorVLHGC.hpp"
40
41
42
class MM_CompactGroupManager : public MM_BaseNonVirtual
43
{
44
/* Data Members */
45
public:
46
protected:
47
private:
48
49
/* Methods */
50
public:
51
/**
52
* Computes the 0-indexed compact group index for the receiver
53
* @param env[in] The thread
54
* @param age region age to compute compact group number for
55
* @param migrationDestination The context to consider for compact group number
56
* @return A 0-indexed value which can be used to look up the compact group if it were owned by migrationDestination
57
*/
58
MMINLINE static UDATA getCompactGroupNumberForAge(MM_EnvironmentVLHGC *env, UDATA age, MM_AllocationContextTarok *migrationDestination)
59
{
60
UDATA maxAge = MM_GCExtensions::getExtensions(env)->tarokRegionMaxAge;
61
Assert_MM_true(age <= maxAge);
62
UDATA contextNumber = migrationDestination->getAllocationContextNumber();
63
return (contextNumber * (maxAge + 1)) + age;
64
}
65
66
/**
67
* Computes the 0-indexed compact group index for the receiver
68
* @param env[in] The thread
69
* @param region Region to compute the compact group number for.
70
* @param migrationDestination The context to consider for compact group number instead of the owning context of the given region
71
* @return A 0-indexed value which can be used to look up the region's compact group if it were owned by migrationDestination
72
*/
73
MMINLINE static UDATA getCompactGroupNumberInContext(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region, MM_AllocationContextTarok *migrationDestination)
74
{
75
return getCompactGroupNumberForAge(env, region->getLogicalAge(), migrationDestination);
76
}
77
78
/**
79
* Computes the 0-indexed compact group index for the receiver
80
* @param env[in] The thread
81
* @param region Region to compute the compact group number for.
82
* @return A 0-indexed value which can be used to look up the regions compact group
83
*/
84
MMINLINE static UDATA getCompactGroupNumber(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)
85
{
86
return getCompactGroupNumberInContext(env, region, region->_allocateData._owningContext);
87
}
88
89
/**
90
* Calculate the maximum index that can be returned for a compact group.
91
* @param env GC thread.
92
* @return a 0-indexed value which represents the maximum that can be returned as a compact group (duration of the system).
93
*/
94
MMINLINE static UDATA getCompactGroupMaxCount(MM_EnvironmentVLHGC *env)
95
{
96
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
97
98
UDATA managedContextCount = MM_GlobalAllocationManagerTarok::calculateIdealManagedContextCount(extensions);
99
return (extensions->tarokRegionMaxAge + 1) * managedContextCount;
100
}
101
102
/**
103
* Derive the allocation context number from the compact group number.
104
* @param env GC thread.
105
* @param compactGroupNumber the compact group number serving as the base.
106
* @return the allocation context number which comprises part of the compact group number.
107
*/
108
MMINLINE static UDATA getAllocationContextNumberFromGroup(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)
109
{
110
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
111
return compactGroupNumber / (extensions->tarokRegionMaxAge + 1);
112
}
113
114
/**
115
* Derive the region age from the compact group number.
116
* @param env GC thread.
117
* @param compactGroupNumber the compact group number serving as the base.
118
* @return the region age which comprises part of the compact group number.
119
*/
120
MMINLINE static UDATA getRegionAgeFromGroup(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)
121
{
122
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
123
return compactGroupNumber % (extensions->tarokRegionMaxAge + 1);
124
}
125
126
/**
127
* Calculate Logical age for region based on Allocation age
128
*
129
* Each next ages interval growth exponentially (specified-based)
130
* To avoid exponent/logarithm operations and as far as maximum logical age is a small constant (order of tens)
131
* it is safe to do calculation incrementally.
132
* Also it is easy to control possible overflow at each step of calculation and explicitly limit amount of work
133
*
134
* AgesIntervalSize(n+1) = AgesIntervalSize(n) * exponentBase;
135
* ThresholdForAge(n+1) = ThresholdForAge(n) + AgesIntervalSize(n+1);
136
*
137
* @param env current thread environment
138
* @param allocationAge for region
139
* @return calculated logical region age
140
*/
141
MMINLINE static UDATA calculateLogicalAgeForRegion(MM_EnvironmentVLHGC *env, U_64 allocationAge)
142
{
143
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
144
145
U_64 unit = (U_64)extensions->tarokAllocationAgeUnit;
146
double exponentBase = extensions->tarokAllocationAgeExponentBase;
147
148
Assert_MM_true(unit > 0);
149
Assert_MM_true(allocationAge <= extensions->tarokMaximumAgeInBytes);
150
151
UDATA logicalAge = 0;
152
bool tooLarge = false;
153
154
U_64 threshold = unit;
155
156
while (!tooLarge && (threshold <= allocationAge)) {
157
unit = (U_64)(unit * exponentBase);
158
U_64 nextThreshold = threshold + unit;
159
160
tooLarge = (nextThreshold < threshold) /* overflow */
161
|| (logicalAge >= extensions->tarokRegionMaxAge); /* maximum logical age reached */
162
163
if (tooLarge) {
164
logicalAge = extensions->tarokRegionMaxAge;
165
} else {
166
threshold = nextThreshold;
167
logicalAge += 1;
168
}
169
}
170
171
return logicalAge;
172
}
173
174
/**
175
* Calculate initial value for maximum allocation age in bytes based on maximumLogicalAge
176
* @param env current thread environment
177
* @param maximumLogicalAge maximum logical age allocation age calculated for
178
*/
179
MMINLINE static U_64 calculateMaximumAllocationAge(MM_EnvironmentVLHGC *env, UDATA maximumLogicalAge)
180
{
181
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
182
U_64 unit = (U_64)extensions->tarokAllocationAgeUnit;
183
double exponentBase = extensions->tarokAllocationAgeExponentBase;
184
Assert_MM_true(unit > 0);
185
Assert_MM_true(maximumLogicalAge > 0);
186
UDATA logicalAge = 1;
187
bool tooLarge = false;
188
U_64 allocationAge = unit;
189
190
while (!tooLarge && (logicalAge < maximumLogicalAge)) {
191
unit = (U_64)(unit * exponentBase);
192
U_64 nextThreshold = allocationAge + unit;
193
194
tooLarge = (nextThreshold < allocationAge); /* overflow */
195
196
if (tooLarge) {
197
allocationAge = U_64_MAX;
198
} else {
199
allocationAge = nextThreshold;
200
logicalAge += 1;
201
}
202
}
203
204
return allocationAge;
205
}
206
207
/**
208
* Check is given region is a member of Nursery Collection Set
209
* Eden region is mandatory part of Nursery Collection Set regardless it's age
210
* non-Eden region is part of Nursery Collection Set if it's age is lower or equal of nursery threshold
211
* @param env[in] The thread
212
* @param region given region
213
* @return true if region is a member of Nursery Collection Set
214
*/
215
MMINLINE static bool isRegionInNursery(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)
216
{
217
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
218
bool result = false;
219
220
if (extensions->tarokAllocationAgeEnabled) {
221
result = region->isEden() || (region->getAllocationAge() <= extensions->tarokMaximumNurseryAgeInBytes);
222
} else {
223
result = region->isEden() || (region->getLogicalAge() <= extensions->tarokNurseryMaxAge._valueSpecified);
224
}
225
226
return result;
227
}
228
229
/**
230
* Check is given region is a DCSS candidate
231
* It is true if it is not a member of Nursery Collection Set and it's age has not reached maximum yet
232
* @param env[in] The thread
233
* @param region given region
234
* @return true if region is a DCSS candidate
235
*/
236
MMINLINE static bool isRegionDCSSCandidate(MM_EnvironmentVLHGC *env, MM_HeapRegionDescriptorVLHGC *region)
237
{
238
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
239
bool result = false;
240
241
if (extensions->tarokAllocationAgeEnabled) {
242
result = !isRegionInNursery(env, region) && (region->getAllocationAge() < extensions->tarokMaximumAgeInBytes);
243
} else {
244
result = !isRegionInNursery(env, region) && (region->getLogicalAge() < extensions->tarokRegionMaxAge);
245
}
246
247
return result;
248
}
249
250
/**
251
* Check is given Compact Group is a DCSS candidate
252
* It is true if it is not a member of Nursery Collection Set and it's age has not reached maximum yet
253
* @param env[in] The thread
254
* @param compactGroupNumber given compact group number
255
* @return true if region is a DCSS candidate
256
*/
257
MMINLINE static bool isCompactGroupDCSSCandidate(MM_EnvironmentVLHGC *env, UDATA compactGroupNumber)
258
{
259
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
260
bool result = false;
261
UDATA ageOfGroup = getRegionAgeFromGroup(env, compactGroupNumber);
262
263
/*
264
* It is no special case for allocation-based aging system because
265
* tarokNurseryMaxAge and tarokRegionMaxAge were set at startup
266
*/
267
result = (ageOfGroup > extensions->tarokNurseryMaxAge._valueSpecified) && (ageOfGroup < extensions->tarokRegionMaxAge);
268
269
return result;
270
}
271
272
protected:
273
private:
274
MM_CompactGroupManager()
275
{
276
_typeId = __FUNCTION__;
277
}
278
279
};
280
281
#endif /* COMPACTGROUPMANAGER_HPP_ */
282
283