Skip to content

Commit f62e631

Browse files
[GR-50446] Avoid sharing bytecode between "no substitutions" call targets.
PullRequest: graal/16277
2 parents cafd84e + 0cffe28 commit f62e631

File tree

1 file changed

+30
-17
lines changed
  • espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl

1 file changed

+30
-17
lines changed

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

Lines changed: 30 additions & 17 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;
@@ -1076,6 +1077,7 @@ public final class MethodVersion implements MethodRef, ModifiersProvider {
10761077
private final ExceptionsAttribute exceptionsAttribute;
10771078

10781079
@CompilationFinal private CallTarget callTarget;
1080+
@CompilationFinal private CallTarget callTargetNoSubstitutions;
10791081

10801082
@CompilationFinal private int vtableIndex = -1;
10811083
@CompilationFinal private int itableIndex = -1;
@@ -1228,11 +1230,22 @@ public RuntimeConstantPool getPool() {
12281230
return pool;
12291231
}
12301232

1233+
@SuppressFBWarnings(value = "DC_DOUBLECHECK", //
1234+
justification = "Publication uses a release fence, assuming data dependency ordering on the reader side.")
12311235
private CallTarget getCallTargetNoSubstitution() {
12321236
CompilerAsserts.neverPartOfCompilation();
12331237
EspressoError.guarantee(getSubstitutions().hasSubstitutionFor(getMethod()),
12341238
"Using 'getCallTargetNoSubstitution' should be done only to bypass the substitution mechanism.");
1235-
return findCallTarget();
1239+
if (callTargetNoSubstitutions == null) {
1240+
synchronized (this) {
1241+
if (callTargetNoSubstitutions == null) {
1242+
CallTarget target = findCallTarget();
1243+
VarHandle.releaseFence();
1244+
callTargetNoSubstitutions = target;
1245+
}
1246+
}
1247+
}
1248+
return callTargetNoSubstitutions;
12361249
}
12371250

12381251
public CallTarget getCallTarget() {
@@ -1253,26 +1266,26 @@ private void resolveCallTarget() {
12531266
if (callTarget != null) {
12541267
return;
12551268
}
1269+
CallTarget target;
12561270
if (proxy != Method.this) {
1257-
this.callTarget = proxy.getCallTarget();
1258-
return;
1259-
}
1260-
1261-
/*
1262-
* The substitution factory does the validation e.g. some substitutions only apply
1263-
* for classes/methods in the boot or platform class loaders. A warning is logged if
1264-
* the validation fails.
1265-
*/
1266-
EspressoRootNode redirectedMethod = getSubstitutions().get(getMethod());
1267-
if (redirectedMethod != null) {
1268-
callTarget = redirectedMethod.getCallTarget();
1269-
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+
}
12701285
}
1271-
1272-
CallTarget target = findCallTarget();
12731286
if (target != null) {
1287+
VarHandle.releaseFence();
12741288
callTarget = target;
1275-
return;
12761289
}
12771290
}
12781291
}

0 commit comments

Comments
 (0)