Skip to content

Commit a257aeb

Browse files
committed
Move interop call adapter dispatch into execute message.
1 parent 4ca3d9c commit a257aeb

File tree

2 files changed

+56
-30
lines changed

2 files changed

+56
-30
lines changed

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmFunction.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,14 @@ public CallTarget getInteropCallAdapter() {
173173
return interopCallAdapter;
174174
}
175175

176-
public void setInteropCallAdapter(CallTarget interopCallAdapter) {
177-
this.interopCallAdapter = interopCallAdapter;
176+
@TruffleBoundary
177+
public CallTarget getOrCreateInteropCallAdapter(WasmLanguage language) {
178+
CallTarget callAdapter = this.interopCallAdapter;
179+
if (callAdapter == null) {
180+
// Benign initialization race: The call target will be the same each time.
181+
callAdapter = language.interopCallAdapterFor(type());
182+
this.interopCallAdapter = callAdapter;
183+
}
184+
return callAdapter;
178185
}
179186
}

wasm/src/org.graalvm.wasm/src/org/graalvm/wasm/WasmFunctionInstance.java

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,23 +42,21 @@
4242

4343
import java.util.Objects;
4444

45-
import org.graalvm.wasm.nodes.WasmCallNode;
46-
import org.graalvm.wasm.nodes.WasmIndirectCallNode;
47-
4845
import com.oracle.truffle.api.CallTarget;
4946
import com.oracle.truffle.api.CompilerDirectives;
5047
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
5148
import com.oracle.truffle.api.RootCallTarget;
5249
import com.oracle.truffle.api.TruffleContext;
50+
import com.oracle.truffle.api.dsl.Bind;
5351
import com.oracle.truffle.api.dsl.Cached;
54-
import com.oracle.truffle.api.dsl.ImportStatic;
52+
import com.oracle.truffle.api.dsl.Specialization;
5553
import com.oracle.truffle.api.interop.InteropLibrary;
5654
import com.oracle.truffle.api.interop.TruffleObject;
57-
import com.oracle.truffle.api.library.CachedLibrary;
5855
import com.oracle.truffle.api.library.ExportLibrary;
5956
import com.oracle.truffle.api.library.ExportMessage;
57+
import com.oracle.truffle.api.nodes.EncapsulatingNodeReference;
58+
import com.oracle.truffle.api.nodes.Node;
6059

61-
@ImportStatic(WasmCallNode.class)
6260
@ExportLibrary(InteropLibrary.class)
6361
public final class WasmFunctionInstance extends EmbedderDataHolder implements TruffleObject {
6462

@@ -137,31 +135,52 @@ boolean isExecutable() {
137135
}
138136

139137
@ExportMessage
140-
Object execute(Object[] arguments,
141-
@CachedLibrary("this") InteropLibrary self,
142-
@Cached WasmIndirectCallNode callNode) {
143-
TruffleContext c = getTruffleContext();
144-
Object prev = c.enter(self);
145-
try {
146-
CallTarget callAdapter = this.function.getInteropCallAdapter();
147-
if (callAdapter == null) {
148-
CompilerDirectives.transferToInterpreterAndInvalidate();
149-
callAdapter = createInteropCallAdapter();
138+
static class Execute {
139+
private static Object execute(WasmFunctionInstance functionInstance, Object[] arguments, CallTarget callAdapter, Node node, Node callNode) {
140+
TruffleContext c = functionInstance.getTruffleContext();
141+
Object prev = c.enter(node);
142+
try {
143+
return callAdapter.call(callNode, WasmArguments.create(functionInstance, arguments));
144+
// throws ArityException, UnsupportedTypeException
145+
} finally {
146+
c.leave(node, prev);
150147
}
151-
return callNode.execute(callAdapter, WasmArguments.create(this, arguments));
152-
// throws ArityException, UnsupportedTypeException
153-
} finally {
154-
c.leave(self, prev);
155148
}
156-
}
157149

158-
@TruffleBoundary
159-
private CallTarget createInteropCallAdapter() {
160-
CallTarget callAdapter = this.function.getInteropCallAdapter();
161-
if (callAdapter == null) {
162-
callAdapter = context.language().interopCallAdapterFor(function.type());
163-
this.function.setInteropCallAdapter(callAdapter);
150+
@SuppressWarnings("unused")
151+
@Specialization(guards = {"actualFunction == cachedFunction"}, limit = "2")
152+
static Object direct(WasmFunctionInstance functionInstance, Object[] arguments,
153+
@Bind("functionInstance.function()") WasmFunction actualFunction,
154+
@Cached("actualFunction") WasmFunction cachedFunction,
155+
@Cached("getOrCreateInteropCallAdapter(functionInstance)") CallTarget cachedCallAdapter,
156+
@Bind Node node) {
157+
return execute(functionInstance, arguments, cachedCallAdapter, node, node);
158+
}
159+
160+
@SuppressWarnings("unused")
161+
@Specialization(guards = {"actualCallAdapter == cachedCallAdapter"}, limit = "3", replaces = "direct")
162+
static Object directAdapter(WasmFunctionInstance functionInstance, Object[] arguments,
163+
@Bind("getOrCreateInteropCallAdapter(functionInstance)") CallTarget actualCallAdapter,
164+
@Cached("actualCallAdapter") CallTarget cachedCallAdapter,
165+
@Bind Node node) {
166+
return execute(functionInstance, arguments, cachedCallAdapter, node, node);
167+
}
168+
169+
@Specialization(replaces = "directAdapter")
170+
static Object indirect(WasmFunctionInstance functionInstance, Object[] arguments,
171+
@Bind Node node) {
172+
CallTarget callAdapter = getOrCreateInteropCallAdapter(functionInstance);
173+
Node callNode = node.isAdoptable() ? node : EncapsulatingNodeReference.getCurrent().get();
174+
return execute(functionInstance, arguments, callAdapter, node, callNode);
175+
}
176+
177+
static CallTarget getOrCreateInteropCallAdapter(WasmFunctionInstance functionInstance) {
178+
WasmFunction function = functionInstance.function();
179+
CallTarget callAdapter = function.getInteropCallAdapter();
180+
if (CompilerDirectives.injectBranchProbability(CompilerDirectives.SLOWPATH_PROBABILITY, callAdapter == null)) {
181+
return function.getOrCreateInteropCallAdapter(functionInstance.context().language());
182+
}
183+
return callAdapter;
164184
}
165-
return callAdapter;
166185
}
167186
}

0 commit comments

Comments
 (0)