Path: blob/master/runtime/gc_verbose_handler_standard_java/VerboseHandlerOutputStandardJava.cpp
5986 views
/*******************************************************************************1* Copyright (c) 1991, 2020 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 "j9modron.h"23#include "modronbase.h"24#include "omrgcconsts.h"25#include "mmhook.h"26#include "gcutils.h"2728#include "CollectionStatisticsStandard.hpp"29#include "ConcurrentGCStats.hpp"30#include "CycleState.hpp"31#include "EnvironmentBase.hpp"32#include "GCExtensions.hpp"33#include "ScanClassesMode.hpp"34#include "VerboseHandlerOutputStandardJava.hpp"35#include "VerboseManager.hpp"36#include "VerboseWriterChain.hpp"37#include "VerboseHandlerJava.hpp"3839#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)40static void verboseHandlerClassUnloadingEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData);41#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */42static void verboseHandlerSlowExclusive(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);4344MM_VerboseHandlerOutput *45MM_VerboseHandlerOutputStandardJava::newInstance(MM_EnvironmentBase *env, MM_VerboseManager *manager)46{47MM_GCExtensions* extensions = MM_GCExtensions::getExtensions(env->getOmrVM());4849MM_VerboseHandlerOutputStandardJava *verboseHandlerOutput = (MM_VerboseHandlerOutputStandardJava *)extensions->getForge()->allocate(sizeof(MM_VerboseHandlerOutputStandardJava), MM_AllocationCategory::FIXED, J9_GET_CALLSITE());50if (NULL != verboseHandlerOutput) {51new(verboseHandlerOutput) MM_VerboseHandlerOutputStandardJava(extensions);52if(!verboseHandlerOutput->initialize(env, manager)) {53verboseHandlerOutput->kill(env);54verboseHandlerOutput = NULL;55}56}57return verboseHandlerOutput;58}5960bool61MM_VerboseHandlerOutputStandardJava::initialize(MM_EnvironmentBase *env, MM_VerboseManager *manager)62{63bool initSuccess = MM_VerboseHandlerOutputStandard::initialize(env, manager);64_mmHooks = J9_HOOK_INTERFACE(MM_GCExtensions::getExtensions(_extensions)->hookInterface);65J9JavaVM *javaVM = (J9JavaVM *)env->getOmrVM()->_language_vm;66_vmHooks = J9_HOOK_INTERFACE(javaVM->hookInterface);6768return initSuccess;69}7071void72MM_VerboseHandlerOutputStandardJava::tearDown(MM_EnvironmentBase *env)73{74MM_VerboseHandlerOutputStandard::tearDown(env);75}7677void78MM_VerboseHandlerOutputStandardJava::outputMemoryInfoInnerStanzaInternal(MM_EnvironmentBase *env, UDATA indent, MM_CollectionStatistics *statsBase)79{80MM_VerboseHandlerJava::outputFinalizableInfo(_manager, env, indent);81}8283void84MM_VerboseHandlerOutputStandardJava::enableVerbose()85{86MM_VerboseHandlerOutputStandard::enableVerbose();8788#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)89(*_mmHooks)->J9HookRegisterWithCallSite(_mmHooks, J9HOOK_MM_CLASS_UNLOADING_END, verboseHandlerClassUnloadingEnd, OMR_GET_CALLSITE(), (void *)this);90#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */91(*_vmHooks)->J9HookRegisterWithCallSite(_vmHooks, J9HOOK_VM_SLOW_EXCLUSIVE, verboseHandlerSlowExclusive, OMR_GET_CALLSITE(), (void *)this);9293}9495void96MM_VerboseHandlerOutputStandardJava::disableVerbose()97{98MM_VerboseHandlerOutputStandard::disableVerbose();99100#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)101(*_mmHooks)->J9HookUnregister(_mmHooks, J9HOOK_MM_CLASS_UNLOADING_END, verboseHandlerClassUnloadingEnd, NULL);102#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */103(*_vmHooks)->J9HookUnregister(_vmHooks, J9HOOK_VM_SLOW_EXCLUSIVE, verboseHandlerSlowExclusive, NULL);104105}106107bool108MM_VerboseHandlerOutputStandardJava::getThreadName(char *buf, UDATA bufLen, OMR_VMThread *vmThread)109{110return MM_VerboseHandlerJava::getThreadName(buf,bufLen,vmThread);111}112113void114MM_VerboseHandlerOutputStandardJava::writeVmArgs(MM_EnvironmentBase* env, MM_VerboseBuffer* buffer)115{116MM_VerboseHandlerJava::writeVmArgs(env, buffer, static_cast<J9JavaVM*>(_omrVM->_language_vm));117}118119void120MM_VerboseHandlerOutputStandardJava::outputUnfinalizedInfo(MM_EnvironmentBase *env, UDATA indent, UDATA unfinalizedCandidates, UDATA unfinalizedEnqueuedCount)121{122if(0 != unfinalizedCandidates) {123_manager->getWriterChain()->formatAndOutput(env, indent, "<finalization candidates=\"%zu\" enqueued=\"%zu\" />", unfinalizedCandidates, unfinalizedEnqueuedCount);124}125}126127void128MM_VerboseHandlerOutputStandardJava::outputOwnableSynchronizerInfo(MM_EnvironmentBase *env, UDATA indent, UDATA ownableSynchronizerCandidates, UDATA ownableSynchronizerCleared)129{130if (0 != ownableSynchronizerCandidates) {131_manager->getWriterChain()->formatAndOutput(env, indent, "<ownableSynchronizers candidates=\"%zu\" cleared=\"%zu\" />", ownableSynchronizerCandidates, ownableSynchronizerCleared);132}133}134135void136MM_VerboseHandlerOutputStandardJava::outputReferenceInfo(MM_EnvironmentBase *env, UDATA indent, const char *referenceType, MM_ReferenceStats *referenceStats, UDATA dynamicThreshold, UDATA maxThreshold)137{138if(0 != referenceStats->_candidates) {139if (0 != maxThreshold) {140_manager->getWriterChain()->formatAndOutput(env, indent, "<references type=\"%s\" candidates=\"%zu\" cleared=\"%zu\" enqueued=\"%zu\" dynamicThreshold=\"%zu\" maxThreshold=\"%zu\" />",141referenceType, referenceStats->_candidates, referenceStats->_cleared, referenceStats->_enqueued, dynamicThreshold, maxThreshold);142} else {143_manager->getWriterChain()->formatAndOutput(env, indent, "<references type=\"%s\" candidates=\"%zu\" cleared=\"%zu\" enqueued=\"%zu\" />",144referenceType, referenceStats->_candidates, referenceStats->_cleared, referenceStats->_enqueued);145}146}147}148149void150MM_VerboseHandlerOutputStandardJava::handleMarkEndInternal(MM_EnvironmentBase* env, void *eventData)151{152MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());153MM_MarkJavaStats *markJavaStats = &extensions->markJavaStats;154MM_WorkPacketStats *workPacketStats = &_extensions->globalGCStats.workPacketStats;155156outputUnfinalizedInfo(env, 1, markJavaStats->_unfinalizedCandidates, markJavaStats->_unfinalizedEnqueued);157158outputOwnableSynchronizerInfo(env, 1, markJavaStats->_ownableSynchronizerCandidates, markJavaStats->_ownableSynchronizerCleared);159160outputReferenceInfo(env, 1, "soft", &markJavaStats->_softReferenceStats, extensions->getDynamicMaxSoftReferenceAge(), extensions->getMaxSoftReferenceAge());161outputReferenceInfo(env, 1, "weak", &markJavaStats->_weakReferenceStats, 0, 0);162outputReferenceInfo(env, 1, "phantom", &markJavaStats->_phantomReferenceStats, 0, 0);163164outputStringConstantInfo(env, 1, markJavaStats->_stringConstantsCandidates, markJavaStats->_stringConstantsCleared);165outputMonitorReferenceInfo(env, 1, markJavaStats->_monitorReferenceCandidates, markJavaStats->_monitorReferenceCleared);166167if (workPacketStats->getSTWWorkStackOverflowOccured()) {168_manager->getWriterChain()->formatAndOutput(env, 1, "<warning details=\"work packet overflow\" count=\"%zu\" packetcount=\"%zu\" />",169workPacketStats->getSTWWorkStackOverflowCount(), workPacketStats->getSTWWorkpacketCountAtOverflow());170}171}172173void174MM_VerboseHandlerOutputStandardJava::handleSlowExclusive(J9HookInterface **hook, UDATA eventNum, void *eventData)175{176J9VMSlowExclusiveEvent *event = (J9VMSlowExclusiveEvent *) eventData;177MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(event->currentThread->omrVMThread);178MM_VerboseManager *manager = getManager();179MM_VerboseWriterChain *writer = manager->getWriterChain();180181char threadName[64];182getThreadName(threadName,sizeof(threadName),event->currentThread->omrVMThread);183184enterAtomicReportingBlock();185writer->formatAndOutput(env, 0,"<warning details=\"slow exclusive request due to %s\" threadname=\"%s\" timems=\"%zu\" />", (event->reason == 1)?"JNICritical":"Exclusive Access", threadName, event->timeTaken);186writer->flush(env);187exitAtomicReportingBlock();188189}190191#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)192void193MM_VerboseHandlerOutputStandardJava::handleClassUnloadEnd(J9HookInterface** hook, UDATA eventNum, void* eventData)194{195MM_ClassUnloadingEndEvent* event = (MM_ClassUnloadingEndEvent*)eventData;196MM_EnvironmentBase* env = MM_EnvironmentBase::getEnvironment(event->currentThread->omrVMThread);197MM_VerboseManager* manager = getManager();198MM_VerboseWriterChain* writer = manager->getWriterChain();199MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());200MM_ClassUnloadStats *classUnloadStats = &extensions->globalGCStats.classUnloadStats;201PORT_ACCESS_FROM_ENVIRONMENT(env);202U_64 duration = 0;203bool deltaTimeSuccess = getTimeDeltaInMicroSeconds(&duration, classUnloadStats->_startTime, classUnloadStats->_endTime);204205enterAtomicReportingBlock();206handleGCOPOuterStanzaStart(env, "classunload", env->_cycleState->_verboseContextID, duration, deltaTimeSuccess);207208U_64 setupTime = j9time_hires_delta(classUnloadStats->_startSetupTime, classUnloadStats->_endSetupTime, J9PORT_TIME_DELTA_IN_MICROSECONDS);209U_64 scanTime = j9time_hires_delta(classUnloadStats->_startScanTime, classUnloadStats->_endScanTime, J9PORT_TIME_DELTA_IN_MICROSECONDS);210U_64 postTime = j9time_hires_delta(classUnloadStats->_startPostTime, classUnloadStats->_endPostTime, J9PORT_TIME_DELTA_IN_MICROSECONDS);211/* !!!Note: classUnloadStats->_classUnloadMutexQuiesceTime is in us already, do not convert it again!!!*/212213writer->formatAndOutput(214env, 1,215"<classunload-info classloadercandidates=\"%zu\" classloadersunloaded=\"%zu\" classesunloaded=\"%zu\" anonymousclassesunloaded=\"%zu\""216" quiescems=\"%llu.%03.3llu\" setupms=\"%llu.%03.3llu\" scanms=\"%llu.%03.3llu\" postms=\"%llu.%03.3llu\" />",217classUnloadStats->_classLoaderCandidates, classUnloadStats->_classLoaderUnloadedCount, classUnloadStats->_classesUnloadedCount, classUnloadStats->_anonymousClassesUnloadedCount,218classUnloadStats->_classUnloadMutexQuiesceTime / 1000, classUnloadStats->_classUnloadMutexQuiesceTime % 1000,219setupTime / 1000, setupTime % 1000,220scanTime / 1000, scanTime % 1000,221postTime / 1000, postTime % 1000);222223handleGCOPOuterStanzaEnd(env);224writer->flush(env);225exitAtomicReportingBlock();226}227#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */228229#if defined(J9VM_GC_MODRON_SCAVENGER)230void231MM_VerboseHandlerOutputStandardJava::handleScavengeEndInternal(MM_EnvironmentBase* env, void *eventData)232{233MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env->getOmrVM());234MM_ScavengeEndEvent* event = (MM_ScavengeEndEvent*)eventData;235236if (event->cycleEnd) {237MM_ScavengerJavaStats *scavengerJavaStats = &extensions->scavengerJavaStats;238239outputUnfinalizedInfo(env, 1, scavengerJavaStats->_unfinalizedCandidates, scavengerJavaStats->_unfinalizedEnqueued);240241outputOwnableSynchronizerInfo(env, 1, scavengerJavaStats->_ownableSynchronizerCandidates, (scavengerJavaStats->_ownableSynchronizerCandidates - scavengerJavaStats->_ownableSynchronizerTotalSurvived));242243outputReferenceInfo(env, 1, "soft", &scavengerJavaStats->_softReferenceStats, extensions->getDynamicMaxSoftReferenceAge(), extensions->getMaxSoftReferenceAge());244outputReferenceInfo(env, 1, "weak", &scavengerJavaStats->_weakReferenceStats, 0, 0);245outputReferenceInfo(env, 1, "phantom", &scavengerJavaStats->_phantomReferenceStats, 0, 0);246247outputMonitorReferenceInfo(env, 1, scavengerJavaStats->_monitorReferenceCandidates, scavengerJavaStats->_monitorReferenceCleared);248}249}250#endif /*defined(J9VM_GC_MODRON_SCAVENGER) */251252#if defined(OMR_GC_MODRON_CONCURRENT_MARK)253254const char*255MM_VerboseHandlerOutputStandardJava::getConcurrentKickoffReason(void *eventData)256{257MM_ConcurrentKickoffEvent* event = (MM_ConcurrentKickoffEvent*)eventData;258const char* reasonString;259260if ((ConcurrentKickoffReason) event->reason == LANGUAGE_DEFINED_REASON) {261262switch (event->languageReason) {263case FORCED_UNLOADING_CLASSES:264reasonString = "unloading classes requested";265break;266case NO_LANGUAGE_KICKOFF_REASON:267/* Should never be the case */268reasonString = "none";269break;270default:271reasonString = "unknown";272break;273}274275} else {276/* Defer to generic reason handler.*/277return MM_VerboseHandlerOutputStandard::getConcurrentKickoffReason(event);278}279280return reasonString;281}282283284#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)285void286MM_VerboseHandlerOutputStandardJava::handleConcurrentHaltedInternal(MM_EnvironmentBase *env, void *eventData)287{288MM_ConcurrentHaltedEvent* event = (MM_ConcurrentHaltedEvent*)eventData;289MM_VerboseManager* manager = getManager();290MM_VerboseWriterChain* writer = manager->getWriterChain();291#define CONCURRENT_STATUS_BUFFER_LENGTH 32292char statusBuffer[CONCURRENT_STATUS_BUFFER_LENGTH];293const char* statusString = MM_ConcurrentGCStats::getConcurrentStatusString(env, event->executionMode, statusBuffer, CONCURRENT_STATUS_BUFFER_LENGTH);294#undef CONCURRENT_STATUS_BUFFER_LENGTH295const char* stateString = "Complete";296if (0 == event->isTracingExhausted) {297stateString = "Tracing incomplete";298}299300switch (event->scanClassesMode) {301case MM_ScanClassesMode::SCAN_CLASSES_NEED_TO_BE_EXECUTED:302case MM_ScanClassesMode::SCAN_CLASSES_CURRENTLY_ACTIVE:303stateString = "Class scanning incomplete";304break;305case MM_ScanClassesMode::SCAN_CLASSES_COMPLETE:306case MM_ScanClassesMode::SCAN_CLASSES_DISABLED:307break;308default:309stateString = "Class scanning bad state";310break;311}312313writer->formatAndOutput(env, 1, "<halted state=\"%s\" status=\"%s\" />", stateString, statusString);314}315#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */316#endif /* defined(OMR_GC_MODRON_CONCURRENT_MARK) */317318#if defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING)319void320verboseHandlerClassUnloadingEnd(J9HookInterface** hook, UDATA eventNum, void* eventData, void* userData)321{322((MM_VerboseHandlerOutputStandardJava *)userData)->handleClassUnloadEnd(hook, eventNum, eventData);323}324#endif /* defined(J9VM_GC_DYNAMIC_CLASS_UNLOADING) */325326void327verboseHandlerSlowExclusive(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData)328{329((MM_VerboseHandlerOutputStandardJava *)userData)->handleSlowExclusive(hook, eventNum, eventData);330}331332333