C1 GraphBuilder::profile_call assert failing when inlining static interface method through MethodHandle

Jorn Vernee jorn.vernee at oracle.com
Thu Feb 13 11:46:51 UTC 2020


Looks like the reproducer code got crumpled up for some reason. Let me 
try again:

public class Test {

     static final MethodHandle MH_m;

     static {
         try {
             MH_m = lookup().findStatic(MyInterface.class, "m", 
MethodType.methodType(void.class));
         } catch (ReflectiveOperationException e) {
             throw new BootstrapMethodError(e);
         }
     }

     public static void main(String[] args) throws Throwable {
         for (int i = 0; i < 20_000; i++) {
             payload();
         }
     }

     static void payload() throws Throwable {
         MH_m.invokeExact();
     }

}

interface MyInterface {
     static void m() {}
}

Jorn

On 13/02/2020 12:39, Jorn Vernee wrote:
> Hi,
>
> We were seeing an assert being hit in C1 when running the project 
> Panama test suite. After some debugging I have narrowed the failure 
> down to the following reproducer:
>
> public class Test { static final MethodHandle MH_m; static { try { 
> MH_m = lookup().findStatic(MyInterface.class, "m", 
> MethodType.methodType(void.class)); } catch 
> (ReflectiveOperationException e) { throw new BootstrapMethodError(e); 
> } } public static void main(String[] args) throws Throwable { for (int 
> i = 0; i < 20_000; i++) { payload(); } } static void payload() throws 
> Throwable { MH_m.invokeExact(); } } interface MyInterface { static 
> void m() {} }
>
> Run with `-Xbatch -XX:TieredStopAtLevel=3`.
>
> The problem is the following assert in GraphBuild::profile_call:
>
>   assert(known_holder == NULL || (known_holder->is_instance_klass() &&
> (!known_holder->is_interface() ||
> ((ciInstanceKlass*)known_holder)->has_nonstatic_concrete_methods())), 
> "should be non-static concrete method");
>
> In this particular case, we are inlining a static method in a known 
> holder which is also an interface, but doesn't have any other 
> non-static concrete methods, so the assert fails.
>
> The MethodHandle seems to be significant since known_holder is NULL 
> when simply calling MyInterface.m(). Looking at the a assert and it's 
> history, I'm not really sure what it's supposed to guard against. It 
> seems to want to check that the callee is non-abstract when we have a 
> known holder, but in that case I'm not sure why it doesn't just use 
> `!callee->is_abstract()`.
>
> Not sure what should be done here? I tried changing the assert to 
> `assert(known_holder == NULL || !callee->is_abstract())` but that 
> seems to fail in other cases. Maybe we can just remove it?
>
> Thanks,
> Jorn
>


More information about the hotspot-compiler-dev mailing list