Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support tracing allocation bytes #9254

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions runtime/gc_base/GCExtensions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ class MM_GCExtensions : public MM_GCExtensionsBase {
double maxRAMPercent; /**< Value of -XX:MaxRAMPercentage specified by the user */
double initialRAMPercent; /**< Value of -XX:InitialRAMPercentage specified by the user */

UDATA objectSamplingBytesGranularity; /**< How often (in bytes) we do an allocation trace (for triggering J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING) */

protected:
private:
protected:
Expand Down Expand Up @@ -317,6 +319,7 @@ class MM_GCExtensions : public MM_GCExtensionsBase {
#endif
, maxRAMPercent(0.0) /* this would get overwritten by user specified value */
, initialRAMPercent(0.0) /* this would get overwritten by user specified value */
, objectSamplingBytesGranularity(512 * 1024) /* default 512KB */
{
_typeId = __FUNCTION__;
}
Expand Down
22 changes: 17 additions & 5 deletions runtime/gc_base/modronapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -866,9 +866,9 @@ j9gc_allocation_threshold_changed(J9VMThread *currentThread)
* j9gc_set_allocation_sampling_interval(vm, (UDATA)4096);
* To trigger an event for every object allocation:
* j9gc_set_allocation_sampling_interval(vm, (UDATA)0);
* The initial MM_GCExtensions::oolObjectSamplingBytesGranularity value is 16M
* or set by command line option "-Xgc:allocationSamplingGranularity".
* By default, the sampling interval is going to be set to 512 KB.
* To disable allocation sampling
* j9gc_set_allocation_sampling_interval(vm, UDATA_MAX);
* The initial MM_GCExtensions::objectSamplingBytesGranularity value is 512KB.
*
* @parm[in] vm The J9JavaVM
* @parm[in] samplingInterval The allocation sampling interval.
Expand All @@ -878,10 +878,22 @@ j9gc_set_allocation_sampling_interval(J9JavaVM *vm, UDATA samplingInterval)
{
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(vm);
if (0 == samplingInterval) {
/* avoid (env->_oolTraceAllocationBytes) % 0 which could be undefined. */
/* avoid (env->_traceAllocationBytes) % 0 which could be undefined. */
samplingInterval = 1;
}
extensions->oolObjectSamplingBytesGranularity = samplingInterval;
extensions->objectSamplingBytesGranularity = samplingInterval;
bool needToChange = false;
if ((UDATA_MAX != samplingInterval) && !extensions->disableInlineAllocationForSamplingBytesGranularity) {
extensions->disableInlineAllocationForSamplingBytesGranularity = true;
needToChange = true;
} else if ((UDATA_MAX == samplingInterval) && extensions->disableInlineAllocationForSamplingBytesGranularity) {
extensions->disableInlineAllocationForSamplingBytesGranularity = false;
needToChange = true;
}
if (needToChange) {
J9VMThread *currentThread = vm->internalVMFunctions->currentVMThread(vm);
j9gc_allocation_threshold_changed(currentThread);
}
}

/**
Expand Down
5 changes: 3 additions & 2 deletions runtime/gc_glue_java/ConfigurationDelegate.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2017, 2019 IBM Corp. and others
* Copyright (c) 2017, 2020 IBM Corp. and others
*
* This program and the accompanying materials are made available under
* the terms of the Eclipse Public License 2.0 which accompanies this
Expand Down Expand Up @@ -325,7 +325,8 @@ class MM_ConfigurationDelegate
vmThread->cardTableShiftSize = 0;
}

if (extensions->fvtest_disableInlineAllocation) {
if ((extensions->fvtest_disableInlineAllocation) || (extensions->disableInlineAllocationForSamplingBytesGranularity)) {
env->disableInlineTLHAllocate();
env->_objectAllocationInterface->disableCachedAllocations(env);
}

Expand Down
47 changes: 33 additions & 14 deletions runtime/gc_modron_startup/mgcalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static uintptr_t stackIterator(J9VMThread *currentThread, J9StackWalkState *walk
static void dumpStackFrames(J9VMThread *currentThread);
static void traceAllocateIndexableObject(J9VMThread *vmThread, J9Class* clazz, uintptr_t objSize, uintptr_t numberOfIndexedFields);
static J9Object * traceAllocateObject(J9VMThread *vmThread, J9Object * object, J9Class* clazz, uintptr_t objSize, uintptr_t numberOfIndexedFields=0);
static bool traceObjectCheck(J9VMThread *vmThread);
static bool traceObjectCheck(J9VMThread *vmThread, bool *shouldTriggerAllocationSampling = NULL);

#define STACK_FRAMES_TO_DUMP 8

Expand All @@ -87,7 +87,7 @@ J9AllocateObjectNoGC(J9VMThread *vmThread, J9Class *clazz, uintptr_t allocateFla

#if defined(J9VM_GC_THREAD_LOCAL_HEAP)
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
if (extensions->instrumentableAllocateHookEnabled || !env->isInlineTLHAllocateEnabled()) {
if (extensions->instrumentableAllocateHookEnabled || extensions->disableInlineAllocationForSamplingBytesGranularity || !env->isInlineTLHAllocateEnabled()) {
/* This function is restricted to only being used for instrumentable allocates so we only need to check that one allocation hook.
* Note that we can't handle hooked allocates since we might be called without a JIT resolve frame and that is required for us to
* report the allocation event.
Expand Down Expand Up @@ -225,12 +225,14 @@ traceAllocateIndexableObject(J9VMThread *vmThread, J9Class* clazz, uintptr_t obj
static J9Object *
traceAllocateObject(J9VMThread *vmThread, J9Object * object, J9Class* clazz, uintptr_t objSize, uintptr_t numberOfIndexedFields)
{
if(traceObjectCheck(vmThread)){
PORT_ACCESS_FROM_VMC(vmThread);
bool shouldTrigggerObjectAllocationSampling = false;
uintptr_t byteGranularity = 0;

if (traceObjectCheck(vmThread, &shouldTrigggerObjectAllocationSampling)){
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
uintptr_t byteGranularity = extensions->oolObjectSamplingBytesGranularity;
J9ROMClass *romClass = clazz->romClass;
byteGranularity = extensions->oolObjectSamplingBytesGranularity;

if (J9ROMCLASS_IS_ARRAY(romClass)){
traceAllocateIndexableObject(vmThread, clazz, objSize, numberOfIndexedFields);
Expand All @@ -239,6 +241,18 @@ traceAllocateObject(J9VMThread *vmThread, J9Object * object, J9Class* clazz, uin
vmThread, clazz, J9UTF8_LENGTH(J9ROMCLASS_CLASSNAME(romClass)), J9UTF8_DATA(J9ROMCLASS_CLASSNAME(romClass)), objSize);
}

/* Keep the remainder, want this to happen so that we don't miss objects
* after seeing large objects
*/
env->_oolTraceAllocationBytes = (env->_oolTraceAllocationBytes) % byteGranularity;
}

if (shouldTrigggerObjectAllocationSampling) {
PORT_ACCESS_FROM_VMC(vmThread);
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
byteGranularity = extensions->objectSamplingBytesGranularity;

TRIGGER_J9HOOK_MM_OBJECT_ALLOCATION_SAMPLING(
extensions->hookInterface,
vmThread,
Expand All @@ -251,7 +265,7 @@ traceAllocateObject(J9VMThread *vmThread, J9Object * object, J9Class* clazz, uin
/* Keep the remainder, want this to happen so that we don't miss objects
* after seeing large objects
*/
env->_oolTraceAllocationBytes = (env->_oolTraceAllocationBytes) % byteGranularity;
env->_traceAllocationBytes = (env->_traceAllocationBytes) % byteGranularity;
}
return object;
}
Expand All @@ -262,14 +276,19 @@ traceAllocateObject(J9VMThread *vmThread, J9Object * object, J9Class* clazz, uin
* Returns true if we should trace the object
* */
static bool
traceObjectCheck(J9VMThread *vmThread)
traceObjectCheck(J9VMThread *vmThread, bool *shouldTriggerAllocationSampling)
{
MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(vmThread->omrVMThread);
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
uintptr_t byteGranularity = 0;

if(extensions->doOutOfLineAllocationTrace){
uintptr_t byteGranularity = extensions->oolObjectSamplingBytesGranularity;

if (NULL != shouldTriggerAllocationSampling) {
byteGranularity = extensions->objectSamplingBytesGranularity;
*shouldTriggerAllocationSampling = env->_traceAllocationBytes >= byteGranularity;
}

if (extensions->doOutOfLineAllocationTrace){
byteGranularity = extensions->oolObjectSamplingBytesGranularity;
if(env->_oolTraceAllocationBytes >= byteGranularity){
return true;
}
Expand Down Expand Up @@ -300,7 +319,7 @@ J9AllocateIndexableObjectNoGC(J9VMThread *vmThread, J9Class *clazz, uint32_t num

#if defined(J9VM_GC_THREAD_LOCAL_HEAP)
MM_GCExtensions *extensions = MM_GCExtensions::getExtensions(env);
if (extensions->instrumentableAllocateHookEnabled || !env->isInlineTLHAllocateEnabled()) {
if (extensions->instrumentableAllocateHookEnabled || extensions->disableInlineAllocationForSamplingBytesGranularity || !env->isInlineTLHAllocateEnabled()) {
/* This function is restricted to only being used for instrumentable allocates so we only need to check that one allocation hook.
* Note that we can't handle hooked allocates since we might be called without a JIT resolve frame and that is required for us to
* report the allocation event.
Expand Down Expand Up @@ -478,7 +497,7 @@ J9AllocateObject(J9VMThread *vmThread, J9Class *clazz, uintptr_t allocateFlags)
}

#if defined(J9VM_GC_THREAD_LOCAL_HEAP)
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold) {
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold || extensions->disableInlineAllocationForSamplingBytesGranularity) {
env->disableInlineTLHAllocate();
}
#endif /* J9VM_GC_THREAD_LOCAL_HEAP */
Expand Down Expand Up @@ -617,7 +636,7 @@ J9AllocateIndexableObject(J9VMThread *vmThread, J9Class *clazz, uint32_t numberO
}

#if defined(J9VM_GC_THREAD_LOCAL_HEAP)
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold ) {
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold || extensions->disableInlineAllocationForSamplingBytesGranularity) {
env->disableInlineTLHAllocate();
}
#endif /* J9VM_GC_THREAD_LOCAL_HEAP */
Expand Down Expand Up @@ -662,7 +681,7 @@ memoryManagerTLHAsyncCallbackHandler(J9VMThread *vmThread, IDATA handlerKey, voi

if (extensions->isStandardGC() || extensions->isVLHGC()) {
#if defined(J9VM_GC_THREAD_LOCAL_HEAP)
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold) {
if (extensions->fvtest_disableInlineAllocation || extensions->instrumentableAllocateHookEnabled || extensions->disableInlineCacheForAllocationThreshold || extensions->disableInlineAllocationForSamplingBytesGranularity) {
Trc_MM_memoryManagerTLHAsyncCallbackHandler_disableInlineTLHAllocates(vmThread,extensions->lowAllocationThreshold,extensions->highAllocationThreshold,extensions->tlhMinimumSize,extensions->tlhMaximumSize);
if (env->isInlineTLHAllocateEnabled()) {
/* BEN TODO: Collapse the env->enable/disableInlineTLHAllocate with these enable/disableCachedAllocations */
Expand Down
5 changes: 1 addition & 4 deletions runtime/jvmti/jvmtiCapability.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,10 +381,7 @@ jvmtiAddCapabilities(jvmtiEnv* env,
goto fail;
}

/* Initial sampling interval is MM_GCExtensions::oolObjectSamplingBytesGranularity which is 16M by default
* or set by command line option -Xgc:allocationSamplingGranularity.
* Set it to 512KB which is default sampling interval as per JEP 331 specification.
*/
/* Initial sampling interval is MM_GCExtensions::objectSamplingBytesGranularity which is 512KB by default. */
vm->memoryManagerFunctions->j9gc_set_allocation_sampling_interval(vm, 512 * 1024);
jvmtiData->flags |= J9JVMTI_FLAG_SAMPLED_OBJECT_ALLOC_ENABLED;
}
Expand Down