Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_trace_vlhgc/TgcInterRegionReferences.cpp
5986 views
1
/*******************************************************************************
2
* Copyright (c) 1991, 2019 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 "j9.h"
24
#include "j9cfg.h"
25
#include "j9port.h"
26
#include "Tgc.hpp"
27
#include "mmhook.h"
28
29
#include "TgcInterRegionReferences.hpp"
30
31
#include "ClassLoaderRememberedSet.hpp"
32
#include "CompactGroupManager.hpp"
33
#include "CycleState.hpp"
34
#include "EnvironmentVLHGC.hpp"
35
#include "GCExtensions.hpp"
36
#include "HeapMapIterator.hpp"
37
#include "HeapRegionDescriptorVLHGC.hpp"
38
#include "HeapRegionIteratorVLHGC.hpp"
39
#include "HeapRegionManager.hpp"
40
#include "MarkMap.hpp"
41
#include "MixedObjectIterator.hpp"
42
#include "PointerArrayIterator.hpp"
43
#include "TgcExtensions.hpp"
44
45
46
/**
47
* Walk the heap to count inter-region references and then output some statistics
48
*/
49
static void
50
tgcHookReportInterRegionReferenceCounting(J9HookInterface** hookInterface, UDATA eventNum, void* eventData, void* userData)
51
{
52
MM_CopyForwardStartEvent* event = (MM_CopyForwardStartEvent *)eventData;
53
J9VMThread *vmThread = static_cast<J9VMThread*>(event->currentThread->_language_vmthread);
54
J9JavaVM *javaVM = vmThread->javaVM;
55
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(vmThread);
56
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
57
58
UDATA heapObjectCount = 0;
59
UDATA heapInSlotCount = 0;
60
UDATA heapOutSlotCount = 0;
61
UDATA heapOutObjectCount = 0;
62
UDATA heapBeyondSlotCount = 0;
63
UDATA heapBeyondObjectCount = 0;
64
UDATA heapCardCount = 0;
65
66
MM_MarkMap *markMap = env->_cycleState->_markMap;
67
MM_HeapRegionManager *regionManager = extensions->heapRegionManager;
68
GC_HeapRegionIteratorVLHGC regionIterator(regionManager);
69
MM_HeapRegionDescriptorVLHGC *region = NULL;
70
PORT_ACCESS_FROM_ENVIRONMENT(env);
71
while (NULL != (region = regionIterator.nextRegion())) {
72
if (region->containsObjects()) {
73
UDATA objectCount = 0;
74
UDATA inSlotCount = 0;
75
UDATA outSlotCount = 0;
76
UDATA outObjectCount = 0;
77
UDATA beyondSlotCount = 0;
78
UDATA beyondObjectCount = 0;
79
UDATA cardCount = 0;
80
81
UDATA regionCompactGroup = MM_CompactGroupManager::getCompactGroupNumber(env, region);
82
UDATA *regionBase = (UDATA *)region->getLowAddress();
83
UDATA *regionTop = (UDATA *)region->getHighAddress();
84
85
MM_HeapMapIterator iterator = MM_HeapMapIterator(extensions, markMap, regionBase, regionTop, false);
86
J9Object *object = NULL;
87
void *lastRSCLObject = NULL;
88
while (NULL != (object = iterator.nextObject())) {
89
bool cardDoesPointOut = false;
90
objectCount += 1;
91
/* first, check the validity of the object's class */
92
J9Class *clazz = J9GC_J9OBJECT_CLAZZ(object, env);
93
Assert_MM_true((UDATA)0x99669966 == clazz->eyecatcher);
94
/* second, verify that it is an instance of a marked class */
95
J9Object *classObject = (J9Object *)clazz->classObject;
96
Assert_MM_true(markMap->isBitSet(classObject));
97
98
/* now that we know the class is valid, verify that this object only refers to other marked objects */
99
switch(extensions->objectModel.getScanType(object)) {
100
case GC_ObjectModel::SCAN_REFERENCE_MIXED_OBJECT:
101
Assert_MM_true(GC_ObjectModel::REF_STATE_REMEMBERED != J9GC_J9VMJAVALANGREFERENCE_STATE(env, object));
102
/* fall through */
103
case GC_ObjectModel::SCAN_MIXED_OBJECT_LINKED:
104
case GC_ObjectModel::SCAN_ATOMIC_MARKABLE_REFERENCE_OBJECT:
105
case GC_ObjectModel::SCAN_MIXED_OBJECT:
106
case GC_ObjectModel::SCAN_OWNABLESYNCHRONIZER_OBJECT:
107
case GC_ObjectModel::SCAN_CLASS_OBJECT:
108
case GC_ObjectModel::SCAN_CLASSLOADER_OBJECT:
109
{
110
Assert_MM_true(extensions->classLoaderRememberedSet->isInstanceRemembered(env, object));
111
112
GC_MixedObjectIterator mixedObjectIterator(javaVM->omrVM, object);
113
GC_SlotObject *slotObject = NULL;
114
UDATA thisObjectIn = 0;
115
UDATA thisObjectOut = 0;
116
UDATA thisObjectBeyond = 0;
117
bool doesPointOut = false;
118
bool doesPointBeyond = false;
119
120
while (NULL != (slotObject = mixedObjectIterator.nextSlot())) {
121
J9Object *target = slotObject->readReferenceFromSlot();
122
if (NULL != target) {
123
MM_HeapRegionDescriptorVLHGC *dest = (MM_HeapRegionDescriptorVLHGC *)regionManager->tableDescriptorForAddress(target);
124
if (dest == region) {
125
inSlotCount += 1;
126
thisObjectIn += 1;
127
} else if (MM_CompactGroupManager::getCompactGroupNumber(env, dest) == regionCompactGroup) {
128
doesPointOut = true;
129
cardDoesPointOut = true;
130
outSlotCount += 1;
131
thisObjectOut += 1;
132
} else {
133
doesPointBeyond = true;
134
cardDoesPointOut = true;
135
beyondSlotCount += 1;
136
thisObjectBeyond += 1;
137
}
138
}
139
}
140
/* note that this will double-count objects which point both out _and_ beyond but that data is considered more valuable than only counting it as one type of external reference */
141
if (doesPointOut) {
142
outObjectCount += 1;
143
}
144
if (doesPointBeyond) {
145
beyondObjectCount += 1;
146
}
147
}
148
break;
149
case GC_ObjectModel::SCAN_POINTER_ARRAY_OBJECT:
150
{
151
Assert_MM_true(extensions->classLoaderRememberedSet->isInstanceRemembered(env, object));
152
153
GC_PointerArrayIterator pointerArrayIterator(javaVM, object);
154
GC_SlotObject *slotObject = NULL;
155
UDATA thisObjectIn = 0;
156
UDATA thisObjectOut = 0;
157
UDATA thisObjectBeyond = 0;
158
bool doesPointOut = false;
159
bool doesPointBeyond = false;
160
161
while (NULL != (slotObject = pointerArrayIterator.nextSlot())) {
162
J9Object *target = slotObject->readReferenceFromSlot();
163
if (NULL != target) {
164
MM_HeapRegionDescriptorVLHGC *dest = (MM_HeapRegionDescriptorVLHGC *)regionManager->tableDescriptorForAddress(target);
165
if (dest == region) {
166
inSlotCount += 1;
167
thisObjectIn += 1;
168
} else if (MM_CompactGroupManager::getCompactGroupNumber(env, dest) == regionCompactGroup) {
169
doesPointOut = true;
170
cardDoesPointOut = true;
171
outSlotCount += 1;
172
thisObjectOut += 1;
173
} else {
174
doesPointBeyond = true;
175
cardDoesPointOut = true;
176
beyondSlotCount += 1;
177
thisObjectBeyond += 1;
178
}
179
}
180
}
181
/* note that this will double-count objects which point both out _and_ beyond but that data is considered more valuable than only counting it as one type of external reference */
182
if (doesPointOut) {
183
outObjectCount += 1;
184
}
185
if (doesPointBeyond) {
186
beyondObjectCount += 1;
187
}
188
}
189
break;
190
case GC_ObjectModel::SCAN_PRIMITIVE_ARRAY_OBJECT:
191
/* nothing to do */
192
break;
193
default:
194
Assert_MM_unreachable();
195
}
196
if (cardDoesPointOut) {
197
if (NULL != lastRSCLObject) {
198
if (((UDATA)lastRSCLObject >> CARD_SIZE_SHIFT) != ((UDATA)object >> CARD_SIZE_SHIFT)) {
199
cardCount += 1;
200
}
201
}
202
lastRSCLObject = object;
203
}
204
}
205
if (NULL != lastRSCLObject) {
206
cardCount += 1;
207
}
208
j9tty_printf(PORTLIB, "Region based %p (group %zu) has %zu objects. %zu \"in\" slots, %zu \"out\" slots (%zu objects), %zu \"beyond\" slots (%zu objects). Creates %zu out/beyond cards\n", regionBase, regionCompactGroup, objectCount, inSlotCount, outSlotCount, outObjectCount, beyondSlotCount, beyondObjectCount, cardCount);
209
heapObjectCount += objectCount;
210
heapInSlotCount += inSlotCount;
211
heapOutSlotCount += outSlotCount;
212
heapOutObjectCount += outObjectCount;
213
heapBeyondSlotCount += beyondSlotCount;
214
heapBeyondObjectCount += beyondObjectCount;
215
heapCardCount += cardCount;
216
}
217
}
218
j9tty_printf(PORTLIB, "Total heap has %zu objects. %zu \"in\" slots, %zu \"out\" slots (%zu objects), %zu \"beyond\" slots (%zu objects). Creates %zu out/beyond cards\n", heapObjectCount, heapInSlotCount, heapOutSlotCount, heapOutObjectCount, heapBeyondSlotCount, heapBeyondObjectCount, heapCardCount);
219
}
220
221
222
/**
223
* Initialize inter region reference tgc tracing.
224
*/
225
bool
226
tgcInterRegionReferencesInitialize(J9JavaVM *javaVM)
227
{
228
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
229
bool result = true;
230
231
J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);
232
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_COPY_FORWARD_END, tgcHookReportInterRegionReferenceCounting, OMR_GET_CALLSITE(), javaVM);
233
PORT_ACCESS_FROM_JAVAVM(javaVM);
234
j9tty_printf(PORTLIB, "TGC inter-region references initialized.\nLegend:\n"
235
"\t\"in\" slot refers to a slot which points into the same region which contains its object\n"
236
"\t\"out\" slot refers to a slot which points into a different region from that which contains its object, yet is in the same compact group\n"
237
"\t\"beyond\" slot refers to a slot which points into a different region from that which contains its object which is also in a different compact group\n"
238
"\t\"out\" or \"beyond\" objects contain \"out\" or \"beyond\" slots, respectively (an object which contains both will be in both totals)\n"
239
);
240
241
return result;
242
}
243
244
void
245
tgcInterRegionReferencesTearDown(J9JavaVM *javaVM)
246
{
247
}
248
249