JDK-8065760 : CHA: Improve abstract method support
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: compiler
  • Affected Version: 9,10
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2014-11-24
  • Updated: 2021-06-30
  • Resolved: 2021-06-01
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 17
17 b25Fixed
Related Reports
Blocks :  
Blocks :  
Relates :  
Relates :  
Description
Consider the following hierarchy:
    interface I1 { public int m(); }
    abstract class C1 implements I1 {}
    class C2 extends C1 { public int m() { return 0; }}
 
Call site:  invokevirtual C1.m() C2

The call site is monomorphic (C2.m()), but inlining during C1 compilation fails with the following message:
   2217    1    b  1       jsr292.DevirtIntfMethod::test (5 bytes)
                     @ 1   jsr292.DevirtIntfMethod$I1::m (0 bytes)   not inlineable


Comments
Changeset: 20479c3d Author: Vladimir Ivanov <vlivanov@openjdk.org> Date: 2021-06-01 12:06:57 +0000 URL: https://git.openjdk.java.net/jdk/commit/20479c3de93736d62bca97c4fe422a19ad87d52a
01-06-2021

In order to cover the reported case, CHA should be extended for abstract methods. Right now, CHA relies on the fact that root method is concrete. The analysis bails out when root method is abstract. Somewhat surprisingly, it works for overpass methods. When there's a default method defined, the JVM fills local method tables for all descendant klasses with overpass methods. It makes CHA happy, since it finds conflicts caused by abstract methods by local method table inspection.
07-02-2017

If a default method is added to I1, inlining occurs: interface I1 { public int m(); default void someMethod() {} } 1536 1 b 1 jsr292.DevirtIntfMethod::test (5 bytes) @ 1 jsr292.DevirtIntfMethod$C2::m (2 bytes) -XX:+TraceDependencies: found a non-root unique target method context = jsr292.DevirtIntfMethod$C1 method = jsr292.DevirtIntfMethod$C2::m -XX:+PrintVtables -XX:+Verbose: invokevirtual selected method: receiver-class:jsr292.DevirtIntfMethod$C1, resolved-class:jsr292.DevirtIntfMethod$C1, method:jsr292.DevirtIntfMethod$C1.m()I, method_holder:jsr292.DevirtIntfMethod$C1, vtable_index:5, access_flags: public volatile synthetic overpass
24-11-2014

-XX:+PrintVtables -XX:+Verbose: invokevirtual resolved method: caller-class:jsr292.DevirtIntfMethod, compile-time-class:jsr292.DevirtIntfMethod$C1, method:jsr292.DevirtIntfMethod$C1.m()I, method_holder:jsr292.DevirtIntfMethod$I1, access_flags: public abstract
24-11-2014