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

CHA: optimize calls through interfaces

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P3 P3
    • 13
    • 9, 10, 11, 12, 13
    • hotspot
    • b07

      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);
       }
      }

            vlivanov Vladimir Ivanov
            never Tom Rodriguez
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: