Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/AllocationContextRealtime.cpp
5986 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2019 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
#include "omr.h"
25
#include "omrcfg.h"
26
27
#include "AtomicOperations.hpp"
28
#include "EnvironmentBase.hpp"
29
#include "EnvironmentRealtime.hpp"
30
#include "GCExtensionsBase.hpp"
31
#include "GlobalGCStats.hpp"
32
#include "HeapRegionDescriptorSegregated.hpp"
33
#include "HeapRegionDescriptorRealtime.hpp"
34
#include "MetronomeStats.hpp"
35
#include "RealtimeGC.hpp"
36
#include "RealtimeMarkingScheme.hpp"
37
#include "RegionPoolSegregated.hpp"
38
#include "Scheduler.hpp"
39
#include "SizeClasses.hpp"
40
41
#include "AllocationContextRealtime.hpp"
42
43
MM_AllocationContextRealtime *
44
MM_AllocationContextRealtime::newInstance(MM_EnvironmentBase *env, MM_GlobalAllocationManagerSegregated *gam, MM_RegionPoolSegregated *regionPool)
45
{
46
MM_AllocationContextRealtime *allocCtxt = (MM_AllocationContextRealtime *)env->getForge()->allocate(sizeof(MM_AllocationContextRealtime), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());
47
if (allocCtxt) {
48
new(allocCtxt) MM_AllocationContextRealtime(env, gam, regionPool);
49
if (!allocCtxt->initialize(env)) {
50
allocCtxt->kill(env);
51
allocCtxt = NULL;
52
}
53
}
54
return allocCtxt;
55
}
56
57
bool
58
MM_AllocationContextRealtime::initialize(MM_EnvironmentBase *env)
59
{
60
if (!MM_AllocationContextSegregated::initialize(env)) {
61
return false;
62
}
63
64
return true;
65
}
66
67
void
68
MM_AllocationContextRealtime::tearDown(MM_EnvironmentBase *env)
69
{
70
MM_AllocationContextSegregated::tearDown(env);
71
}
72
73
void
74
MM_AllocationContextRealtime::signalSmallRegionDepleted(MM_EnvironmentBase *env, uintptr_t sizeClass)
75
{
76
/* If we do not have a region yet, try to trigger a GC */
77
MM_GCExtensionsBase *ext = env->getExtensions();
78
MM_Scheduler *sched = (MM_Scheduler *)ext->dispatcher;
79
sched->checkStartGC((MM_EnvironmentRealtime *) env);
80
}
81
82
bool
83
MM_AllocationContextRealtime::trySweepAndAllocateRegionFromSmallSizeClass(MM_EnvironmentBase *env, uintptr_t sizeClass, uintptr_t *sweepCount, U_64 *sweepStartTime)
84
{
85
bool result = false;
86
87
#if defined(OMR_GC_REALTIME)
88
MM_GCExtensionsBase *ext = env->getExtensions();
89
MM_RealtimeGC *realtimeGC = ext->realtimeGC;
90
MM_SizeClasses *sizeClasses = ext->defaultSizeClasses;
91
92
uintptr_t nonDeterministicSweepCount = *sweepCount;
93
U_64 nonDeterministicSweepStartTime = *sweepStartTime;
94
95
/* Do not attempt this optimization while sweeping arraylets (at least not while the region may contain a spine). */
96
if (realtimeGC->shouldPerformNonDeterministicSweep()) {
97
OMRPORT_ACCESS_FROM_ENVIRONMENT(env);
98
/* Heuristic (or better, extrapolation): if occupancy is very high, do not retry too many times to sweep.
99
* Still, try at least once no matter how high the occupancy is (even if sharp 1.0), to jump over a local walls (short series of full regions).
100
* The heuristic assumes that the sweep list is (roughly) ordered by occupancy (low occupancy at front).
101
*/
102
if (nonDeterministicSweepCount <= (sizeClasses->getNumCells(sizeClass) * (1 - _regionPool->getOccupancy(sizeClass)))) {
103
104
if (nonDeterministicSweepCount == 0) {
105
nonDeterministicSweepStartTime = omrtime_hires_clock();
106
}
107
108
MM_HeapRegionDescriptorSegregated *region = _regionPool->sweepAndAllocateRegionFromSmallSizeClass(env, sizeClass);
109
if (region != NULL) {
110
/* Count each non determinist sweep */
111
ext->globalGCStats.metronomeStats.nonDeterministicSweepCount += 1;
112
nonDeterministicSweepCount++;
113
/* Find the longest streak (both as count of sweeps and time spent) of consecutive sweeps for one alloc */
114
if (nonDeterministicSweepCount > ext->globalGCStats.metronomeStats.nonDeterministicSweepConsecutive) {
115
ext->globalGCStats.metronomeStats.nonDeterministicSweepConsecutive = nonDeterministicSweepCount;
116
}
117
U_64 deltaTime = omrtime_hires_delta(nonDeterministicSweepStartTime, omrtime_hires_clock(), OMRPORT_TIME_DELTA_IN_MICROSECONDS);
118
if (deltaTime > ext->globalGCStats.metronomeStats.nonDeterministicSweepDelay) {
119
ext->globalGCStats.metronomeStats.nonDeterministicSweepDelay = deltaTime;
120
}
121
MM_AtomicOperations::storeSync();
122
_smallRegions[sizeClass] = region;
123
/* Don't update bytesAllocated because unswept regions are still considered to be in use */
124
result = true;
125
}
126
}
127
}
128
#endif
129
130
return result;
131
}
132
133
uintptr_t *
134
MM_AllocationContextRealtime::allocateLarge(MM_EnvironmentBase *env, uintptr_t sizeInBytesRequired)
135
{
136
MM_GCExtensionsBase *ext = env->getExtensions();
137
MM_Scheduler *sched = (MM_Scheduler *)ext->dispatcher;
138
139
/* See if we should start a GC */
140
sched->checkStartGC((MM_EnvironmentRealtime *) env);
141
142
/* Call parent to try to get a large object region */
143
uintptr_t *result = MM_AllocationContextSegregated::allocateLarge(env, sizeInBytesRequired);
144
//TODO SATB extract into a method
145
if ((NULL != result) && (GC_MARK == ((MM_EnvironmentRealtime *) env)->getAllocationColor())) {
146
ext->realtimeGC->getMarkingScheme()->mark((omrobjectptr_t)result);
147
}
148
149
return result;
150
}
151
152
bool
153
MM_AllocationContextRealtime::shouldPreMarkSmallCells(MM_EnvironmentBase *env)
154
{
155
MM_GCExtensionsBase *ext = env->getExtensions();
156
bool result = false;
157
158
if (NULL != ext->realtimeGC) {
159
MM_EnvironmentRealtime *envRT = (MM_EnvironmentRealtime *) env;
160
result = (GC_MARK == envRT->getAllocationColor());
161
}
162
163
return result;
164
}
165
166