C1 GraphBuilder::profile_call assert failing when inlining static interface method through MethodHandle
Jorn Vernee
jorn.vernee at oracle.com
Fri Feb 14 14:16:01 UTC 2020
Hi Vlad,
I've filed here: https://bugs.openjdk.java.net/browse/JDK-8239083
FWIW, looking at the caller of this function:
GraphBuilder::try_inline_full, it seems that arguments to the call are
also profiled, which makes sense for a static call as well.
Jorn
On 13/02/2020 17:55, Vladimir Ivanov wrote:
> Hi Jorn,
>
> The assert does looks too strong and should be adjusted.
>
> But it looks surprising that profiling is peformend for static methods:
>
> assert(..., "should be non-static concrete method");
>
> Please, file a bug.
>
> Best regards,
> Vladimir Ivanov
>
> On 13.02.2020 14:46, Jorn Vernee wrote:
>> 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