From 586a6f4536a6e9dbccaae4fb5f5fa2ac57274628 Mon Sep 17 00:00:00 2001 From: Marius Date: Thu, 5 Oct 2023 07:59:22 -0700 Subject: [PATCH] Add options for sizing the IProfiler hash tables Two new -Xjit options are introduced which can be used to control the number of buckets in the two hash tables used by IProfiler: -Xjit:iprofilerBcHashTableSize= -Xjit:iprofilerMethodHashTableSize= Note that these hash tables are not dynamically resizeable. This commit does not change the default values for these two hash tables. Signed-off-by: Marius --- runtime/compiler/control/J9Options.cpp | 7 +++++++ runtime/compiler/control/J9Options.hpp | 2 ++ runtime/compiler/runtime/IProfiler.cpp | 26 ++++++++++++-------------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/runtime/compiler/control/J9Options.cpp b/runtime/compiler/control/J9Options.cpp index 3591e0579be..81be702b1d6 100644 --- a/runtime/compiler/control/J9Options.cpp +++ b/runtime/compiler/control/J9Options.cpp @@ -171,6 +171,9 @@ int32_t J9::Options::_iProfilerMemoryConsumptionLimit=32*1024*1024; #else int32_t J9::Options::_iProfilerMemoryConsumptionLimit=18*1024*1024; #endif +int32_t J9::Options::_iProfilerBcHashTableSize = 34501; // prime number; Note: 131049 * 8 fits in 1 segment of persistent memory +int32_t J9::Options::_iProfilerMethodHashTableSize = 12007; // 32707 could be another good value for larger apps + int32_t J9::Options::_IprofilerOffSubtractionFactor = 500; int32_t J9::Options::_IprofilerOffDivisionFactor = 16; @@ -1005,6 +1008,8 @@ TR::OptionTable OMR::Options::_feOptions[] = { TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_interpreterSamplingThresholdInStartupMode, 0, "F%d", NOT_IN_SUBSET}, {"invocationThresholdToTriggerLowPriComp=", "M\tNumber of times a loopy method must be invoked to be eligible for LPQ", TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_invocationThresholdToTriggerLowPriComp, 0, "F%d", NOT_IN_SUBSET }, + {"iprofilerBcHashTableSize=", "M\tSize of the backbone for the IProfiler bytecode hash table", + TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_iProfilerBcHashTableSize, 0, "F%d", NOT_IN_SUBSET}, {"iprofilerBufferInterarrivalTimeToExitDeepIdle=", "M\tIn ms. If 4 IP buffers arrive back-to-back more frequently than this value, JIT exits DEEP_IDLE", TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_iProfilerBufferInterarrivalTimeToExitDeepIdle, 0, "F%d", NOT_IN_SUBSET }, {"iprofilerBufferMaxPercentageToDiscard=", "O\tpercentage of interpreter profiling buffers " @@ -1024,6 +1029,8 @@ TR::OptionTable OMR::Options::_feOptions[] = { TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_maxIprofilingCountInStartupMode, 0, "F%d", NOT_IN_SUBSET}, {"iprofilerMemoryConsumptionLimit=", "O\tlimit on memory consumption for interpreter profiling data", TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_iProfilerMemoryConsumptionLimit, 0, "P%d", NOT_IN_SUBSET}, + {"iprofilerMethodHashTableSize=", "M\tSize of the backbone for the IProfiler method (fanin) hash table", + TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_iProfilerMethodHashTableSize, 0, "F%d", NOT_IN_SUBSET}, {"iprofilerNumOutstandingBuffers=", "O\tnumber of outstanding interpreter profiling buffers " "allowed in the system. Specify 0 to disable this optimization", TR::Options::setStaticNumeric, (intptr_t)&TR::Options::_iprofilerNumOutstandingBuffers, 0, "F%d", NOT_IN_SUBSET}, diff --git a/runtime/compiler/control/J9Options.hpp b/runtime/compiler/control/J9Options.hpp index 55584153b3e..234034eb0e5 100644 --- a/runtime/compiler/control/J9Options.hpp +++ b/runtime/compiler/control/J9Options.hpp @@ -277,6 +277,8 @@ class OMR_EXTENSIBLE Options : public OMR::OptionsConnector static int32_t _iprofilerFailRateThreshold; // will reactivate Iprofiler if failure rate exceeds this threshold static int32_t _iprofilerFailHistorySize; static int32_t _iProfilerMemoryConsumptionLimit; + static int32_t _iProfilerBcHashTableSize; + static int32_t _iProfilerMethodHashTableSize; static int32_t _IprofilerOffSubtractionFactor; static int32_t _IprofilerOffDivisionFactor; diff --git a/runtime/compiler/runtime/IProfiler.cpp b/runtime/compiler/runtime/IProfiler.cpp index 24dce75bc7c..c36be3aa4fe 100644 --- a/runtime/compiler/runtime/IProfiler.cpp +++ b/runtime/compiler/runtime/IProfiler.cpp @@ -75,7 +75,6 @@ #include "runtime/J9Profiler.hpp" #include "omrformatconsts.h" -#define BC_HASH_TABLE_SIZE 34501 // 131071// 34501 #undef IPROFILER_CONTENDED_LOCKING #define ALLOC_HASH_TABLE_SIZE 1201 #define TEST_verbose 0 @@ -85,7 +84,6 @@ #define TEST_disableCSI 0 #undef PERSISTENCE_VERBOSE -#define IPMETHOD_HASH_TABLE_SIZE 12007 #define MAX_THREE(X,Y,Z) ((X>Y)?((X>Z)?X:Z):((Y>Z)?Y:Z)) @@ -594,9 +592,9 @@ TR_IProfiler::TR_IProfiler(J9JITConfig *jitConfig) _hashTableMonitor = TR::Monitor::create("JIT-InterpreterProfilingMonitor"); // bytecode hashtable - _bcHashTable = (TR_IPBytecodeHashTableEntry**)jitPersistentAlloc(BC_HASH_TABLE_SIZE*sizeof(TR_IPBytecodeHashTableEntry*)); + _bcHashTable = (TR_IPBytecodeHashTableEntry**)jitPersistentAlloc(TR::Options::_iProfilerBcHashTableSize*sizeof(TR_IPBytecodeHashTableEntry*)); if (_bcHashTable != NULL) - memset(_bcHashTable, 0, BC_HASH_TABLE_SIZE*sizeof(TR_IPBytecodeHashTableEntry*)); + memset(_bcHashTable, 0, TR::Options::_iProfilerBcHashTableSize*sizeof(TR_IPBytecodeHashTableEntry*)); else _isIProfilingEnabled = false; @@ -605,9 +603,9 @@ TR_IProfiler::TR_IProfiler(J9JITConfig *jitConfig) if (_allocHashTable != NULL) memset(_allocHashTable, 0, ALLOC_HASH_TABLE_SIZE*sizeof(TR_IPBCDataAllocation*)); #endif - _methodHashTable = (TR_IPMethodHashTableEntry **) jitPersistentAlloc(IPMETHOD_HASH_TABLE_SIZE * sizeof(TR_IPMethodHashTableEntry *)); + _methodHashTable = (TR_IPMethodHashTableEntry **) jitPersistentAlloc(TR::Options::_iProfilerMethodHashTableSize * sizeof(TR_IPMethodHashTableEntry *)); if (_methodHashTable != NULL) - memset(_methodHashTable, 0, IPMETHOD_HASH_TABLE_SIZE * sizeof(TR_IPMethodHashTableEntry *)); + memset(_methodHashTable, 0, TR::Options::_iProfilerMethodHashTableSize * sizeof(TR_IPMethodHashTableEntry *)); _readSampleRequestsHistory = (TR_ReadSampleRequestsHistory *) jitPersistentAlloc(sizeof (TR_ReadSampleRequestsHistory)); if (!_readSampleRequestsHistory || !_readSampleRequestsHistory->init(TR::Options::_iprofilerFailHistorySize)) { @@ -649,7 +647,7 @@ TR_IProfiler::isCallGraphProfilingEnabled() inline int32_t TR_IProfiler::bcHash(uintptr_t pc) { - return (int32_t)((pc & 0x7FFFFFFF) % BC_HASH_TABLE_SIZE); + return (int32_t)((pc & 0x7FFFFFFF) % TR::Options::_iProfilerBcHashTableSize); } inline int32_t @@ -661,7 +659,7 @@ TR_IProfiler::allocHash(uintptr_t pc) inline int32_t TR_IProfiler::methodHash(uintptr_t data) { - return (int32_t)((data & 0x7FFFFFFF) % IPMETHOD_HASH_TABLE_SIZE); + return (int32_t)((data & 0x7FFFFFFF) % TR::Options::_iProfilerMethodHashTableSize); } bool @@ -3479,7 +3477,7 @@ uint32_t TR_IProfiler::releaseAllEntries() { uint32_t count = 0; - for (int32_t bucket = 0; bucket < BC_HASH_TABLE_SIZE; bucket++) + for (int32_t bucket = 0; bucket < TR::Options::_iProfilerBcHashTableSize; bucket++) { for (TR_IPBytecodeHashTableEntry *entry = _bcHashTable[bucket]; entry; entry = entry->getNext()) { @@ -3497,7 +3495,7 @@ uint32_t TR_IProfiler::countEntries() { uint32_t count = 0; - for (int32_t bucket = 0; bucket < BC_HASH_TABLE_SIZE; bucket++) + for (int32_t bucket = 0; bucket < TR::Options::_iProfilerBcHashTableSize; bucket++) for (TR_IPBytecodeHashTableEntry *entry = _bcHashTable[bucket]; entry; entry = entry->getNext()) count++; return count; @@ -3508,7 +3506,7 @@ TR_IProfiler::countEntries() // void TR_IProfiler::setupEntriesInHashTable(TR_IProfiler *ip) { - for (int32_t bucket = 0; bucket < BC_HASH_TABLE_SIZE; bucket++) + for (int32_t bucket = 0; bucket < TR::Options::_iProfilerBcHashTableSize; bucket++) { TR_IPBytecodeHashTableEntry *entry = _bcHashTable[bucket], *prevEntry = NULL; @@ -3606,7 +3604,7 @@ void TR_IProfiler::checkMethodHashTable() } fprintf(fout, "printing method hash table\n");fflush(fout); - for (int32_t bucket = 0; bucket < IPMETHOD_HASH_TABLE_SIZE; bucket++) + for (int32_t bucket = 0; bucket < TR::Options::_iProfilerMethodHashTableSize; bucket++) { TR_IPMethodHashTableEntry *entry = _methodHashTable[bucket]; @@ -4790,7 +4788,7 @@ void TR_AggregationHT::sortByNameAndPrint(TR_J9VMBase *fe) void TR_IProfiler::dumpIPBCDataCallGraph(J9VMThread* vmThread) { fprintf(stderr, "Dumping info ...\n"); - TR_AggregationHT aggregationHT(BC_HASH_TABLE_SIZE); + TR_AggregationHT aggregationHT(TR::Options::_iProfilerBcHashTableSize); if (aggregationHT.getSize() == 0) // OOM { fprintf(stderr, "Cannot allocate memory. Bailing out.\n"); @@ -4815,7 +4813,7 @@ void TR_IProfiler::dumpIPBCDataCallGraph(J9VMThread* vmThread) TR_J9VMBase * fe = TR_J9VMBase::get(javaVM->jitConfig, vmThread); fprintf(stderr, "Aggregating per method ...\n"); - for (int32_t bucket = 0; bucket < BC_HASH_TABLE_SIZE; bucket++) + for (int32_t bucket = 0; bucket < TR::Options::_iProfilerBcHashTableSize; bucket++) { //fprintf(stderr, "Looking at bucket %d\n", bucket); for (TR_IPBytecodeHashTableEntry *entry = _bcHashTable[bucket]; entry; entry = entry->getNext())