Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/MarkingDelegate.hpp
5985 views
1
/*******************************************************************************
2
* Copyright (c) 2017, 2021 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
#if !defined(MARKINGDELEGATE_HPP_)
24
#define MARKINGDELEGATE_HPP_
25
26
#include "j9nonbuilder.h"
27
#include "objectdescription.h"
28
29
#include "FlattenedArrayObjectScanner.hpp"
30
#include "GCExtensions.hpp"
31
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
32
#include "MarkMap.hpp"
33
#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */
34
#include "MixedObjectScanner.hpp"
35
#include "ModronTypes.hpp"
36
#include "ReferenceObjectScanner.hpp"
37
#include "PointerArrayObjectScanner.hpp"
38
39
class GC_ObjectScanner;
40
class MM_EnvironmentBase;
41
class MM_HeapRegionDescriptorStandard;
42
class MM_MarkingScheme;
43
class MM_ReferenceStats;
44
45
class MM_MarkingDelegate
46
{
47
/* Data members & types */
48
private:
49
OMR_VM *_omrVM;
50
MM_GCExtensions *_extensions;
51
MM_MarkingScheme *_markingScheme;
52
bool _collectStringConstantsEnabled;
53
bool _shouldScanUnfinalizedObjects;
54
bool _shouldScanOwnableSynchronizerObjects;
55
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
56
MM_MarkMap *_markMap; /**< This is set when dynamic class loading is enabled, NULL otherwise */
57
volatile bool _anotherClassMarkPass; /**< Used in completeClassMark for another scanning request*/
58
volatile bool _anotherClassMarkLoopIteration; /**< Used in completeClassMark for another loop iteration request (set by the Main thread)*/
59
#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */
60
61
62
protected:
63
64
public:
65
66
/* Methods */
67
68
private:
69
MMINLINE void clearReference(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, bool isReferenceCleared, bool referentMustBeCleared);
70
MMINLINE bool getReferenceStatus(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, bool *referentMustBeMarked, bool *isReferenceCleared);
71
fomrobject_t *setupReferenceObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason);
72
uintptr_t setupPointerArrayScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo, uintptr_t *slotsToDo);
73
74
protected:
75
76
public:
77
MM_MarkingDelegate()
78
: _omrVM(NULL)
79
, _extensions(NULL)
80
, _markingScheme(NULL)
81
, _collectStringConstantsEnabled(false)
82
, _shouldScanUnfinalizedObjects(false)
83
, _shouldScanOwnableSynchronizerObjects(false)
84
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
85
, _markMap(NULL)
86
, _anotherClassMarkPass(false)
87
, _anotherClassMarkLoopIteration(false)
88
#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */
89
{}
90
91
/**
92
* Initialize the delegate.
93
*
94
* @param env environment for calling thread
95
* @param markingScheme the marking scheme that the delegate is bound to
96
* @return true if delegate initialized successfully
97
*/
98
bool initialize(MM_EnvironmentBase *env, MM_MarkingScheme *markingScheme);
99
100
/**
101
* Delegate methods interfacing with MM_MarkingScheme.
102
*/
103
void workerSetupForGC(MM_EnvironmentBase *env);
104
void workerCompleteGC(MM_EnvironmentBase *env);
105
void workerCleanupAfterGC(MM_EnvironmentBase *env);
106
void mainSetupForGC(MM_EnvironmentBase *env);
107
void mainSetupForWalk(MM_EnvironmentBase *env);
108
void mainCleanupAfterGC(MM_EnvironmentBase *env);
109
void scanRoots(MM_EnvironmentBase *env, bool processLists = true);
110
void completeMarking(MM_EnvironmentBase *env);
111
112
void startRootListProcessing(MM_EnvironmentBase *env);
113
114
uintptr_t setupIndexableScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo, uintptr_t *sizeInElementsToDo, fomrobject_t **basePtr, uintptr_t *flags) { return 0; }
115
116
MMINLINE GC_ObjectScanner *
117
getObjectScanner(MM_EnvironmentBase *env, omrobjectptr_t objectPtr, void *scannerSpace, MM_MarkingSchemeScanReason reason, uintptr_t *sizeToDo)
118
{
119
J9Class *clazz = J9GC_J9OBJECT_CLAZZ(objectPtr, env);
120
UDATA const referenceSize = env->compressObjectReferences() ? sizeof(uint32_t) : sizeof(uintptr_t);
121
122
/* object class must have proper eye catcher */
123
Assert_MM_true((UDATA)0x99669966 == clazz->eyecatcher);
124
125
GC_ObjectScanner *objectScanner = NULL;
126
switch(_extensions->objectModel.getScanType(objectPtr)) {
127
case GC_ObjectModel::SCAN_MIXED_OBJECT_LINKED:
128
case GC_ObjectModel::SCAN_ATOMIC_MARKABLE_REFERENCE_OBJECT:
129
case GC_ObjectModel::SCAN_MIXED_OBJECT:
130
case GC_ObjectModel::SCAN_OWNABLESYNCHRONIZER_OBJECT:
131
case GC_ObjectModel::SCAN_CLASS_OBJECT:
132
case GC_ObjectModel::SCAN_CLASSLOADER_OBJECT:
133
objectScanner = GC_MixedObjectScanner::newInstance(env, objectPtr, scannerSpace, 0);
134
*sizeToDo = referenceSize + ((GC_MixedObjectScanner *)objectScanner)->getBytesRemaining();
135
break;
136
case GC_ObjectModel::SCAN_POINTER_ARRAY_OBJECT:
137
{
138
uintptr_t slotsToDo = 0;
139
uintptr_t startIndex = setupPointerArrayScanner(env, objectPtr, reason, sizeToDo, &slotsToDo);
140
objectScanner = GC_PointerArrayObjectScanner::newInstance(env, objectPtr, scannerSpace, GC_ObjectScanner::indexableObject, slotsToDo, startIndex);
141
break;
142
}
143
case GC_ObjectModel::SCAN_FLATTENED_ARRAY_OBJECT:
144
{
145
/* TODO: Flattened arrays do not support array splitting */
146
uintptr_t slotsToDo = 0;
147
uintptr_t startIndex = 0;
148
objectScanner = GC_FlattenedArrayObjectScanner::newInstance(env, objectPtr, scannerSpace, GC_ObjectScanner::indexableObject, slotsToDo, startIndex);
149
break;
150
}
151
case GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT:
152
{
153
fomrobject_t *referentSlotPtr = setupReferenceObjectScanner(env, objectPtr, reason);
154
objectScanner = GC_ReferenceObjectScanner::newInstance(env, objectPtr, referentSlotPtr, scannerSpace, 0);
155
*sizeToDo = referenceSize + ((GC_ReferenceObjectScanner *)objectScanner)->getBytesRemaining();
156
break;
157
}
158
case GC_ObjectModel::SCAN_PRIMITIVE_ARRAY_OBJECT:
159
/* nothing to do */
160
*sizeToDo = 0;
161
break;
162
default:
163
Assert_MM_unreachable();
164
}
165
166
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
167
if (isDynamicClassUnloadingEnabled()) {
168
/* only mark the class the first time we scan any array, always mark class for mixed/reference objects */
169
if ((NULL != objectScanner) && objectScanner->isHeadObjectScanner()) {
170
/* Note: this code cloned from MM_MarkingScheme::inlineMarkObjectNoCheck(), inaccessible here */
171
if (_markMap->atomicSetBit(clazz->classObject)) {
172
/* class object was previously unmarked so push it to workstack */
173
env->_workStack.push(env, (void *)clazz->classObject);
174
env->_markStats._objectsMarked += 1;
175
}
176
}
177
}
178
#endif /* J9VM_GC_DYNAMIC_CLASS_UNLOADING */
179
180
return objectScanner;
181
}
182
183
/**
184
* Delegate methods used by MM_MarkingSchemeRootmarker and MM_MarkingSchemeRootClearer.
185
*/
186
MMINLINE bool
187
shouldScanUnfinalizedObjects()
188
{
189
return _shouldScanUnfinalizedObjects;
190
}
191
192
MMINLINE void
193
shouldScanUnfinalizedObjects(bool shouldScanUnfinalizedObjects)
194
{
195
_shouldScanUnfinalizedObjects = shouldScanUnfinalizedObjects;
196
}
197
198
MMINLINE bool
199
shouldScanOwnableSynchronizerObjects()
200
{
201
return _shouldScanOwnableSynchronizerObjects;
202
}
203
204
MMINLINE void
205
shouldScanOwnableSynchronizerObjects(bool shouldScanOwnableSynchronizerObjects)
206
{
207
_shouldScanOwnableSynchronizerObjects = shouldScanOwnableSynchronizerObjects;
208
}
209
210
void scanClass(MM_EnvironmentBase *env, J9Class *clazz);
211
212
bool processReference(MM_EnvironmentBase *env, omrobjectptr_t objectPtr);
213
void processReferenceList(MM_EnvironmentBase *env, MM_HeapRegionDescriptorStandard* region, omrobjectptr_t headOfList, MM_ReferenceStats *referenceStats);
214
215
void handleWorkPacketOverflowItem(MM_EnvironmentBase *env, omrobjectptr_t objectPtr)
216
{
217
if (GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT == _extensions->objectModel.getScanType(objectPtr)) {
218
/* since we popped this object from the work packet, it is our responsibility to record it in the list of reference objects */
219
/* we know that the object must be in the collection set because it was on a work packet */
220
/* we don't need to process cleared or enqueued references */
221
processReference(env, objectPtr);
222
}
223
}
224
225
/**
226
* Helper methods used by classes other than MM_MarkingScheme.
227
*/
228
#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)
229
static void clearClassLoadersScannedFlag(MM_EnvironmentBase *env);
230
MMINLINE bool isDynamicClassUnloadingEnabled() { return NULL != _markMap; }
231
#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */
232
};
233
234
#endif /* MARKINGDELEGATE_HPP_ */
235
236