|
1 | 1 | /*
|
2 |
| - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
4 | 4 | *
|
5 | 5 | * This code is free software; you can redistribute it and/or modify it
|
|
35 | 35 | import jdk.internal.foreign.HeapMemorySegmentImpl.OfShort;
|
36 | 36 | import jdk.internal.misc.Unsafe;
|
37 | 37 | import jdk.internal.misc.VM;
|
| 38 | +import jdk.internal.vm.annotation.DontInline; |
38 | 39 | import jdk.internal.vm.annotation.ForceInline;
|
39 | 40 |
|
40 | 41 | import java.lang.foreign.MemorySegment;
|
@@ -175,39 +176,63 @@ public static OfDouble arrayOfDoubleSegment(Object base, long offset, long lengt
|
175 | 176 | return new OfDouble(offset, base, length, readOnly, bufferScope);
|
176 | 177 | }
|
177 | 178 |
|
178 |
| - public static NativeMemorySegmentImpl allocateSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl, |
179 |
| - boolean shouldReserve) { |
| 179 | + public static NativeMemorySegmentImpl allocateNativeSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl, |
| 180 | + boolean shouldReserve, boolean init) { |
| 181 | + long address = SegmentFactories.allocateNativeInternal(byteSize, byteAlignment, sessionImpl, shouldReserve, init); |
| 182 | + return new NativeMemorySegmentImpl(address, byteSize, false, sessionImpl); |
| 183 | + } |
| 184 | + |
| 185 | + private static long allocateNativeInternal(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl, |
| 186 | + boolean shouldReserve, boolean init) { |
180 | 187 | ensureInitialized();
|
| 188 | + Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment); |
181 | 189 | sessionImpl.checkValidState();
|
182 | 190 | if (VM.isDirectMemoryPageAligned()) {
|
183 | 191 | byteAlignment = Math.max(byteAlignment, AbstractMemorySegmentImpl.NIO_ACCESS.pageSize());
|
184 | 192 | }
|
185 |
| - long alignedSize = Math.max(1L, byteAlignment > MAX_MALLOC_ALIGN ? |
186 |
| - byteSize + (byteAlignment - 1) : |
187 |
| - byteSize); |
| 193 | + // Align the allocation size up to a multiple of 8 so we can init the memory with longs |
| 194 | + long alignedSize = init ? Utils.alignUp(byteSize, Long.BYTES) : byteSize; |
| 195 | + |
| 196 | + long allocationSize; |
| 197 | + long allocationBase; |
| 198 | + long result; |
| 199 | + if (byteAlignment > MAX_MALLOC_ALIGN) { |
| 200 | + allocationSize = alignedSize + byteAlignment - MAX_MALLOC_ALIGN; |
| 201 | + if (shouldReserve) { |
| 202 | + AbstractMemorySegmentImpl.NIO_ACCESS.reserveMemory(allocationSize, byteSize); |
| 203 | + } |
| 204 | + |
| 205 | + allocationBase = allocateMemoryWrapper(allocationSize); |
| 206 | + result = Utils.alignUp(allocationBase, byteAlignment); |
| 207 | + } else { |
| 208 | + allocationSize = alignedSize; |
| 209 | + if (shouldReserve) { |
| 210 | + AbstractMemorySegmentImpl.NIO_ACCESS.reserveMemory(allocationSize, byteSize); |
| 211 | + } |
188 | 212 |
|
189 |
| - if (shouldReserve) { |
190 |
| - AbstractMemorySegmentImpl.NIO_ACCESS.reserveMemory(alignedSize, byteSize); |
| 213 | + allocationBase = allocateMemoryWrapper(allocationSize); |
| 214 | + result = allocationBase; |
191 | 215 | }
|
192 | 216 |
|
193 |
| - long buf = allocateMemoryWrapper(alignedSize); |
194 |
| - long alignedBuf = Utils.alignUp(buf, byteAlignment); |
195 |
| - NativeMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize, |
196 |
| - false, sessionImpl); |
| 217 | + if (init) { |
| 218 | + initNativeMemory(result, alignedSize); |
| 219 | + } |
197 | 220 | sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() {
|
198 | 221 | @Override
|
199 | 222 | public void cleanup() {
|
200 |
| - UNSAFE.freeMemory(buf); |
| 223 | + UNSAFE.freeMemory(allocationBase); |
201 | 224 | if (shouldReserve) {
|
202 |
| - AbstractMemorySegmentImpl.NIO_ACCESS.unreserveMemory(alignedSize, byteSize); |
| 225 | + AbstractMemorySegmentImpl.NIO_ACCESS.unreserveMemory(allocationSize, byteSize); |
203 | 226 | }
|
204 | 227 | }
|
205 | 228 | });
|
206 |
| - if (alignedSize != byteSize) { |
207 |
| - long delta = alignedBuf - buf; |
208 |
| - segment = (NativeMemorySegmentImpl) segment.asSlice(delta, byteSize); |
| 229 | + return result; |
| 230 | + } |
| 231 | + |
| 232 | + private static void initNativeMemory(long address, long byteSize) { |
| 233 | + for (long i = 0; i < byteSize; i += Long.BYTES) { |
| 234 | + UNSAFE.putLongUnaligned(null, address + i, 0); |
209 | 235 | }
|
210 |
| - return segment; |
211 | 236 | }
|
212 | 237 |
|
213 | 238 | private static long allocateMemoryWrapper(long size) {
|
|
0 commit comments