Skip to content

Commit 41ad2b6

Browse files
committed
[GR-33950] Allocate and manage WasmMemory as a direct ByteBuffer.
PullRequest: graal/10132
2 parents 6399fc8 + b0b6988 commit 41ad2b6

File tree

5 files changed

+75
-42
lines changed

5 files changed

+75
-42
lines changed

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmLanguage.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545
import org.graalvm.options.OptionDescriptors;
4646
import org.graalvm.wasm.api.WebAssembly;
47-
import org.graalvm.wasm.memory.UnsafeWasmMemory;
4847
import org.graalvm.wasm.memory.WasmMemory;
4948

5049
import com.oracle.truffle.api.CallTarget;
@@ -105,9 +104,7 @@ protected void finalizeContext(WasmContext context) {
105104
super.finalizeContext(context);
106105
for (int i = 0; i < context.memories().count(); ++i) {
107106
final WasmMemory memory = context.memories().memory(i);
108-
if (memory instanceof UnsafeWasmMemory) {
109-
((UnsafeWasmMemory) memory).free();
110-
}
107+
memory.close();
111108
}
112109
try {
113110
context.fdManager().close();

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/api/WebAssembly.java

Lines changed: 31 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,17 @@
4040
*/
4141
package org.graalvm.wasm.api;
4242

43-
import com.oracle.truffle.api.CompilerAsserts;
44-
import com.oracle.truffle.api.TruffleContext;
45-
import com.oracle.truffle.api.interop.InteropException;
46-
import com.oracle.truffle.api.interop.InteropLibrary;
47-
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
48-
import com.oracle.truffle.api.interop.UnknownIdentifierException;
49-
import com.oracle.truffle.api.interop.UnsupportedMessageException;
43+
import static java.lang.Integer.compareUnsigned;
44+
import static org.graalvm.wasm.WasmMath.minUnsigned;
45+
import static org.graalvm.wasm.api.JsConstants.JS_LIMITS;
46+
47+
import java.nio.ByteBuffer;
48+
import java.util.ArrayList;
49+
import java.util.HashMap;
50+
import java.util.List;
51+
import java.util.Map;
52+
import java.util.Objects;
53+
5054
import org.graalvm.collections.EconomicMap;
5155
import org.graalvm.collections.Pair;
5256
import org.graalvm.wasm.EmbedderDataHolder;
@@ -73,15 +77,13 @@
7377
import org.graalvm.wasm.memory.UnsafeWasmMemory;
7478
import org.graalvm.wasm.memory.WasmMemory;
7579

76-
import java.util.ArrayList;
77-
import java.util.HashMap;
78-
import java.util.List;
79-
import java.util.Map;
80-
import java.util.Objects;
81-
82-
import static java.lang.Integer.compareUnsigned;
83-
import static org.graalvm.wasm.WasmMath.minUnsigned;
84-
import static org.graalvm.wasm.api.JsConstants.JS_LIMITS;
80+
import com.oracle.truffle.api.CompilerAsserts;
81+
import com.oracle.truffle.api.TruffleContext;
82+
import com.oracle.truffle.api.interop.InteropException;
83+
import com.oracle.truffle.api.interop.InteropLibrary;
84+
import com.oracle.truffle.api.interop.InvalidArrayIndexException;
85+
import com.oracle.truffle.api.interop.UnknownIdentifierException;
86+
import com.oracle.truffle.api.interop.UnsupportedMessageException;
8587

8688
public class WebAssembly extends Dictionary {
8789
private final WasmContext currentContext;
@@ -103,6 +105,7 @@ public WebAssembly(WasmContext currentContext) {
103105
addMember("mem_alloc", new Executable(args -> memAlloc(args)));
104106
addMember("mem_grow", new Executable(args -> memGrow(args)));
105107
addMember("mem_set_grow_callback", new Executable(args -> memSetGrowCallback(args)));
108+
addMember("mem_as_byte_buffer", new Executable(args -> memAsByteBuffer(args)));
106109

107110
addMember("global_alloc", new Executable(args -> globalAlloc(args)));
108111
addMember("global_read", new Executable(args -> globalRead(args)));
@@ -620,6 +623,18 @@ public static void invokeMemGrowCallback(WasmMemory memory) {
620623
}
621624
}
622625

626+
private static Object memAsByteBuffer(Object[] args) {
627+
checkArgumentCount(args, 1);
628+
if (args[0] instanceof WasmMemory) {
629+
WasmMemory memory = (WasmMemory) args[0];
630+
ByteBuffer buffer = memory.asByteBuffer();
631+
if (buffer != null) {
632+
return WasmContext.get(null).environment().asGuestValue(buffer);
633+
}
634+
}
635+
return WasmVoidResult.getInstance();
636+
}
637+
623638
private static Object globalAlloc(Object[] args) {
624639
checkArgumentCount(args, 3);
625640

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/ByteArrayWasmMemory.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@
4747
import static org.graalvm.wasm.constants.Sizes.MAX_MEMORY_INSTANCE_SIZE;
4848
import static org.graalvm.wasm.constants.Sizes.MEMORY_PAGE_SIZE;
4949

50+
import java.nio.ByteBuffer;
51+
5052
import org.graalvm.wasm.constants.Sizes;
5153
import org.graalvm.wasm.exception.Failure;
5254
import org.graalvm.wasm.exception.WasmException;
@@ -408,4 +410,14 @@ public WasmMemory duplicate() {
408410
System.arraycopy(buffer, 0, other.buffer, 0, buffer.length);
409411
return other;
410412
}
413+
414+
@Override
415+
public void close() {
416+
buffer = null;
417+
}
418+
419+
@Override
420+
public ByteBuffer asByteBuffer() {
421+
return null;
422+
}
411423
}

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/UnsafeWasmMemory.java

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -48,22 +48,19 @@
4848
import static org.graalvm.wasm.constants.Sizes.MEMORY_PAGE_SIZE;
4949

5050
import java.lang.reflect.Field;
51+
import java.nio.ByteBuffer;
5152

5253
import org.graalvm.wasm.constants.Sizes;
5354
import org.graalvm.wasm.exception.Failure;
5455
import org.graalvm.wasm.exception.WasmException;
5556

5657
import com.oracle.truffle.api.CompilerDirectives;
5758
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
58-
import com.oracle.truffle.api.interop.InteropLibrary;
59-
import com.oracle.truffle.api.library.ExportLibrary;
60-
import com.oracle.truffle.api.library.ExportMessage;
6159
import com.oracle.truffle.api.nodes.Node;
6260

6361
import sun.misc.Unsafe;
6462

65-
@ExportLibrary(InteropLibrary.class)
66-
public final class UnsafeWasmMemory extends WasmMemory implements AutoCloseable {
63+
public final class UnsafeWasmMemory extends WasmMemory {
6764
/**
6865
* @see #declaredMinSize()
6966
*/
@@ -88,6 +85,8 @@ public final class UnsafeWasmMemory extends WasmMemory implements AutoCloseable
8885
*/
8986
private final int maxAllowedSize;
9087

88+
private ByteBuffer buffer;
89+
9190
private static final Unsafe unsafe;
9291

9392
private UnsafeWasmMemory(int declaredMinSize, int declaredMaxSize, int initialSize, int maxAllowedSize) {
@@ -102,13 +101,23 @@ private UnsafeWasmMemory(int declaredMinSize, int declaredMaxSize, int initialSi
102101
this.size = declaredMinSize;
103102
this.maxAllowedSize = maxAllowedSize;
104103
final long byteSize = byteSize();
104+
this.buffer = allocateBuffer(byteSize);
105+
this.startAddress = getBufferAddress(buffer);
106+
}
107+
108+
@TruffleBoundary
109+
private static ByteBuffer allocateBuffer(final long byteSize) {
110+
assert (int) byteSize == byteSize : byteSize;
105111
try {
106-
this.startAddress = unsafe.allocateMemory(byteSize);
112+
return ByteBuffer.allocateDirect((int) byteSize);
107113
} catch (OutOfMemoryError error) {
108-
CompilerDirectives.transferToInterpreter();
109114
throw WasmException.create(Failure.MEMORY_ALLOCATION_FAILED);
110115
}
111-
unsafe.setMemory(startAddress, byteSize, (byte) 0);
116+
}
117+
118+
@TruffleBoundary
119+
private static long getBufferAddress(ByteBuffer buffer) {
120+
return ((sun.nio.ch.DirectBuffer) buffer).address();
112121
}
113122

114123
public UnsafeWasmMemory(int declaredMinSize, int declaredMaxSize, int maxAllowedSize) {
@@ -170,10 +179,10 @@ public boolean grow(int extraPageSize) {
170179
// computation of targetByteSize does not overflow.
171180
final int targetByteSize = multiplyExact(addExact(size(), extraPageSize), MEMORY_PAGE_SIZE);
172181
try {
173-
final long updatedStartAddress = unsafe.allocateMemory(targetByteSize);
182+
ByteBuffer updatedBuffer = allocateBuffer(targetByteSize);
183+
final long updatedStartAddress = getBufferAddress(updatedBuffer);
174184
unsafe.copyMemory(startAddress, updatedStartAddress, byteSize());
175-
unsafe.setMemory(updatedStartAddress + byteSize(), targetByteSize - byteSize(), (byte) 0);
176-
unsafe.freeMemory(startAddress);
185+
buffer = updatedBuffer;
177186
startAddress = updatedStartAddress;
178187
size += extraPageSize;
179188
invokeGrowCallback();
@@ -348,7 +357,7 @@ public WasmMemory duplicate() {
348357
}
349358

350359
public void free() {
351-
unsafe.freeMemory(this.startAddress);
360+
buffer = null;
352361
startAddress = 0;
353362
size = 0;
354363
}
@@ -364,15 +373,9 @@ public void close() {
364373
}
365374
}
366375

367-
@SuppressWarnings("static-method")
368-
@ExportMessage
369-
public boolean isPointer() {
370-
return true;
371-
}
372-
373-
@ExportMessage
374-
public long asPointer() {
375-
return startAddress;
376+
@Override
377+
public ByteBuffer asByteBuffer() {
378+
return buffer.duplicate();
376379
}
377380

378381
static {

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/memory/WasmMemory.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
*/
4141
package org.graalvm.wasm.memory;
4242

43+
import java.nio.ByteBuffer;
4344
import java.nio.ByteOrder;
4445
import java.nio.charset.StandardCharsets;
4546

@@ -68,7 +69,7 @@
6869
import com.oracle.truffle.api.profiles.BranchProfile;
6970

7071
@ExportLibrary(InteropLibrary.class)
71-
public abstract class WasmMemory extends EmbedderDataHolder implements TruffleObject {
72+
public abstract class WasmMemory extends EmbedderDataHolder implements TruffleObject, AutoCloseable {
7273

7374
private Object growCallback = null;
7475

@@ -505,4 +506,9 @@ public Object getGrowCallback() {
505506
protected void invokeGrowCallback() {
506507
WebAssembly.invokeMemGrowCallback(this);
507508
}
509+
510+
@Override
511+
public abstract void close();
512+
513+
public abstract ByteBuffer asByteBuffer();
508514
}

0 commit comments

Comments
 (0)