Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6986483

CHA: optimize calls through interfaces

    Details

    • Type: Enhancement
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 9, 10, 11, 12, 13
    • Fix Version/s: 13
    • Component/s: hotspot
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b07

      Description

      I take a little time to create a simple test case to reproduce a bug
      found by Charles Nutter with c2.
      see http://groups.google.com/group/jvm-languages/browse_thread/thread/6c9e05ecd28fdcd4#

      Here is the test case,
      There is 3 classes A, B, C that inherit from AbstractFoo that implements Foo.
      The method test do a virtual call to check() and because
      check() is implemented in AbstractFoo we expect that this call should be
      de-virtualized then inlined.

      c2 fails, foo.check() is compiled as a virtual call :(
      With c1, there is no problem, CHA works correctly.

      Rémi

      ------------------------------------------------------------------------------------------------

      public class InlineTest {
       interface Foo {
         public boolean check(int generation);
       }

       static class AbstractFoo implements Foo {
         private final int value;

         protected AbstractFoo(int value) {
           this.value = value;
         }

         public boolean check(int generation) {
           return this.getClass().hashCode() - value == generation;
         }
       }

       static class A extends AbstractFoo {
         public A(int value) {
           super(value);
         }
       }
       static class B extends AbstractFoo {
         public B(int value) {
           super(value);
         }
       }
       static class C extends AbstractFoo {
         public C(int value) {
           super(value);
         }
       }

       private static final int CONST = A.class.hashCode();

       private static int count;

       private static void test(Foo foo) {
         if (foo.check(0)) {
             count += 2;
             //System.out.println("foo");
         } else {
             count += 1;
             //System.out.println("bar");
         }
       }

       public static void main(String[] args) {
         Foo[] array = new Foo[100000];
         int threshold = 20000;
         for(int i=0; i<threshold; i++) {
           array[i] = new A(CONST);
         }

         for(int i=threshold; i<array.length; i++) {
           array[i] = (i%2 == 0)? new B(0): new C(CONST);
         }

         for(int i=0; i<array.length; i++) {
           test(array[i]);
         }

         System.out.println(count);
       }
      }

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                vlivanov Vladimir Ivanov
                Reporter:
                never Tom Rodriguez
              • Votes:
                0 Vote for this issue
                Watchers:
                5 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: