@@ -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