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

[GR-61151] Trim internal JFR stacktraces to match OpenJDK #10385

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ public final class VMInspectionOptions {
AccumulatingLocatableMultiOptionValue.Strings.buildWithCommaDelimiter(),
VMInspectionOptions::validateEnableMonitoringFeatures);

@Option(help = "Determine whether to trim internal frames from JFR stacktraces (defaults to true).")//
public static final HostedOptionKey<Boolean> JfrTrimInternalStackTraces = new HostedOptionKey<>(true, VMInspectionOptions::notSupportedOnWindows);

@Option(help = "Dumps all runtime compiled methods on SIGUSR2.", type = OptionType.User) //
public static final HostedOptionKey<Boolean> DumpRuntimeCompilationOnSignal = new HostedOptionKey<>(false, VMInspectionOptions::notSupportedOnWindows);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@
import com.oracle.svm.core.Uninterruptible;
import com.oracle.svm.core.collections.EnumBitmask;
import com.oracle.svm.core.thread.JavaThreads;
import com.oracle.svm.core.VMInspectionOptions;

/**
* This file contains the VM-level events that Native Image supports on all JDK versions. The event
* 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");
private static final int defaultInternalSkipCount = VMInspectionOptions.JfrTrimInternalStackTraces.getValue() ? 5 : 0;
public static final JfrEvent ThreadStart = create("jdk.ThreadStart", defaultInternalSkipCount - 1);
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 Down Expand Up @@ -69,32 +71,44 @@ public final class JfrEvent {
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 OldObjectSample = create("jdk.OldObjectSample", 7);
public static final JfrEvent ObjectAllocationSample = create("jdk.ObjectAllocationSample", 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);
return new JfrEvent(name, defaultInternalSkipCount, flags);
}

@Platforms(Platform.HOSTED_ONLY.class)
private JfrEvent(String name, JfrEventFlags... flags) {
public 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() {
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 @@ -293,8 +293,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 @@ -57,7 +57,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. */
/* Sample size, excluding the header and the end marker. */
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