8348668: Prevent first resource cleanup in confined arena from escaping

Reviewed-by: liach
This commit is contained in:
Jorn Vernee 2025-01-30 14:55:37 +00:00
parent 2efb6aaadb
commit fac63d4383
3 changed files with 38 additions and 17 deletions

View file

@ -86,11 +86,20 @@ final class ConfinedSession extends MemorySessionImpl {
* A confined resource list; no races are possible here. * A confined resource list; no races are possible here.
*/ */
static final class ConfinedResourceList extends ResourceList { static final class ConfinedResourceList extends ResourceList {
// The first element of the list is pulled into a separate field
// which helps escape analysis keep track of the instance, allowing
// it to be scalar replaced.
ResourceCleanup cache;
@Override @Override
void add(ResourceCleanup cleanup) { void add(ResourceCleanup cleanup) {
if (fst != ResourceCleanup.CLOSED_LIST) { if (fst != ResourceCleanup.CLOSED_LIST) {
cleanup.next = fst; if (cache == null) {
fst = cleanup; cache = cleanup;
} else {
cleanup.next = fst;
fst = cleanup;
}
} else { } else {
throw alreadyClosed(); throw alreadyClosed();
} }
@ -101,7 +110,11 @@ final class ConfinedSession extends MemorySessionImpl {
if (fst != ResourceCleanup.CLOSED_LIST) { if (fst != ResourceCleanup.CLOSED_LIST) {
ResourceCleanup prev = fst; ResourceCleanup prev = fst;
fst = ResourceCleanup.CLOSED_LIST; fst = ResourceCleanup.CLOSED_LIST;
cleanup(prev); RuntimeException pendingException = null;
if (cache != null) {
pendingException = cleanupSingle(cache, pendingException);
}
cleanup(prev, pendingException);
} else { } else {
throw alreadyClosed(); throw alreadyClosed();
} }

View file

@ -261,19 +261,13 @@ public abstract sealed class MemorySessionImpl
} }
static void cleanup(ResourceCleanup first) { static void cleanup(ResourceCleanup first) {
RuntimeException pendingException = null; cleanup(first, null);
}
static void cleanup(ResourceCleanup first, RuntimeException pendingException) {
ResourceCleanup current = first; ResourceCleanup current = first;
while (current != null) { while (current != null) {
try { pendingException = cleanupSingle(current, pendingException);
current.cleanup();
} catch (RuntimeException ex) {
if (pendingException == null) {
pendingException = ex;
} else if (ex != pendingException) {
// note: self-suppression is not supported
pendingException.addSuppressed(ex);
}
}
current = current.next; current = current.next;
} }
if (pendingException != null) { if (pendingException != null) {
@ -281,6 +275,20 @@ public abstract sealed class MemorySessionImpl
} }
} }
static RuntimeException cleanupSingle(ResourceCleanup resource, RuntimeException pendingException) {
try {
resource.cleanup();
} catch (RuntimeException ex) {
if (pendingException == null) {
pendingException = ex;
} else if (ex != pendingException) {
// note: self-suppression is not supported
pendingException.addSuppressed(ex);
}
}
return pendingException;
}
public abstract static class ResourceCleanup { public abstract static class ResourceCleanup {
ResourceCleanup next; ResourceCleanup next;

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -64,9 +64,9 @@ public class AllocTest extends CLayouts {
} }
@Benchmark @Benchmark
public MemorySegment alloc_confined() { public long alloc_confined() {
try (Arena arena = Arena.ofConfined()) { try (Arena arena = Arena.ofConfined()) {
return arena.allocate(size); return arena.allocate(size).address();
} }
} }