Path: blob/master/runtime/gc_trace/TgcParallel.cpp
5985 views
/*******************************************************************************1* Copyright (c) 1991, 2021 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* 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-exception20*******************************************************************************/2122#include "j9.h"23#include "j9cfg.h"24#include "j9port.h"25#include "modronopt.h"26#include "mmhook.h"27#include "ModronAssertions.h"2829#if defined(J9VM_GC_VLHGC)30#include "CycleStateVLHGC.hpp"31#endif /* J9VM_GC_VLHGC */32#include "EnvironmentVLHGC.hpp"33#include "GCExtensions.hpp"34#include "TgcExtensions.hpp"35#include "VMThreadListIterator.hpp"3637/****************************************38* Hook callbacks39****************************************40*/4142static void43tgcHookGlobalGcEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)44{45MM_GlobalGCEndEvent* event = (MM_GlobalGCEndEvent*)eventData;46J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;47J9JavaVM *javaVM = vmThread->javaVM;48MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);49MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);50TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;51PORT_ACCESS_FROM_JAVAVM(javaVM);525354uint64_t RSScanTotalTime = parallelExtensions->RSScanEndTime - parallelExtensions->RSScanStartTime;5556if (0 != RSScanTotalTime) {57tgcExtensions->printf("RS : busy stall acquire release exchange \n");5859GC_VMThreadListIterator markThreadListIterator(vmThread);60J9VMThread *walkThread = NULL;61while ((walkThread = markThreadListIterator.nextVMThread()) != NULL) {62MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(walkThread->omrVMThread);63if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {64bool shouldIncludeThread = true;65if (extensions->isStandardGC()) {66#if defined(J9VM_GC_MODRON_STANDARD)67/* Concurrent RS Scan Task does not have its own stats struct,68* so rely on Mark Task stats gcCount, which is atm identical (all phases of one GC are run with same number of threads) */69shouldIncludeThread = env->_markStats._gcCount == extensions->globalGCStats.gcCount;70#endif /* defined(J9VM_GC_MODRON_STANDARD) */71}7273/* Get RS busy and stall times and convert time from microseconds to milliseconds for reporting */74uint64_t rsStallTimeInMillis = ((uint64_t)(env->_workPacketStats.getStallTime())) / 1000;75uint64_t rsBusyTimeInMillis = (RSScanTotalTime / 1000) - rsStallTimeInMillis;7677if (shouldIncludeThread) {78tgcExtensions->printf("%4zu: %5llu %5llu %5zu %5zu %5zu\n",79env->getWorkerID(),80rsBusyTimeInMillis,81rsStallTimeInMillis,82env->_workPacketStatsRSScan.workPacketsAcquired,83env->_workPacketStatsRSScan.workPacketsReleased,84env->_workPacketStatsRSScan.workPacketsExchanged);85}86}87}88}8990uint64_t markTotalTime = parallelExtensions->markEndTime - parallelExtensions->markStartTime;9192if (0 != markTotalTime) {93tgcExtensions->printf("Mark: busy stall acquire release exchange split array split size\n");9495GC_VMThreadListIterator markThreadListIterator(vmThread);96J9VMThread *walkThread = NULL;97while ((walkThread = markThreadListIterator.nextVMThread()) != NULL) {98/* TODO: Are we guaranteed to get the threads in the right order? */99MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);100if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {101uint64_t markStatsStallTime = 0;102intptr_t splitArraysProcessed = 0;103intptr_t splitArraysAmount = 0;104bool shouldIncludeThread = true;105if (extensions->isVLHGC()) {106#if defined(J9VM_GC_VLHGC)107markStatsStallTime = env->_markVLHGCStats.getStallTime();108splitArraysProcessed = env->_markVLHGCStats._splitArraysProcessed;109shouldIncludeThread = env->_markVLHGCStats._gcCount == extensions->globalVLHGCStats.gcCount;110#endif /* J9VM_GC_VLHGC */111} else if (extensions->isStandardGC()) {112#if defined(J9VM_GC_MODRON_STANDARD)113markStatsStallTime = env->_markStats.getStallTime();114splitArraysProcessed = env->getGCEnvironment()->_markJavaStats.splitArraysProcessed;115splitArraysAmount = env->getGCEnvironment()->_markJavaStats.splitArraysAmount;116shouldIncludeThread = env->_markStats._gcCount == extensions->globalGCStats.gcCount;117#endif /* defined(J9VM_GC_MODRON_STANDARD) */118}119120if (shouldIncludeThread) {121intptr_t avgSplitSize = 0;122if (0 != splitArraysProcessed) {123avgSplitSize = splitArraysAmount / splitArraysProcessed;124}125tgcExtensions->printf("%4zu: %5llu %5llu %5zu %5zu %5zu %5zu %7zu\n",126env->getWorkerID(),127j9time_hires_delta(0, markTotalTime - (markStatsStallTime + env->_workPacketStats.getStallTime()), J9PORT_TIME_DELTA_IN_MILLISECONDS),128j9time_hires_delta(0, markStatsStallTime + env->_workPacketStats.getStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),129env->_workPacketStats.workPacketsAcquired,130env->_workPacketStats.workPacketsReleased,131env->_workPacketStats.workPacketsExchanged,132splitArraysProcessed,133avgSplitSize);134}135136/* TODO: VLHGC doesn't record gc count yet, allowing us to determine if thread participated */137if (extensions->isVLHGC()) {138/* TODO: Must reset thread-local stats after using them -- is there another answer? */139/* When it becomes possible for a GC to not use all of the worker threads, this becomes140* necessary, otherwise we might use outdated stats.141*/142env->_workPacketStats.clear();143}144145parallelExtensions->markStartTime = 0;146parallelExtensions->markEndTime = 0;147}148}149}150151uint64_t sweepTotalTime = parallelExtensions->sweepEndTime - parallelExtensions->sweepStartTime;152153if (0 != sweepTotalTime) {154intptr_t mainSweepChunksTotal = 0;155uint64_t mainSweepMergeTime = 0;156if (extensions->isVLHGC()) {157#if defined(J9VM_GC_VLHGC)158MM_EnvironmentVLHGC *mainEnv = MM_EnvironmentVLHGC::getEnvironment(vmThread);159mainSweepChunksTotal = mainEnv->_sweepVLHGCStats.sweepChunksTotal;160mainSweepMergeTime = mainEnv->_sweepVLHGCStats.mergeTime;161#endif /* J9VM_GC_VLHGC */162} else if (extensions->isStandardGC()) {163#if defined(J9VM_GC_MODRON_STANDARD)164MM_EnvironmentBase *mainEnv = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);165mainSweepChunksTotal = mainEnv->_sweepStats.sweepChunksTotal;166mainSweepMergeTime = mainEnv->_sweepStats.mergeTime;167#endif /* defined(J9VM_GC_MODRON_STANDARD) */168}169170tgcExtensions->printf("Sweep: busy idle sections %zu merge %llu\n",171mainSweepChunksTotal,172j9time_hires_delta(0, mainSweepMergeTime, J9PORT_TIME_DELTA_IN_MILLISECONDS));173174175GC_VMThreadListIterator sweepThreadListIterator(vmThread);176J9VMThread *walkThread = NULL;177while ((walkThread = sweepThreadListIterator.nextVMThread()) != NULL) {178/* TODO: Are we guaranteed to get the threads in the right order? */179MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);180if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {181uint64_t sweepIdleTime = 0;182intptr_t sweepChunksProcessed = 0;183bool shouldIncludeThread = true;184if (extensions->isVLHGC()) {185#if defined(J9VM_GC_VLHGC)186sweepIdleTime = env->_sweepVLHGCStats.idleTime;187sweepChunksProcessed = env->_sweepVLHGCStats.sweepChunksProcessed;188shouldIncludeThread = env->_sweepVLHGCStats._gcCount == extensions->globalVLHGCStats.gcCount;189#endif /* J9VM_GC_VLHGC */190} else if (extensions->isStandardGC()) {191#if defined(J9VM_GC_MODRON_STANDARD)192sweepIdleTime = env->_sweepStats.idleTime;193sweepChunksProcessed = env->_sweepStats.sweepChunksProcessed;194shouldIncludeThread = env->_sweepStats._gcCount == extensions->globalGCStats.gcCount;195#endif /* defined(J9VM_GC_MODRON_STANDARD) */196}197198parallelExtensions->sweepStartTime = 0;199parallelExtensions->sweepEndTime = 0;200201if (shouldIncludeThread) {202tgcExtensions->printf("%4zu: %6llu %6llu %8zu\n",203env->getWorkerID(),204j9time_hires_delta(0, sweepTotalTime - sweepIdleTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),205j9time_hires_delta(0, sweepIdleTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),206sweepChunksProcessed);207}208}209}210}211}212213static void214tgcHookGlobalGcMarkStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)215{216MM_MarkStartEvent* event = (MM_MarkStartEvent*)eventData;217MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);218MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);219TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;220OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);221222parallelExtensions->markStartTime = omrtime_hires_clock();223}224225static void226tgcHookGlobalGcMarkEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)227{228MM_MarkEndEvent* event = (MM_MarkEndEvent*)eventData;229MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);230MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);231TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;232OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);233234parallelExtensions->markEndTime = omrtime_hires_clock();235}236237#if defined(J9VM_GC_MODRON_SCAVENGER)238static void239tgcHookLocalGcEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)240{241MM_LocalGCEndEvent* event = (MM_LocalGCEndEvent*)eventData;242J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;243MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vmThread->javaVM);244MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);245246J9VMThread *walkThread;247uint64_t scavengeTotalTime;248PORT_ACCESS_FROM_VMC(vmThread);249OMRPORT_ACCESS_FROM_J9PORT(PORTLIB);250251char timestamp[32];252int64_t timeInMillis = j9time_current_time_millis();253omrstr_ftime_ex(timestamp, sizeof(timestamp), "%Y-%m-%dT%H:%M:%S", timeInMillis, OMRSTR_FTIME_FLAG_LOCAL);254tgcExtensions->printf("\n");255tgcExtensions->printf("Scavenger parallel and progress stats, timestamp=\"%s.%ld\"\n", timestamp, timeInMillis % 1000);256257tgcExtensions->printf(" gc thrID busy stall acquire release acquire release acquire split avg split alias to deep total deepest\n");258tgcExtensions->printf(" (micros) (micros) freelist freelist scanlist scanlist lock arrays arraysize copycache lists deep objs list\n");259260scavengeTotalTime = event->incrementEndTime - event->incrementStartTime;261uintptr_t gcCount = extensions->scavengerStats._gcCount;262263GC_VMThreadListIterator scavengeThreadListIterator(vmThread);264while ((walkThread = scavengeThreadListIterator.nextVMThread()) != NULL) {265/* TODO: Are we guaranteed to get the threads in the right order? */266MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(walkThread->omrVMThread);267if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {268/* check if this thread participated in the GC */269if (env->_scavengerStats._gcCount == extensions->scavengerStats._gcCount) {270intptr_t avgArraySplitAmount = 0;271if (0 != env->_scavengerStats._arraySplitCount) {272avgArraySplitAmount = env->_scavengerStats._arraySplitAmount / env->_scavengerStats._arraySplitCount;273}274tgcExtensions->printf("SCV.T %6zu %4zu %8llu %8llu %5zu %5zu %5zu %5zu %5zu %5zu %5zu %7zu %6zu %6zu %6zu \n",275gcCount,276env->getWorkerID(),277j9time_hires_delta(0, scavengeTotalTime - env->_scavengerStats.getStallTime(), J9PORT_TIME_DELTA_IN_MICROSECONDS),278j9time_hires_delta(0, env->_scavengerStats.getStallTime(), J9PORT_TIME_DELTA_IN_MICROSECONDS),279env->_scavengerStats._acquireFreeListCount,280env->_scavengerStats._releaseFreeListCount,281env->_scavengerStats._acquireScanListCount,282env->_scavengerStats._releaseScanListCount,283env->_scavengerStats._acquireListLockCount,284env->_scavengerStats._arraySplitCount,285avgArraySplitAmount,286env->_scavengerStats._aliasToCopyCacheCount,287env->_scavengerStats._totalDeepStructures,288env->_scavengerStats._totalObjsDeepScanned,289env->_scavengerStats._depthDeepestStructure);290}291}292}293294tgcExtensions->printf("\n");295tgcExtensions->printf(" gc micros idle busy active lists caches copied scanned updates scaling");296if (extensions->isConcurrentScavengerEnabled()) {297tgcExtensions->printf(" rb-copy rb-update\n");298} else {299tgcExtensions->printf("\n");300}301302uintptr_t recordCount = 0;303uintptr_t totalRecordUpdates = 0;304MM_ScavengerCopyScanRatio::UpdateHistory *historyRecord = extensions->copyScanRatio.getHistory(&recordCount);305MM_ScavengerCopyScanRatio::UpdateHistory *endRecord = historyRecord + recordCount;306MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);307#if defined(OMR_GC_CONCURRENT_SCAVENGER)308uint64_t prevReadObjectBarrierCopy = 0;309uint64_t prevReadObjectBarrierUpdate = 0;310#endif /* OMR_GC_CONCURRENT_SCAVENGER */311while (historyRecord < endRecord) {312totalRecordUpdates += historyRecord->updates;313uint64_t elapsedMicros = extensions->copyScanRatio.getSpannedMicros(env, historyRecord);314double majorUpdates = (double)historyRecord->majorUpdates;315double lists = (double)historyRecord->lists / majorUpdates;316double caches = (double)historyRecord->caches / majorUpdates;317double threads = (double)historyRecord->threads / majorUpdates;318double waitingThreads = (double)historyRecord->waits / (double)historyRecord->updates;319double busyThreads = threads - waitingThreads;320double scalingFactor = extensions->copyScanRatio.getScalingFactor(env, historyRecord);321tgcExtensions->printf("SCV.H %6zu %6zu %6.1f %6.1f %6.1f %6.1f %6.1f %8zu %8zu %7zu %0.4f",322gcCount, elapsedMicros, waitingThreads, busyThreads, threads, lists, caches,323historyRecord->copied, historyRecord->scanned, historyRecord->updates, scalingFactor);324#if defined(OMR_GC_CONCURRENT_SCAVENGER)325if (extensions->isConcurrentScavengerEnabled()) {326tgcExtensions->printf(" %7zu %9zu\n", historyRecord->readObjectBarrierCopy - prevReadObjectBarrierCopy, historyRecord->readObjectBarrierUpdate - prevReadObjectBarrierUpdate);327prevReadObjectBarrierCopy = historyRecord->readObjectBarrierCopy;328prevReadObjectBarrierUpdate = historyRecord->readObjectBarrierUpdate;329} else330#endif /* OMR_GC_CONCURRENT_SCAVENGER */331{332tgcExtensions->printf("\n");333}334historyRecord += 1;335}336337tgcExtensions->printf("\n");338tgcExtensions->printf(" \tgc\tleaf\talias\tsync-#\tsync-ms\twork-#\twork-ms\tend-#\tend-ms\tscaling\tupdates(major) overflow missed(minor)\n");339tgcExtensions->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,340extensions->scavengerStats._leafObjectCount, extensions->scavengerStats._aliasToCopyCacheCount,341extensions->scavengerStats._syncStallCount, j9time_hires_delta(0, extensions->scavengerStats._syncStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),342extensions->scavengerStats._workStallCount, j9time_hires_delta(0, extensions->scavengerStats._workStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),343extensions->scavengerStats._completeStallCount, j9time_hires_delta(0, extensions->scavengerStats._completeStallTime, J9PORT_TIME_DELTA_IN_MICROSECONDS),344extensions->copyScanRatio.getScalingFactor(env), extensions->copyScanRatio.getScalingUpdateCount(), extensions->copyScanRatio.getOverflowCount(), (extensions->scavengerStats._copyScanUpdates - totalRecordUpdates)345);346347tgcExtensions->printf("\n");348tgcExtensions->printf("SCV.D\t%lu", gcCount);349for (uint32_t i = 0; i < OMR_SCAVENGER_DISTANCE_BINS; i++) {350tgcExtensions->printf("\t%lu", extensions->scavengerStats._copy_distance_counts[i]);351}352tgcExtensions->printf("\n");353354tgcExtensions->printf("\n");355tgcExtensions->printf("SCV.C\t%lu", gcCount);356for (uint32_t i = 0; i < 16; i++) {357tgcExtensions->printf("\t%lu", extensions->scavengerStats._copy_cachesize_counts[i]);358}359tgcExtensions->printf("\t%lu\n", extensions->scavengerStats._copy_cachesize_sum);360}361#endif /* J9VM_GC_MODRON_SCAVENGER */362363#if defined(J9VM_GC_VLHGC)364static void365tgcHookCopyForwardEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)366{367MM_LocalGCStartEvent* event = (MM_LocalGCStartEvent*)eventData;368J9VMThread* vmThread = (J9VMThread*)event->currentThread->_language_vmthread;369MM_EnvironmentVLHGC *mainEnv = MM_EnvironmentVLHGC::getEnvironment(vmThread);370MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(vmThread);371372J9VMThread *walkThread;373uint64_t copyForwardTotalTime;374PORT_ACCESS_FROM_VMC(vmThread);375376tgcExtensions->printf("CP-FW: total | rem-set | copy | mark\n");377tgcExtensions->printf(" busy stall | stall | stall acquire release acquire release split terminate | stall acquire release exchange split\n");378tgcExtensions->printf(" (ms) (ms) | (ms) | (ms) freelist freelist scanlist scanlist arrays (ms) | (ms) packets packets packets arrays\n");379380MM_CopyForwardStats *copyForwardStats = &static_cast<MM_CycleStateVLHGC*>(mainEnv->_cycleState)->_vlhgcIncrementStats._copyForwardStats;381copyForwardTotalTime = copyForwardStats->_endTime - copyForwardStats->_startTime;382383GC_VMThreadListIterator threadListIterator(vmThread);384while ((walkThread = threadListIterator.nextVMThread()) != NULL) {385/* TODO: Are we guaranteed to get the threads in the right order? */386MM_EnvironmentVLHGC *env = MM_EnvironmentVLHGC::getEnvironment(walkThread);387if ((walkThread == vmThread) || (env->getThreadType() == GC_WORKER_THREAD)) {388if (env->_copyForwardStats._gcCount == MM_GCExtensions::getExtensions(env)->globalVLHGCStats.gcCount) {389uint64_t totalStallTime = env->_copyForwardStats.getStallTime() + env->_workPacketStats.getStallTime();390tgcExtensions->printf("%4zu: %5llu %5llu %5llu %5llu %5zu %5zu %5zu %5zu %5zu %5llu %5llu %5zu %5zu %5zu %5zu\n",391env->getWorkerID(),392j9time_hires_delta(0, copyForwardTotalTime - totalStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),393j9time_hires_delta(0, totalStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),394j9time_hires_delta(0, env->_copyForwardStats._irrsStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),395j9time_hires_delta(0, env->_copyForwardStats.getCopyForwardStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),396env->_copyForwardStats._acquireFreeListCount,397env->_copyForwardStats._releaseFreeListCount,398env->_copyForwardStats._acquireScanListCount,399env->_copyForwardStats._releaseScanListCount,400env->_copyForwardStats._copiedArraysSplit,401j9time_hires_delta(0, env->_copyForwardStats._abortStallTime, J9PORT_TIME_DELTA_IN_MILLISECONDS),402j9time_hires_delta(0, env->_copyForwardStats._markStallTime + env->_workPacketStats.getStallTime(), J9PORT_TIME_DELTA_IN_MILLISECONDS),403env->_workPacketStats.workPacketsAcquired,404env->_workPacketStats.workPacketsReleased,405env->_workPacketStats.workPacketsExchanged,406env->_copyForwardStats._markedArraysSplit);407}408}409}410}411#endif /* J9VM_GC_VLHGC */412413414static void415tgcHookGlobalGcSweepStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)416{417MM_SweepStartEvent* event = (MM_SweepStartEvent*)eventData;418MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);419MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);420TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;421OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);422423parallelExtensions->sweepStartTime = omrtime_hires_clock();424}425426static void427tgcHookGlobalGcSweepEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)428{429MM_SweepEndEvent* event = (MM_SweepEndEvent*)eventData;430MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);431MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);432TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;433OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);434435parallelExtensions->sweepEndTime = omrtime_hires_clock();436}437438static void439tgcHookConcurrentRSStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)440{441MM_ConcurrentRememberedSetScanStartEvent* event = (MM_ConcurrentRememberedSetScanStartEvent*)eventData;442MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);443MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);444TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;445OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);446447parallelExtensions->RSScanStartTime = omrtime_hires_clock();448}449450static void451tgcHookConcurrentRSEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)452{453MM_ConcurrentRememberedSetScanEndEvent* event = (MM_ConcurrentRememberedSetScanEndEvent*)eventData;454MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(event->currentThread);455MM_TgcExtensions *tgcExtensions = MM_TgcExtensions::getExtensions(extensions);456TgcParallelExtensions *parallelExtensions = &tgcExtensions->_parallel;457OMRPORT_ACCESS_FROM_OMRVMTHREAD(event->currentThread);458459parallelExtensions->RSScanEndTime = omrtime_hires_clock();460}461462463/****************************************464* Initialization465****************************************466*/467468bool469tgcParallelInitialize(J9JavaVM *javaVM)470{471MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(javaVM);472bool result = true;473474J9HookInterface** omrHooks = J9_HOOK_INTERFACE(extensions->omrHookInterface);475J9HookInterface** privateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);476(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_MARK_START, tgcHookGlobalGcMarkStart, OMR_GET_CALLSITE(), NULL);477(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_MARK_END, tgcHookGlobalGcMarkEnd, OMR_GET_CALLSITE(), NULL);478(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_START, tgcHookGlobalGcSweepStart, OMR_GET_CALLSITE(), NULL);479(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_SWEEP_END, tgcHookGlobalGcSweepEnd, OMR_GET_CALLSITE(), NULL);480(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_CONCURRENT_REMEMBERED_SET_SCAN_START, tgcHookConcurrentRSStart, OMR_GET_CALLSITE(), NULL);481(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_CONCURRENT_REMEMBERED_SET_SCAN_END, tgcHookConcurrentRSEnd, OMR_GET_CALLSITE(), NULL);482483if (extensions->isVLHGC()) {484#if defined(J9VM_GC_VLHGC)485(*privateHooks)->J9HookRegisterWithCallSite(privateHooks, J9HOOK_MM_PRIVATE_COPY_FORWARD_END, tgcHookCopyForwardEnd, OMR_GET_CALLSITE(), NULL);486#endif /* J9VM_GC_VLHGC*/487}488(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_GLOBAL_GC_END, tgcHookGlobalGcEnd, OMR_GET_CALLSITE(), NULL);489if (extensions->isStandardGC()) {490#if defined(J9VM_GC_MODRON_SCAVENGER)491(*omrHooks)->J9HookRegisterWithCallSite(omrHooks, J9HOOK_MM_OMR_LOCAL_GC_END, tgcHookLocalGcEnd, OMR_GET_CALLSITE(), NULL);492#endif /* J9VM_GC_MODRON_SCAVENGER */493}494495return result;496}497498499