Skip to content

Commit 0c865a7

Browse files
committed
8315637: JDK-8314249 broke libgraal
Reviewed-by: dnsimon, matsaave
1 parent 683672c commit 0c865a7

File tree

3 files changed

+135
-50
lines changed

3 files changed

+135
-50
lines changed

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/CompilerToVM.java

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -336,48 +336,55 @@ int lookupNameAndTypeRefIndexInPool(HotSpotConstantPool constantPool, int rawInd
336336

337337
/**
338338
* Gets the name of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
339-
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
340-
* on the given {@opcode}.
339+
* referenced by the {@code which}.
341340
*
342341
* The behavior of this method is undefined if the class holding the {@code constantPool}
343-
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
342+
* has not yet been rewritten, or {@code which} is not a valid index for
344343
* this class for the given {@code opcode}
344+
*
345+
* @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
346+
* must be {@code rawIndex}
345347
*/
346-
String lookupNameInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
347-
return lookupNameInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
348+
String lookupNameInPool(HotSpotConstantPool constantPool, int which, int opcode) {
349+
return lookupNameInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
348350
}
349351

350-
private native String lookupNameInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
352+
private native String lookupNameInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
351353

352354
/**
353355
* Gets the signature of the {@code JVM_CONSTANT_NameAndType} entry in {@code constantPool}
354-
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
355-
* on the given {@opcode}.
356+
* referenced by the {@code which}.
356357
*
357358
* The behavior of this method is undefined if the class holding the {@code constantPool}
358-
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
359+
* has not yet been rewritten, or {@code which} is not a valid index for
359360
* this class for the given {@code opcode}
361+
*
362+
* @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
363+
* must be {@code rawIndex}
360364
*/
361-
String lookupSignatureInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
362-
return lookupSignatureInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
365+
String lookupSignatureInPool(HotSpotConstantPool constantPool, int which, int opcode) {
366+
return lookupSignatureInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
363367
}
364368

365-
private native String lookupSignatureInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
369+
private native String lookupSignatureInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
366370

367371
/**
368372
* Gets the {@code JVM_CONSTANT_Class} index from the entry in {@code constantPool}
369-
* referenced by the {@code rawIndex}. The meaning of {@code rawIndex} is dependent
373+
* referenced by the {@code which}. The meaning of {@code which} is dependent
370374
* on the given {@opcode}.
371375
*
372376
* The behavior of this method is undefined if the class holding the {@code constantPool}
373-
* has not yet been rewritten, or {@code rawIndex} is not a valid index for
377+
* has not yet been rewritten, or {@code which} is not a valid index for
374378
* this class for the given {@code opcode}
379+
*
380+
* @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
381+
* must be {@code rawIndex}
375382
*/
376-
int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int rawIndex, int opcode) {
377-
return lookupKlassRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), rawIndex, opcode);
383+
int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, int which, int opcode) {
384+
return lookupKlassRefIndexInPool(constantPool, constantPool.getConstantPoolPointer(), which, opcode);
378385
}
379386

380-
private native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int rawIndex, int opcode);
387+
private native int lookupKlassRefIndexInPool(HotSpotConstantPool constantPool, long constantPoolPointer, int which, int opcode);
381388

382389
/**
383390
* Looks up a class denoted by the {@code JVM_CONSTANT_Class} entry at index {@code cpi} in

src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotConstantPool.java

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -396,18 +396,6 @@ private int getNameAndTypeRefIndexAt(int rawIndex, int opcode) {
396396
return compilerToVM().lookupNameAndTypeRefIndexInPool(this, rawIndex, opcode);
397397
}
398398

399-
/**
400-
* Gets the name of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by another
401-
* entry denoted by {@code which}.
402-
*
403-
* @param rawIndex rewritten index in the bytecode stream
404-
* @param opcode the opcode of the instruction for which the lookup is being performed
405-
* @return name as {@link String}
406-
*/
407-
private String getNameOf(int rawIndex, int opcode) {
408-
return compilerToVM().lookupNameInPool(this, rawIndex, opcode);
409-
}
410-
411399
/**
412400
* Gets the name reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry at
413401
* index {@code index}.
@@ -421,17 +409,6 @@ private int getNameRefIndexAt(int index) {
421409
return refIndex & 0xFFFF;
422410
}
423411

424-
/**
425-
* Gets the signature of a {@code JVM_CONSTANT_NameAndType} constant pool entry referenced by
426-
* another entry denoted by {@code which}.
427-
*
428-
* @param rawIndex rewritten index in the bytecode stream
429-
* @param opcode the opcode of the instruction for which the lookup is being performed
430-
* @return signature as {@link String}
431-
*/
432-
private String getSignatureOf(int rawIndex, int opcode) {
433-
return compilerToVM().lookupSignatureInPool(this, rawIndex, opcode);
434-
}
435412

436413
/**
437414
* Gets the signature reference index of a {@code JVM_CONSTANT_NameAndType} constant pool entry
@@ -449,12 +426,13 @@ private int getSignatureRefIndexAt(int index) {
449426
/**
450427
* Gets the klass reference index constant pool entry at index {@code index}.
451428
*
452-
* @param rawIndex rewritten index in the bytecode stream
429+
* @param which for INVOKE{VIRTUAL,SPECIAL,STATIC,INTERFACE}, must be {@code cpci}. For all other bytecodes,
430+
* must be {@code rawIndex}
453431
* @param opcode the opcode of the instruction for which the lookup is being performed
454432
* @return klass reference index
455433
*/
456-
private int getKlassRefIndexAt(int rawIndex, int opcode) {
457-
return compilerToVM().lookupKlassRefIndexInPool(this, rawIndex, opcode);
434+
private int getKlassRefIndexAt(int which, int opcode) {
435+
return compilerToVM().lookupKlassRefIndexInPool(this, which, opcode);
458436
}
459437

460438
/**
@@ -719,18 +697,26 @@ private static JavaType getJavaType(final Object type) {
719697

720698
@Override
721699
public JavaMethod lookupMethod(int rawIndex, int opcode, ResolvedJavaMethod caller) {
722-
final int cpci = rawIndexToConstantPoolCacheIndex(rawIndex, opcode);
723-
final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, cpci, (byte) opcode, (HotSpotResolvedJavaMethodImpl) caller);
700+
int which; // interpretation depends on opcode
701+
if (opcode == Bytecodes.INVOKEDYNAMIC) {
702+
if (!isInvokedynamicIndex(rawIndex)) {
703+
throw new IllegalArgumentException("expected a raw index for INVOKEDYNAMIC but got " + rawIndex);
704+
}
705+
which = rawIndex;
706+
} else {
707+
which = rawIndexToConstantPoolCacheIndex(rawIndex, opcode);
708+
}
709+
final HotSpotResolvedJavaMethod method = compilerToVM().lookupMethodInPool(this, which, (byte) opcode, (HotSpotResolvedJavaMethodImpl) caller);
724710
if (method != null) {
725711
return method;
726712
} else {
727713
// Get the method's name and signature.
728-
String name = getNameOf(cpci, opcode);
729-
HotSpotSignature signature = new HotSpotSignature(runtime(), getSignatureOf(cpci, opcode));
714+
String name = compilerToVM().lookupNameInPool(this, which, opcode);
715+
HotSpotSignature signature = new HotSpotSignature(runtime(), compilerToVM().lookupSignatureInPool(this, which, opcode));
730716
if (opcode == Bytecodes.INVOKEDYNAMIC) {
731717
return new UnresolvedJavaMethod(name, signature, runtime().getMethodHandleClass());
732718
} else {
733-
final int klassIndex = getKlassRefIndexAt(cpci, opcode);
719+
final int klassIndex = getKlassRefIndexAt(which, opcode);
734720
final Object type = compilerToVM().lookupKlassInPool(this, klassIndex);
735721
return new UnresolvedJavaMethod(name, signature, getJavaType(type));
736722
}

test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/ConstantPoolTest.java

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ static String concatString2(String a, String b) {
160160
return a + b;
161161
}
162162

163+
// We never call this method, so its indy is never resolved.
164+
static String concatString3_never_call(String a, String b) {
165+
return a + b;
166+
}
167+
163168
static void invokeHandle(MethodHandle mh) throws Throwable {
164169
mh.invokeExact(0);
165170
}
@@ -184,7 +189,7 @@ public void lookupAppendixTest() throws Throwable {
184189
lookupAppendixTest_virtual();
185190
}
186191

187-
public void lookupAppendixTest_dynamic(String methodName) throws Exception {
192+
private void lookupAppendixTest_dynamic(String methodName) throws Exception {
188193
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
189194
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
190195
Signature methodSig = metaAccess.parseMethodDescriptor("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
@@ -209,7 +214,7 @@ public void lookupAppendixTest_dynamic(String methodName) throws Exception {
209214
Assert.assertTrue(constant.toString().startsWith("Object["), "wrong appendix: " + constant);
210215
}
211216

212-
public void lookupAppendixTest_virtual() throws Exception {
217+
private void lookupAppendixTest_virtual() throws Exception {
213218
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
214219
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
215220
Signature methodSig = metaAccess.parseMethodDescriptor("(Ljava/lang/invoke/MethodHandle;)V");
@@ -233,4 +238,91 @@ public void lookupAppendixTest_virtual() throws Exception {
233238
//System.out.println("constant = " + constant);
234239
Assert.assertTrue(constant.toString().startsWith("Object["), "wrong appendix: " + constant);
235240
}
241+
242+
static void invokeVirtual(Object o) {
243+
o.hashCode();
244+
}
245+
246+
@Test
247+
public void lookupMethodTest_dynamic() throws Exception {
248+
concatString1("aaa", "bbb"); // force the indy to be resolved
249+
250+
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
251+
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
252+
Signature methodSig = metaAccess.parseMethodDescriptor("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
253+
ResolvedJavaMethod m = type.findMethod("concatString1", methodSig);
254+
Assert.assertNotNull(m);
255+
256+
// Expected:
257+
// aload_0;
258+
// aload_1;
259+
// invokedynamic ...StringConcatFactory.makeConcatWithConstants...
260+
byte[] bytecode = m.getCode();
261+
Assert.assertNotNull(bytecode);
262+
Assert.assertEquals(8, bytecode.length);
263+
Assert.assertEquals(ALOAD_0, beU1(bytecode, 0));
264+
Assert.assertEquals(ALOAD_1, beU1(bytecode, 1));
265+
Assert.assertEquals(INVOKEDYNAMIC, beU1(bytecode, 2));
266+
267+
// Note: internally HotSpot stores the indy index as a native int32, but m.getCode() byte-swaps all such
268+
// indices so they appear to be big-endian.
269+
int rawIndex = beS4(bytecode, 3);
270+
System.out.println("rawIndex = " + rawIndex);
271+
JavaMethod callee = m.getConstantPool().lookupMethod(rawIndex, INVOKEDYNAMIC, /*caller=*/m);
272+
System.out.println("callee = " + callee);
273+
Assert.assertTrue(callee.toString().equals("HotSpotMethod<Invokers$Holder.linkToTargetMethod(Object, Object, Object)>"),
274+
"wrong method: " + callee);
275+
}
276+
277+
@Test
278+
public void lookupMethodTest_dynamic_unresolved() throws Exception {
279+
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
280+
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
281+
Signature methodSig = metaAccess.parseMethodDescriptor("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
282+
ResolvedJavaMethod m = type.findMethod("concatString3_never_call", methodSig);
283+
Assert.assertNotNull(m);
284+
285+
// Expected:
286+
// aload_0;
287+
// aload_1;
288+
// invokedynamic ...StringConcatFactory.makeConcatWithConstants...
289+
byte[] bytecode = m.getCode();
290+
Assert.assertNotNull(bytecode);
291+
Assert.assertEquals(8, bytecode.length);
292+
Assert.assertEquals(ALOAD_0, beU1(bytecode, 0));
293+
Assert.assertEquals(ALOAD_1, beU1(bytecode, 1));
294+
Assert.assertEquals(INVOKEDYNAMIC, beU1(bytecode, 2));
295+
296+
// Note: internally HotSpot stores the indy index as a native int32, but m.getCode() byte-swaps all such
297+
// indices so they appear to be big-endian.
298+
int rawIndex = beS4(bytecode, 3);
299+
System.out.println("rawIndex = " + rawIndex);
300+
JavaMethod callee = m.getConstantPool().lookupMethod(rawIndex, INVOKEDYNAMIC, /*caller=*/m);
301+
System.out.println("callee = " + callee);
302+
Assert.assertTrue(callee.toString().startsWith("jdk.vm.ci.meta.UnresolvedJavaMethod"),
303+
"wrong method: " + callee);
304+
}
305+
306+
@Test
307+
public void lookupMethodTest_virtual() throws Exception {
308+
MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();
309+
ResolvedJavaType type = metaAccess.lookupJavaType(ConstantPoolTest.class);
310+
Signature methodSig = metaAccess.parseMethodDescriptor("(Ljava/lang/Object;)V");
311+
ResolvedJavaMethod m = type.findMethod("invokeVirtual", methodSig);
312+
Assert.assertNotNull(m);
313+
314+
// Expected
315+
// 0: aload_0
316+
// 1: invokevirtual #rawIndex // Method Method java/lang/Object.hashCode:()I
317+
byte[] bytecode = m.getCode();
318+
Assert.assertNotNull(bytecode);
319+
Assert.assertEquals(ALOAD_0, beU1(bytecode, 0));
320+
Assert.assertEquals(INVOKEVIRTUAL, beU1(bytecode, 1));
321+
int rawIndex = beU2(bytecode, 2);
322+
System.out.println("rawIndex = " + rawIndex);
323+
JavaMethod callee = m.getConstantPool().lookupMethod(rawIndex, INVOKEVIRTUAL, /*caller=*/m);
324+
System.out.println("callee = " + callee);
325+
Assert.assertTrue(callee.toString().equals("HotSpotMethod<Object.hashCode()>"),
326+
"wrong method: " + callee);
327+
}
236328
}

0 commit comments

Comments
 (0)