From 09e489912b566dae09507d4c860c5bcd7aa804f6 Mon Sep 17 00:00:00 2001 From: Marius Date: Sat, 7 Oct 2023 08:32:35 -0700 Subject: [PATCH] Fix bug related to CodeCache utilization reporting PR https://github.com/eclipse/omr/pull/7129 moved the code that writes a TR::CodeCache pointer into the beginning of the code cache segment towards the end of the OMR::CodeCache::initialize routine. This makes sense because we want to 'advertise' to the world the newly created TR::CodeCache structure only after this structure has been fully initialized. However, OMR::CodeCache::initialize() routine contains an early return that is taken when the JIT does not need trampolines. On this path we no longer write the TR::CodeCache pointer into the beginning of the code cache segment and the VM is unable to retrieve code cache utilization statistics. This commit avoid the early return mentioned above. Signed-off-by: Marius --- compiler/runtime/OMRCodeCache.cpp | 129 +++++++++++++++--------------- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/compiler/runtime/OMRCodeCache.cpp b/compiler/runtime/OMRCodeCache.cpp index 89fa6590915..5a322de4685 100644 --- a/compiler/runtime/OMRCodeCache.cpp +++ b/compiler/runtime/OMRCodeCache.cpp @@ -327,89 +327,88 @@ OMR::CodeCache::initialize(TR::CodeCacheManager *manager, TR_ASSERT( (((size_t)_CCPreLoadedCodeBase) & config.codeCacheHelperAlignmentMask()) == 0, "Per-code cache helper sizes do not account for alignment requirements." ); _coldCodeAlloc = _CCPreLoadedCodeBase; _trampolineSyncList = NULL; - - return true; } - - // Helpers are located at the top of the code cache (offset N), growing down towards the base (offset 0) - size_t trampolineSpaceSize = config.trampolineCodeSize() * config.numRuntimeHelpers(); - // _helperTop is heapTop - _helperBase = _helperTop - trampolineSpaceSize; - _helperBase = (uint8_t *)(((size_t)_helperBase) & (~config.codeCacheTrampolineAlignmentBytes())); - - if (!config.needsMethodTrampolines()) - { - // There is no need in method trampolines when there is going to be - // only one code cache segment - // - _trampolineBase = _helperBase; - _tempTrampolinesMax = 0; - } - else + else // Trampolines are needed { + // Helpers are located at the top of the code cache (offset N), growing down towards the base (offset 0) + size_t trampolineSpaceSize = config.trampolineCodeSize() * config.numRuntimeHelpers(); // _helperTop is heapTop - // (_helperTop - segment->heapBase) is heapSize + _helperBase = _helperTop - trampolineSpaceSize; + _helperBase = (uint8_t *)(((size_t)_helperBase) & (~config.codeCacheTrampolineAlignmentBytes())); - _trampolineBase = _helperBase - - ((_helperBase - _segment->segmentBase())*config.trampolineSpacePercentage()/100); + if (!config.needsMethodTrampolines()) + { + // There is no need in method trampolines when there is going to be + // only one code cache segment + // + _trampolineBase = _helperBase; + _tempTrampolinesMax = 0; + } + else + { + // _helperTop is heapTop + // (_helperTop - segment->heapBase) is heapSize - // Grab the configuration details from the JIT platform code - // - // (_helperTop - segment->heapBase) is heapSize - config.mccCallbacks().codeCacheConfig(static_cast(_helperTop - _segment->segmentBase()), &_tempTrampolinesMax); - } + _trampolineBase = _helperBase - + ((_helperBase - _segment->segmentBase())*config.trampolineSpacePercentage()/100); - mcc_printf("mcc_initialize: trampoline base %p\n", _trampolineBase); + // Grab the configuration details from the JIT platform code + // + // (_helperTop - segment->heapBase) is heapSize + config.mccCallbacks().codeCacheConfig(static_cast(_helperTop - _segment->segmentBase()), &_tempTrampolinesMax); + } - // set the temporary trampoline slab right under the helper trampolines, should be already aligned - _tempTrampolineTop = _helperBase; - _tempTrampolineBase = _tempTrampolineTop - (config.trampolineCodeSize() * _tempTrampolinesMax); - _tempTrampolineNext = _tempTrampolineBase; + mcc_printf("mcc_initialize: trampoline base %p\n", _trampolineBase); - // Check if we have enough space in the code cache to contain the trampolines - if (_trampolineBase >= _tempTrampolineNext && config.needsMethodTrampolines()) - { - _hashEntrySlab->free(manager); - return false; - } + // set the temporary trampoline slab right under the helper trampolines, should be already aligned + _tempTrampolineTop = _helperBase; + _tempTrampolineBase = _tempTrampolineTop - (config.trampolineCodeSize() * _tempTrampolinesMax); + _tempTrampolineNext = _tempTrampolineBase; + + // Check if we have enough space in the code cache to contain the trampolines + if (_trampolineBase >= _tempTrampolineNext && config.needsMethodTrampolines()) + { + _hashEntrySlab->free(manager); + return false; + } - // set the allocation pointer to right after the temporary trampolines - _trampolineAllocationMark = _tempTrampolineBase; - _trampolineReservationMark = _trampolineAllocationMark; + // set the allocation pointer to right after the temporary trampolines + _trampolineAllocationMark = _tempTrampolineBase; + _trampolineReservationMark = _trampolineAllocationMark; - // set the pre loaded per Cache Helper slab - _CCPreLoadedCodeTop = (uint8_t *)(((size_t)_trampolineBase) & (~config.codeCacheHelperAlignmentMask())); - _CCPreLoadedCodeBase = _CCPreLoadedCodeTop - config.ccPreLoadedCodeSize(); - TR_ASSERT( (((size_t)_CCPreLoadedCodeBase) & config.codeCacheHelperAlignmentMask()) == 0, "Per-code cache helper sizes do not account for alignment requirements." ); - _coldCodeAlloc = _CCPreLoadedCodeBase; + // set the pre loaded per Cache Helper slab + _CCPreLoadedCodeTop = (uint8_t *)(((size_t)_trampolineBase) & (~config.codeCacheHelperAlignmentMask())); + _CCPreLoadedCodeBase = _CCPreLoadedCodeTop - config.ccPreLoadedCodeSize(); + TR_ASSERT( (((size_t)_CCPreLoadedCodeBase) & config.codeCacheHelperAlignmentMask()) == 0, "Per-code cache helper sizes do not account for alignment requirements." ); + _coldCodeAlloc = _CCPreLoadedCodeBase; - // Set helper trampoline table available - // - config.mccCallbacks().createHelperTrampolines((uint8_t *)_helperBase, config.numRuntimeHelpers()); + // Set helper trampoline table available + // + config.mccCallbacks().createHelperTrampolines((uint8_t *)_helperBase, config.numRuntimeHelpers()); - _trampolineSyncList = NULL; - if (_tempTrampolinesMax) - { - // Initialize temporary trampoline synchronization list - if (!self()->allocateTempTrampolineSyncBlock()) + _trampolineSyncList = NULL; + if (_tempTrampolinesMax) { - _hashEntrySlab->free(manager); - return false; + // Initialize temporary trampoline synchronization list + if (!self()->allocateTempTrampolineSyncBlock()) + { + _hashEntrySlab->free(manager); + return false; + } } - } - if (config.needsMethodTrampolines()) - { - // Initialize hashtables to hold trampolines for resolved and unresolved methods - _resolvedMethodHT = CodeCacheHashTable::allocate(manager); - _unresolvedMethodHT = CodeCacheHashTable::allocate(manager); - if (_resolvedMethodHT==NULL || _unresolvedMethodHT==NULL) + if (config.needsMethodTrampolines()) { - _hashEntrySlab->free(manager); - return false; + // Initialize hashtables to hold trampolines for resolved and unresolved methods + _resolvedMethodHT = CodeCacheHashTable::allocate(manager); + _unresolvedMethodHT = CodeCacheHashTable::allocate(manager); + if (_resolvedMethodHT==NULL || _unresolvedMethodHT==NULL) + { + _hashEntrySlab->free(manager); + return false; + } } } - // Before returning, let's adjust the free space seen by VM. // Usable space is between _warmCodeAlloc and _trampolineBase. Everything else is overhead size_t spaceLost = (_warmCodeAlloc - _segment->segmentBase()) + (_segment->segmentTop() - _trampolineBase);