< prev index next >

test/hotspot/jtreg/compiler/cha/StrengthReduceInterfaceCall.java

Print this page

        

@@ -77,618 +77,10 @@
         run(ThreeLevelHierarchyAbstractVsDefault.class);
         run(ThreeLevelDefaultHierarchy.class);
         run(ThreeLevelDefaultHierarchy1.class);
     }
 
-    public static class ObjectToString extends ATest<ObjectToString.I> {
-        public ObjectToString() { super(I.class, C.class); }
-
-        interface J           { String toString(); }
-        interface I extends J {}
-
-        static class C implements I {}
-
-        interface K1 extends I {}
-        interface K2 extends I { String toString(); } // K2.tS() ABSTRACT
-        // interface K3 extends I { default String toString() { return "K3"; } // K2.tS() DEFAULT
-
-        static class D implements I { public String toString() { return "D"; }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public String toString() { return "DJ2"; }}
-
-        @Override
-        public Object test(I i) { return ObjectToStringHelper.test(i); /* invokeinterface I.toString() */ }
-
-        @TestCase
-        public void testMono() {
-            // 0. Trigger compilation of a monomorphic call site
-            compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testBi() {
-            // 0. Trigger compilation of a bimorphic call site
-            compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-            // compiler.cha.StrengthReduceInterfaceCall$ObjectToString::test (5 bytes)
-            //     @ 1   compiler.cha.StrengthReduceInterfaceCall$ObjectToStringHelper::test (7 bytes)   inline (hot)
-            //       @ 1   java.lang.Object::toString (36 bytes)   virtual call
-
-            // No dependency - no invalidation
-            repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
-            assertCompiled();
-
-            initialize(K1.class,   // intf  K1             <: intf I <: intf J
-                       K2.class,   // intf  K2.tS ABSTRACT <: intf I <: intf J
-                       DJ1.class,  //      DJ1                       <: intf J
-                       DJ2.class); //      DJ2.tS                    <: intf J
-            assertCompiled();
-
-            initialize(D.class); // D.tS <: intf I <: intf J
-            assertCompiled();
-
-            call(new C() { public String toString() { return "Cn"; }}); // Cn.tS <: C.tS <: intf I
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ObjectHashCode extends ATest<ObjectHashCode.I> {
-        public ObjectHashCode() { super(I.class, C.class); }
-
-        interface J {}
-        interface I extends J {}
-
-        static class C implements I {}
-
-        interface K1 extends I {}
-        interface K2 extends I { int hashCode(); } // K2.hC() ABSTRACT
-        // interface K3 extends I { default int hashCode() { return CORRECT; } // K2.hC() DEFAULT
-
-        static class D implements I { public int hashCode() { return super.hashCode(); }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public int hashCode() { return super.hashCode(); }}
-
-        @Override
-        public Object test(I i) {
-            return ObjectHashCodeHelper.test(i); /* invokeinterface I.hashCode() */
-        }
-
-        @TestCase
-        public void testMono() {
-            // 0. Trigger compilation of a monomorphic call site
-            compile(monomophic()); // C1 <: C <: intf I <: intf J <: Object.hashCode()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testBi() {
-            // 0. Trigger compilation of a bimorphic call site
-            compile(bimorphic()); // C1 <: C <: intf I <: intf J <: Object.toString()
-            assertCompiled();
-
-            // Dependency: none
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C <: intf I <: intf J <: Object.hashCode()
-            assertCompiled();
-
-            // Dependency: none
-
-            // No dependency - no invalidation
-            repeat(100, () -> call(new C(){})); // Cn <: C <: intf I
-            assertCompiled();
-
-            initialize(K1.class,   // intf  K1             <: intf I <: intf J
-                       K2.class,   // intf  K2.hC ABSTRACT <: intf I <: intf J
-                       DJ1.class,  //      DJ1                       <: intf J
-                       DJ2.class); //      DJ2.hC                    <: intf J
-            assertCompiled();
-
-            initialize(D.class); // D.hC <: intf I <: intf J
-            assertCompiled();
-
-            call(new C() { public int hashCode() { return super.hashCode(); }}); // Cn.hC <: C.hC <: intf I
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class TwoLevelHierarchyLinear extends ATest<TwoLevelHierarchyLinear.I> {
-        public TwoLevelHierarchyLinear() { super(I.class, C.class); }
-
-        interface J { default Object m() { return WRONG; } }
-
-        interface I extends J { Object m(); }
-        static class C implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class D implements I { public Object m() { return WRONG;   }}
-
-        static class DJ1 implements J {}
-        static class DJ2 implements J { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m();
-        }
-
-        @TestCase
-        public void testMega1() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            // 2. No dependency invalidation on class loading of unrelated classes: different context
-            initialize(K1.class,   // intf  K1            <: intf I.m ABSTRACT <: intf J.m DEFAULT
-                       K2.class,   // intf  K2.m ABSTRACT <: intf I.m ABSTRACT <: intf J.m DEFAULT
-                       DJ1.class,  //      DJ1                                 <: intf J.m DEFAULT
-                       DJ2.class); //      DJ2.m                               <: intf J.m DEFAULT
-            assertCompiled();
-
-            // 3. Dependency invalidation on D <: I
-            initialize(D.class); // D.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertNotCompiled();
-
-            // 4. Recompilation: no inlining, no dependencies
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @TestCase
-        public void testMega2() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. Dependency invalidation
-            initialize(K3.class); // intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertNotCompiled();
-
-            // 2. Recompilation: still inlines
-            // FIXME: no default method support in CHA yet
-            compile(megamorphic());
-            call(new K3() { public Object m() { return CORRECT; }}); // K3n.m <: intf K3.m DEFAULT <: intf I.m ABSTRACT <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // 3. Recompilation: no inlining, no dependencies
-            compile(megamorphic());
-            call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: intf K3.m DEFAULT  <: intf I.m ABSTRACT <: intf J.m DEFAULT
-            assertCompiled();
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelHierarchyLinear extends ATest<ThreeLevelHierarchyLinear.I> {
-        public ThreeLevelHierarchyLinear() { super(I.class, C.class); }
-
-        interface J           { Object m(); }
-        interface I extends J {}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        static class DI implements I { public Object m() { return WRONG;   }}
-        static class DJ implements J { public Object m() { return WRONG;   }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // I <: J.m ABSTRACT
-        }
-
-        @TestCase
-        public void testMega1() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I
-            assertCompiled(); // No deopt on not-yet-seen receiver
-
-            // 2. No dependency invalidation: different context
-            initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
-                       K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
-                       K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // 3. Dependency invalidation: DI.m <: I
-            initialize(DI.class); //      DI.m          <: intf I <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // 4. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled(); // no dependency
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @TestCase
-        public void testMega2() {
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // Dependency invalidation
-            initialize(K3.class); // intf K3.m DEFAULT <: intf I;
-            assertNotCompiled(); // FIXME: default methods in sub-interfaces shouldn't be taken into account by CHA
-
-            // Recompilation with a dependency
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            call(new K3() { public Object m() { return CORRECT; }}); // Kn.m <: K3.m DEFAULT <: intf I <: intf J.m ABSTRACT
-            assertNotCompiled();
-
-            // Recompilation w/o a dependency
-            compile(megamorphic());
-            // Dependency: none
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() { public Object m() { return WRONG; }}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelHierarchyAbstractVsDefault extends ATest<ThreeLevelHierarchyAbstractVsDefault.I> {
-        public ThreeLevelHierarchyAbstractVsDefault() { super(I.class, C.class); }
-
-        interface J1                { default Object m() { return WRONG; } } // intf J1.m DEFAULT
-        interface J2 extends J1     { Object m(); }                          // intf J2.m ABSTRACT <: intf J1
-        interface I  extends J1, J2 {}                                       // intf  I.m OVERPASS <: intf J1,J2
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // intf I.m OVERPASS
-        }
-
-        static class DI implements I { public Object m() { return WRONG;   }}
-
-        static class DJ11 implements J1 {}
-        static class DJ12 implements J1 { public Object m() { return WRONG; }}
-
-        static class DJ2 implements J2 { public Object m() { return WRONG;   }}
-
-        interface K11 extends J1 {}
-        interface K12 extends J1 { Object m(); }
-        interface K13 extends J1 { default Object m() { return WRONG; }}
-        interface K21 extends J2 {}
-        interface K22 extends J2 { Object m(); }
-        interface K23 extends J2 { default Object m() { return WRONG; }}
-
-
-        public void testMega1() {
-            // 0. Trigger compilation of megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deopt/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C(){})); // Cn <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertCompiled();
-
-            // 2. No dependency invalidation: different context
-            initialize(K11.class, K12.class, K13.class,
-                       K21.class, K22.class, K23.class);
-
-            // 3. Dependency invalidation: Cn.m <: C <: I
-            call(new C() { public Object m() { return CORRECT; }}); // Cn.m <: C.m <: intf I.m OVERPASS <: intf J2.m ABSTRACT <: intf J1.m DEFAULT
-            assertNotCompiled();
-
-            // 4. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }});
-            assertCompiled(); // no inlining
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        public void testMega2() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: type = unique_concrete_method, context = I, method = C.m
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No dependency invalidation: different context
-            initialize(DJ11.class,
-                       DJ12.class,
-                       DJ2.class);
-            assertCompiled();
-
-            // 2. Dependency invalidation: DI.m <: I
-            initialize(DI.class);
-            assertNotCompiled();
-
-            // 3. Recompilation w/o a dependency
-            compile(megamorphic());
-            call(new C() { public Object m() { return CORRECT; }});
-            assertCompiled(); // no inlining
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() { public Object m() { return WRONG; }}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelDefaultHierarchy extends ATest<ThreeLevelDefaultHierarchy.I> {
-        public ThreeLevelDefaultHierarchy() { super(I.class, C.class); }
-
-        interface J           { default Object m() { return WRONG; }}
-        interface I extends J {}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class DI implements I { public Object m() { return WRONG; }}
-        static class DJ implements J { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // no inlining since J.m is a default method
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic()); // C1,C2,C3 <: C.m <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-
-            // Dependency: none
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C() {}));
-            assertCompiled();
-
-            // 2. No dependency and no inlining
-            initialize(DJ.class,  //      DJ.m                    <: intf J.m ABSTRACT
-                       DI.class,  //      DI.m          <: intf I <: intf J.m ABSTRACT
-                       K1.class,  // intf K1            <: intf I <: intf J.m ABSTRACT
-                       K2.class); // intf K2.m ABSTRACT <: intf I <: intf J.m ABSTRACT
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
-    public static class ThreeLevelDefaultHierarchy1 extends ATest<ThreeLevelDefaultHierarchy1.I> {
-        public ThreeLevelDefaultHierarchy1() { super(I.class, C.class); }
-
-        interface J1                { Object m();}
-        interface J2 extends J1     { default Object m() { return WRONG; }  }
-        interface I  extends J1, J2 {}
-
-        static class C  implements I { public Object m() { return CORRECT; }}
-
-        interface K1 extends I {}
-        interface K2 extends I { Object m(); }
-        interface K3 extends I { default Object m() { return WRONG; }}
-
-        static class DI implements I { public Object m() { return WRONG; }}
-        static class DJ1 implements J1 { public Object m() { return WRONG; }}
-        static class DJ2 implements J2 { public Object m() { return WRONG; }}
-
-        @DontInline
-        public Object test(I i) {
-            return i.m(); // no inlining since J.m is a default method
-        }
-
-        @TestCase
-        public void testMega() {
-            // 0. Trigger compilation of a megamorphic call site
-            compile(megamorphic());
-            assertCompiled();
-
-            // Dependency: none
-
-            checkInvalidReceiver(); // ensure proper type check on receiver is preserved
-
-            // 1. No deoptimization/invalidation on not-yet-seen receiver
-            repeat(100, () -> call(new C() {}));
-            assertCompiled();
-
-            // 2. No dependency, no inlining
-            // CHA doesn't support default methods yet.
-            initialize(DJ1.class,
-                       DJ2.class,
-                       DI.class,
-                       K1.class,
-                       K2.class,
-                       K3.class);
-            assertCompiled();
-        }
-
-        @Override
-        public void checkInvalidReceiver() {
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I o = (I) unsafeCastMH(I.class).invokeExact(new Object()); // unrelated
-                test(o);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J1() { public Object m() { return WRONG; } }); // super interface
-                test(j);
-            });
-            assertCompiled();
-
-            shouldThrow(IncompatibleClassChangeError.class, () -> {
-                I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() {}); // super interface
-                test(j);
-            });
-            assertCompiled();
-        }
-    }
-
     /* =========================================================== */
 
     interface Action {
         int run();
     }
< prev index next >