Skip to content

[GR-61151] Remove internal frames from the top of JFR event stacktraces. #11082

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

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
* IDs depend on the JDK version (see metadata.xml file) and are computed at image build time.
*/
public final class JfrEvent {
public static final JfrEvent ThreadStart = create("jdk.ThreadStart");
public static final JfrEvent ThreadStart = create("jdk.ThreadStart", 4);
public static final JfrEvent ThreadEnd = create("jdk.ThreadEnd");
public static final JfrEvent ThreadCPULoad = create("jdk.ThreadCPULoad");
public static final JfrEvent DataLoss = create("jdk.DataLoss");
Expand All @@ -60,41 +60,54 @@ public final class JfrEvent {
public static final JfrEvent SafepointBegin = create("jdk.SafepointBegin", JfrEventFlags.HasDuration);
public static final JfrEvent SafepointEnd = create("jdk.SafepointEnd", JfrEventFlags.HasDuration);
public static final JfrEvent ExecuteVMOperation = create("jdk.ExecuteVMOperation", JfrEventFlags.HasDuration);
public static final JfrEvent JavaMonitorEnter = create("jdk.JavaMonitorEnter", JfrEventFlags.HasDuration);
public static final JfrEvent ThreadPark = create("jdk.ThreadPark", JfrEventFlags.HasDuration);
public static final JfrEvent JavaMonitorWait = create("jdk.JavaMonitorWait", JfrEventFlags.HasDuration);
public static final JfrEvent JavaMonitorInflate = create("jdk.JavaMonitorInflate", JfrEventFlags.HasDuration);
public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB");
public static final JfrEvent JavaMonitorEnter = create("jdk.JavaMonitorEnter", 5, JfrEventFlags.HasDuration);
public static final JfrEvent ThreadPark = create("jdk.ThreadPark", 5, JfrEventFlags.HasDuration);
public static final JfrEvent JavaMonitorWait = create("jdk.JavaMonitorWait", 5, JfrEventFlags.HasDuration);
public static final JfrEvent JavaMonitorInflate = create("jdk.JavaMonitorInflate", 5, JfrEventFlags.HasDuration);
public static final JfrEvent ObjectAllocationInNewTLAB = create("jdk.ObjectAllocationInNewTLAB", 5);
public static final JfrEvent GCHeapSummary = create("jdk.GCHeapSummary");
public static final JfrEvent ThreadAllocationStatistics = create("jdk.ThreadAllocationStatistics");
public static final JfrEvent SystemGC = create("jdk.SystemGC", JfrEventFlags.HasDuration);
public static final JfrEvent AllocationRequiringGC = create("jdk.AllocationRequiringGC");
public static final JfrEvent OldObjectSample = create("jdk.OldObjectSample");
public static final JfrEvent ObjectAllocationSample = create("jdk.ObjectAllocationSample", JfrEventFlags.SupportsThrottling);
public static final JfrEvent SystemGC = create("jdk.SystemGC", 5, JfrEventFlags.HasDuration);
public static final JfrEvent AllocationRequiringGC = create("jdk.AllocationRequiringGC", 5);
public static final JfrEvent OldObjectSample = create("jdk.OldObjectSample", 7);
public static final JfrEvent ObjectAllocationSample = create("jdk.ObjectAllocationSample", 5, JfrEventFlags.SupportsThrottling);
public static final JfrEvent NativeMemoryUsage = create("jdk.NativeMemoryUsage");
public static final JfrEvent NativeMemoryUsageTotal = create("jdk.NativeMemoryUsageTotal");

private final long id;
private final String name;
private final int flags;
private final int skipCount;

@Platforms(Platform.HOSTED_ONLY.class)
public static JfrEvent create(String name, JfrEventFlags... flags) {
return new JfrEvent(name, flags);
private static JfrEvent create(String name, JfrEventFlags... flags) {
return new JfrEvent(name, -1, flags);
}

@Platforms(Platform.HOSTED_ONLY.class)
private JfrEvent(String name, JfrEventFlags... flags) {
private static JfrEvent create(String name, int skipCount, JfrEventFlags... flags) {
return new JfrEvent(name, skipCount, flags);
}

@Platforms(Platform.HOSTED_ONLY.class)
private JfrEvent(String name, int skipCount, JfrEventFlags... flags) {
this.id = JfrMetadataTypeLibrary.lookupPlatformEvent(name);
this.name = name;
this.flags = EnumBitmask.computeBitmask(flags);
this.skipCount = skipCount;
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public long getId() {
return id;
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public int getSkipCount() {
assert skipCount >= 0 : "method may only be called for events that need a stack trace";
return skipCount;
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
public String getName() {
return name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,9 +272,7 @@ private static int recordIp(SamplerSampleWriterData data, CodePointer ip) {
/* Increment the number of seen frames. */
data.setSeenFrames(data.getSeenFrames() + 1);

if (shouldSkipFrame(data)) {
return NO_ERROR;
} else if (shouldTruncate(data)) {
if (shouldTruncate(data)) {
return TRUNCATED;
}

Expand All @@ -288,15 +286,10 @@ private static int recordIp(SamplerSampleWriterData data, CodePointer ip) {
return BUFFER_SIZE_EXCEEDED;
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
private static boolean shouldSkipFrame(SamplerSampleWriterData data) {
return data.getSeenFrames() <= data.getSkipCount();
}

@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
private static boolean shouldTruncate(SamplerSampleWriterData data) {
int numFrames = data.getSeenFrames() - data.getSkipCount();
if (numFrames > data.getMaxDepth()) {
int maxFrames = data.getMaxDepth() + data.getSkipCount();
if (data.getSeenFrames() > maxFrames) {
/* The stack size exceeds given depth. Stop walk! */
data.setTruncated(true);
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,8 @@ public long getStackTraceId(int skipCount) {
}

@Uninterruptible(reason = "Result is only valid until epoch changes.", callerMustBe = true)
public long getStackTraceId(JfrEvent eventType, int skipCount) {
return getStackTraceId(eventType.getId(), skipCount);
public long getStackTraceId(JfrEvent eventType) {
return getStackTraceId(eventType.getId(), eventType.getSkipCount());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static void emit0(UnsignedWord gcId, UnsignedWord size) {
JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.AllocationRequiringGC);
JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks());
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.AllocationRequiringGC, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.AllocationRequiringGC));
JfrNativeEventWriter.putLong(data, gcId.rawValue());
JfrNativeEventWriter.putLong(data, size.rawValue());
JfrNativeEventWriter.endSmallEvent(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public static void emit0(Object obj, long previousOwnerTid, long startTicks) {
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, duration);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorEnter, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorEnter));
JfrNativeEventWriter.putClass(data, obj.getClass());
JfrNativeEventWriter.putLong(data, previousOwnerTid);
JfrNativeEventWriter.putLong(data, Word.objectToUntrackedPointer(obj).rawValue());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

package com.oracle.svm.core.jfr.events;

import jdk.graal.compiler.word.Word;
import org.graalvm.nativeimage.StackValue;

import com.oracle.svm.core.Uninterruptible;
Expand All @@ -39,6 +38,8 @@
import com.oracle.svm.core.jfr.SubstrateJVM;
import com.oracle.svm.core.monitor.MonitorInflationCause;

import jdk.graal.compiler.word.Word;

public class JavaMonitorInflateEvent {
public static void emit(Object obj, long startTicks, MonitorInflationCause cause) {
if (HasJfrSupport.get()) {
Expand All @@ -47,7 +48,7 @@ public static void emit(Object obj, long startTicks, MonitorInflationCause cause
}

@Uninterruptible(reason = "Accesses a JFR buffer.")
public static void emit0(Object obj, long startTicks, MonitorInflationCause cause) {
private static void emit0(Object obj, long startTicks, MonitorInflationCause cause) {
long duration = JfrTicks.duration(startTicks);
if (JfrEvent.JavaMonitorInflate.shouldEmit(duration)) {
JfrNativeEventWriterData data = StackValue.get(JfrNativeEventWriterData.class);
Expand All @@ -57,7 +58,7 @@ public static void emit0(Object obj, long startTicks, MonitorInflationCause caus
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, duration);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorInflate, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorInflate));
JfrNativeEventWriter.putClass(data, obj.getClass());
JfrNativeEventWriter.putLong(data, Word.objectToUntrackedPointer(obj).rawValue());
JfrNativeEventWriter.putLong(data, getId(cause));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ private static void emit0(long startTicks, Object obj, long notifier, long timeo
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, duration);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorWait, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.JavaMonitorWait));
JfrNativeEventWriter.putClass(data, obj.getClass());
JfrNativeEventWriter.putLong(data, notifier);
JfrNativeEventWriter.putLong(data, timeout);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private static void emitObjectAllocationInNewTLAB(long startTicks, DynamicHub hu
JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.ObjectAllocationInNewTLAB);
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ObjectAllocationInNewTLAB, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ObjectAllocationInNewTLAB));
JfrNativeEventWriter.putClass(data, DynamicHub.toClass(hub));
JfrNativeEventWriter.putLong(data, allocationSize.rawValue());
JfrNativeEventWriter.putLong(data, tlabSize.rawValue());
Expand All @@ -88,7 +88,7 @@ private static void emitObjectAllocationSample(long startTicks, DynamicHub hub)
JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.ObjectAllocationSample);
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ObjectAllocationSample, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ObjectAllocationSample));
JfrNativeEventWriter.putClass(data, DynamicHub.toClass(hub));
JfrNativeEventWriter.putLong(data, weight);
JfrNativeEventWriter.endSmallEvent(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private static void emit0(long startTicks, boolean invokedConcurrent) {
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, duration);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.SystemGC, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.SystemGC));
JfrNativeEventWriter.putBoolean(data, invokedConcurrent);
JfrNativeEventWriter.endSmallEvent(data);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private static void emit0(long startTicks, Object obj, boolean isAbsolute, long
JfrNativeEventWriter.putLong(data, startTicks);
JfrNativeEventWriter.putLong(data, duration);
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ThreadPark, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ThreadPark));
JfrNativeEventWriter.putClass(data, parkedClass);
JfrNativeEventWriter.putLong(data, timeout);
JfrNativeEventWriter.putLong(data, until);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static void emit(Thread thread) {
JfrNativeEventWriter.beginSmallEvent(data, JfrEvent.ThreadStart);
JfrNativeEventWriter.putLong(data, JfrTicks.elapsedTicks());
JfrNativeEventWriter.putEventThread(data);
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ThreadStart, 0));
JfrNativeEventWriter.putLong(data, SubstrateJVM.get().getStackTraceId(JfrEvent.ThreadStart));
JfrNativeEventWriter.putThread(data, thread);
JfrNativeEventWriter.putLong(data, JavaThreads.getParentThreadId(thread));
JfrNativeEventWriter.endSmallEvent(data);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private void release(JfrOldObject sample) {
private void store(Object obj, UnsignedWord span, UnsignedWord allocatedSize, int arrayLength) {
Thread thread = JavaThreads.getCurrentThreadOrNull();
long threadId = thread == null ? 0L : JavaThreads.getThreadId(thread);
long stackTraceId = thread == null ? 0L : SubstrateJVM.get().getStackTraceId(JfrEvent.OldObjectSample, 0);
long stackTraceId = thread == null ? 0L : SubstrateJVM.get().getStackTraceId(JfrEvent.OldObjectSample);
UnsignedWord heapUsedAfterLastGC = Heap.getHeap().getUsedMemoryAfterLastGC();

JfrOldObject sample = (JfrOldObject) freeList.pop();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ private static void serializeStackTraces(SamplerBuffer rawStackTraceBuffer) {
int sampleSize = current.readInt(0);
current = current.add(Integer.BYTES);

/* Padding. */
/* Number of vframes that should be skipped at the top of the stack trace. */
int skipCount = current.readInt(0);
current = current.add(Integer.BYTES);

/* Tick. */
Expand All @@ -132,16 +133,16 @@ private static void serializeStackTraces(SamplerBuffer rawStackTraceBuffer) {

assert current.subtract(entryStart).equal(SamplerSampleWriter.getHeaderSize());

current = serializeStackTrace(current, end, sampleSize, sampleHash, isTruncated, sampleTick, threadId, threadState);
current = serializeStackTrace(current, end, sampleSize, sampleHash, isTruncated, sampleTick, threadId, threadState, skipCount);
}

SamplerBufferAccess.reinitialize(rawStackTraceBuffer);
}

@Uninterruptible(reason = "Wraps the call to the possibly interruptible serializer.", calleeMustBe = false)
private static Pointer serializeStackTrace(Pointer rawStackTrace, Pointer bufferEnd, int sampleSize, int sampleHash,
boolean isTruncated, long sampleTick, long threadId, long threadState) {
boolean isTruncated, long sampleTick, long threadId, long threadState, int skipCount) {
return SamplerStackTraceSerializer.singleton().serializeStackTrace(rawStackTrace, bufferEnd, sampleSize,
sampleHash, isTruncated, sampleTick, threadId, threadState);
sampleHash, isTruncated, sampleTick, threadId, threadState, skipCount);
}
}
Loading
Loading