Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/runtime/gc_trace/TgcParallel.cpp
5985 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
#include "j9.h"
24
#include "j9cfg.h"
25
#include "j9port.h"
26
#include "modronopt.h"
27
#include "mmhook.h"
28
#include "ModronAssertions.h"
29
30
#if defined(J9VM_GC_VLHGC)
31
#include "CycleStateVLHGC.hpp"
32
#endif /* J9VM_GC_VLHGC */
33
#include "EnvironmentVLHGC.hpp"
34
#include "GCExtensions.hpp"
35
#include "TgcExtensions.hpp"
36
#include "VMThreadListIterator.hpp"
37
38
/****************************************
39
* Hook callbacks
40
****************************************
41
*/
42
43
static void
44
tgcHookGlobalGcEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
45
{
46
MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;
47
J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;
48
J9JavaVM *javaVM = vmThread->javaVM;
49
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
50
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
51
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
52
PORT_ACCESS_FROM_JAVAVM(javaVM);
53
54
55
uint64_t RSScanTotalTime = parallelExtensions->RSScanEndTime - parallelExtensions->RSScanStartTime;
56
57
if (0 != RSScanTotalTime) {
58
tgcExtensions->printf("RS : busy stall acquire release exchange \n");
59
60
GC_VMThreadListIterator markThreadListIterator(vmThread);
61
J9VMThread *walkThread = NULL;
62
while ((walkThread = markThreadListIterator.nextVMThread()) != NULL) {
63
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(walkThread->omrVMThread);
64
if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {
65
bool shouldIncludeThread = true;
66
if (extensions->isStandardGC()) {
67
#if defined(J9VM_GC_MODRON_STANDARD)
68
/* Concurrent RS Scan Task does not have its own stats struct,
69
* so rely on Mark Task stats gcCount, which is atm identical (all phases of one GC are run with same number of threads) */
70
shouldIncludeThread = env->_markStats._gcCount == extensions->globalGCStats.gcCount;
71
#endif /* defined(J9VM_GC_MODRON_STANDARD) */
72
}
73
74
/* Get RS busy and stall times and convert time from microseconds to milliseconds for reporting */
75
uint64_t rsStallTimeInMillis = ((uint64_t)(env->_workPacketStats.getStallTime())) / 1000;
76
uint64_t rsBusyTimeInMillis = (RSScanTotalTime / 1000) - rsStallTimeInMillis;
77
78
if (shouldIncludeThread) {
79
tgcExtensions->printf("%4zu: %5llu %5llu %5zu %5zu %5zu\n",
80
env->getWorkerID(),
81
rsBusyTimeInMillis,
82
rsStallTimeInMillis,
83
env->_workPacketStatsRSScan.workPacketsAcquired,
84
env->_workPacketStatsRSScan.workPacketsReleased,
85
env->_workPacketStatsRSScan.workPacketsExchanged);
86
}
87
}
88
}
89
}
90
91
uint64_t markTotalTime = parallelExtensions->markEndTime - parallelExtensions->markStartTime;
92
93
if (0 != markTotalTime) {
94
tgcExtensions->printf("Mark: busy stall acquire release exchange split array split size\n");
95
96
GC_VMThreadListIterator markThreadListIterator(vmThread);
97
J9VMThread *walkThread = NULL;
98
while ((walkThread = markThreadListIterator.nextVMThread()) != NULL) {
99
/* TODO: Are we guaranteed to get the threads in the right order? */
100
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);
101
if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {
102
uint64_t markStatsStallTime = 0;
103
intptr_t splitArraysProcessed = 0;
104
intptr_t splitArraysAmount = 0;
105
bool shouldIncludeThread = true;
106
if (extensions->isVLHGC()) {
107
#if defined(J9VM_GC_VLHGC)
108
markStatsStallTime = env->_markVLHGCStats.getStallTime();
109
splitArraysProcessed = env->_markVLHGCStats._splitArraysProcessed;
110
shouldIncludeThread = env->_markVLHGCStats._gcCount == extensions->globalVLHGCStats.gcCount;
111
#endif /* J9VM_GC_VLHGC */
112
} else if (extensions->isStandardGC()) {
113
#if defined(J9VM_GC_MODRON_STANDARD)
114
markStatsStallTime = env->_markStats.getStallTime();
115
splitArraysProcessed = env->getGCEnvironment()->_markJavaStats.splitArraysProcessed;
116
splitArraysAmount = env->getGCEnvironment()->_markJavaStats.splitArraysAmount;
117
shouldIncludeThread = env->_markStats._gcCount == extensions->globalGCStats.gcCount;
118
#endif /* defined(J9VM_GC_MODRON_STANDARD) */
119
}
120
121
if (shouldIncludeThread) {
122
intptr_t avgSplitSize = 0;
123
if (0 != splitArraysProcessed) {
124
avgSplitSize = splitArraysAmount / splitArraysProcessed;
125
}
126
tgcExtensions->printf("%4zu: %5llu %5llu %5zu %5zu %5zu %5zu %7zu\n",
127
env->getWorkerID(),
128
j9time_hires_delta(0, markTotalTime - (markStatsStallTime + env->_workPacketStats.getStallTime()), J9PORT_TIME_DELTA_IN_MILLISECONDS),
129
j9time_hires_delta(0, markStatsStallTime + env->_workPacketStats.getStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),
130
env->_workPacketStats.workPacketsAcquired,
131
env->_workPacketStats.workPacketsReleased,
132
env->_workPacketStats.workPacketsExchanged,
133
splitArraysProcessed,
134
avgSplitSize);
135
}
136
137
/* TODO: VLHGC doesn't record gc count yet, allowing us to determine if thread participated */
138
if (extensions->isVLHGC()) {
139
/* TODO: Must reset thread-local stats after using them -- is there another answer? */
140
/* When it becomes possible for a GC to not use all of the worker threads, this becomes
141
* necessary, otherwise we might use outdated stats.
142
*/
143
env->_workPacketStats.clear();
144
}
145
146
parallelExtensions->markStartTime = 0;
147
parallelExtensions->markEndTime = 0;
148
}
149
}
150
}
151
152
uint64_t sweepTotalTime = parallelExtensions->sweepEndTime - parallelExtensions->sweepStartTime;
153
154
if (0 != sweepTotalTime) {
155
intptr_t mainSweepChunksTotal = 0;
156
uint64_t mainSweepMergeTime = 0;
157
if (extensions->isVLHGC()) {
158
#if defined(J9VM_GC_VLHGC)
159
MM_EnvironmentVLHGC *mainEnv = MM_EnvironmentVLHGC::getEnvironment(vmThread);
160
mainSweepChunksTotal = mainEnv->_sweepVLHGCStats.sweepChunksTotal;
161
mainSweepMergeTime = mainEnv->_sweepVLHGCStats.mergeTime;
162
#endif /* J9VM_GC_VLHGC */
163
} else if (extensions->isStandardGC()) {
164
#if defined(J9VM_GC_MODRON_STANDARD)
165
MM_EnvironmentBase *mainEnv = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
166
mainSweepChunksTotal = mainEnv->_sweepStats.sweepChunksTotal;
167
mainSweepMergeTime = mainEnv->_sweepStats.mergeTime;
168
#endif /* defined(J9VM_GC_MODRON_STANDARD) */
169
}
170
171
tgcExtensions->printf("Sweep: busy idle sections %zu merge %llu\n",
172
mainSweepChunksTotal,
173
j9time_hires_delta(0, mainSweepMergeTime, J9PORT_TIME_DELTA_IN_MILLISECONDS));
174
175
176
GC_VMThreadListIterator sweepThreadListIterator(vmThread);
177
J9VMThread *walkThread = NULL;
178
while ((walkThread = sweepThreadListIterator.nextVMThread()) != NULL) {
179
/* TODO: Are we guaranteed to get the threads in the right order? */
180
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);
181
if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {
182
uint64_t sweepIdleTime = 0;
183
intptr_t sweepChunksProcessed = 0;
184
bool shouldIncludeThread = true;
185
if (extensions->isVLHGC()) {
186
#if defined(J9VM_GC_VLHGC)
187
sweepIdleTime = env->_sweepVLHGCStats.idleTime;
188
sweepChunksProcessed = env->_sweepVLHGCStats.sweepChunksProcessed;
189
shouldIncludeThread = env->_sweepVLHGCStats._gcCount == extensions->globalVLHGCStats.gcCount;
190
#endif /* J9VM_GC_VLHGC */
191
} else if (extensions->isStandardGC()) {
192
#if defined(J9VM_GC_MODRON_STANDARD)
193
sweepIdleTime = env->_sweepStats.idleTime;
194
sweepChunksProcessed = env->_sweepStats.sweepChunksProcessed;
195
shouldIncludeThread = env->_sweepStats._gcCount == extensions->globalGCStats.gcCount;
196
#endif /* defined(J9VM_GC_MODRON_STANDARD) */
197
}
198
199
parallelExtensions->sweepStartTime = 0;
200
parallelExtensions->sweepEndTime = 0;
201
202
if (shouldIncludeThread) {
203
tgcExtensions->printf("%4zu: %6llu %6llu %8zu\n",
204
env->getWorkerID(),
205
j9time_hires_delta(0, sweepTotalTime - sweepIdleTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
206
j9time_hires_delta(0, sweepIdleTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
207
sweepChunksProcessed);
208
}
209
}
210
}
211
}
212
}
213
214
static void
215
tgcHookGlobalGcMarkStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
216
{
217
MM_MarkStartEvent* event = (MM_MarkStartEvent*)eventData;
218
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
219
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
220
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
221
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
222
223
parallelExtensions->markStartTime = omrtime_hires_clock();
224
}
225
226
static void
227
tgcHookGlobalGcMarkEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
228
{
229
MM_MarkEndEvent* event = (MM_MarkEndEvent*)eventData;
230
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
231
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
232
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
233
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
234
235
parallelExtensions->markEndTime = omrtime_hires_clock();
236
}
237
238
#if defined(J9VM_GC_MODRON_SCAVENGER)
239
static void
240
tgcHookLocalGcEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
241
{
242
MM_LocalGCEndEvent* event = (MM_LocalGCEndEvent*)eventData;
243
J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;
244
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);
245
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
246
247
J9VMThread *walkThread;
248
uint64_t scavengeTotalTime;
249
PORT_ACCESS_FROM_VMC(vmThread);
250
OMRPORT_ACCESS_FROM_J9PORT(PORTLIB);
251
252
char timestamp[32];
253
int64_t timeInMillis = j9time_current_time_millis();
254
omrstr_ftime_ex(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", timeInMillis, OMRSTR_FTIME_FLAG_LOCAL);
255
tgcExtensions->printf("\n");
256
tgcExtensions->printf("Scavenger parallel and progress stats, timestamp=\"%s.%ld\"\n", timestamp, timeInMillis % 1000);
257
258
tgcExtensions->printf(" gc thrID busy stall acquire release acquire release acquire split avg split alias to deep total deepest\n");
259
tgcExtensions->printf(" (micros) (micros) freelist freelist scanlist scanlist lock arrays arraysize copycache lists deep objs list\n");
260
261
scavengeTotalTime = event->incrementEndTime - event->incrementStartTime;
262
uintptr_t gcCount = extensions->scavengerStats._gcCount;
263
264
GC_VMThreadListIterator scavengeThreadListIterator(vmThread);
265
while ((walkThread = scavengeThreadListIterator.nextVMThread()) != NULL) {
266
/* TODO: Are we guaranteed to get the threads in the right order? */
267
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(walkThread->omrVMThread);
268
if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {
269
/* check if this thread participated in the GC */
270
if (env->_scavengerStats._gcCount == extensions->scavengerStats._gcCount) {
271
intptr_t avgArraySplitAmount = 0;
272
if (0 != env->_scavengerStats._arraySplitCount) {
273
avgArraySplitAmount = env->_scavengerStats._arraySplitAmount / env->_scavengerStats._arraySplitCount;
274
}
275
tgcExtensions->printf("SCV.T %6zu %4zu %8llu %8llu %5zu %5zu %5zu %5zu %5zu %5zu %5zu %7zu %6zu %6zu %6zu \n",
276
gcCount,
277
env->getWorkerID(),
278
j9time_hires_delta(0, scavengeTotalTime - env->_scavengerStats.getStallTime(), J9PORT_TIME_DELTA_IN_MICROSECONDS),
279
j9time_hires_delta(0, env->_scavengerStats.getStallTime(), J9PORT_TIME_DELTA_IN_MICROSECONDS),
280
env->_scavengerStats._acquireFreeListCount,
281
env->_scavengerStats._releaseFreeListCount,
282
env->_scavengerStats._acquireScanListCount,
283
env->_scavengerStats._releaseScanListCount,
284
env->_scavengerStats._acquireListLockCount,
285
env->_scavengerStats._arraySplitCount,
286
avgArraySplitAmount,
287
env->_scavengerStats._aliasToCopyCacheCount,
288
env->_scavengerStats._totalDeepStructures,
289
env->_scavengerStats._totalObjsDeepScanned,
290
env->_scavengerStats._depthDeepestStructure);
291
}
292
}
293
}
294
295
tgcExtensions->printf("\n");
296
tgcExtensions->printf(" gc micros idle busy active lists caches copied scanned updates scaling");
297
if (extensions->isConcurrentScavengerEnabled()) {
298
tgcExtensions->printf(" rb-copy rb-update\n");
299
} else {
300
tgcExtensions->printf("\n");
301
}
302
303
uintptr_t recordCount = 0;
304
uintptr_t totalRecordUpdates = 0;
305
MM_ScavengerCopyScanRatio::UpdateHistory *historyRecord = extensions->copyScanRatio.getHistory(&recordCount);
306
MM_ScavengerCopyScanRatio::UpdateHistory *endRecord = historyRecord + recordCount;
307
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
308
#if defined(OMR_GC_CONCURRENT_SCAVENGER)
309
uint64_t prevReadObjectBarrierCopy = 0;
310
uint64_t prevReadObjectBarrierUpdate = 0;
311
#endif /* OMR_GC_CONCURRENT_SCAVENGER */
312
while (historyRecord < endRecord) {
313
totalRecordUpdates += historyRecord->updates;
314
uint64_t elapsedMicros = extensions->copyScanRatio.getSpannedMicros(env, historyRecord);
315
double majorUpdates = (double)historyRecord->majorUpdates;
316
double lists = (double)historyRecord->lists / majorUpdates;
317
double caches = (double)historyRecord->caches / majorUpdates;
318
double threads = (double)historyRecord->threads / majorUpdates;
319
double waitingThreads = (double)historyRecord->waits / (double)historyRecord->updates;
320
double busyThreads = threads - waitingThreads;
321
double scalingFactor = extensions->copyScanRatio.getScalingFactor(env, historyRecord);
322
tgcExtensions->printf("SCV.H %6zu %6zu %6.1f %6.1f %6.1f %6.1f %6.1f %8zu %8zu %7zu %0.4f",
323
gcCount, elapsedMicros, waitingThreads, busyThreads, threads, lists, caches,
324
historyRecord->copied, historyRecord->scanned, historyRecord->updates, scalingFactor);
325
#if defined(OMR_GC_CONCURRENT_SCAVENGER)
326
if (extensions->isConcurrentScavengerEnabled()) {
327
tgcExtensions->printf(" %7zu %9zu\n", historyRecord->readObjectBarrierCopy - prevReadObjectBarrierCopy, historyRecord->readObjectBarrierUpdate - prevReadObjectBarrierUpdate);
328
prevReadObjectBarrierCopy = historyRecord->readObjectBarrierCopy;
329
prevReadObjectBarrierUpdate = historyRecord->readObjectBarrierUpdate;
330
} else
331
#endif /* OMR_GC_CONCURRENT_SCAVENGER */
332
{
333
tgcExtensions->printf("\n");
334
}
335
historyRecord += 1;
336
}
337
338
tgcExtensions->printf("\n");
339
tgcExtensions->printf(" \tgc\tleaf\talias\tsync-#\tsync-ms\twork-#\twork-ms\tend-#\tend-ms\tscaling\tupdates(major) overflow missed(minor)\n");
340
tgcExtensions->printf("SCV.M\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%lu\t%.3f\t%lu\t\t%lu\t %lu\n", gcCount,
341
extensions->scavengerStats._leafObjectCount, extensions->scavengerStats._aliasToCopyCacheCount,
342
extensions->scavengerStats._syncStallCount, j9time_hires_delta(0, extensions->scavengerStats._syncStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),
343
extensions->scavengerStats._workStallCount, j9time_hires_delta(0, extensions->scavengerStats._workStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),
344
extensions->scavengerStats._completeStallCount, j9time_hires_delta(0, extensions->scavengerStats._completeStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),
345
extensions->copyScanRatio.getScalingFactor(env), extensions->copyScanRatio.getScalingUpdateCount(), extensions->copyScanRatio.getOverflowCount(), (extensions->scavengerStats._copyScanUpdates - totalRecordUpdates)
346
);
347
348
tgcExtensions->printf("\n");
349
tgcExtensions->printf("SCV.D\t%lu", gcCount);
350
for (uint32_t i = 0; i < OMR_SCAVENGER_DISTANCE_BINS; i++) {
351
tgcExtensions->printf("\t%lu", extensions->scavengerStats._copy_distance_counts[i]);
352
}
353
tgcExtensions->printf("\n");
354
355
tgcExtensions->printf("\n");
356
tgcExtensions->printf("SCV.C\t%lu", gcCount);
357
for (uint32_t i = 0; i < 16; i++) {
358
tgcExtensions->printf("\t%lu", extensions->scavengerStats._copy_cachesize_counts[i]);
359
}
360
tgcExtensions->printf("\t%lu\n", extensions->scavengerStats._copy_cachesize_sum);
361
}
362
#endif /* J9VM_GC_MODRON_SCAVENGER */
363
364
#if defined(J9VM_GC_VLHGC)
365
static void
366
tgcHookCopyForwardEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
367
{
368
MM_LocalGCStartEvent* event = (MM_LocalGCStartEvent*)eventData;
369
J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;
370
MM_EnvironmentVLHGC *mainEnv = MM_EnvironmentVLHGC::getEnvironment(vmThread);
371
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vmThread);
372
373
J9VMThread *walkThread;
374
uint64_t copyForwardTotalTime;
375
PORT_ACCESS_FROM_VMC(vmThread);
376
377
tgcExtensions->printf("CP-FW: total | rem-set | copy | mark\n");
378
tgcExtensions->printf(" busy stall | stall | stall acquire release acquire release split terminate | stall acquire release exchange split\n");
379
tgcExtensions->printf(" (ms) (ms) | (ms) | (ms) freelist freelist scanlist scanlist arrays (ms) | (ms) packets packets packets arrays\n");
380
381
MM_CopyForwardStats *copyForwardStats = &static_cast<MM_CycleStateVLHGC*>(mainEnv->_cycleState)->_vlhgcIncrementStats._copyForwardStats;
382
copyForwardTotalTime = copyForwardStats->_endTime - copyForwardStats->_startTime;
383
384
GC_VMThreadListIterator threadListIterator(vmThread);
385
while ((walkThread = threadListIterator.nextVMThread()) != NULL) {
386
/* TODO: Are we guaranteed to get the threads in the right order? */
387
MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);
388
if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {
389
if (env->_copyForwardStats._gcCount == MM_GCExtensions::getExtensions(env)->globalVLHGCStats.gcCount) {
390
uint64_t totalStallTime = env->_copyForwardStats.getStallTime() + env->_workPacketStats.getStallTime();
391
tgcExtensions->printf("%4zu: %5llu %5llu %5llu %5llu %5zu %5zu %5zu %5zu %5zu %5llu %5llu %5zu %5zu %5zu %5zu\n",
392
env->getWorkerID(),
393
j9time_hires_delta(0, copyForwardTotalTime - totalStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
394
j9time_hires_delta(0, totalStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
395
j9time_hires_delta(0, env->_copyForwardStats._irrsStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
396
j9time_hires_delta(0, env->_copyForwardStats.getCopyForwardStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),
397
env->_copyForwardStats._acquireFreeListCount,
398
env->_copyForwardStats._releaseFreeListCount,
399
env->_copyForwardStats._acquireScanListCount,
400
env->_copyForwardStats._releaseScanListCount,
401
env->_copyForwardStats._copiedArraysSplit,
402
j9time_hires_delta(0, env->_copyForwardStats._abortStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),
403
j9time_hires_delta(0, env->_copyForwardStats._markStallTime + env->_workPacketStats.getStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),
404
env->_workPacketStats.workPacketsAcquired,
405
env->_workPacketStats.workPacketsReleased,
406
env->_workPacketStats.workPacketsExchanged,
407
env->_copyForwardStats._markedArraysSplit);
408
}
409
}
410
}
411
}
412
#endif /* J9VM_GC_VLHGC */
413
414
415
static void
416
tgcHookGlobalGcSweepStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
417
{
418
MM_SweepStartEvent* event = (MM_SweepStartEvent*)eventData;
419
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
420
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
421
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
422
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
423
424
parallelExtensions->sweepStartTime = omrtime_hires_clock();
425
}
426
427
static void
428
tgcHookGlobalGcSweepEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
429
{
430
MM_SweepEndEvent* event = (MM_SweepEndEvent*)eventData;
431
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
432
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
433
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
434
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
435
436
parallelExtensions->sweepEndTime = omrtime_hires_clock();
437
}
438
439
static void
440
tgcHookConcurrentRSStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
441
{
442
MM_ConcurrentRememberedSetScanStartEvent* event = (MM_ConcurrentRememberedSetScanStartEvent*)eventData;
443
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
444
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
445
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
446
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
447
448
parallelExtensions->RSScanStartTime = omrtime_hires_clock();
449
}
450
451
static void
452
tgcHookConcurrentRSEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
453
{
454
MM_ConcurrentRememberedSetScanEndEvent* event = (MM_ConcurrentRememberedSetScanEndEvent*)eventData;
455
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);
456
MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);
457
TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;
458
OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);
459
460
parallelExtensions->RSScanEndTime = omrtime_hires_clock();
461
}
462
463
464
/****************************************
465
* Initialization
466
****************************************
467
*/
468
469
bool
470
tgcParallelInitialize(J9JavaVM *javaVM)
471
{
472
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);
473
bool result = true;
474
475
J9HookInterface** omrHooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);
476
J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);
477
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_MARK_START, tgcHookGlobalGcMarkStart, OMR_GET_CALLSITE(), NULL);
478
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_MARK_END, tgcHookGlobalGcMarkEnd, OMR_GET_CALLSITE(), NULL);
479
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_START, tgcHookGlobalGcSweepStart, OMR_GET_CALLSITE(), NULL);
480
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_END, tgcHookGlobalGcSweepEnd, OMR_GET_CALLSITE(), NULL);
481
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_CONCURRENT_REMEMBERED_SET_SCAN_START, tgcHookConcurrentRSStart, OMR_GET_CALLSITE(), NULL);
482
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_CONCURRENT_REMEMBERED_SET_SCAN_END, tgcHookConcurrentRSEnd, OMR_GET_CALLSITE(), NULL);
483
484
if (extensions->isVLHGC()) {
485
#if defined(J9VM_GC_VLHGC)
486
(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_COPY_FORWARD_END, tgcHookCopyForwardEnd, OMR_GET_CALLSITE(), NULL);
487
#endif /* J9VM_GC_VLHGC*/
488
}
489
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, tgcHookGlobalGcEnd, OMR_GET_CALLSITE(), NULL);
490
if (extensions->isStandardGC()) {
491
#if defined(J9VM_GC_MODRON_SCAVENGER)
492
(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_END, tgcHookLocalGcEnd, OMR_GET_CALLSITE(), NULL);
493
#endif /* J9VM_GC_MODRON_SCAVENGER */
494
}
495
496
return result;
497
}
498
499