Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_realtime/RealtimeMarkingSchemeRootClearer.hpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 2019, 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_Metronome
26
*/
27
28
#if !defined(REALTIMEROOTCLEARER_HPP_)
29
#define REALTIMEROOTCLEARER_HPP_
30
31
#include "j9.h"
32
#include "j9cfg.h"
33
#include "modronopt.h"
34
35
#include "EnvironmentRealtime.hpp"
36
#include "RealtimeRootScanner.hpp"
37
#include "RealtimeGC.hpp"
38
#include "RealtimeMarkingScheme.hpp"
39
40
/**
41
* This scanner will mark objects that pass through its doSlot.
42
*/
43
class MM_RealtimeMarkingSchemeRootClearer : public MM_RealtimeRootScanner
44
{
45
/* Data members / types */
46
public:
47
protected:
48
private:
49
50
/* Methods */
51
public:
52
53
/**
54
* Simple chained constructor.
55
*/
56
MM_RealtimeMarkingSchemeRootClearer(MM_EnvironmentRealtime *env, MM_RealtimeGC *realtimeGC) :
57
MM_RealtimeRootScanner(env, realtimeGC)
58
{
59
_typeId = __FUNCTION__;
60
}
61
62
/**
63
* This should not be called
64
*/
65
virtual void
66
doSlot(J9Object** slot)
67
{
68
Assert_MM_unreachable();
69
}
70
71
/**
72
* This scanner can be instantiated so we must give it a name.
73
*/
74
virtual const char*
75
scannerName()
76
{
77
return "Clearable";
78
}
79
80
/**
81
* Destroys unmarked monitors.
82
*/
83
virtual void
84
doMonitorReference(J9ObjectMonitor *objectMonitor, GC_HashTableIterator *monitorReferenceIterator)
85
{
86
J9ThreadAbstractMonitor * monitor = (J9ThreadAbstractMonitor*)objectMonitor->monitor;
87
if(!_markingScheme->isMarked((J9Object *)monitor->userData)) {
88
monitorReferenceIterator->removeSlot();
89
/* We must call objectMonitorDestroy (as opposed to omrthread_monitor_destroy) when the
90
* monitor is not internal to the GC */
91
static_cast<J9JavaVM*>(_omrVM->_language_vm)->internalVMFunctions->objectMonitorDestroy(static_cast<J9JavaVM*>(_omrVM->_language_vm), (J9VMThread *)_env->getLanguageVMThread(), (omrthread_monitor_t)monitor);
92
}
93
}
94
95
/**
96
* Wraps the MM_RootScanner::scanMonitorReferences method to disable yielding during the scan.
97
* @see MM_RootScanner::scanMonitorReferences()
98
*/
99
virtual void
100
scanMonitorReferences(MM_EnvironmentBase *envBase)
101
{
102
MM_EnvironmentRealtime *env = (MM_EnvironmentRealtime *)envBase;
103
104
/* @NOTE For SRT and MT to play together this needs to be investigated */
105
if(_singleThread || J9MODRON_HANDLE_NEXT_WORK_UNIT(env)) {
106
reportScanningStarted(RootScannerEntity_MonitorReferences);
107
108
J9ObjectMonitor *objectMonitor = NULL;
109
J9MonitorTableListEntry *monitorTableList = static_cast<J9JavaVM*>(_omrVM->_language_vm)->monitorTableList;
110
while (NULL != monitorTableList) {
111
J9HashTable *table = monitorTableList->monitorTable;
112
if (NULL != table) {
113
GC_HashTableIterator iterator(table);
114
iterator.disableTableGrowth();
115
while (NULL != (objectMonitor = (J9ObjectMonitor*)iterator.nextSlot())) {
116
doMonitorReference(objectMonitor, &iterator);
117
if (shouldYieldFromMonitorScan()) {
118
yield();
119
}
120
}
121
iterator.enableTableGrowth();
122
}
123
monitorTableList = monitorTableList->next;
124
}
125
126
reportScanningEnded(RootScannerEntity_MonitorReferences);
127
}
128
}
129
130
virtual CompletePhaseCode scanMonitorReferencesComplete(MM_EnvironmentBase *envBase) {
131
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
132
reportScanningStarted(RootScannerEntity_MonitorReferenceObjectsComplete);
133
((J9JavaVM *)env->getLanguageVM())->internalVMFunctions->objectMonitorDestroyComplete((J9JavaVM *)env->getLanguageVM(), (J9VMThread *)env->getLanguageVMThread());
134
reportScanningEnded(RootScannerEntity_MonitorReferenceObjectsComplete);
135
return complete_phase_OK;
136
}
137
138
virtual void scanWeakReferenceObjects(MM_EnvironmentBase *envBase) {
139
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
140
reportScanningStarted(RootScannerEntity_WeakReferenceObjects);
141
142
_realtimeGC->getRealtimeDelegate()->scanWeakReferenceObjects(env);
143
144
reportScanningEnded(RootScannerEntity_WeakReferenceObjects);
145
}
146
147
virtual CompletePhaseCode scanWeakReferencesComplete(MM_EnvironmentBase *envBase) {
148
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
149
reportScanningStarted(RootScannerEntity_WeakReferenceObjectsComplete);
150
151
if (env->_currentTask->synchronizeGCThreadsAndReleaseMain(env, UNIQUE_ID)) {
152
env->_cycleState->_referenceObjectOptions |= MM_CycleState::references_clear_weak;
153
env->_currentTask->releaseSynchronizedGCThreads(env);
154
}
155
156
reportScanningEnded(RootScannerEntity_WeakReferenceObjectsComplete);
157
158
return complete_phase_OK;
159
}
160
161
virtual void scanSoftReferenceObjects(MM_EnvironmentBase *envBase) {
162
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
163
reportScanningStarted(RootScannerEntity_SoftReferenceObjects);
164
165
_realtimeGC->getRealtimeDelegate()->scanSoftReferenceObjects(env);
166
167
reportScanningEnded(RootScannerEntity_SoftReferenceObjects);
168
}
169
170
virtual CompletePhaseCode scanSoftReferencesComplete(MM_EnvironmentBase *envBase) {
171
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
172
reportScanningStarted(RootScannerEntity_SoftReferenceObjectsComplete);
173
if (env->_currentTask->synchronizeGCThreadsAndReleaseMain(env, UNIQUE_ID)) {
174
env->_cycleState->_referenceObjectOptions |= MM_CycleState::references_clear_soft;
175
env->_currentTask->releaseSynchronizedGCThreads(env);
176
}
177
reportScanningEnded(RootScannerEntity_SoftReferenceObjectsComplete);
178
return complete_phase_OK;
179
}
180
181
virtual void scanPhantomReferenceObjects(MM_EnvironmentBase *envBase) {
182
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
183
reportScanningStarted(RootScannerEntity_PhantomReferenceObjects);
184
185
_realtimeGC->getRealtimeDelegate()->scanPhantomReferenceObjects(env);
186
187
reportScanningEnded(RootScannerEntity_PhantomReferenceObjects);
188
}
189
190
virtual CompletePhaseCode scanPhantomReferencesComplete(MM_EnvironmentBase *envBase) {
191
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
192
reportScanningStarted(RootScannerEntity_PhantomReferenceObjectsComplete);
193
if (env->_currentTask->synchronizeGCThreadsAndReleaseMain(env, UNIQUE_ID)) {
194
env->_cycleState->_referenceObjectOptions |= MM_CycleState::references_clear_phantom;
195
env->_currentTask->releaseSynchronizedGCThreads(env);
196
}
197
/* phantom reference processing may resurrect objects - scan them now */
198
_realtimeGC->completeMarking(MM_EnvironmentRealtime::getEnvironment(env));
199
reportScanningEnded(RootScannerEntity_PhantomReferenceObjectsComplete);
200
return complete_phase_OK;
201
}
202
203
#if defined(J9VM_GC_FINALIZATION)
204
/**
205
* Wraps the MM_RootScanner::scanUnfinalizedObjects method to disable yielding during the scan
206
* then yield after scanning.
207
* @see MM_RootScanner::scanUnfinalizedObjects()
208
*/
209
virtual void
210
scanUnfinalizedObjects(MM_EnvironmentBase *envBase) {
211
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
212
213
reportScanningStarted(RootScannerEntity_UnfinalizedObjects);
214
/* allow the marking scheme to handle this */
215
_realtimeGC->getRealtimeDelegate()->scanUnfinalizedObjects(env);
216
reportScanningEnded(RootScannerEntity_UnfinalizedObjects);
217
}
218
219
virtual CompletePhaseCode scanUnfinalizedObjectsComplete(MM_EnvironmentBase *envBase) {
220
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
221
reportScanningStarted(RootScannerEntity_UnfinalizedObjectsComplete);
222
/* ensure that all unfinalized processing is complete before we start marking additional objects */
223
env->_currentTask->synchronizeGCThreads(env, UNIQUE_ID);
224
_realtimeGC->completeMarking(env);
225
reportScanningEnded(RootScannerEntity_UnfinalizedObjectsComplete);
226
return complete_phase_OK;
227
}
228
229
virtual void doFinalizableObject(j9object_t object) {
230
Assert_MM_unreachable();
231
}
232
#endif /* J9VM_GC_FINALIZATION */
233
234
virtual void
235
scanOwnableSynchronizerObjects(MM_EnvironmentBase *envBase) {
236
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
237
238
reportScanningStarted(RootScannerEntity_OwnableSynchronizerObjects);
239
/* allow the marking scheme to handle this */
240
_realtimeGC->getRealtimeDelegate()->scanOwnableSynchronizerObjects(env);
241
reportScanningEnded(RootScannerEntity_OwnableSynchronizerObjects);
242
}
243
244
/**
245
* Wraps the MM_RootScanner::scanJNIWeakGlobalReferences method to disable yielding during the scan.
246
* @see MM_RootScanner::scanJNIWeakGlobalReferences()
247
*/
248
virtual void
249
scanJNIWeakGlobalReferences(MM_EnvironmentBase *envBase)
250
{
251
MM_EnvironmentRealtime *env = MM_EnvironmentRealtime::getEnvironment(envBase);
252
253
env->disableYield();
254
MM_RootScanner::scanJNIWeakGlobalReferences(env);
255
env->enableYield();
256
}
257
258
/**
259
* Clears slots holding unmarked objects.
260
*/
261
virtual void
262
doJNIWeakGlobalReference(J9Object **slotPtr)
263
{
264
J9Object *objectPtr = *slotPtr;
265
if(objectPtr && !_markingScheme->isMarked(objectPtr)) {
266
*slotPtr = NULL;
267
}
268
}
269
270
#if defined(J9VM_OPT_JVMTI)
271
/**
272
* Clears slots holding unmarked objects.
273
*/
274
virtual void
275
doJVMTIObjectTagSlot(J9Object **slotPtr, GC_JVMTIObjectTagTableIterator *objectTagTableIterator)
276
{
277
J9Object *objectPtr = *slotPtr;
278
if(objectPtr && !_markingScheme->isMarked(objectPtr)) {
279
*slotPtr = NULL;
280
}
281
}
282
#endif /* J9VM_OPT_JVMTI */
283
284
protected:
285
private:
286
};
287
288
#endif /* REALTIMEROOTCLEARER_HPP_ */
289
290
291