diff --git a/src/java.base/share/classes/java/lang/foreign/Arena.java b/src/java.base/share/classes/java/lang/foreign/Arena.java index 195f8a44db6..7618fa727a4 100644 --- a/src/java.base/share/classes/java/lang/foreign/Arena.java +++ b/src/java.base/share/classes/java/lang/foreign/Arena.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, 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 @@ -219,6 +219,9 @@ public interface Arena extends SegmentAllocator, AutoCloseable { * Segments allocated with the returned arena can be * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. * Calling {@link #close()} on the returned arena will result in an {@link UnsupportedOperationException}. + *
+ * Memory segments {@linkplain #allocate(long, long) allocated} by the returned arena + * are zero-initialized. * * @return a new arena that is managed, automatically, by the garbage collector */ @@ -231,6 +234,9 @@ public interface Arena extends SegmentAllocator, AutoCloseable { * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. * Calling {@link #close()} on the returned arena will result in * an {@link UnsupportedOperationException}. + *
+ * Memory segments {@linkplain #allocate(long, long) allocated} by the returned arena + * are zero-initialized. */ static Arena global() { class Holder { @@ -243,6 +249,9 @@ public interface Arena extends SegmentAllocator, AutoCloseable { * {@return a new confined arena} Segments allocated with the confined arena can be * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by the thread * that created the arena, the arena's owner thread. + *
+ * Memory segments {@linkplain #allocate(long, long) allocated} by the returned arena + * are zero-initialized. */ static Arena ofConfined() { return MemorySessionImpl.createConfined(Thread.currentThread()).asArena(); @@ -251,6 +260,9 @@ public interface Arena extends SegmentAllocator, AutoCloseable { /** * {@return a new shared arena} Segments allocated with the global arena can be * {@linkplain MemorySegment#isAccessibleBy(Thread) accessed} by any thread. + *
+ * Memory segments {@linkplain #allocate(long, long) allocated} by the returned arena + * are zero-initialized. */ static Arena ofShared() { return MemorySessionImpl.createShared().asArena(); diff --git a/test/jdk/java/foreign/TestScope.java b/test/jdk/java/foreign/TestScope.java index 337dce7d0ca..4047789d89e 100644 --- a/test/jdk/java/foreign/TestScope.java +++ b/test/jdk/java/foreign/TestScope.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024 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 @@ -31,8 +31,11 @@ import org.testng.annotations.*; import java.lang.foreign.Arena; import java.lang.foreign.MemorySegment; import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; import java.nio.ByteBuffer; import java.nio.IntBuffer; +import java.util.HexFormat; +import java.util.stream.LongStream; import static org.testng.Assert.*; @@ -108,6 +111,30 @@ public class TestScope { testDerivedBufferScope(segment1.reinterpret(10)); } + @Test + public void testZeroedOfAuto() { + testZeroed(Arena.ofAuto()); + } + + @Test + public void testZeroedGlobal() { + testZeroed(Arena.global()); + } + + @Test + public void testZeroedOfConfined() { + try (Arena arena = Arena.ofConfined()) { + testZeroed(arena); + } + } + + @Test + public void testZeroedOfShared() { + try (Arena arena = Arena.ofShared()) { + testZeroed(arena); + } + } + void testDerivedBufferScope(MemorySegment segment) { ByteBuffer buffer = segment.asByteBuffer(); MemorySegment.Scope expectedScope = segment.scope(); @@ -119,4 +146,14 @@ public class TestScope { IntBuffer view = buffer.asIntBuffer(); assertEquals(expectedScope, MemorySegment.ofBuffer(view).scope()); } + + private static final MemorySegment ZEROED_MEMORY = MemorySegment.ofArray(new byte[8102]); + + void testZeroed(Arena arena) { + long byteSize = ZEROED_MEMORY.byteSize(); + var segment = arena.allocate(byteSize, Long.BYTES); + long mismatch = ZEROED_MEMORY.mismatch(segment); + assertEquals(mismatch, -1); + } + }