Skip to content

Commit e7ac90c

Browse files
authored
Merge pull request eclipse-openj9#20498 from ymanton/disclaim-scc
Add functionality to disclaim SCC memory periodically
2 parents 1c95046 + 4b8483d commit e7ac90c

File tree

6 files changed

+149
-8
lines changed

6 files changed

+149
-8
lines changed

runtime/compiler/control/HookedByTheJit.cpp

+32-5
Original file line numberDiff line numberDiff line change
@@ -4515,14 +4515,26 @@ size_t getRSS_Kb()
45154515
return rss;
45164516
}
45174517

4518+
#if defined(J9VM_OPT_SHARED_CLASSES) && defined(LINUX)
4519+
void disclaimSharedClassCache(TR_J9SharedCache *sharedCache, uint64_t crtElapsedTime)
4520+
{
4521+
size_t rssBefore = getRSS_Kb();
4522+
int32_t numDisclaimed = sharedCache->disclaimSharedCaches();
4523+
size_t rssAfter = getRSS_Kb();
4524+
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))
4525+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d SCC segments RSS before=%zu KB, RSS after=%zu KB, delta=%zd KB = %5.2f%%",
4526+
(uint32_t)crtElapsedTime, numDisclaimed, rssBefore, rssAfter, rssBefore - rssAfter, ((long)(rssAfter - rssBefore) * 100.0 / rssBefore));
4527+
}
4528+
#endif // defined(J9VM_OPT_SHARED_CLASSES) && defined(LINUX)
4529+
45184530
void disclaimDataCaches(uint64_t crtElapsedTime)
45194531
{
45204532
size_t rssBefore = getRSS_Kb();
45214533
int numDisclaimed = TR_DataCacheManager::getManager()->disclaimAllDataCaches();
45224534
size_t rssAfter = getRSS_Kb();
45234535
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))
4524-
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d Data Cache segments RSS before=%zu KB, RSS after=%zu KB, delta=%zu KB",
4525-
(uint32_t)crtElapsedTime, numDisclaimed, rssBefore, rssAfter, rssBefore - rssAfter);
4536+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d Data Cache segments RSS before=%zu KB, RSS after=%zu KB, delta=%zd KB = %5.2f%%",
4537+
(uint32_t)crtElapsedTime, numDisclaimed, rssBefore, rssAfter, rssBefore - rssAfter, ((long)(rssAfter - rssBefore) * 100.0 / rssBefore));
45264538
}
45274539

45284540
void disclaimIProfilerSegments(uint64_t crtElapsedTime)
@@ -4535,8 +4547,8 @@ void disclaimIProfilerSegments(uint64_t crtElapsedTime)
45354547
int numSegDisclaimed = iprofilerAllocator->disclaimAllSegments();
45364548
size_t rssAfter = getRSS_Kb();
45374549
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))
4538-
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d IProfiler segments out of %d. RSS before=%zu KB, RSS after=%zu KB, delta=%zu KB",
4539-
(uint32_t)crtElapsedTime, numSegDisclaimed, iprofilerAllocator->getNumSegments(), rssBefore, rssAfter, rssBefore - rssAfter);
4550+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d IProfiler segments out of %d. RSS before=%zu KB, RSS after=%zu KB, delta=%zd KB = %5.2f%%",
4551+
(uint32_t)crtElapsedTime, numSegDisclaimed, iprofilerAllocator->getNumSegments(), rssBefore, rssAfter, rssBefore - rssAfter, ((long)(rssAfter - rssBefore) * 100.0 / rssBefore));
45404552
}
45414553
}
45424554

@@ -4546,7 +4558,7 @@ void disclaimCodeCaches(uint64_t crtElapsedTime)
45464558
int numDisclaimed = TR::CodeCacheManager::instance()->disclaimAllCodeCaches();
45474559
size_t rssAfter = getRSS_Kb();
45484560
if (TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance))
4549-
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d Code Caches RSS before=%zu KB, RSS after=%zu KB, delta=%zu KB = %5.2f%%",
4561+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "t=%u JIT disclaimed %d Code Caches RSS before=%zu KB, RSS after=%zu KB, delta=%zd KB = %5.2f%%",
45504562
(uint32_t)crtElapsedTime, numDisclaimed, rssBefore, rssAfter, rssBefore - rssAfter, ((long)(rssAfter - rssBefore) * 100.0 / rssBefore));
45514563
}
45524564

@@ -4557,6 +4569,7 @@ void memoryDisclaimLogic(TR::CompilationInfo *compInfo, uint64_t crtElapsedTime,
45574569
static uint64_t lastCodeCacheDisclaimTime = 0;
45584570
static int32_t lastNumAllocatedCodeCaches = 0;
45594571
static uint64_t lastIProfilerDisclaimTime = 0;
4572+
static uint64_t lastSCCDisclaimTime = 0;
45604573
static uint32_t lastNumCompilationsDuringIProfilerDisclaim = 0;
45614574

45624575
J9JITConfig *jitConfig = compInfo->getJITConfig();
@@ -4571,6 +4584,20 @@ void memoryDisclaimLogic(TR::CompilationInfo *compInfo, uint64_t crtElapsedTime,
45714584
if (javaVM->phase != J9VM_PHASE_NOT_STARTUP || jitState == STARTUP_STATE)
45724585
return;
45734586

4587+
#if defined(J9VM_OPT_SHARED_CLASSES) && defined(LINUX)
4588+
TR_J9VMBase *fej9 = TR_J9VMBase::get(jitConfig, compInfo->getSamplerThread(), TR_J9VMBase::AOT_VM);
4589+
TR_J9SharedCache *sharedCache = fej9->sharedCache();
4590+
if (sharedCache && sharedCache->isDisclaimEnabled())
4591+
{
4592+
// Disclaim if there was a large time interval since the last disclaim
4593+
if (crtElapsedTime > lastSCCDisclaimTime + 12 * TR::Options::_minTimeBetweenMemoryDisclaims)
4594+
{
4595+
disclaimSharedClassCache(sharedCache, crtElapsedTime);
4596+
lastSCCDisclaimTime = crtElapsedTime;
4597+
}
4598+
}
4599+
#endif // defined(J9VM_OPT_SHARED_CLASSES) && defined(LINUX)
4600+
45744601
if (TR_DataCacheManager::getManager()->isDisclaimEnabled())
45754602
{
45764603
// Ensure we don't do it too often

runtime/compiler/control/J9Options.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -2929,7 +2929,8 @@ J9::Options::fePostProcessJIT(void * base)
29292929

29302930
if (!self()->getOption(TR_DisableDataCacheDisclaiming) ||
29312931
!self()->getOption(TR_DisableIProfilerDataDisclaiming) ||
2932-
self()->getOption(TR_EnableCodeCacheDisclaiming))
2932+
self()->getOption(TR_EnableCodeCacheDisclaiming) ||
2933+
self()->getOption(TR_EnableSharedCacheDisclaiming))
29332934
{
29342935
// Check requirements for memory disclaiming (Linux kernel and default page size)
29352936
TR::Options::disableMemoryDisclaimIfNeeded(jitConfig);
@@ -3002,6 +3003,7 @@ J9::Options::disableMemoryDisclaimIfNeeded(J9JITConfig *jitConfig)
30023003
TR::Options::getCmdLineOptions()->setOption(TR_DisableDataCacheDisclaiming);
30033004
TR::Options::getCmdLineOptions()->setOption(TR_DisableIProfilerDataDisclaiming);
30043005
TR::Options::getCmdLineOptions()->setOption(TR_EnableCodeCacheDisclaiming, false);
3006+
TR::Options::getCmdLineOptions()->setOption(TR_EnableSharedCacheDisclaiming, false);
30053007
}
30063008
return shouldDisableMemoryDisclaim;
30073009
}

runtime/compiler/control/OptionsPostRestore.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,8 @@ J9::OptionsPostRestore::postProcessInternalCompilerOptions()
830830

831831
if (!TR::Options::getCmdLineOptions()->getOption(TR_DisableDataCacheDisclaiming) ||
832832
!TR::Options::getCmdLineOptions()->getOption(TR_DisableIProfilerDataDisclaiming) ||
833-
TR::Options::getCmdLineOptions()->getOption(TR_EnableCodeCacheDisclaiming))
833+
TR::Options::getCmdLineOptions()->getOption(TR_EnableCodeCacheDisclaiming) ||
834+
TR::Options::getCmdLineOptions()->getOption(TR_EnableSharedCacheDisclaiming))
834835
{
835836
TR::Options::disableMemoryDisclaimIfNeeded(_jitConfig);
836837
}

runtime/compiler/env/J9SharedCache.cpp

+77
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,26 @@
4848
#include "runtime/JITServerAOTDeserializer.hpp"
4949
#endif
5050

51+
// for madvise
52+
#ifdef LINUX
53+
#include <sys/mman.h>
54+
#ifndef MADV_NOHUGEPAGE
55+
#define MADV_NOHUGEPAGE 15
56+
#endif // MADV_NOHUGEPAGE
57+
#ifndef MADV_PAGEOUT
58+
#define MADV_PAGEOUT 21
59+
#endif // MADV_PAGEOUT
60+
#endif
61+
5162
#define LOG(logLevel, format, ...) \
5263
if (_logLevel >= logLevel) \
5364
{ \
5465
log("" format "", ##__VA_ARGS__); \
5566
}
5667

5768
// From CompositeCache.cpp
69+
#define RWUPDATEPTR(ca) (((uint8_t *)(ca)) + (ca)->readWriteSRP)
70+
#define CAEND(ca) (((uint8_t *)(ca)) + (ca)->totalBytes)
5871
#define UPDATEPTR(ca) (((uint8_t *)(ca)) + (ca)->updateSRP)
5972
#define SEGUPDATEPTR(ca) (((uint8_t *)(ca)) + (ca)->segmentSRP)
6073

@@ -105,6 +118,67 @@ TR_J9SharedCache::validateAOTHeader(J9JITConfig *jitConfig, J9VMThread *vmThread
105118
}
106119
}
107120

121+
#if defined(LINUX)
122+
bool TR_J9SharedCache::disclaim(const uint8_t *start, const uint8_t *end, UDATA pageSize, bool trace)
123+
{
124+
uint8_t *nextPage = (uint8_t *)(((UDATA)start + (pageSize - 1)) & ~(pageSize - 1));
125+
if (nextPage < end)
126+
{
127+
int ret = madvise(nextPage, end - nextPage, MADV_PAGEOUT);
128+
if (ret == 0)
129+
return true;
130+
if (trace)
131+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "WARNING: Failed to use madvise to disclaim memory for shared class cache; errno: %d", errno);
132+
// Temporary failure, don't disable disclaim permanently if this happens.
133+
if (errno == EAGAIN)
134+
return true;
135+
}
136+
return false;
137+
}
138+
139+
int32_t TR_J9SharedCache::disclaimSharedCaches()
140+
{
141+
int32_t numDisclaimed = 0;
142+
143+
if (!_disclaimEnabled)
144+
return numDisclaimed;
145+
146+
J9SharedClassCacheDescriptor *scHead = getCacheDescriptorList();
147+
J9SharedClassCacheDescriptor *scCur = scHead;
148+
PORT_ACCESS_FROM_JAVAVM(_javaVM); // for j9vmem_supported_page_sizes
149+
UDATA pageSize = j9vmem_supported_page_sizes()[0];
150+
bool trace = TR::Options::getCmdLineOptions()->getVerboseOption(TR_VerbosePerformance);
151+
152+
do
153+
{
154+
uint8_t *rwStart = RWUPDATEPTR(scCur->cacheStartAddress);
155+
uint8_t *rwEnd = SEGUPDATEPTR(scCur->cacheStartAddress);
156+
if (!disclaim(rwStart, rwEnd, pageSize, trace))
157+
{
158+
if (trace)
159+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "WARNING: Disabling shared class cache disclaiming from now on");
160+
_disclaimEnabled = false;
161+
break;
162+
}
163+
numDisclaimed++;
164+
uint8_t *updateStart = UPDATEPTR(scCur->cacheStartAddress);
165+
uint8_t *updateEnd = CAEND(scCur->cacheStartAddress);
166+
if (!disclaim(updateStart, updateEnd, pageSize, trace))
167+
{
168+
if (trace)
169+
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "WARNING: Disabling shared class cache disclaiming from now on");
170+
_disclaimEnabled = false;
171+
break;
172+
}
173+
numDisclaimed++;
174+
scCur = scCur->next;
175+
}
176+
while (scCur != scHead);
177+
178+
return numDisclaimed;
179+
}
180+
#endif // defined(LINUX)
181+
108182
TR_YesNoMaybe TR_J9SharedCache::isSharedCacheDisabledBecauseFull(TR::CompilationInfo *compInfo)
109183
{
110184
if (_sharedCacheDisabledBecauseFull == TR_maybe)
@@ -186,6 +260,9 @@ TR_J9SharedCache::TR_J9SharedCache(TR_J9VMBase *fe)
186260
_aotStats = fe->getPrivateConfig()->aotStats;
187261
_sharedCacheConfig = _javaVM->sharedClassConfig;
188262
_numDigitsForCacheOffsets = 8;
263+
#if defined(LINUX)
264+
_disclaimEnabled = TR::Options::getCmdLineOptions()->getOption(TR_EnableSharedCacheDisclaiming);
265+
#endif
189266

190267
#if defined(J9VM_OPT_JITSERVER)
191268
TR_ASSERT_FATAL(_sharedCacheConfig || _compInfo->getPersistentInfo()->getRemoteCompilationMode() == JITServer::SERVER

runtime/compiler/env/J9SharedCache.hpp

+34
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,34 @@ class TR_J9SharedCache : public TR_SharedCache
105105

106106
static void validateAOTHeader(J9JITConfig *jitConfig, J9VMThread *vmThread, TR::CompilationInfo *compInfo);
107107

108+
#if defined(LINUX)
109+
/**
110+
* \brief Returns whether SCC disclaiming is enabled.
111+
*
112+
* This function returns a boolean that represents whether SCC disclaiming is enabled or not.
113+
* SCC disclaiming may be enabled or disabled via an option, and if enabled, may later be
114+
* disabled due to an error.
115+
*
116+
* \return True if SCC disclaiming is enabled, false otherwise.
117+
*/
118+
virtual bool isDisclaimEnabled() { return _disclaimEnabled; }
119+
120+
/**
121+
* \brief Disclaims SCC memory pages, causing them to be paged out of the resident set.
122+
*
123+
* This function causes the occupied parts of the SCC to be disclaimed. For each layer
124+
* the ROM class area which starts at the beginning of the layer and extends forward,
125+
* and the metadata area which starts at the end of the layer and extends backwards,
126+
* are both disclaimed, causing the underlying memory pages to be paged out of the
127+
* resident set.
128+
*
129+
* This function does nothing if SCC disclaiming is disabled.
130+
*
131+
* \return The number of areas disclaimed.
132+
*/
133+
virtual int32_t disclaimSharedCaches();
134+
#endif
135+
108136
/**
109137
* \brief Converts a shared cache offset, calculated from the end of the SCC, into the
110138
* metadata section of the SCC into a pointer.
@@ -421,6 +449,8 @@ class TR_J9SharedCache : public TR_SharedCache
421449
virtual J9SharedClassCacheDescriptor *getCacheDescriptorList();
422450

423451
protected:
452+
static bool disclaim(const uint8_t *start, const uint8_t *end, UDATA pageSize, bool trace);
453+
424454
/**
425455
* \brief Helper method; used to check if a pointer is within the SCC
426456
*
@@ -620,6 +650,10 @@ class TR_J9SharedCache : public TR_SharedCache
620650
uint32_t _logLevel;
621651
bool _verboseHints;
622652

653+
#if defined(LINUX)
654+
bool _disclaimEnabled;
655+
#endif
656+
623657
static TR_J9SharedCacheDisabledReason _sharedCacheState;
624658
static TR_YesNoMaybe _sharedCacheDisabledBecauseFull;
625659
static UDATA _storeSharedDataFailedLength;

runtime/compiler/runtime/J9CodeCache.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ J9::CodeCache::disclaim(TR::CodeCacheManager *manager, bool canDisclaimOnSwap)
918918
if (trace)
919919
TR_VerboseLog::writeLineLocked(TR_Vlog_PERF, "WARNING: Failed to use madvise to disclaim memory for code cache");
920920

921-
if (ret == EINVAL)
921+
if (errno != EAGAIN)
922922
{
923923
manager->setDisclaimEnabled(false); // Don't try to disclaim again, since support seems to be missing
924924
if (trace)

0 commit comments

Comments
 (0)