@@ -116,6 +116,11 @@ public enum LinkState {
116116
117117 private ResolutionDag resolutionDag ;
118118
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+ */
119124 public void tryLink (WasmInstance instance ) {
120125 // The first execution of a WebAssembly call target will trigger the linking of the modules
121126 // that are inside the current context (which will happen behind the call boundary).
@@ -125,22 +130,20 @@ public void tryLink(WasmInstance instance) {
125130 // compilation, and this check will fold away.
126131 // If the code is compiled synchronously, then this check will persist in the compiled code.
127132 // 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 ())) {
130134 tryLinkOutsidePartialEvaluation (instance );
131- } else {
132- assert instance .isLinkCompleted () || instance .isLinkInProgress ();
133135 }
134136 }
135137
136138 /**
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)
137142 * @see #tryLinkOutsidePartialEvaluation(WasmInstance, ImportValueSupplier)
138143 */
139144 public void tryLink (WasmInstance instance , ImportValueSupplier imports ) {
140- if (instance .isNonLinked () || instance . isLinkFailed ()) {
145+ if (! instance .isLinkCompleted ()) {
141146 tryLinkOutsidePartialEvaluation (instance , imports );
142- } else {
143- assert instance .isLinkCompleted () || instance .isLinkInProgress ();
144147 }
145148 }
146149
@@ -151,7 +154,7 @@ private static WasmException linkFailedError(WasmInstance instance) {
151154
152155 @ CompilerDirectives .TruffleBoundary
153156 private void tryLinkOutsidePartialEvaluation (WasmInstance entryPointInstance ) {
154- tryLink (entryPointInstance , null );
157+ tryLinkOutsidePartialEvaluation (entryPointInstance , null );
155158 }
156159
157160 /**
@@ -166,25 +169,28 @@ private void tryLinkOutsidePartialEvaluation(WasmInstance entryPointInstance) {
166169 */
167170 @ CompilerDirectives .TruffleBoundary
168171 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+ }
188194 }
189195 }
190196
0 commit comments