Skip to content

Commit 98f5caf

Browse files
committed
Added memory grow notification system.
1 parent 00acbca commit 98f5caf

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ public WebAssembly(WasmContext currentContext) {
101101

102102
addMember("mem_alloc", new Executable(args -> memAlloc(args)));
103103
addMember("mem_grow", new Executable(args -> memGrow(args)));
104+
addMember("mem_set_grow_callback", new Executable(args -> memSetGrowCallback(args)));
104105

105106
addMember("global_alloc", new Executable(args -> globalAlloc(args)));
106107
addMember("global_read", new Executable(args -> globalRead(args)));
@@ -583,6 +584,35 @@ public static long memGrow(WasmMemory memory, int delta) {
583584
return pageSize;
584585
}
585586

587+
private static Object memSetGrowCallback(Object[] args) {
588+
InteropLibrary lib = InteropLibrary.getUncached();
589+
if (!(args[0] instanceof WasmMemory)) {
590+
throw new WasmJsApiException(WasmJsApiException.Kind.TypeError, "First argument must be wasm memory");
591+
}
592+
if (!lib.isExecutable(args[1])) {
593+
throw new WasmJsApiException(WasmJsApiException.Kind.TypeError, "Second argument must be executable");
594+
}
595+
WasmMemory memory = (WasmMemory) args[0];
596+
return memSetGrowCallback(memory, args[1]);
597+
}
598+
599+
private static Object memSetGrowCallback(WasmMemory memory, Object callback) {
600+
memory.setGrowCallback(callback);
601+
return WasmVoidResult.getInstance();
602+
}
603+
604+
public static void invokeMemGrowCallback(WasmMemory memory) {
605+
Object callback = memory.getGrowCallback();
606+
if (callback != null) {
607+
InteropLibrary lib = InteropLibrary.getUncached();
608+
try {
609+
lib.execute(callback, memory);
610+
} catch (InteropException e) {
611+
throw new WasmJsApiException(WasmJsApiException.Kind.TypeError, "Unable to call memory grow callback", e);
612+
}
613+
}
614+
}
615+
586616
private static Object globalAlloc(Object[] args) {
587617
checkArgumentCount(args, 3);
588618

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -146,6 +146,7 @@ public int declaredMaxSize() {
146146
@TruffleBoundary
147147
public synchronized boolean grow(int extraPageSize) {
148148
if (extraPageSize == 0) {
149+
invokeGrowCallback();
149150
return true;
150151
} else if (compareUnsigned(extraPageSize, maxAllowedSize) <= 0 && compareUnsigned(size() + extraPageSize, maxAllowedSize) <= 0) {
151152
try {
@@ -155,6 +156,7 @@ public synchronized boolean grow(int extraPageSize) {
155156
final byte[] newBuffer = new byte[targetByteSize];
156157
System.arraycopy(buffer, 0, newBuffer, 0, buffer.length);
157158
buffer = newBuffer;
159+
invokeGrowCallback();
158160
return true;
159161
} catch (OutOfMemoryError error) {
160162
throw WasmException.create(Failure.MEMORY_ALLOCATION_FAILED);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ public int declaredMaxSize() {
159159
@TruffleBoundary
160160
public boolean grow(int extraPageSize) {
161161
if (extraPageSize == 0) {
162+
invokeGrowCallback();
162163
return true;
163164
} else if (compareUnsigned(extraPageSize, maxAllowedSize) <= 0 && compareUnsigned(size() + extraPageSize, maxAllowedSize) <= 0) {
164165
// Condition above and limit on maxPageSize (see ModuleLimits#MAX_MEMORY_SIZE) ensure
@@ -171,6 +172,7 @@ public boolean grow(int extraPageSize) {
171172
unsafe.freeMemory(startAddress);
172173
startAddress = updatedStartAddress;
173174
size += extraPageSize;
175+
invokeGrowCallback();
174176
return true;
175177
} catch (OutOfMemoryError error) {
176178
throw WasmException.create(Failure.MEMORY_ALLOCATION_FAILED);

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,13 @@
6464
import com.oracle.truffle.api.library.ExportMessage;
6565
import com.oracle.truffle.api.nodes.Node;
6666
import com.oracle.truffle.api.profiles.BranchProfile;
67+
import org.graalvm.wasm.api.WebAssembly;
6768

6869
@ExportLibrary(InteropLibrary.class)
6970
public abstract class WasmMemory implements TruffleObject {
7071

72+
private Object growCallback = null;
73+
7174
public abstract void copy(Node node, int src, int dst, int n);
7275

7376
/**
@@ -489,4 +492,16 @@ public void writeArrayElement(long address, Object value,
489492
}
490493
store_i32_8(null, (int) address, rawValue);
491494
}
495+
496+
public void setGrowCallback(Object growCallback) {
497+
this.growCallback = growCallback;
498+
}
499+
500+
public Object getGrowCallback() {
501+
return growCallback;
502+
}
503+
504+
protected void invokeGrowCallback() {
505+
WebAssembly.invokeMemGrowCallback(this);
506+
}
492507
}

0 commit comments

Comments
 (0)