Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_trace/TgcTerse.cpp
5985 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 "modronopt.h"
27
#include "Tgc.hpp"
28
#include "mmhook_internal.h"
29
#include "HeapIteratorAPI.h"
30
31
#include "GCExtensions.hpp"
32
#include "TgcExtensions.hpp"
33
34
/**
35
* Private struct used as the user data for the iterator callbacks. The regionDesc will get set
36
* by the region iterator callback.
37
*/
38
typedef struct FixDeadObjectsIteratorCallbackUserData {
39
J9MM_IterateRegionDescriptor* regionDesc; /* Temp - used internally by iterator functions */
40
} FixDeadObjectsIteratorCallbackUserData;
41
42
/**
43
* Iterator callbacks, these are chained to eventually get to objects and their regions.
44
*/
45
static jvmtiIterationControl fix_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData);
46
static jvmtiIterationControl fix_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData);
47
static jvmtiIterationControl fix_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData);
48
static jvmtiIterationControl fix_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void* userData);
49
static jvmtiIterationControl dump_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData);
50
51
/**
52
* @todo Provide function documentation
53
*/
54
static void
55
dumpHeap(J9JavaVM *javaVM)
56
{
57
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
58
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
59
TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;
60
61
/* Flush any VM level changes to prepare for a safe slot walk */
62
TRIGGER_J9HOOK_MM_PRIVATE_WALK_HEAP_START(MM_GCExtensions::getExtensions(javaVM)->privateHookInterface, extensions->getOmrVM());
63
64
javaVM->memoryManagerFunctions->j9mm_iterate_all_objects(javaVM, javaVM->portLibrary, j9mm_iterator_flag_include_holes, dump_objectIteratorCallback, terseExtensions);
65
66
TRIGGER_J9HOOK_MM_PRIVATE_WALK_HEAP_END(MM_GCExtensions::getExtensions(javaVM)->privateHookInterface, extensions->getOmrVM());
67
}
68
69
static jvmtiIterationControl
70
dump_objectIteratorCallback(J9JavaVM *vm, J9MM_IterateObjectDescriptor* objectDesc, void *userData)
71
{
72
TgcTerseExtensions *terseExtensions = (TgcTerseExtensions*)userData;
73
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vm);
74
75
tgcExtensions->printf("*DH(%d)* %p %s",
76
terseExtensions->gcCount,
77
objectDesc->object,
78
objectDesc->isObject ? "a" : "f");
79
80
if (objectDesc->isObject) {
81
tgcExtensions->printf(" x%p ", objectDesc->size);
82
tgcPrintClass(vm, J9GC_J9OBJECT_CLAZZ_VM(objectDesc->object, vm));
83
tgcExtensions->printf("\n");
84
} else {
85
tgcExtensions->printf(" x%p\n", objectDesc->size);
86
}
87
88
return JVMTI_ITERATION_CONTINUE;
89
}
90
91
/**
92
* @todo Provide function documentation
93
*/
94
static void
95
tgcHookGlobalGcStart(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
96
{
97
MM_GlobalGCStartEvent* event = (MM_GlobalGCStartEvent*)eventData;
98
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
99
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
100
TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;
101
102
terseExtensions->gcCount += 1;
103
/* TODO: Sovereign also prints the size of the allocation that caused the failure */
104
tgcExtensions->printf("*** gc(%zu) ***\n", terseExtensions->gcCount);
105
dumpHeap((J9JavaVM*)event->currentThread->_vm->_language_vm);
106
}
107
108
/**
109
* @todo Provide function documentation
110
*/
111
static void
112
tgcHookGlobalGcEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
113
{
114
MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;
115
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
116
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
117
TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;
118
119
tgcExtensions->printf("** gc(%zu) done **\n", terseExtensions->gcCount);
120
dumpHeap((J9JavaVM*)event->currentThread->_vm->_language_vm);
121
}
122
123
/**
124
* @todo Provide function documentation
125
*/
126
static void
127
tgcHookLocalGcStart(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
128
{
129
MM_LocalGCStartEvent* event = (MM_LocalGCStartEvent*)eventData;
130
J9VMThread* vmThread = (J9VMThread*) event->currentThread->_language_vmthread;
131
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);
132
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
133
TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;
134
135
terseExtensions->gcCount += 1;
136
/* TODO: Sovereign also prints the size of the allocation that caused the failure */
137
tgcExtensions->printf("*** gc(%zu) ***\n", terseExtensions->gcCount);
138
dumpHeap(vmThread->javaVM);
139
}
140
141
/**
142
* @todo Provide function documentation
143
*/
144
static void
145
tgcHookLocalGcEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
146
{
147
MM_LocalGCEndEvent* event = (MM_LocalGCEndEvent*)eventData;
148
J9VMThread* vmThread = (J9VMThread*) event->currentThread->_language_vmthread;
149
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);
150
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
151
TgcTerseExtensions *terseExtensions = &tgcExtensions->_terse;
152
153
tgcExtensions->printf("** gc(%zu) done **\n", terseExtensions->gcCount);
154
dumpHeap(vmThread->javaVM);
155
}
156
157
/**
158
* @todo Provide function documentation
159
*/
160
static void
161
tgcHookGlobalGcSweepEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)
162
{
163
MM_SweepEndEvent* event = (MM_SweepEndEvent*)eventData;
164
J9VMThread *vmThread = static_cast<J9VMThread*>(event->currentThread->_language_vmthread);
165
J9JavaVM* javaVM = vmThread->javaVM;
166
167
/* Fix up the heap so that it can safely be walked later */
168
FixDeadObjectsIteratorCallbackUserData iteratorData;
169
iteratorData.regionDesc = NULL;
170
javaVM->memoryManagerFunctions->j9mm_iterate_heaps(javaVM, javaVM->portLibrary, 0, fix_heapIteratorCallback, &iteratorData);
171
}
172
173
/**
174
* @todo Provide function documentation
175
*/
176
bool
177
tgcTerseInitialize(J9JavaVM *javaVM)
178
{
179
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
180
bool result = true;
181
182
J9HookInterface** omrHooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);
183
J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);
184
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_START, tgcHookGlobalGcStart, OMR_GET_CALLSITE(), NULL);
185
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, tgcHookGlobalGcEnd, OMR_GET_CALLSITE(), NULL);
186
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_START, tgcHookLocalGcStart, OMR_GET_CALLSITE(), NULL);
187
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_END, tgcHookLocalGcEnd, OMR_GET_CALLSITE(), NULL);
188
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_END, tgcHookGlobalGcSweepEnd, OMR_GET_CALLSITE(), NULL);
189
190
return result;
191
}
192
193
static jvmtiIterationControl
194
fix_heapIteratorCallback(J9JavaVM* vm, J9MM_IterateHeapDescriptor* heapDesc, void* userData)
195
{
196
FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;
197
vm->memoryManagerFunctions->j9mm_iterate_spaces(vm, vm->portLibrary, heapDesc, 0, fix_spaceIteratorCallback, castUserData);
198
return JVMTI_ITERATION_CONTINUE;
199
}
200
201
static jvmtiIterationControl
202
fix_spaceIteratorCallback(J9JavaVM* vm, J9MM_IterateSpaceDescriptor* spaceDesc, void* userData)
203
{
204
FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;
205
vm->memoryManagerFunctions->j9mm_iterate_regions(vm, vm->portLibrary, spaceDesc, 0, fix_regionIteratorCallback, castUserData);
206
return JVMTI_ITERATION_CONTINUE;
207
}
208
209
static jvmtiIterationControl
210
fix_regionIteratorCallback(J9JavaVM* vm, J9MM_IterateRegionDescriptor* regionDesc, void* userData)
211
{
212
FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;
213
castUserData->regionDesc = regionDesc;
214
vm->memoryManagerFunctions->j9mm_iterate_region_objects(vm, vm->portLibrary, regionDesc, 0, fix_objectIteratorCallback, castUserData);
215
return JVMTI_ITERATION_CONTINUE;
216
}
217
218
static jvmtiIterationControl
219
fix_objectIteratorCallback(J9JavaVM* vm, J9MM_IterateObjectDescriptor* objectDesc, void* userData)
220
{
221
FixDeadObjectsIteratorCallbackUserData* castUserData = (FixDeadObjectsIteratorCallbackUserData*)userData;
222
223
/* Check the mark state of each object. If it isn't marked, build a dead object. */
224
if( !vm->memoryManagerFunctions->j9gc_ext_is_marked(vm, objectDesc->object) ) {
225
vm->memoryManagerFunctions->j9mm_abandon_object(vm, castUserData->regionDesc, objectDesc);
226
}
227
228
return JVMTI_ITERATION_CONTINUE;
229
}
230
231