Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/RealtimeMarkingScheme.cpp
5986 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
#include "omr.h"
24
25
#include "CycleState.hpp"
26
#include "EnvironmentRealtime.hpp"
27
#include "RealtimeGC.hpp"
28
#include "RealtimeMarkingScheme.hpp"
29
#include "RealtimeMarkTask.hpp"
30
31
/**
32
* Allocate and initialize a new instance of the receiver.
33
* @return a new instance of the receiver, or NULL on failure.
34
*/
35
MM_RealtimeMarkingScheme *
36
MM_RealtimeMarkingScheme::newInstance(MM_EnvironmentBase *env, MM_RealtimeGC *realtimeGC)
37
{
38
MM_RealtimeMarkingScheme *instance;
39
40
instance = (MM_RealtimeMarkingScheme *)env->getForge()->allocate(sizeof(MM_RealtimeMarkingScheme), MM_AllocationCategory::FIXED, OMR_GET_CALLSITE());
41
if (instance) {
42
new(instance) MM_RealtimeMarkingScheme(env, realtimeGC);
43
if (!instance->initialize(env)) {
44
instance->kill(env);
45
instance = NULL;
46
}
47
}
48
49
return instance;
50
}
51
52
/**
53
* Free the receiver and all associated resources.
54
*/
55
void
56
MM_RealtimeMarkingScheme::kill(MM_EnvironmentBase *env)
57
{
58
tearDown(env);
59
env->getForge()->free(this);
60
}
61
62
/**
63
* Intialize the RealtimeMarkingScheme instance.
64
*
65
*/
66
bool
67
MM_RealtimeMarkingScheme::initialize(MM_EnvironmentBase *env)
68
{
69
if (!MM_SegregatedMarkingScheme::initialize(env)) {
70
return false;
71
}
72
73
_scheduler = _realtimeGC->_sched;
74
75
return true;
76
}
77
78
/**
79
* Teardown the RealtimeMarkingScheme instance.
80
*
81
*/
82
void
83
MM_RealtimeMarkingScheme::tearDown(MM_EnvironmentBase *env)
84
{
85
MM_SegregatedMarkingScheme::tearDown(env);
86
}
87
88
void
89
MM_RealtimeMarkingScheme::markLiveObjectsInit(MM_EnvironmentBase *env, bool initMarkMap)
90
{
91
MM_EnvironmentRealtime *realtimeEnv = MM_EnvironmentRealtime::getEnvironment(env);
92
realtimeEnv->getWorkStack()->reset(realtimeEnv, _realtimeGC->_workPackets);
93
94
/* These are thread-local stats that should probably be moved
95
* into the MM_MarkStats structure.
96
*/
97
realtimeEnv->resetScannedCounters();
98
99
/* The write barrier must be enabled before any scanning begins. The double barrier will
100
* be enabled for the duration of the thread scans. It gets disabled on a per thread basis
101
* as the threads get scanned. It also gets "disabled" on a global basis once all threads
102
* are scanned.
103
*/
104
if (realtimeEnv->_currentTask->synchronizeGCThreadsAndReleaseMain(realtimeEnv, UNIQUE_ID)) {
105
_realtimeGC->enableWriteBarrier(realtimeEnv);
106
_realtimeGC->enableDoubleBarrier(realtimeEnv);
107
/* BEN TODO: Ragged barrier here */
108
realtimeEnv->_currentTask->releaseSynchronizedGCThreads(realtimeEnv);
109
}
110
}
111
112
void
113
MM_RealtimeMarkingScheme::markLiveObjectsRoots(MM_EnvironmentBase *env)
114
{
115
MM_EnvironmentRealtime *realtimeEnv = MM_EnvironmentRealtime::getEnvironment(env);
116
MM_MetronomeDelegate *metronomeDelegate = _realtimeGC->getRealtimeDelegate();
117
118
metronomeDelegate->markLiveObjectsRoots(realtimeEnv);
119
_scheduler->condYieldFromGC(realtimeEnv);
120
}
121
122
void
123
MM_RealtimeMarkingScheme::markLiveObjectsScan(MM_EnvironmentBase *env)
124
{
125
MM_EnvironmentRealtime *realtimeEnv = MM_EnvironmentRealtime::getEnvironment(env);
126
MM_MetronomeDelegate *metronomeDelegate = _realtimeGC->getRealtimeDelegate();
127
128
/* Heap Marking and barrier processing. Cannot delay barrier processing until the end.*/
129
_realtimeGC->completeMarking(realtimeEnv);
130
131
metronomeDelegate->markLiveObjectsScan(realtimeEnv);
132
133
if (realtimeEnv->_currentTask->synchronizeGCThreadsAndReleaseMain(realtimeEnv, UNIQUE_ID)) {
134
metronomeDelegate->setUnmarkedImpliesCleared();
135
realtimeEnv->_currentTask->releaseSynchronizedGCThreads(realtimeEnv);
136
}
137
}
138
139
void
140
MM_RealtimeMarkingScheme::markLiveObjectsComplete(MM_EnvironmentBase *env)
141
{
142
MM_EnvironmentRealtime *realtimeEnv = MM_EnvironmentRealtime::getEnvironment(env);
143
MM_MetronomeDelegate *metronomeDelegate = _realtimeGC->getRealtimeDelegate();
144
145
metronomeDelegate->markLiveObjectsComplete(realtimeEnv);
146
147
_scheduler->condYieldFromGC(realtimeEnv);
148
149
/* Do a final tracing phase to complete the marking phase. It should not be possible for any thread,
150
* including NHRT's, to add elements to the rememberedSet between the end of this completeMarking() call and when
151
* we disable the write barrier since the entire live set will be completed.
152
*/
153
_realtimeGC->completeMarking(realtimeEnv);
154
155
metronomeDelegate->checkReferenceBuffer(realtimeEnv);
156
157
if (realtimeEnv->_currentTask->synchronizeGCThreadsAndReleaseMain(realtimeEnv, UNIQUE_ID)) {
158
metronomeDelegate->unsetUnmarkedImpliesCleared();
159
160
/* This is the symmetric call to the enabling of the write barrier that happens at the top of this method. */
161
_realtimeGC->disableWriteBarrier(realtimeEnv);
162
/* BEN TODO: Ragged barrier here */
163
164
/* reset flag "overflow happened this GC cycle" */
165
_realtimeGC->_workPackets->getIncrementalOverflowHandler()->resetOverflowThisGCCycle();
166
167
Assert_MM_true(_realtimeGC->_workPackets->isAllPacketsEmpty());
168
169
realtimeEnv->_currentTask->releaseSynchronizedGCThreads(realtimeEnv);
170
}
171
}
172
173
/**
174
* If maxCount == MAX_UNIT, we run till work stack is empty and we return true, if at least one
175
* object is marked.
176
* Otherwise, mark up to maxCount of objects. If we reached the limit return false, which means we are
177
* not finished yet.
178
*/
179
bool
180
MM_RealtimeMarkingScheme::incrementalCompleteScan(MM_EnvironmentRealtime *env, uintptr_t maxCount)
181
{
182
uintptr_t item;
183
uintptr_t count = 0, countSinceLastYieldCheck = 0;
184
uintptr_t scannedPointersSumSinceLastYieldCheck = 0;
185
186
while(0 != (item = (uintptr_t)env->getWorkStack()->pop(env))) {
187
uintptr_t scannedPointers;
188
if (IS_ITEM_ARRAYLET(item)) {
189
fomrobject_t *arraylet = ITEM_TO_ARRAYLET(item);
190
scannedPointers = _realtimeGC->getRealtimeDelegate()->scanPointerArraylet(env, arraylet);
191
} else {
192
omrobjectptr_t objectPtr = ITEM_TO_OBJECT(item);
193
scannedPointers = _realtimeGC->getRealtimeDelegate()->scanObject(env, objectPtr);
194
}
195
196
countSinceLastYieldCheck += 1;
197
scannedPointersSumSinceLastYieldCheck += scannedPointers;
198
199
if (((countSinceLastYieldCheck * 2) + scannedPointersSumSinceLastYieldCheck) > _extensions->traceCostToCheckYield) {
200
_scheduler->condYieldFromGC(env);
201
202
scannedPointersSumSinceLastYieldCheck = 0;
203
countSinceLastYieldCheck = 0;
204
}
205
206
if (++count >= maxCount) {
207
return false;
208
}
209
}
210
211
if (maxCount == MAX_UINT) {
212
return (count != 0);
213
} else {
214
return true;
215
}
216
}
217
218
219