Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_glue_java/ContractslotScanner.hpp
5985 views
1
2
/*******************************************************************************
3
* Copyright (c) 1991, 2017 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 "Base.hpp"
25
#include "ClassIterator.hpp"
26
#include "CollectorLanguageInterfaceImpl.hpp"
27
#include "ConfigurationDelegate.hpp"
28
#include "EnvironmentBase.hpp"
29
#include "FinalizableObjectBuffer.hpp"
30
#include "FinalizableReferenceBuffer.hpp"
31
#include "FinalizeListManager.hpp"
32
#include "GCExtensions.hpp"
33
#include "Heap.hpp"
34
#include "HeapRegionDescriptorStandard.hpp"
35
#include "HeapRegionIteratorStandard.hpp"
36
#include "ModronAssertions.h"
37
#include "ObjectAccessBarrier.hpp"
38
#include "OwnableSynchronizerObjectBuffer.hpp"
39
#include "OwnableSynchronizerObjectList.hpp"
40
#include "RootScanner.hpp"
41
#include "RootScannerTypes.h"
42
#include "UnfinalizedObjectBuffer.hpp"
43
#include "UnfinalizedObjectList.hpp"
44
45
/* All slot scanner for full VM slot walk.
46
* @copydoc MM_RootScanner
47
* @ingroup GC_Modron_Base
48
*/
49
class MM_ContractSlotScanner : public MM_RootScanner
50
{
51
private:
52
void *_srcBase;
53
void *_srcTop;
54
void *_dstBase;
55
protected:
56
public:
57
58
private:
59
protected:
60
public:
61
MM_ContractSlotScanner(MM_EnvironmentBase *env, void *srcBase, void *srcTop, void *dstBase) :
62
MM_RootScanner(env, true)
63
,_srcBase(srcBase)
64
,_srcTop(srcTop)
65
,_dstBase(dstBase)
66
{}
67
68
virtual void
69
doSlot(J9Object **slotPtr)
70
{
71
J9Object *objectPtr = *slotPtr;
72
if(NULL != objectPtr) {
73
if((objectPtr >= (J9Object *)_srcBase) && (objectPtr < (J9Object *)_srcTop)) {
74
objectPtr = (J9Object *)((((UDATA)objectPtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
75
*slotPtr = objectPtr;
76
}
77
}
78
}
79
80
virtual void
81
doClass(J9Class *clazz)
82
{
83
volatile j9object_t *objectSlotPtr = NULL;
84
85
/* walk all object slots */
86
GC_ClassIterator classIterator(_env, clazz);
87
while((objectSlotPtr = classIterator.nextSlot()) != NULL) {
88
/* discard volatile since we must be in stop-the-world mode */
89
doSlot((j9object_t*)objectSlotPtr);
90
}
91
/* There is no need to walk the J9Class slots since no values within this struct could
92
* move during a nursery contract.
93
*/
94
}
95
96
virtual void
97
scanUnfinalizedObjects(MM_EnvironmentBase *env)
98
{
99
reportScanningStarted(RootScannerEntity_UnfinalizedObjects);
100
101
/* Only walk MEMORY_TYPE_NEW regions since MEMORY_TYPE_OLD regions would not contain
102
* any objects that would move during a nursery contract.
103
*/
104
MM_HeapRegionDescriptorStandard *region = NULL;
105
GC_HeapRegionIteratorStandard regionIterator(env->getExtensions()->heap->getHeapRegionManager());
106
while(NULL != (region = regionIterator.nextRegion())) {
107
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
108
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
109
for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {
110
MM_UnfinalizedObjectList *list = &regionExtension->_unfinalizedObjectLists[i];
111
list->startUnfinalizedProcessing();
112
}
113
}
114
}
115
116
GC_HeapRegionIteratorStandard regionIterator2(env->getExtensions()->heap->getHeapRegionManager());
117
while(NULL != (region = regionIterator2.nextRegion())) {
118
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
119
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
120
for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {
121
MM_UnfinalizedObjectList *list = &regionExtension->_unfinalizedObjectLists[i];
122
if (!list->wasEmpty()) {
123
J9Object *object = list->getPriorList();
124
while (NULL != object) {
125
J9Object *movePtr = object;
126
if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {
127
movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
128
}
129
/* read the next link out of the moved copy of the object before we add it to the buffer */
130
object = _extensions->accessBarrier->getFinalizeLink(movePtr);
131
/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */
132
env->getGCEnvironment()->_unfinalizedObjectBuffer->add(env, movePtr);
133
}
134
}
135
}
136
}
137
}
138
139
/* restore everything to a flushed state before exiting */
140
env->getGCEnvironment()->_unfinalizedObjectBuffer->flush(env);
141
reportScanningEnded(RootScannerEntity_UnfinalizedObjects);
142
}
143
144
virtual void
145
scanOwnableSynchronizerObjects(MM_EnvironmentBase *env)
146
{
147
reportScanningStarted(RootScannerEntity_OwnableSynchronizerObjects);
148
149
/* Only walk MEMORY_TYPE_NEW regions since MEMORY_TYPE_OLD regions would not contain
150
* any objects that would move during a nursery contract.
151
*/
152
MM_HeapRegionDescriptorStandard *region = NULL;
153
GC_HeapRegionIteratorStandard regionIterator(env->getExtensions()->heap->getHeapRegionManager());
154
while(NULL != (region = regionIterator.nextRegion())) {
155
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
156
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
157
for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {
158
MM_OwnableSynchronizerObjectList *list = &regionExtension->_ownableSynchronizerObjectLists[i];
159
list->startOwnableSynchronizerProcessing();
160
}
161
}
162
}
163
164
GC_HeapRegionIteratorStandard regionIterator2(env->getExtensions()->heap->getHeapRegionManager());
165
while(NULL != (region = regionIterator2.nextRegion())) {
166
if ((MEMORY_TYPE_NEW == (region->getTypeFlags() & MEMORY_TYPE_NEW))) {
167
MM_HeapRegionDescriptorStandardExtension *regionExtension = MM_ConfigurationDelegate::getHeapRegionDescriptorStandardExtension(env, region);
168
for (UDATA i = 0; i < regionExtension->_maxListIndex; i++) {
169
MM_OwnableSynchronizerObjectList *list = &regionExtension->_ownableSynchronizerObjectLists[i];
170
if (!list->wasEmpty()) {
171
J9Object *object = list->getPriorList();
172
while (NULL != object) {
173
J9Object *movePtr = object;
174
if ((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {
175
movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
176
}
177
/* read the next link out of the moved copy of the object before we add it to the buffer */
178
J9Object *next = _extensions->accessBarrier->getOwnableSynchronizerLink(movePtr);
179
/* the last object in the list pointing itself, after the object moved, the link still points to old object address */
180
if (object != next) {
181
object = next;
182
} else {
183
/* reach the end of the list */
184
object = NULL;
185
}
186
/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */
187
env->getGCEnvironment()->_ownableSynchronizerObjectBuffer->add(env, movePtr);
188
}
189
}
190
}
191
}
192
}
193
194
/* restore everything to a flushed state before exiting */
195
env->getGCEnvironment()->_ownableSynchronizerObjectBuffer->flush(env);
196
reportScanningEnded(RootScannerEntity_OwnableSynchronizerObjects);
197
}
198
199
#if defined(J9VM_GC_FINALIZATION)
200
void
201
doFinalizableObject(J9Object *objectPtr)
202
{
203
Assert_MM_unreachable();
204
}
205
206
virtual void
207
scanFinalizableObjects(MM_EnvironmentBase *env)
208
{
209
reportScanningStarted(RootScannerEntity_FinalizableObjects);
210
211
GC_FinalizeListManager * finalizeListManager = _extensions->finalizeListManager;
212
{
213
GC_FinalizableObjectBuffer objectBuffer(_extensions);
214
/* walk finalizable objects loaded by the system class loader */
215
j9object_t systemObject = finalizeListManager->resetSystemFinalizableObjects();
216
while (NULL != systemObject) {
217
J9Object *movePtr = systemObject;
218
if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {
219
movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
220
}
221
/* read the next link out of the moved copy of the object before we add it to the buffer */
222
systemObject = _extensions->accessBarrier->getFinalizeLink(movePtr);
223
/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */
224
objectBuffer.add(env, movePtr);
225
}
226
objectBuffer.flush(env);
227
}
228
229
{
230
GC_FinalizableObjectBuffer objectBuffer(_extensions);
231
/* walk finalizable objects loaded by the all other class loaders */
232
j9object_t defaultObject = finalizeListManager->resetDefaultFinalizableObjects();
233
while (NULL != defaultObject) {
234
J9Object *movePtr = defaultObject;
235
if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {
236
movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
237
}
238
/* read the next link out of the moved copy of the object before we add it to the buffer */
239
defaultObject = _extensions->accessBarrier->getFinalizeLink(movePtr);
240
/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */
241
objectBuffer.add(env, movePtr);
242
}
243
objectBuffer.flush(env);
244
}
245
246
{
247
/* walk reference objects */
248
GC_FinalizableReferenceBuffer referenceBuffer(_extensions);
249
j9object_t referenceObject = finalizeListManager->resetReferenceObjects();
250
while (NULL != referenceObject) {
251
J9Object *movePtr = referenceObject;
252
if((movePtr >= (J9Object *)_srcBase) && (movePtr < (J9Object *)_srcTop)) {
253
movePtr = (J9Object *)((((UDATA)movePtr) - ((UDATA)_srcBase)) + ((UDATA)_dstBase));
254
}
255
/* read the next link out of the moved copy of the object before we add it to the buffer */
256
referenceObject = _extensions->accessBarrier->getReferenceLink(movePtr);
257
/* store the object in this thread's buffer. It will be flushed to the appropriate list when necessary. */
258
referenceBuffer.add(env, movePtr);
259
}
260
referenceBuffer.flush(env);
261
}
262
263
reportScanningEnded(RootScannerEntity_FinalizableObjects);
264
}
265
#endif /* J9VM_GC_FINALIZATION */
266
};
267
268