Skip to content

Commit

Permalink
Merge pull request eclipse-omr#7278 from amicic/flushCachesForGC_hook
Browse files Browse the repository at this point in the history
Introduce Flush Caches For GC hook
  • Loading branch information
babsingh authored Mar 2, 2024
2 parents 53e909c + ced2f45 commit 8bea58e
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 14 deletions.
36 changes: 22 additions & 14 deletions gc/base/OMRVMInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ extern "C" {
* Actions required prior to walking the heap.
*/
void
hookWalkHeapStart(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
hookWalkHeapStart(J9HookInterface **hook, uintptr_t eventNum, void *eventData, void *userData)
{
MM_WalkHeapStartEvent* event = (MM_WalkHeapStartEvent*)eventData;
MM_WalkHeapStartEvent *event = (MM_WalkHeapStartEvent *)eventData;
GC_OMRVMInterface::flushCachesForWalk(event->omrVM);
}

/**
* Actions required after to walking the heap.
*/
void
hookWalkHeapEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, void* userData)
hookWalkHeapEnd(J9HookInterface** hook, uintptr_t eventNum, void *eventData, void *userData)
{
/* Nothing to do right now */
}
Expand All @@ -69,7 +69,7 @@ hookWalkHeapEnd(J9HookInterface** hook, uintptr_t eventNum, void* eventData, voi
void
GC_OMRVMInterface::initializeExtensions(MM_GCExtensionsBase *extensions)
{
J9HookInterface** mmPrivateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);
J9HookInterface **mmPrivateHooks = J9_HOOK_INTERFACE(extensions->privateHookInterface);

(*mmPrivateHooks)->J9HookRegisterWithCallSite(mmPrivateHooks, J9HOOK_MM_PRIVATE_WALK_HEAP_START, hookWalkHeapStart, OMR_GET_CALLSITE(), NULL);
(*mmPrivateHooks)->J9HookRegisterWithCallSite(mmPrivateHooks, J9HOOK_MM_PRIVATE_WALK_HEAP_END, hookWalkHeapEnd, OMR_GET_CALLSITE(), NULL);
Expand All @@ -88,19 +88,19 @@ GC_OMRVMInterface::getOmrHookInterface(MM_GCExtensionsBase *extensions)
* Flush Cache for walk.
*/
void
GC_OMRVMInterface::flushCachesForWalk(OMR_VM* omrVM)
GC_OMRVMInterface::flushCachesForWalk(OMR_VM *omrVM)
{
/*
* Environment at this point might be fake, so we can not get this thread info
* however only one thread suppose to have an exclusive access at this point
*/
//Assert_MM_true(J9_XACCESS_EXCLUSIVE == vm->exclusiveAccessState);

OMR_VMThread *omrVMThread;
OMR_VMThread *omrVMThread = NULL;

GC_OMRVMThreadListIterator threadListIterator(omrVM);

while((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
while ((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
MM_EnvironmentBase *envToFlush = MM_EnvironmentBase::getEnvironment(omrVMThread);
GC_OMRVMThreadInterface::flushCachesForWalk(envToFlush);
}
Expand All @@ -112,20 +112,28 @@ GC_OMRVMInterface::flushCachesForWalk(OMR_VM* omrVM)
void
GC_OMRVMInterface::flushCachesForGC(MM_EnvironmentBase *env)
{
OMRPORT_ACCESS_FROM_ENVIRONMENT(env);

MM_GCExtensionsBase *extensions = env->getExtensions();
OMR_VMThread *omrVMThread;
OMR_VMThread *omrVMThread = NULL;
UDATA allocatedBytesMax = extensions->bytesAllocatedMost;
OMR_VMThread *vmThreadMax = extensions->vmThreadAllocatedMost;

TRIGGER_J9HOOK_MM_OMR_FLUSH_CACHES_FOR_GC(
extensions->omrHookInterface,
env->getOmrVMThread(),
omrtime_hires_clock(),
J9HOOK_MM_OMR_FLUSH_CACHES_FOR_GC);

GC_OMRVMThreadListIterator threadListIterator(env->getOmrVM());

while((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
while ((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
/* Grab allocation bytes stats per-thread before they're cleared */
MM_EnvironmentBase* threadEnv = MM_EnvironmentBase::getEnvironment(omrVMThread);
MM_AllocationStats * stats= threadEnv->_objectAllocationInterface->getAllocationStats();
MM_EnvironmentBase *threadEnv = MM_EnvironmentBase::getEnvironment(omrVMThread);
MM_AllocationStats *stats= threadEnv->_objectAllocationInterface->getAllocationStats();
UDATA allocatedBytes = stats->bytesAllocated();

if(allocatedBytes >= allocatedBytesMax){
if (allocatedBytes >= allocatedBytesMax){
allocatedBytesMax = allocatedBytes;
vmThreadMax = omrVMThread;
}
Expand All @@ -142,11 +150,11 @@ GC_OMRVMInterface::flushCachesForGC(MM_EnvironmentBase *env)
void
GC_OMRVMInterface::flushNonAllocationCaches(MM_EnvironmentBase *env)
{
OMR_VMThread *omrVMThread;
OMR_VMThread *omrVMThread = NULL;

GC_OMRVMThreadListIterator threadListIterator(env->getOmrVM());

while((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
while ((omrVMThread = threadListIterator.nextOMRVMThread()) != NULL) {
GC_OMRVMThreadInterface::flushNonAllocationCaches(MM_EnvironmentBase::getEnvironment(omrVMThread));
}
}
13 changes: 13 additions & 0 deletions gc/include/omrmm.hdf
Original file line number Diff line number Diff line change
Expand Up @@ -285,4 +285,17 @@ typedef uintptr_t (*condYieldFromGCFunctionPtr) (OMR_VMThread *omrVMThread, uint
<data type="uint64_t" name="timestamp" description="time of event" />
</event>

<event>
<name>J9HOOK_MM_OMR_FLUSH_CACHES_FOR_GC</name>
<description>
This is called slightly after exclusive VM access is acquired, and slightly before various GC start hooks.
This is called before flush itself, which deletes all the stats of the various application thread caches.
So, it's very similar to the GC start event, except all the stats are still available for reporting and processing.
</description>
<struct>MM_FlushCachesForGCEvent</struct>
<data type="struct OMR_VMThread*" name="currentThread" description="current thread" />
<data type="uint64_t" name="timestamp" description="time of event" />
<data type="uintptr_t" name="eventid" description="unique identifier for event" />
</event>

</interface>

0 comments on commit 8bea58e

Please sign in to comment.