Path: blob/master/src/hotspot/share/jfr/periodic/jfrPeriodic.cpp
41149 views
/*1* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#include "precompiled.hpp"25#include "jvm.h"26#include "classfile/classLoaderDataGraph.hpp"27#include "classfile/classLoaderStats.hpp"28#include "classfile/javaClasses.hpp"29#include "classfile/stringTable.hpp"30#include "classfile/symbolTable.hpp"31#include "classfile/systemDictionary.hpp"32#include "code/codeCache.hpp"33#include "compiler/compileBroker.hpp"34#include "gc/shared/gcConfiguration.hpp"35#include "gc/shared/gcTrace.hpp"36#include "gc/shared/gcVMOperations.hpp"37#include "gc/shared/objectCountEventSender.hpp"38#include "jfr/jfrEvents.hpp"39#include "jfr/periodic/jfrModuleEvent.hpp"40#include "jfr/periodic/jfrOSInterface.hpp"41#include "jfr/periodic/jfrThreadCPULoadEvent.hpp"42#include "jfr/periodic/jfrThreadDumpEvent.hpp"43#include "jfr/periodic/jfrNetworkUtilization.hpp"44#include "jfr/recorder/jfrRecorder.hpp"45#include "jfr/support/jfrThreadId.hpp"46#include "jfr/utilities/jfrThreadIterator.hpp"47#include "jfr/utilities/jfrTime.hpp"48#include "jfrfiles/jfrPeriodic.hpp"49#include "logging/log.hpp"50#include "memory/heapInspection.hpp"51#include "memory/resourceArea.hpp"52#include "oops/oop.inline.hpp"53#include "runtime/arguments.hpp"54#include "runtime/flags/jvmFlag.hpp"55#include "runtime/globals.hpp"56#include "runtime/interfaceSupport.inline.hpp"57#include "runtime/os.hpp"58#include "runtime/os_perf.hpp"59#include "runtime/thread.inline.hpp"60#include "runtime/sweeper.hpp"61#include "runtime/vmThread.hpp"62#include "runtime/vm_version.hpp"63#include "services/classLoadingService.hpp"64#include "services/management.hpp"65#include "services/threadService.hpp"66#include "utilities/exceptions.hpp"67#include "utilities/globalDefinitions.hpp"68#if INCLUDE_G1GC69#include "gc/g1/g1HeapRegionEventSender.hpp"70#endif71#if INCLUDE_SHENANDOAHGC72#include "gc/shenandoah/shenandoahJfrSupport.hpp"73#endif74/**75* JfrPeriodic class76* Implementation of declarations in77* xsl generated traceRequestables.hpp78*/79#define TRACE_REQUEST_FUNC(id) void JfrPeriodicEventSet::request##id(void)8081TRACE_REQUEST_FUNC(JVMInformation) {82ResourceMark rm;83EventJVMInformation event;84event.set_jvmName(VM_Version::vm_name());85event.set_jvmVersion(VM_Version::internal_vm_info_string());86event.set_javaArguments(Arguments::java_command());87event.set_jvmArguments(Arguments::jvm_args());88event.set_jvmFlags(Arguments::jvm_flags());89event.set_jvmStartTime(Management::vm_init_done_time());90event.set_pid(os::current_process_id());91event.commit();92}9394TRACE_REQUEST_FUNC(OSInformation) {95ResourceMark rm;96char* os_name = NEW_RESOURCE_ARRAY(char, 2048);97JfrOSInterface::os_version(&os_name);98EventOSInformation event;99event.set_osVersion(os_name);100event.commit();101}102103TRACE_REQUEST_FUNC(VirtualizationInformation) {104EventVirtualizationInformation event;105event.set_name(JfrOSInterface::virtualization_name());106event.commit();107}108109TRACE_REQUEST_FUNC(ModuleRequire) {110JfrModuleEvent::generate_module_dependency_events();111}112113TRACE_REQUEST_FUNC(ModuleExport) {114JfrModuleEvent::generate_module_export_events();115}116117/*118* This is left empty on purpose, having ExecutionSample as a requestable119* is a way of getting the period. The period is passed to ThreadSampling::update_period.120* Implementation in jfrSamples.cpp121*/122TRACE_REQUEST_FUNC(ExecutionSample) {123}124TRACE_REQUEST_FUNC(NativeMethodSample) {125}126127TRACE_REQUEST_FUNC(ThreadDump) {128ResourceMark rm;129EventThreadDump event;130event.set_result(JfrDcmdEvent::thread_dump());131event.commit();132}133134static int _native_library_callback(const char* name, address base, address top, void *param) {135EventNativeLibrary event(UNTIMED);136event.set_name(name);137event.set_baseAddress((u8)base);138event.set_topAddress((u8)top);139event.set_endtime(*(JfrTicks*) param);140event.commit();141return 0;142}143144TRACE_REQUEST_FUNC(NativeLibrary) {145JfrTicks ts= JfrTicks::now();146os::get_loaded_modules_info(&_native_library_callback, (void *)&ts);147}148149TRACE_REQUEST_FUNC(InitialEnvironmentVariable) {150JfrOSInterface::generate_initial_environment_variable_events();151}152153TRACE_REQUEST_FUNC(CPUInformation) {154CPUInformation cpu_info;155int ret_val = JfrOSInterface::cpu_information(cpu_info);156if (ret_val == OS_ERR) {157log_debug(jfr, system)( "Unable to generate requestable event CPUInformation");158return;159}160if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {161return;162}163if (ret_val == OS_OK) {164EventCPUInformation event;165event.set_cpu(cpu_info.cpu_name());166event.set_description(cpu_info.cpu_description());167event.set_sockets(cpu_info.number_of_sockets());168event.set_cores(cpu_info.number_of_cores());169event.set_hwThreads(cpu_info.number_of_hardware_threads());170event.commit();171}172}173174TRACE_REQUEST_FUNC(CPULoad) {175double u = 0; // user time176double s = 0; // kernel time177double t = 0; // total time178int ret_val = OS_ERR;179{180// Can take some time on certain platforms, especially under heavy load.181// Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.182ThreadToNativeFromVM transition(JavaThread::current());183ret_val = JfrOSInterface::cpu_loads_process(&u, &s, &t);184}185if (ret_val == OS_ERR) {186log_debug(jfr, system)( "Unable to generate requestable event CPULoad");187return;188}189if (ret_val == OS_OK) {190EventCPULoad event;191event.set_jvmUser((float)u);192event.set_jvmSystem((float)s);193event.set_machineTotal((float)t);194event.commit();195}196}197198TRACE_REQUEST_FUNC(ThreadCPULoad) {199JfrThreadCPULoadEvent::send_events();200}201202TRACE_REQUEST_FUNC(NetworkUtilization) {203JfrNetworkUtilization::send_events();204}205206TRACE_REQUEST_FUNC(CPUTimeStampCounter) {207EventCPUTimeStampCounter event;208event.set_fastTimeEnabled(JfrTime::is_ft_enabled());209event.set_fastTimeAutoEnabled(JfrTime::is_ft_supported());210event.set_osFrequency(os::elapsed_frequency());211event.set_fastTimeFrequency(JfrTime::frequency());212event.commit();213}214215TRACE_REQUEST_FUNC(SystemProcess) {216char pid_buf[16];217SystemProcess* processes = NULL;218int num_of_processes = 0;219JfrTicks start_time = JfrTicks::now();220int ret_val = JfrOSInterface::system_processes(&processes, &num_of_processes);221if (ret_val == OS_ERR) {222log_debug(jfr, system)( "Unable to generate requestable event SystemProcesses");223return;224}225JfrTicks end_time = JfrTicks::now();226if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {227return;228}229if (ret_val == OS_OK) {230// feature is implemented, write real event231while (processes != NULL) {232SystemProcess* tmp = processes;233const char* info = processes->command_line();234if (info == NULL) {235info = processes->path();236}237if (info == NULL) {238info = processes->name();239}240if (info == NULL) {241info = "?";242}243jio_snprintf(pid_buf, sizeof(pid_buf), "%d", processes->pid());244EventSystemProcess event(UNTIMED);245event.set_pid(pid_buf);246event.set_commandLine(info);247event.set_starttime(start_time);248event.set_endtime(end_time);249event.commit();250processes = processes->next();251delete tmp;252}253}254}255256TRACE_REQUEST_FUNC(ThreadContextSwitchRate) {257double rate = 0.0;258int ret_val = OS_ERR;259{260// Can take some time on certain platforms, especially under heavy load.261// Transition to native to avoid unnecessary stalls for pending safepoint synchronizations.262ThreadToNativeFromVM transition(JavaThread::current());263ret_val = JfrOSInterface::context_switch_rate(&rate);264}265if (ret_val == OS_ERR) {266log_debug(jfr, system)( "Unable to generate requestable event ThreadContextSwitchRate");267return;268}269if (ret_val == FUNCTIONALITY_NOT_IMPLEMENTED) {270return;271}272if (ret_val == OS_OK) {273EventThreadContextSwitchRate event;274event.set_switchRate((float)rate + 0.0f);275event.commit();276}277}278279#define SEND_FLAGS_OF_TYPE(eventType, flagType) \280do { \281JVMFlag *flag = JVMFlag::flags; \282while (flag->name() != NULL) { \283if (flag->is_ ## flagType()) { \284if (flag->is_unlocked()) { \285Event ## eventType event; \286event.set_name(flag->name()); \287event.set_value(flag->get_ ## flagType()); \288event.set_origin(static_cast<u8>(flag->get_origin())); \289event.commit(); \290} \291} \292++flag; \293} \294} while (0)295296TRACE_REQUEST_FUNC(IntFlag) {297SEND_FLAGS_OF_TYPE(IntFlag, int);298}299300TRACE_REQUEST_FUNC(UnsignedIntFlag) {301SEND_FLAGS_OF_TYPE(UnsignedIntFlag, uint);302}303304TRACE_REQUEST_FUNC(LongFlag) {305SEND_FLAGS_OF_TYPE(LongFlag, intx);306}307308TRACE_REQUEST_FUNC(UnsignedLongFlag) {309SEND_FLAGS_OF_TYPE(UnsignedLongFlag, uintx);310SEND_FLAGS_OF_TYPE(UnsignedLongFlag, uint64_t);311SEND_FLAGS_OF_TYPE(UnsignedLongFlag, size_t);312}313314TRACE_REQUEST_FUNC(DoubleFlag) {315SEND_FLAGS_OF_TYPE(DoubleFlag, double);316}317318TRACE_REQUEST_FUNC(BooleanFlag) {319SEND_FLAGS_OF_TYPE(BooleanFlag, bool);320}321322TRACE_REQUEST_FUNC(StringFlag) {323SEND_FLAGS_OF_TYPE(StringFlag, ccstr);324}325326class VM_GC_SendObjectCountEvent : public VM_GC_HeapInspection {327public:328VM_GC_SendObjectCountEvent() : VM_GC_HeapInspection(NULL, true) {}329virtual void doit() {330ObjectCountEventSender::enable_requestable_event();331collect();332ObjectCountEventSender::disable_requestable_event();333}334};335336TRACE_REQUEST_FUNC(ObjectCount) {337VM_GC_SendObjectCountEvent op;338VMThread::execute(&op);339}340341TRACE_REQUEST_FUNC(G1HeapRegionInformation) {342G1GC_ONLY(G1HeapRegionEventSender::send_events());343}344345// Java Mission Control (JMC) uses (Java) Long.MIN_VALUE to describe that a346// long value is undefined.347static jlong jmc_undefined_long = min_jlong;348349TRACE_REQUEST_FUNC(GCConfiguration) {350GCConfiguration conf;351jlong pause_target = conf.has_pause_target_default_value() ? jmc_undefined_long : conf.pause_target();352EventGCConfiguration event;353event.set_youngCollector(conf.young_collector());354event.set_oldCollector(conf.old_collector());355event.set_parallelGCThreads(conf.num_parallel_gc_threads());356event.set_concurrentGCThreads(conf.num_concurrent_gc_threads());357event.set_usesDynamicGCThreads(conf.uses_dynamic_gc_threads());358event.set_isExplicitGCConcurrent(conf.is_explicit_gc_concurrent());359event.set_isExplicitGCDisabled(conf.is_explicit_gc_disabled());360event.set_gcTimeRatio(conf.gc_time_ratio());361event.set_pauseTarget((s8)pause_target);362event.commit();363}364365TRACE_REQUEST_FUNC(GCTLABConfiguration) {366GCTLABConfiguration conf;367EventGCTLABConfiguration event;368event.set_usesTLABs(conf.uses_tlabs());369event.set_minTLABSize(conf.min_tlab_size());370event.set_tlabRefillWasteLimit(conf.tlab_refill_waste_limit());371event.commit();372}373374TRACE_REQUEST_FUNC(GCSurvivorConfiguration) {375GCSurvivorConfiguration conf;376EventGCSurvivorConfiguration event;377event.set_maxTenuringThreshold(conf.max_tenuring_threshold());378event.set_initialTenuringThreshold(conf.initial_tenuring_threshold());379event.commit();380}381382TRACE_REQUEST_FUNC(GCHeapConfiguration) {383GCHeapConfiguration conf;384EventGCHeapConfiguration event;385event.set_minSize(conf.min_size());386event.set_maxSize(conf.max_size());387event.set_initialSize(conf.initial_size());388event.set_usesCompressedOops(conf.uses_compressed_oops());389event.set_compressedOopsMode(conf.narrow_oop_mode());390event.set_objectAlignment(conf.object_alignment_in_bytes());391event.set_heapAddressBits(conf.heap_address_size_in_bits());392event.commit();393}394395TRACE_REQUEST_FUNC(YoungGenerationConfiguration) {396GCYoungGenerationConfiguration conf;397jlong max_size = conf.has_max_size_default_value() ? jmc_undefined_long : conf.max_size();398EventYoungGenerationConfiguration event;399event.set_maxSize((u8)max_size);400event.set_minSize(conf.min_size());401event.set_newRatio(conf.new_ratio());402event.commit();403}404405TRACE_REQUEST_FUNC(InitialSystemProperty) {406SystemProperty* p = Arguments::system_properties();407JfrTicks time_stamp = JfrTicks::now();408while (p != NULL) {409if (!p->internal()) {410EventInitialSystemProperty event(UNTIMED);411event.set_key(p->key());412event.set_value(p->value());413event.set_endtime(time_stamp);414event.commit();415}416p = p->next();417}418}419420TRACE_REQUEST_FUNC(ThreadAllocationStatistics) {421ResourceMark rm;422int initial_size = Threads::number_of_threads();423GrowableArray<jlong> allocated(initial_size);424GrowableArray<traceid> thread_ids(initial_size);425JfrTicks time_stamp = JfrTicks::now();426JfrJavaThreadIterator iter;427while (iter.has_next()) {428JavaThread* const jt = iter.next();429assert(jt != NULL, "invariant");430allocated.append(jt->cooked_allocated_bytes());431thread_ids.append(JFR_THREAD_ID(jt));432}433434// Write allocation statistics to buffer.435for(int i = 0; i < thread_ids.length(); i++) {436EventThreadAllocationStatistics event(UNTIMED);437event.set_allocated(allocated.at(i));438event.set_thread(thread_ids.at(i));439event.set_endtime(time_stamp);440event.commit();441}442}443444/**445* PhysicalMemory event represents:446*447* @totalSize == The amount of physical memory (hw) installed and reported by the OS, in bytes.448* @usedSize == The amount of physical memory currently in use in the system (reserved/committed), in bytes.449*450* Both fields are systemwide, i.e. represents the entire OS/HW environment.451* These fields do not include virtual memory.452*453* If running inside a guest OS on top of a hypervisor in a virtualized environment,454* the total memory reported is the amount of memory configured for the guest OS by the hypervisor.455*/456TRACE_REQUEST_FUNC(PhysicalMemory) {457u8 totalPhysicalMemory = os::physical_memory();458EventPhysicalMemory event;459event.set_totalSize(totalPhysicalMemory);460event.set_usedSize(totalPhysicalMemory - os::available_memory());461event.commit();462}463464TRACE_REQUEST_FUNC(JavaThreadStatistics) {465EventJavaThreadStatistics event;466event.set_activeCount(ThreadService::get_live_thread_count());467event.set_daemonCount(ThreadService::get_daemon_thread_count());468event.set_accumulatedCount(ThreadService::get_total_thread_count());469event.set_peakCount(ThreadService::get_peak_thread_count());470event.commit();471}472473TRACE_REQUEST_FUNC(ClassLoadingStatistics) {474EventClassLoadingStatistics event;475event.set_loadedClassCount(ClassLoadingService::loaded_class_count());476event.set_unloadedClassCount(ClassLoadingService::unloaded_class_count());477event.commit();478}479480class JfrClassLoaderStatsClosure : public ClassLoaderStatsClosure {481public:482JfrClassLoaderStatsClosure() : ClassLoaderStatsClosure(NULL) {}483484bool do_entry(oop const& key, ClassLoaderStats const& cls) {485const ClassLoaderData* this_cld = cls._class_loader != NULL ?486java_lang_ClassLoader::loader_data_acquire(cls._class_loader) : NULL;487const ClassLoaderData* parent_cld = cls._parent != NULL ?488java_lang_ClassLoader::loader_data_acquire(cls._parent) : NULL;489EventClassLoaderStatistics event;490event.set_classLoader(this_cld);491event.set_parentClassLoader(parent_cld);492event.set_classLoaderData((intptr_t)cls._cld);493event.set_classCount(cls._classes_count);494event.set_chunkSize(cls._chunk_sz);495event.set_blockSize(cls._block_sz);496event.set_hiddenClassCount(cls._hidden_classes_count);497event.set_hiddenChunkSize(cls._hidden_chunk_sz);498event.set_hiddenBlockSize(cls._hidden_block_sz);499event.commit();500return true;501}502503void createEvents(void) {504_stats->iterate(this);505}506};507508class JfrClassLoaderStatsVMOperation : public ClassLoaderStatsVMOperation {509public:510JfrClassLoaderStatsVMOperation() : ClassLoaderStatsVMOperation(NULL) { }511512void doit() {513JfrClassLoaderStatsClosure clsc;514ClassLoaderDataGraph::loaded_cld_do(&clsc);515clsc.createEvents();516}517};518519TRACE_REQUEST_FUNC(ClassLoaderStatistics) {520JfrClassLoaderStatsVMOperation op;521VMThread::execute(&op);522}523524template<typename EVENT>525static void emit_table_statistics(TableStatistics statistics) {526EVENT event;527event.set_bucketCount(statistics._number_of_buckets);528event.set_entryCount(statistics._number_of_entries);529event.set_totalFootprint(statistics._total_footprint);530event.set_bucketCountMaximum(statistics._maximum_bucket_size);531event.set_bucketCountAverage(statistics._average_bucket_size);532event.set_bucketCountVariance(statistics._variance_of_bucket_size);533event.set_bucketCountStandardDeviation(statistics._stddev_of_bucket_size);534event.set_insertionRate(statistics._add_rate);535event.set_removalRate(statistics._remove_rate);536event.commit();537}538539TRACE_REQUEST_FUNC(SymbolTableStatistics) {540TableStatistics statistics = SymbolTable::get_table_statistics();541emit_table_statistics<EventSymbolTableStatistics>(statistics);542}543544TRACE_REQUEST_FUNC(StringTableStatistics) {545TableStatistics statistics = StringTable::get_table_statistics();546emit_table_statistics<EventStringTableStatistics>(statistics);547}548549TRACE_REQUEST_FUNC(PlaceholderTableStatistics) {550TableStatistics statistics = SystemDictionary::placeholders_statistics();551emit_table_statistics<EventPlaceholderTableStatistics>(statistics);552}553554TRACE_REQUEST_FUNC(LoaderConstraintsTableStatistics) {555TableStatistics statistics = SystemDictionary::loader_constraints_statistics();556emit_table_statistics<EventLoaderConstraintsTableStatistics>(statistics);557}558559TRACE_REQUEST_FUNC(ProtectionDomainCacheTableStatistics) {560TableStatistics statistics = SystemDictionary::protection_domain_cache_statistics();561emit_table_statistics<EventProtectionDomainCacheTableStatistics>(statistics);562}563564TRACE_REQUEST_FUNC(CompilerStatistics) {565EventCompilerStatistics event;566event.set_compileCount(CompileBroker::get_total_compile_count());567event.set_bailoutCount(CompileBroker::get_total_bailout_count());568event.set_invalidatedCount(CompileBroker::get_total_invalidated_count());569event.set_osrCompileCount(CompileBroker::get_total_osr_compile_count());570event.set_standardCompileCount(CompileBroker::get_total_standard_compile_count());571event.set_osrBytesCompiled(CompileBroker::get_sum_osr_bytes_compiled());572event.set_standardBytesCompiled(CompileBroker::get_sum_standard_bytes_compiled());573event.set_nmethodsSize(CompileBroker::get_sum_nmethod_size());574event.set_nmethodCodeSize(CompileBroker::get_sum_nmethod_code_size());575event.set_peakTimeSpent(CompileBroker::get_peak_compilation_time());576event.set_totalTimeSpent(CompileBroker::get_total_compilation_time());577event.commit();578}579580TRACE_REQUEST_FUNC(CompilerConfiguration) {581EventCompilerConfiguration event;582event.set_threadCount(CICompilerCount);583event.set_tieredCompilation(TieredCompilation);584event.commit();585}586587TRACE_REQUEST_FUNC(CodeCacheStatistics) {588// Emit stats for all available code heaps589for (int bt = 0; bt < CodeBlobType::NumTypes; ++bt) {590if (CodeCache::heap_available(bt)) {591EventCodeCacheStatistics event;592event.set_codeBlobType((u1)bt);593event.set_startAddress((u8)CodeCache::low_bound(bt));594event.set_reservedTopAddress((u8)CodeCache::high_bound(bt));595event.set_entryCount(CodeCache::blob_count(bt));596event.set_methodCount(CodeCache::nmethod_count(bt));597event.set_adaptorCount(CodeCache::adapter_count(bt));598event.set_unallocatedCapacity(CodeCache::unallocated_capacity(bt));599event.set_fullCount(CodeCache::get_codemem_full_count(bt));600event.commit();601}602}603}604605TRACE_REQUEST_FUNC(CodeCacheConfiguration) {606EventCodeCacheConfiguration event;607event.set_initialSize(InitialCodeCacheSize);608event.set_reservedSize(ReservedCodeCacheSize);609event.set_nonNMethodSize(NonNMethodCodeHeapSize);610event.set_profiledSize(ProfiledCodeHeapSize);611event.set_nonProfiledSize(NonProfiledCodeHeapSize);612event.set_expansionSize(CodeCacheExpansionSize);613event.set_minBlockLength(CodeCacheMinBlockLength);614event.set_startAddress((u8)CodeCache::low_bound());615event.set_reservedTopAddress((u8)CodeCache::high_bound());616event.commit();617}618619TRACE_REQUEST_FUNC(CodeSweeperStatistics) {620EventCodeSweeperStatistics event;621event.set_sweepCount(NMethodSweeper::traversal_count());622event.set_methodReclaimedCount(NMethodSweeper::total_nof_methods_reclaimed());623event.set_totalSweepTime(NMethodSweeper::total_time_sweeping());624event.set_peakFractionTime(NMethodSweeper::peak_sweep_fraction_time());625event.set_peakSweepTime(NMethodSweeper::peak_sweep_time());626event.commit();627}628629TRACE_REQUEST_FUNC(CodeSweeperConfiguration) {630EventCodeSweeperConfiguration event;631event.set_sweeperEnabled(MethodFlushing);632event.set_flushingEnabled(UseCodeCacheFlushing);633event.set_sweepThreshold(NMethodSweeper::sweep_threshold_bytes());634event.commit();635}636637638TRACE_REQUEST_FUNC(ShenandoahHeapRegionInformation) {639#if INCLUDE_SHENANDOAHGC640if (UseShenandoahGC) {641VM_ShenandoahSendHeapRegionInfoEvents op;642VMThread::execute(&op);643}644#endif645}646647648