@@ -116,6 +116,11 @@ public enum LinkState {
116
116
117
117
private ResolutionDag resolutionDag ;
118
118
119
+ /**
120
+ * Tries to link a module instance and other module instances in the store.
121
+ *
122
+ * @param instance the module instance that triggered the linking
123
+ */
119
124
public void tryLink (WasmInstance instance ) {
120
125
// The first execution of a WebAssembly call target will trigger the linking of the modules
121
126
// that are inside the current context (which will happen behind the call boundary).
@@ -125,22 +130,20 @@ public void tryLink(WasmInstance instance) {
125
130
// compilation, and this check will fold away.
126
131
// If the code is compiled synchronously, then this check will persist in the compiled code.
127
132
// We nevertheless invalidate the compiled code that reaches this point.
128
- if (CompilerDirectives .injectBranchProbability (CompilerDirectives .SLOWPATH_PROBABILITY , instance .isNonLinked () || instance .isLinkFailed ())) {
129
- // TODO: Once we support multi-threading, add adequate synchronization here.
133
+ if (CompilerDirectives .injectBranchProbability (CompilerDirectives .SLOWPATH_PROBABILITY , !instance .isLinkCompleted ())) {
130
134
tryLinkOutsidePartialEvaluation (instance );
131
- } else {
132
- assert instance .isLinkCompleted () || instance .isLinkInProgress ();
133
135
}
134
136
}
135
137
136
138
/**
139
+ * Tries to link a module instantiated via the JS API, with imports supplied by an importObject.
140
+ *
141
+ * @see org.graalvm.wasm.api.WebAssembly#moduleInstantiate(WasmModule, Object)
137
142
* @see #tryLinkOutsidePartialEvaluation(WasmInstance, ImportValueSupplier)
138
143
*/
139
144
public void tryLink (WasmInstance instance , ImportValueSupplier imports ) {
140
- if (instance .isNonLinked () || instance . isLinkFailed ()) {
145
+ if (! instance .isLinkCompleted ()) {
141
146
tryLinkOutsidePartialEvaluation (instance , imports );
142
- } else {
143
- assert instance .isLinkCompleted () || instance .isLinkInProgress ();
144
147
}
145
148
}
146
149
@@ -151,7 +154,7 @@ private static WasmException linkFailedError(WasmInstance instance) {
151
154
152
155
@ CompilerDirectives .TruffleBoundary
153
156
private void tryLinkOutsidePartialEvaluation (WasmInstance entryPointInstance ) {
154
- tryLink (entryPointInstance , null );
157
+ tryLinkOutsidePartialEvaluation (entryPointInstance , null );
155
158
}
156
159
157
160
/**
@@ -166,25 +169,28 @@ private void tryLinkOutsidePartialEvaluation(WasmInstance entryPointInstance) {
166
169
*/
167
170
@ CompilerDirectives .TruffleBoundary
168
171
private void tryLinkOutsidePartialEvaluation (WasmInstance entryPointInstance , ImportValueSupplier imports ) {
169
- if (entryPointInstance .isLinkFailed ()) {
170
- // If the linking of this module failed already, then throw.
171
- throw linkFailedError (entryPointInstance );
172
- }
173
- // Some Truffle configurations allow that the code gets compiled before executing the code.
174
- // We therefore check the link state again.
175
- if (entryPointInstance .isNonLinked ()) {
176
- if (resolutionDag == null ) {
177
- resolutionDag = new ResolutionDag ();
178
- }
179
- final WasmStore store = entryPointInstance .store ();
180
- Map <String , WasmInstance > instances = store .moduleInstances ();
181
- ArrayList <Throwable > failures = new ArrayList <>();
182
- final int maxStartFunctionIndex = runLinkActions (store , instances , imports , failures );
183
- linkTopologically (store , failures , maxStartFunctionIndex );
184
- assignTypeEquivalenceClasses (store );
185
- resolutionDag = null ;
186
- runStartFunctions (instances , failures );
187
- checkFailures (failures );
172
+ final WasmStore store = entryPointInstance .store ();
173
+ synchronized (store ) {
174
+ var linkState = entryPointInstance .linkState ();
175
+ if (linkState == LinkState .failed ) {
176
+ // If the linking of this module failed already, then throw.
177
+ throw linkFailedError (entryPointInstance );
178
+ }
179
+ // Some Truffle configurations allow the code to be compiled before executing the code.
180
+ // We therefore check the link state again.
181
+ if (linkState == LinkState .nonLinked ) {
182
+ if (resolutionDag == null ) {
183
+ resolutionDag = new ResolutionDag ();
184
+ }
185
+ Map <String , WasmInstance > instances = store .moduleInstances ();
186
+ ArrayList <Throwable > failures = new ArrayList <>();
187
+ final int maxStartFunctionIndex = runLinkActions (store , instances , imports , failures );
188
+ linkTopologically (store , failures , maxStartFunctionIndex );
189
+ assignTypeEquivalenceClasses (store );
190
+ resolutionDag = null ;
191
+ runStartFunctions (instances , failures );
192
+ checkFailures (failures );
193
+ }
188
194
}
189
195
}
190
196
0 commit comments