Skip to content

Commit 409216a

Browse files
[GR-70360] Fix JFR memory leak in Java event TLBs.
PullRequest: graal/22302
2 parents 5fd12cb + 0dc1a92 commit 409216a

File tree

2 files changed

+8
-4
lines changed

2 files changed

+8
-4
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrBufferAccess.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.jfr;
2626

27-
import jdk.graal.compiler.word.Word;
2827
import org.graalvm.nativeimage.c.struct.SizeOf;
2928
import org.graalvm.word.Pointer;
3029
import org.graalvm.word.UnsignedWord;
@@ -37,6 +36,7 @@
3736
import com.oracle.svm.core.util.UnsignedUtils;
3837

3938
import jdk.graal.compiler.api.replacements.Fold;
39+
import jdk.graal.compiler.word.Word;
4040

4141
/**
4242
* Used to access the raw memory of a {@link JfrBuffer}.
@@ -178,7 +178,7 @@ public static boolean isThreadLocal(JfrBuffer buffer) {
178178

179179
/**
180180
* If a buffer can't be freed right away, then we retire it instead. Retired buffers are ignored
181-
* by the JFR infrastructure and may be reinstate or freed at a later point in time.
181+
* by the JFR infrastructure and may be reinstated or freed at a later point in time.
182182
*/
183183
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
184184
public static void setRetired(JfrBuffer buffer) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/JfrThreadLocal.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ public UnsignedWord getThreadLocalBufferSize() {
123123
}
124124

125125
public void teardown() {
126+
// At this point all native buffers should be freed already.
126127
getNativeBufferList().teardown();
128+
// At this point Java buffers will be retired or freed.
127129
getJavaBufferList().teardown();
128130
}
129131

@@ -161,10 +163,12 @@ public static void stopRecording(IsolateThread isolateThread, boolean freeJavaBu
161163
flushToGlobalMemoryAndFreeBuffer(nb);
162164

163165
JfrBuffer jb = javaBuffer.get(isolateThread);
164-
javaBuffer.set(isolateThread, Word.nullPointer());
165166
if (freeJavaBuffer) {
167+
javaBuffer.set(isolateThread, Word.nullPointer());
166168
flushToGlobalMemoryAndFreeBuffer(jb);
167169
} else {
170+
// Do not reset the thread local since we may need it to reinstate the buffer in the
171+
// next recording.
168172
flushToGlobalMemoryAndRetireBuffer(jb);
169173
}
170174

@@ -213,7 +217,7 @@ private static void flushToGlobalMemoryAndFreeBuffer(JfrBuffer buffer) {
213217
@Uninterruptible(reason = "Locking without transition requires that the whole critical section is uninterruptible.")
214218
private static void flushToGlobalMemoryAndRetireBuffer(JfrBuffer buffer) {
215219
assert VMOperation.isInProgressAtSafepoint();
216-
if (buffer.isNull()) {
220+
if (buffer.isNull() || JfrBufferAccess.isRetired(buffer)) {
217221
return;
218222
}
219223

0 commit comments

Comments
 (0)