Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_modron_standard/ReadBarrierVerifier.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 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
24
/**
25
* @file
26
* @ingroup GC_Modron_Base
27
*/
28
29
30
#include "ReadBarrierVerifier.hpp"
31
32
#include "AtomicOperations.hpp"
33
#include "Debug.hpp"
34
#include "EnvironmentStandard.hpp"
35
#include "HeapRegionManager.hpp"
36
#include "j9cfg.h"
37
#include "mmhook_internal.h"
38
#include "ModronAssertions.h"
39
40
#include "RootScannerReadBarrierVerifier.hpp"
41
#include "Scavenger.hpp"
42
#include "SublistFragment.hpp"
43
44
#if defined(OMR_ENV_DATA64) && defined(OMR_GC_FULL_POINTERS)
45
46
MM_ReadBarrierVerifier *
47
MM_ReadBarrierVerifier::newInstance(MM_EnvironmentBase *env, MM_MarkingScheme *markingScheme)
48
{
49
MM_ReadBarrierVerifier *barrier;
50
51
barrier = (MM_ReadBarrierVerifier *)env->getForge()->allocate(sizeof(MM_ReadBarrierVerifier), MM_AllocationCategory::FIXED, J9_GET_CALLSITE());
52
if (barrier) {
53
new(barrier) MM_ReadBarrierVerifier(env, markingScheme);
54
if (!barrier->initialize(env)) {
55
barrier->kill(env);
56
barrier = NULL;
57
}
58
}
59
60
return barrier;
61
}
62
63
bool
64
MM_ReadBarrierVerifier::initialize(MM_EnvironmentBase *env)
65
{
66
return MM_StandardAccessBarrier::initialize(env);
67
}
68
69
void
70
MM_ReadBarrierVerifier::kill(MM_EnvironmentBase *env)
71
{
72
tearDown(env);
73
env->getForge()->free(this);
74
}
75
76
void
77
MM_ReadBarrierVerifier::tearDown(MM_EnvironmentBase *env)
78
{
79
MM_StandardAccessBarrier::tearDown(env);
80
}
81
bool
82
MM_ReadBarrierVerifier::preObjectRead(J9VMThread *vmThread, J9Object *srcObject, fj9object_t *srcAddress)
83
{
84
Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);
85
healSlot(_extensions, srcAddress);
86
87
return true;
88
}
89
90
void
91
MM_ReadBarrierVerifier::poisonSlot(MM_GCExtensionsBase *extensions, omrobjectptr_t *slot)
92
{
93
uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();
94
uintptr_t heapTop = (uintptr_t)extensions->heap->getHeapTop();
95
uintptr_t referenceFromSlot = (uintptr_t)*slot;
96
97
if ((heapTop > referenceFromSlot) && (heapBase <= referenceFromSlot)) {
98
uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;
99
*slot = (omrobjectptr_t) (shadowHeapBase + (referenceFromSlot - heapBase));
100
}
101
}
102
103
void
104
MM_ReadBarrierVerifier::poisonJniWeakReferenceSlots(MM_EnvironmentBase *env)
105
{
106
MM_RootScannerReadBarrierVerifier scanner(env, true, true);
107
scanner.scanJNIWeakGlobalReferences(env);
108
}
109
110
void
111
MM_ReadBarrierVerifier::poisonMonitorReferenceSlots(MM_EnvironmentBase *env)
112
{
113
MM_RootScannerReadBarrierVerifier scanner(env, true, true);
114
scanner.scanMonitorReferences(env);
115
}
116
117
void
118
MM_ReadBarrierVerifier::poisonClass(MM_EnvironmentBase *env)
119
{
120
MM_RootScannerReadBarrierVerifier scanner(env, true, true);
121
scanner.scanClass(env);
122
}
123
124
void
125
MM_ReadBarrierVerifier::poisonSlots(MM_EnvironmentBase *env)
126
{
127
MM_GCExtensionsBase *extensions = env->getExtensions();
128
if (1 == extensions->fvtest_enableJNIGlobalWeakReadBarrierVerification) {
129
poisonJniWeakReferenceSlots(env);
130
}
131
if (1 == extensions->fvtest_enableMonitorObjectsReadBarrierVerification) {
132
poisonMonitorReferenceSlots(env);
133
}
134
if (1 == extensions->fvtest_enableClassStaticsReadBarrierVerification) {
135
poisonClass(env);
136
}
137
}
138
139
void
140
MM_ReadBarrierVerifier::healSlot(MM_GCExtensionsBase *extensions, fomrobject_t *srcAddress)
141
{
142
uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;
143
uintptr_t shadowHeapTop = (uintptr_t)extensions->shadowHeapTop;
144
GC_SlotObject slotObject(extensions->getOmrVM(), srcAddress);
145
omrobjectptr_t object = slotObject.readReferenceFromSlot();
146
147
if ((shadowHeapTop > (uintptr_t)object) && (shadowHeapBase <= (uintptr_t)object)) {
148
149
uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();
150
uintptr_t healedAddress = heapBase + ((uintptr_t)object - shadowHeapBase);
151
152
/* We don't care if the write fails, some other thread probably wrote a healed value to the slot */
153
slotObject.atomicWriteReferenceToSlot(object, (omrobjectptr_t)healedAddress);
154
155
}
156
}
157
158
void
159
MM_ReadBarrierVerifier::healSlot(MM_GCExtensionsBase *extensions, omrobjectptr_t *slot)
160
{
161
uintptr_t shadowHeapBase = (uintptr_t)extensions->shadowHeapBase;
162
uintptr_t shadowHeapTop = (uintptr_t)extensions->shadowHeapTop;
163
uintptr_t referenceFromSlot = (uintptr_t)*slot;
164
165
if ((shadowHeapTop > referenceFromSlot) && (shadowHeapBase <= referenceFromSlot)) {
166
167
uintptr_t heapBase = (uintptr_t)extensions->heap->getHeapBase();
168
uintptr_t healedHeapAddress = heapBase + (referenceFromSlot - shadowHeapBase);
169
170
/* We don't care if the write fails, some other thread probably wrote a healed value to the slot */
171
MM_AtomicOperations::lockCompareExchange((uintptr_t *)slot, referenceFromSlot, healedHeapAddress);
172
173
}
174
}
175
176
void
177
MM_ReadBarrierVerifier::healJniWeakReferenceSlots(MM_EnvironmentBase *env)
178
{
179
MM_RootScannerReadBarrierVerifier scanner(env, true);
180
scanner.scanJNIWeakGlobalReferences(env);
181
}
182
183
void
184
MM_ReadBarrierVerifier::healMonitorReferenceSlots(MM_EnvironmentBase *env)
185
{
186
MM_RootScannerReadBarrierVerifier scanner(env, true);
187
scanner.scanMonitorReferences(env);
188
}
189
190
void
191
MM_ReadBarrierVerifier::healClass(MM_EnvironmentBase *env)
192
{
193
MM_RootScannerReadBarrierVerifier scanner(env, true);
194
scanner.scanClass(env);
195
}
196
197
void
198
MM_ReadBarrierVerifier::healSlots(MM_EnvironmentBase *env)
199
{
200
MM_GCExtensionsBase *extensions = env->getExtensions();
201
if (1 == extensions->fvtest_enableJNIGlobalWeakReadBarrierVerification) {
202
healJniWeakReferenceSlots(env);
203
}
204
if (1 == extensions->fvtest_enableMonitorObjectsReadBarrierVerification) {
205
healMonitorReferenceSlots(env);
206
}
207
if (1 == extensions->fvtest_enableClassStaticsReadBarrierVerification) {
208
healClass(env);
209
}
210
211
}
212
213
bool
214
MM_ReadBarrierVerifier::preObjectRead(J9VMThread *vmThread, J9Class *srcClass, j9object_t *srcAddress)
215
{
216
Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);
217
healSlot(_extensions, srcAddress);
218
return true;
219
}
220
221
bool
222
MM_ReadBarrierVerifier::preWeakRootSlotRead(J9VMThread *vmThread, j9object_t *srcAddress)
223
{
224
Assert_MM_true(vmThread->javaVM->internalVMFunctions->currentVMThread(vmThread->javaVM) == vmThread);
225
healSlot(_extensions, srcAddress);
226
return true;
227
}
228
229
bool
230
MM_ReadBarrierVerifier::preWeakRootSlotRead(J9JavaVM *vm, j9object_t *srcAddress)
231
{
232
healSlot(_extensions, srcAddress);
233
return true;
234
}
235
236
#endif /* defined(OMR_ENV_DATA64) && defined(OMR_GC_FULL_POINTERS) */
237
238
239