Skip to content

Commit 0cffe28

Browse files
Improve double-checked locking for call targets
1 parent 10c99ba commit 0cffe28

File tree

1 file changed

+22
-18
lines changed
  • espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl

1 file changed

+22
-18
lines changed

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import static com.oracle.truffle.espresso.classfile.Constants.REF_invokeVirtual;
4343

4444
import java.io.PrintStream;
45+
import java.lang.invoke.VarHandle;
4546
import java.lang.reflect.Modifier;
4647
import java.util.ArrayList;
4748
import java.util.Arrays;
@@ -1229,14 +1230,18 @@ public RuntimeConstantPool getPool() {
12291230
return pool;
12301231
}
12311232

1233+
@SuppressFBWarnings(value = "DC_DOUBLECHECK", //
1234+
justification = "Publication uses a release fence, assuming data dependency ordering on the reader side.")
12321235
private CallTarget getCallTargetNoSubstitution() {
12331236
CompilerAsserts.neverPartOfCompilation();
12341237
EspressoError.guarantee(getSubstitutions().hasSubstitutionFor(getMethod()),
12351238
"Using 'getCallTargetNoSubstitution' should be done only to bypass the substitution mechanism.");
12361239
if (callTargetNoSubstitutions == null) {
12371240
synchronized (this) {
12381241
if (callTargetNoSubstitutions == null) {
1239-
callTargetNoSubstitutions = findCallTarget();
1242+
CallTarget target = findCallTarget();
1243+
VarHandle.releaseFence();
1244+
callTargetNoSubstitutions = target;
12401245
}
12411246
}
12421247
}
@@ -1261,27 +1266,26 @@ private void resolveCallTarget() {
12611266
if (callTarget != null) {
12621267
return;
12631268
}
1269+
CallTarget target;
12641270
if (proxy != Method.this) {
1265-
this.callTarget = proxy.getCallTarget();
1266-
return;
1267-
}
1268-
1269-
/*
1270-
* The substitution factory does the validation e.g. some substitutions only apply
1271-
* for classes/methods in the boot or platform class loaders. A warning is logged if
1272-
* the validation fails.
1273-
*/
1274-
EspressoRootNode redirectedMethod = getSubstitutions().get(getMethod());
1275-
if (redirectedMethod != null) {
1276-
callTarget = redirectedMethod.getCallTarget();
1277-
return;
1271+
target = proxy.getCallTarget();
1272+
} else {
1273+
/*
1274+
* The substitution factory does the validation e.g. some substitutions only
1275+
* apply for classes/methods in the boot or platform class loaders. A warning is
1276+
* logged if the validation fails.
1277+
*/
1278+
EspressoRootNode redirectedMethod = getSubstitutions().get(getMethod());
1279+
if (redirectedMethod != null) {
1280+
target = redirectedMethod.getCallTarget();
1281+
} else {
1282+
assert callTargetNoSubstitutions == null;
1283+
target = findCallTarget();
1284+
}
12781285
}
1279-
assert callTargetNoSubstitutions == null;
1280-
1281-
CallTarget target = findCallTarget();
12821286
if (target != null) {
1287+
VarHandle.releaseFence();
12831288
callTarget = target;
1284-
return;
12851289
}
12861290
}
12871291
}

0 commit comments

Comments
 (0)