diff --git a/src/java.base/share/classes/jdk/internal/foreign/ConfinedSession.java b/src/java.base/share/classes/jdk/internal/foreign/ConfinedSession.java index ec1e8fa7b15..47dfc69e887 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/ConfinedSession.java +++ b/src/java.base/share/classes/jdk/internal/foreign/ConfinedSession.java @@ -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(); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java index cc2e746ce4d..2163146f1a9 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java @@ -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; diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java b/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java index a70861a0dda..4ae78d6d99e 100644 --- a/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java +++ b/test/micro/org/openjdk/bench/java/lang/foreign/AllocTest.java @@ -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. * * This code is free software; you can redistribute it and/or modify it @@ -64,9 +64,9 @@ public class AllocTest extends CLayouts { } @Benchmark - public MemorySegment alloc_confined() { + public long alloc_confined() { try (Arena arena = Arena.ofConfined()) { - return arena.allocate(size); + return arena.allocate(size).address(); } }