Skip to content

Commit 16d66fb

Browse files
[GR-71252] Crema: invokedynamic fixes.
PullRequest: graal/22575
2 parents f3b4c11 + d7eda89 commit 16d66fb

File tree

5 files changed

+43
-39
lines changed

5 files changed

+43
-39
lines changed

substratevm/src/com.oracle.svm.interpreter.metadata/src/com/oracle/svm/interpreter/metadata/BytecodeStream.java

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -260,16 +260,6 @@ public static char readCPI2(byte[] code, int curBCI) {
260260
return (char) ByteUtils.beU2(code, curBCI + 1);
261261
}
262262

263-
/**
264-
* Reads a 2-byte constant pool index for the current instruction, reading each byte with
265-
* volatile semantics. Note that this does not read the 2 bytes atomically.
266-
*
267-
* @return the constant pool index
268-
*/
269-
public static char readCPI2Volatile(byte[] code, int curBCI) {
270-
return (char) (((ByteUtils.volatileBeU1(code, curBCI + 1) & 0xff) << 8) | (ByteUtils.volatileBeU1(code, curBCI + 1 + 1) & 0xff));
271-
}
272-
273263
/**
274264
* Reads a constant pool index for the current instruction.
275265
*
@@ -371,25 +361,20 @@ private static String unknownVariableLengthBytecodeMessage(int opcode) {
371361
return "unknown variable-length bytecode: " + opcode;
372362
}
373363

374-
@Platforms(Platform.HOSTED_ONLY.class)
375-
public static void patchAppendixCPI(byte[] code, int curBCI, int appendixCPI) {
376-
int opcode = opcode(code, curBCI);
377-
switch (opcode) {
378-
case INVOKEDYNAMIC:
379-
code[curBCI + 3] = (byte) ((appendixCPI >> 8) & 0xFF);
380-
code[curBCI + 4] = (byte) (appendixCPI & 0xFF);
381-
break;
382-
default:
383-
throw VMError.shouldNotReachHereAtRuntime();
384-
}
364+
/**
365+
* Reads the 2-byte extra CPI for the current invokedynamic instruction, reading each byte with
366+
* volatile semantics. Note that this does not read the 2 bytes atomically.
367+
*/
368+
public static char readIndyExtraCPIVolatile(byte[] code, int curBCI) {
369+
return (char) ((ByteUtils.volatileBeU1(code, curBCI + 3) << 8) | ByteUtils.volatileBeU1(code, curBCI + 4));
385370
}
386371

387372
public static void patchIndyExtraCPI(byte[] code, int curBCI, int extraCPI) {
388373
int opcode = opcode(code, curBCI);
389374
switch (opcode) {
390375
case INVOKEDYNAMIC:
391-
code[curBCI + 1] = (byte) ((extraCPI >> 8) & 0xFF);
392-
code[curBCI + 2] = (byte) (extraCPI & 0xFF);
376+
code[curBCI + 3] = (byte) ((extraCPI >> 8) & 0xFF);
377+
code[curBCI + 4] = (byte) (extraCPI & 0xFF);
393378
break;
394379
default:
395380
throw VMError.shouldNotReachHereAtRuntime();

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/BuildTimeConstantPool.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,7 +448,7 @@ public void hydrate(InterpreterResolvedObjectType type) {
448448
// in the CP.
449449
newAppendixCPI = appendixConstant(JavaConstant.NULL_POINTER);
450450
}
451-
BytecodeStream.patchAppendixCPI(code, bci, newAppendixCPI);
451+
BytecodeStream.patchIndyExtraCPI(code, bci, newAppendixCPI);
452452
}
453453

454454
BytecodeStream.patchCPI(code, bci, newCPI);

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/CremaSupportImpl.java

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import static com.oracle.svm.espresso.classfile.Constants.ACC_SUPER;
4343
import static com.oracle.svm.espresso.classfile.Constants.JVM_ACC_WRITTEN_FLAGS;
4444
import static com.oracle.svm.espresso.shared.meta.SignaturePolymorphicIntrinsic.InvokeGeneric;
45+
import static com.oracle.svm.interpreter.Interpreter.unbasic;
4546
import static com.oracle.svm.interpreter.InterpreterStubSection.getCremaStubForVTableIndex;
4647

4748
import java.lang.invoke.MethodType;
@@ -122,6 +123,7 @@
122123
import com.oracle.svm.interpreter.metadata.InterpreterResolvedJavaMethod;
123124
import com.oracle.svm.interpreter.metadata.InterpreterResolvedJavaType;
124125
import com.oracle.svm.interpreter.metadata.InterpreterResolvedObjectType;
126+
import com.oracle.svm.interpreter.metadata.InterpreterUnresolvedSignature;
125127

126128
import jdk.graal.compiler.word.Word;
127129
import jdk.vm.ci.meta.ResolvedJavaField;
@@ -1312,12 +1314,15 @@ public Object invokeBasic(Target_java_lang_invoke_MemberName memberName, Object
13121314
@Override
13131315
public Object linkToVirtual(Object[] args) {
13141316
// This is AOT-compiled code calling MethodHandle.linkToVirtual
1317+
// See also PolymorphicSignatureWrapperMethod.buildGraph
13151318
Target_java_lang_invoke_MemberName mnTarget = (Target_java_lang_invoke_MemberName) args[args.length - 1];
13161319
InterpreterResolvedJavaMethod target = InterpreterResolvedJavaMethod.fromMemberName(mnTarget);
1317-
Object[] basicArgs = Arrays.copyOf(args, args.length - 1);
1320+
InterpreterUnresolvedSignature signature = target.getSignature();
1321+
Object[] basicArgs = unbasic(args, signature, true);
13181322
logIntrinsic("[from compiled] linkToVirtual ", target, basicArgs);
13191323
try {
1320-
return InterpreterToVM.dispatchInvocation(target, basicArgs, true, false, false, false, true);
1324+
Object result = InterpreterToVM.dispatchInvocation(target, basicArgs, true, false, false, false, true);
1325+
return Interpreter.rebasic(result, signature.getReturnKind());
13211326
} catch (SemanticJavaException e) {
13221327
throw uncheckedThrow(e.getCause());
13231328
}
@@ -1326,12 +1331,15 @@ public Object linkToVirtual(Object[] args) {
13261331
@Override
13271332
public Object linkToStatic(Object[] args) {
13281333
// This is AOT-compiled code calling MethodHandle.linkToStatic
1334+
// See also PolymorphicSignatureWrapperMethod.buildGraph
13291335
Target_java_lang_invoke_MemberName mnTarget = (Target_java_lang_invoke_MemberName) args[args.length - 1];
13301336
InterpreterResolvedJavaMethod target = InterpreterResolvedJavaMethod.fromMemberName(mnTarget);
1331-
Object[] basicArgs = Arrays.copyOf(args, args.length - 1);
1337+
InterpreterUnresolvedSignature signature = target.getSignature();
1338+
Object[] basicArgs = unbasic(args, signature, false);
13321339
logIntrinsic("[from compiled] linkToStatic ", target, basicArgs);
13331340
try {
1334-
return InterpreterToVM.dispatchInvocation(target, basicArgs, false, false, false, false, true);
1341+
Object result = InterpreterToVM.dispatchInvocation(target, basicArgs, false, false, false, false, true);
1342+
return Interpreter.rebasic(result, signature.getReturnKind());
13351343
} catch (SemanticJavaException e) {
13361344
throw uncheckedThrow(e.getCause());
13371345
}
@@ -1340,12 +1348,15 @@ public Object linkToStatic(Object[] args) {
13401348
@Override
13411349
public Object linkToSpecial(Object[] args) {
13421350
// This is AOT-compiled code calling MethodHandle.linkToSpecial
1351+
// See also PolymorphicSignatureWrapperMethod.buildGraph
13431352
Target_java_lang_invoke_MemberName mnTarget = (Target_java_lang_invoke_MemberName) args[args.length - 1];
13441353
InterpreterResolvedJavaMethod target = InterpreterResolvedJavaMethod.fromMemberName(mnTarget);
1345-
Object[] basicArgs = Arrays.copyOf(args, args.length - 1);
1354+
InterpreterUnresolvedSignature signature = target.getSignature();
1355+
Object[] basicArgs = unbasic(args, signature, true);
13461356
logIntrinsic("[from compiled] linkToSpecial ", target, basicArgs);
13471357
try {
1348-
return InterpreterToVM.dispatchInvocation(target, basicArgs, false, false, false, false, true);
1358+
Object result = InterpreterToVM.dispatchInvocation(target, basicArgs, false, false, false, false, true);
1359+
return Interpreter.rebasic(result, signature.getReturnKind());
13491360
} catch (SemanticJavaException e) {
13501361
throw uncheckedThrow(e.getCause());
13511362
}
@@ -1354,12 +1365,15 @@ public Object linkToSpecial(Object[] args) {
13541365
@Override
13551366
public Object linkToInterface(Object[] args) {
13561367
// This is AOT-compiled code calling MethodHandle.linkToInterface
1368+
// See also PolymorphicSignatureWrapperMethod.buildGraph
13571369
Target_java_lang_invoke_MemberName mnTarget = (Target_java_lang_invoke_MemberName) args[args.length - 1];
13581370
InterpreterResolvedJavaMethod target = InterpreterResolvedJavaMethod.fromMemberName(mnTarget);
1359-
Object[] basicArgs = Arrays.copyOf(args, args.length - 1);
1371+
InterpreterUnresolvedSignature signature = target.getSignature();
1372+
Object[] basicArgs = unbasic(args, signature, true);
13601373
logIntrinsic("[from compiled] linkToInterface ", target, basicArgs);
13611374
try {
1362-
return InterpreterToVM.dispatchInvocation(target, basicArgs, true, false, false, true, true);
1375+
Object result = InterpreterToVM.dispatchInvocation(target, basicArgs, true, false, false, true, true);
1376+
return Interpreter.rebasic(result, signature.getReturnKind());
13631377
} catch (SemanticJavaException e) {
13641378
throw uncheckedThrow(e.getCause());
13651379
}

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/Interpreter.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -548,7 +548,8 @@ public static Object execute(InterpreterFrame frame, InterpreterResolvedJavaMeth
548548
case LinkToStatic, LinkToSpecial, LinkToVirtual, LinkToInterface -> {
549549
InterpreterResolvedJavaMethod resolutionSeed = getLinkToTarget(frame);
550550
InterpreterUnresolvedSignature signature = resolutionSeed.getSignature();
551-
Object[] basicArgs = unbasic(frame, signature, false);
551+
boolean hasReceiver = intrinsic != SignaturePolymorphicIntrinsic.LinkToStatic;
552+
Object[] basicArgs = unbasic(frame, signature, hasReceiver);
552553
// This should integrate with the debugger GR-70801
553554
boolean preferStayInInterpreter = forceStayInInterpreter;
554555
traceLinkTo(resolutionSeed, intrinsic, indent);
@@ -573,7 +574,10 @@ private static InterpreterResolvedJavaMethod getLinkToTarget(InterpreterFrame fr
573574
}
574575

575576
private static Object[] unbasic(InterpreterFrame frame, InterpreterUnresolvedSignature targetSig, boolean inclReceiver) {
576-
Object[] arguments = frame.getArguments();
577+
return unbasic(frame.getArguments(), targetSig, inclReceiver);
578+
}
579+
580+
static Object[] unbasic(Object[] arguments, InterpreterUnresolvedSignature targetSig, boolean inclReceiver) {
577581
int parameterCount = targetSig.getParameterCount(inclReceiver);
578582
Object[] res = new Object[parameterCount];
579583
int start = 0;
@@ -588,7 +592,7 @@ private static Object[] unbasic(InterpreterFrame frame, InterpreterUnresolvedSig
588592
}
589593

590594
// Transforms ints to sub-words
591-
public static Object unbasic(Object arg, JavaKind kind) {
595+
private static Object unbasic(Object arg, JavaKind kind) {
592596
return switch (kind) {
593597
case Boolean -> (int) arg != 0;
594598
case Byte -> (byte) (int) arg;
@@ -598,7 +602,7 @@ public static Object unbasic(Object arg, JavaKind kind) {
598602
};
599603
}
600604

601-
private static Object rebasic(Object value, JavaKind returnType) {
605+
static Object rebasic(Object value, JavaKind returnType) {
602606
// @formatter:off
603607
return switch (returnType) {
604608
case Boolean -> stackIntToBoolean((int) value);
@@ -1401,7 +1405,8 @@ private static int invoke(InterpreterFrame callerFrame, InterpreterResolvedJavaM
14011405
throw SemanticJavaException.raise(e);
14021406
}
14031407
BytecodeStream.patchIndyExtraCPI(code, curBCI, extraCPI);
1404-
assert BytecodeStream.readCPI2Volatile(code, curBCI) == extraCPI;
1408+
assert BytecodeStream.readIndyExtraCPIVolatile(code, curBCI) == extraCPI;
1409+
assert BytecodeStream.readCPI2(code, curBCI) == indyCPI;
14051410
}
14061411
CallSiteLink link = invokeDynamicConstant.getCallSiteLink(extraCPI);
14071412
while (!link.matchesCallSite(method, curBCI)) {
@@ -1411,7 +1416,7 @@ private static int invoke(InterpreterFrame callerFrame, InterpreterResolvedJavaM
14111416
* still safe to use in `getCallSiteLink`. `matchesCallSite` ensures we have the
14121417
* full extraCPI.
14131418
*/
1414-
extraCPI = BytecodeStream.readCPI2Volatile(code, curBCI);
1419+
extraCPI = BytecodeStream.readIndyExtraCPIVolatile(code, curBCI);
14151420
link = invokeDynamicConstant.getCallSiteLink(extraCPI);
14161421
}
14171422
if (link instanceof SuccessfulCallSiteLink successfulCallSiteLink) {

substratevm/src/com.oracle.svm.interpreter/src/com/oracle/svm/interpreter/classfile/ClassFile.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1000,7 +1000,7 @@ private byte[] recomputeConstantPoolIndices(ResolvedJavaMethod method) {
10001000
// The VM already provides the resolved bootstrap method and appendix.
10011001
// Investigate how to persist the appendix (arbitrary object) on the constant pool.
10021002
BytecodeStream.patchCPI(code, bci, 0);
1003-
BytecodeStream.patchAppendixCPI(code, bci, 0);
1003+
BytecodeStream.patchIndyExtraCPI(code, bci, 0);
10041004
break;
10051005
}
10061006
// @formatter:on

0 commit comments

Comments
 (0)