From 24685fe2924b3308eb9a25464d152d59c398bbfc Mon Sep 17 00:00:00 2001 From: Marius Date: Mon, 2 Oct 2023 06:38:57 -0700 Subject: [PATCH] Fix code cache segment race condition The first two fields of a TR::CodeCache data structures are `_warmCodeAlloc` and `_coldCodeAlloc` and they used by a third party (e.g. the JVM) to compute the amount of free space in the code cache. During the TR::CodeCache initialization we populate the _warmCodeAlloc and _coldCodeAlloc fields and then write a pointer to the TR::CodeCache structure at the beginning of the segment that provides memory for the code cache itself. Just before writing this pointer we need to issue a write memory barrier to ensure that the values of _warmCodeAlloc and _coldCodeAlloc are seen by another thread at the time when the pointer to the TR::CodeCache is written at the begining of the memory segment. Signed-off-by: Marius --- compiler/runtime/OMRCodeCache.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/runtime/OMRCodeCache.cpp b/compiler/runtime/OMRCodeCache.cpp index 442f5747af3..89fa6590915 100644 --- a/compiler/runtime/OMRCodeCache.cpp +++ b/compiler/runtime/OMRCodeCache.cpp @@ -26,6 +26,7 @@ #include #include #include +#include "AtomicSupport.hpp" #include "env/FrontEnd.hpp" #include "control/Options.hpp" #include "control/Options_inlines.hpp" @@ -309,9 +310,6 @@ OMR::CodeCache::initialize(TR::CodeCacheManager *manager, _sizeOfLargestFreeWarmBlock = 0; _lastAllocatedBlock = NULL; // MP - omrthread_jit_write_protect_disable(); - *((TR::CodeCache **)(_segment->segmentBase())) = self(); // Write a pointer to this cache at the beginning of the segment - omrthread_jit_write_protect_enable(); _warmCodeAlloc = _segment->segmentBase() + sizeof(this); _warmCodeAlloc = (uint8_t *)align((size_t)_warmCodeAlloc, config.codeCacheAlignment()); @@ -417,6 +415,13 @@ OMR::CodeCache::initialize(TR::CodeCacheManager *manager, size_t spaceLost = (_warmCodeAlloc - _segment->segmentBase()) + (_segment->segmentTop() - _trampolineBase); _manager->increaseCurrTotalUsedInBytes(spaceLost); + // Now that we have initialized the code cache, (including _warmCodeAlloc and _coldCodeAlloc) + // write a pointer to this cache at the beginning of the segment + VM_AtomicSupport::writeBarrier(); + omrthread_jit_write_protect_disable(); + *((TR::CodeCache **)(_segment->segmentBase())) = self(); + omrthread_jit_write_protect_enable(); + return true; }