diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrBufferAccess.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrBufferAccess.java index cc38a316cba5..a6aaacc8fc4e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrBufferAccess.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrBufferAccess.java @@ -24,7 +24,6 @@ */ package com.oracle.svm.core.jfr; -import jdk.graal.compiler.word.Word; import org.graalvm.nativeimage.c.struct.SizeOf; import org.graalvm.word.Pointer; import org.graalvm.word.UnsignedWord; @@ -37,6 +36,7 @@ import com.oracle.svm.core.util.UnsignedUtils; import jdk.graal.compiler.api.replacements.Fold; +import jdk.graal.compiler.word.Word; /** * Used to access the raw memory of a {@link JfrBuffer}. @@ -178,7 +178,7 @@ public static boolean isThreadLocal(JfrBuffer buffer) { /** * If a buffer can't be freed right away, then we retire it instead. Retired buffers are ignored - * by the JFR infrastructure and may be reinstate or freed at a later point in time. + * by the JFR infrastructure and may be reinstated or freed at a later point in time. */ @Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) public static void setRetired(JfrBuffer buffer) { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java index d5f58382182d..98d7daea7ce8 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java @@ -123,7 +123,9 @@ public UnsignedWord getThreadLocalBufferSize() { } public void teardown() { + // At this point all native buffers should be freed already. getNativeBufferList().teardown(); + // At this point Java buffers will be retired or freed. getJavaBufferList().teardown(); } @@ -161,10 +163,12 @@ public static void stopRecording(IsolateThread isolateThread, boolean freeJavaBu flushToGlobalMemoryAndFreeBuffer(nb); JfrBuffer jb = javaBuffer.get(isolateThread); - javaBuffer.set(isolateThread, Word.nullPointer()); if (freeJavaBuffer) { + javaBuffer.set(isolateThread, Word.nullPointer()); flushToGlobalMemoryAndFreeBuffer(jb); } else { + // Do not reset the thread local since we may need it to reinstate the buffer in the + // next recording. flushToGlobalMemoryAndRetireBuffer(jb); } @@ -213,7 +217,7 @@ private static void flushToGlobalMemoryAndFreeBuffer(JfrBuffer buffer) { @Uninterruptible(reason = "Locking without transition requires that the whole critical section is uninterruptible.") private static void flushToGlobalMemoryAndRetireBuffer(JfrBuffer buffer) { assert VMOperation.isInProgressAtSafepoint(); - if (buffer.isNull()) { + if (buffer.isNull() || JfrBufferAccess.isRetired(buffer)) { return; }