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.
*/
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
void add(ResourceCleanup cleanup) {
if (fst != ResourceCleanup.CLOSED_LIST) {
cleanup.next = fst;
fst = cleanup;
if (cache == null) {
cache = cleanup;
} else {
cleanup.next = fst;
fst = cleanup;
}
} else {
throw alreadyClosed();
}
@ -101,7 +110,11 @@ final class ConfinedSession extends MemorySessionImpl {
if (fst != ResourceCleanup.CLOSED_LIST) {
ResourceCleanup prev = fst;
fst = ResourceCleanup.CLOSED_LIST;
cleanup(prev);
RuntimeException pendingException = null;
if (cache != null) {
pendingException = cleanupSingle(cache, pendingException);
}
cleanup(prev, pendingException);
} else {
throw alreadyClosed();
}

View file

@ -261,19 +261,13 @@ public abstract sealed class MemorySessionImpl
}
static void cleanup(ResourceCleanup first) {
RuntimeException pendingException = null;
cleanup(first, null);
}
static void cleanup(ResourceCleanup first, RuntimeException pendingException) {
ResourceCleanup current = first;
while (current != null) {
try {
current.cleanup();
} catch (RuntimeException ex) {
if (pendingException == null) {
pendingException = ex;
} else if (ex != pendingException) {
// note: self-suppression is not supported
pendingException.addSuppressed(ex);
}
}
pendingException = cleanupSingle(current, pendingException);
current = current.next;
}
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 {
ResourceCleanup next;