diff --git a/runtime/oti/j9nonbuilder.h b/runtime/oti/j9nonbuilder.h index 2cbe8a70de9..47e64458166 100644 --- a/runtime/oti/j9nonbuilder.h +++ b/runtime/oti/j9nonbuilder.h @@ -590,6 +590,12 @@ typedef struct J9JFRThreadAllocationStatistics { U_64 allocated; } J9JFRThreadAllocationStatistics; +typedef struct J9JFRPhysicalMemory { + J9JFR_EVENT_COMMON_FIELDS + U_64 totalSize; + U_64 usedSize; +} J9JFRPhysicalMemory; + #endif /* defined(J9VM_OPT_JFR) */ /* @ddr_namespace: map_to_type=J9CfrError */ diff --git a/runtime/vm/BufferWriter.hpp b/runtime/vm/BufferWriter.hpp index eeb6874d101..9f4ffb233d4 100644 --- a/runtime/vm/BufferWriter.hpp +++ b/runtime/vm/BufferWriter.hpp @@ -349,11 +349,13 @@ class VM_BufferWriter { { OMRPORT_ACCESS_FROM_J9PORT(_portLibrary); va_list args; + va_list args_copy; va_start(args, format); + va_copy(args_copy, args); /* Minus 1 because omrstr_vprintf accounts for null terminator if buffer is null. */ uintptr_t totalLength = omrstr_vprintf(NULL, 0, format, args) - 1; if (checkBounds(totalLength)) { - omrstr_vprintf((char *)_cursor, _bufferEnd - _cursor, format, args); + omrstr_vprintf((char *)_cursor, _bufferEnd - _cursor, format, args_copy); _cursor += totalLength; } va_end(args); diff --git a/runtime/vm/JFRChunkWriter.hpp b/runtime/vm/JFRChunkWriter.hpp index 61c2eea5f86..c307af32d25 100644 --- a/runtime/vm/JFRChunkWriter.hpp +++ b/runtime/vm/JFRChunkWriter.hpp @@ -218,7 +218,7 @@ class VM_JFRChunkWriter { static constexpr int MONITOR_ENTER_EVENT_SIZE = sizeof(U_32) + (3 * LEB128_64_SIZE) + (5 * LEB128_32_SIZE); static constexpr int THREAD_PARK_EVENT_SIZE = (9 * sizeof(U_64)) + sizeof(U_32); static constexpr int JVM_INFORMATION_EVENT_SIZE = 3000; - static constexpr int PHYSICAL_MEMORY_EVENT_SIZE = (4 * sizeof(U_64)) + sizeof(U_32); + static constexpr int PHYSICAL_MEMORY_EVENT_SIZE = LEB128_32_SIZE + (4 * LEB128_64_SIZE); static constexpr int VIRTUALIZATION_INFORMATION_EVENT_SIZE = 50; static constexpr int CPU_INFORMATION_EVENT_SIZE = 600; static constexpr int OS_INFORMATION_EVENT_SIZE = 100; @@ -479,6 +479,8 @@ class VM_JFRChunkWriter { pool_do(_constantPoolTypes.getGarbageCollectionTable(), &writeGarbageCollectionEvent, _bufferWriter); + pool_do(_constantPoolTypes.getPhysicalMemoryTable(), &writePhysicalMemoryEvent, _bufferWriter); + pool_do(_constantPoolTypes.getGCHeapSummaryTable(), &writeGCHeapSummaryEvent, _bufferWriter); pool_do(_constantPoolTypes.getNetworkUtilizationTable(), &writeNetworkUtilizationEvent, this); @@ -544,10 +546,6 @@ class VM_JFRChunkWriter { if (_constantPoolTypes.shouldWriteYoungGenerationConfigurationEvent()) { writeYoungGenerationConfigurationEvent(); } - - if (_constantPoolTypes.shouldWritePhysicalMemory()) { - writePhysicalMemoryEvent(); - } } writeJFRHeader(); @@ -875,6 +873,32 @@ class VM_JFRChunkWriter { writeEventSize(_bufferWriter, dataStart); } + static void + writePhysicalMemoryEvent(void *anElement, void *userData) + { + PhysicalMemoryEntry *entry = (PhysicalMemoryEntry *)anElement; + VM_BufferWriter *_bufferWriter = (VM_BufferWriter *)userData; + + /* reserve size field */ + U_8 *dataStart = reserveEventSize(_bufferWriter); + + /* write event type */ + _bufferWriter->writeLEB128(PhysicalMemoryID); + + /* write start time */ + _bufferWriter->writeLEB128(entry->ticks); + + /* write total size */ + _bufferWriter->writeLEB128(entry->totalSize); + + /* write used size */ + _bufferWriter->writeLEB128(entry->usedSize); + + /* write size */ + writeEventSize(_bufferWriter, dataStart); + } + + void writeJFRChunkToFile() { @@ -1047,7 +1071,7 @@ class VM_JFRChunkWriter { requiredBufferSize += OS_INFORMATION_EVENT_SIZE; - requiredBufferSize += PHYSICAL_MEMORY_EVENT_SIZE; + requiredBufferSize += (_constantPoolTypes.getPhysicalMemoryCount() * PHYSICAL_MEMORY_EVENT_SIZE); requiredBufferSize += VIRTUALIZATION_INFORMATION_EVENT_SIZE; diff --git a/runtime/vm/JFRConstantPoolTypes.cpp b/runtime/vm/JFRConstantPoolTypes.cpp index 3f5636a02df..fa42c04c91b 100644 --- a/runtime/vm/JFRConstantPoolTypes.cpp +++ b/runtime/vm/JFRConstantPoolTypes.cpp @@ -1561,6 +1561,28 @@ VM_JFRConstantPoolTypes::addThreadAllocationStatistics(J9JFRThreadAllocationStat entry->threadIndex = threadAlocationData->currentThreadTID; entry->allocated = threadAlocationData->allocated; + _threadAllocationStatisticsCount += 1; + +done: + return; +} + +void +VM_JFRConstantPoolTypes::addPhysicalMemoryEntry(J9JFRPhysicalMemory *physicalMemoryData) +{ + PhysicalMemoryEntry *entry = (PhysicalMemoryEntry *)pool_newElement(_physicalMemoryTable); + + if (NULL == entry) { + _buildResult = OutOfMemory; + goto done; + } + + entry->ticks = physicalMemoryData->startTicks; + entry->totalSize = physicalMemoryData->totalSize; + entry->usedSize = physicalMemoryData->usedSize; + + _physicalMemoryCount += 1; + done: return; } diff --git a/runtime/vm/JFRConstantPoolTypes.hpp b/runtime/vm/JFRConstantPoolTypes.hpp index 87080fa9f54..6dd18e21220 100644 --- a/runtime/vm/JFRConstantPoolTypes.hpp +++ b/runtime/vm/JFRConstantPoolTypes.hpp @@ -467,6 +467,12 @@ struct ThreadDumpEntry { UDATA resultLength; }; +struct PhysicalMemoryEntry { + I_64 ticks; + U_64 totalSize; + U_64 usedSize; +}; + struct JFRConstantEvents { JVMInformationEntry JVMInfoEntry; CPUInformationEntry CPUInfoEntry; @@ -563,6 +569,8 @@ class VM_JFRConstantPoolTypes { UDATA _threadDumpCount; J9Pool *_threadAllocationStatisticsTable; UDATA _threadAllocationStatisticsCount; + J9Pool *_physicalMemoryTable; + UDATA _physicalMemoryCount; /* Periodic events. */ bool _shouldWriteJVMInformation; @@ -573,7 +581,6 @@ class VM_JFRConstantPoolTypes { bool _shouldWriteInitialEnvironmentVariableEvents; bool _shouldWritewriteGCHeapConfigurationEvent; bool _shouldWriteYoungGenerationConfigurationEvent; - bool _shouldWritePhysicalMemory; bool _shouldWriteSystemProcess; bool _shouldWriteNativeLibrary; bool _shouldWriteModuleRequire; @@ -881,6 +888,9 @@ class VM_JFRConstantPoolTypes { void addGCHeapSummaryEntry(J9JFRGCHeapSummary *gcHeapSummaryData); void addNetworkUtilizationEntry(J9JFRNetworkUtilization *networkUtilizationData); + + void addPhysicalMemoryEntry(J9JFRPhysicalMemory *physicalMemoryData); + void addDataLossEntry(J9JFRDataLoss *dataLossData); void addThreadDumpEntry(J9JFRThreadDump *threadDumpData); @@ -1274,6 +1284,16 @@ class VM_JFRConstantPoolTypes { return _stackFrameCount; } + UDATA getPhysicalMemoryCount() + { + return _physicalMemoryCount; + } + + J9Pool *getPhysicalMemoryTable() + { + return _physicalMemoryTable; + } + bool shouldWriteJVMInformation() { return _shouldWriteJVMInformation; @@ -1314,11 +1334,6 @@ class VM_JFRConstantPoolTypes { return _shouldWriteYoungGenerationConfigurationEvent; } - bool shouldWritePhysicalMemory() - { - return _shouldWritePhysicalMemory; - } - bool shouldWriteSystemProcess() { return _shouldWriteSystemProcess; @@ -1448,7 +1463,7 @@ class VM_JFRConstantPoolTypes { _shouldWriteYoungGenerationConfigurationEvent = true; break; case J9JFR_EVENT_TYPE_PHYSICAL_MEMORY: - _shouldWritePhysicalMemory = true; + addPhysicalMemoryEntry((J9JFRPhysicalMemory *)event); break; case J9JFR_EVENT_TYPE_SYSTEM_PROCESS: _shouldWriteSystemProcess = true; @@ -2232,6 +2247,8 @@ class VM_JFRConstantPoolTypes { , _threadDumpCount(0) , _threadAllocationStatisticsTable(NULL) , _threadAllocationStatisticsCount(0) + , _physicalMemoryTable(NULL) + , _physicalMemoryCount(0) , _shouldWriteJVMInformation(false) , _shouldWriteCPUInformationEvent(false) , _shouldWriteVirtualizationInformationEvent(false) @@ -2240,7 +2257,6 @@ class VM_JFRConstantPoolTypes { , _shouldWriteInitialEnvironmentVariableEvents(false) , _shouldWritewriteGCHeapConfigurationEvent(false) , _shouldWriteYoungGenerationConfigurationEvent(false) - , _shouldWritePhysicalMemory(false) , _shouldWriteSystemProcess(false) , _shouldWriteNativeLibrary(false) , _shouldWriteModuleRequire(false) @@ -2406,6 +2422,13 @@ class VM_JFRConstantPoolTypes { goto done; } + _physicalMemoryTable = pool_new(sizeof(PhysicalMemoryEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary)); + if (NULL == _physicalMemoryTable) { + _buildResult = OutOfMemory; + goto done; + } + + _systemProcessTable = pool_new(sizeof(SystemProcessEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary)); if (NULL == _systemProcessTable) { _buildResult = OutOfMemory; @@ -2585,6 +2608,7 @@ class VM_JFRConstantPoolTypes { pool_kill(_dataLossTable); pool_kill(_threadDumpTable); pool_kill(_threadAllocationStatisticsTable); + pool_kill(_physicalMemoryTable); freeNetworkInterfaceNames(); j9mem_free_memory(_globalStringTable); } diff --git a/runtime/vm/jfr.cpp b/runtime/vm/jfr.cpp index c618e7b9d5c..28650fb4cf3 100644 --- a/runtime/vm/jfr.cpp +++ b/runtime/vm/jfr.cpp @@ -197,7 +197,6 @@ jfrEventSize(J9JFREvent *jfrEvent) case J9JFR_EVENT_TYPE_INITIAL_ENVIRONMENT_VARIABLE: case J9JFR_EVENT_TYPE_GC_HEAP_CONFIGURATION: case J9JFR_EVENT_TYPE_YOUNG_GENERATION_CONFIGURATION: - case J9JFR_EVENT_TYPE_PHYSICAL_MEMORY: case J9JFR_EVENT_TYPE_SYSTEM_PROCESS: case J9JFR_EVENT_TYPE_MODULE_REQUIRE: case J9JFR_EVENT_TYPE_MODULE_EXPORT: @@ -205,6 +204,9 @@ jfrEventSize(J9JFREvent *jfrEvent) case J9JFR_EVENT_TYPE_NATIVE_LIBRARY: size = sizeof(J9JFREvent); break; + case J9JFR_EVENT_TYPE_PHYSICAL_MEMORY: + size = sizeof(J9JFRPhysicalMemory); + break; default: Assert_VM_unreachable(); break; @@ -1621,6 +1623,24 @@ jfrThreadStatistics(J9VMThread *currentThread) } +static void +jfrPhysicalMemory(J9VMThread *currentThread) +{ + PORT_ACCESS_FROM_VMC(currentThread); + + J9MemoryInfo memInfo = {0}; + I_32 rc = j9sysinfo_get_memory_info(&memInfo); + + if (0 == rc) { + J9JFRPhysicalMemory *jfrEvent = (J9JFRPhysicalMemory *)reserveBuffer(currentThread, currentThread, sizeof(J9JFRPhysicalMemory)); + if (NULL != jfrEvent) { + initializeEventFields(currentThread, currentThread, (J9JFREvent *)jfrEvent, J9JFR_EVENT_TYPE_PHYSICAL_MEMORY); + jfrEvent->totalSize = memInfo.totalPhysical; + jfrEvent->usedSize = memInfo.totalPhysical - memInfo.availPhysical; + } + } +} + static int J9THREAD_PROC jfrSamplingThreadProc(void *entryArg) { @@ -2352,10 +2372,7 @@ JfrPeriodicEventSet::requestClassLoaderStatistics(J9VMThread *currentThread) void JfrPeriodicEventSet::requestPhysicalMemory(J9VMThread *currentThread) { - J9JFREvent *jfrEvent = (J9JFREvent *)reserveBuffer(currentThread, currentThread, sizeof(J9JFREvent)); - if (NULL != jfrEvent) { - initializeEventFields(currentThread, currentThread, jfrEvent, J9JFR_EVENT_TYPE_PHYSICAL_MEMORY); - } + jfrPhysicalMemory(currentThread); } void