36 * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
37 * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
38 * -Xbatch -XX:+WhiteBoxAPI -Xmixed
39 * -XX:-TieredCompilation
40 * compiler.cha.StrengthReduceInterfaceCall
41 *
42 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
43 * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
44 * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
45 * -Xbatch -XX:+WhiteBoxAPI -Xmixed
46 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1
47 * compiler.cha.StrengthReduceInterfaceCall
48 */
49 package compiler.cha;
50
51 import jdk.internal.misc.Unsafe;
52 import jdk.internal.org.objectweb.asm.ClassWriter;
53 import jdk.internal.org.objectweb.asm.MethodVisitor;
54 import jdk.internal.vm.annotation.DontInline;
55 import sun.hotspot.WhiteBox;
56
57 import java.io.IOException;
58 import java.lang.annotation.Retention;
59 import java.lang.annotation.RetentionPolicy;
60 import java.lang.invoke.MethodHandle;
61 import java.lang.invoke.MethodHandles;
62 import java.lang.reflect.Method;
63 import java.util.HashMap;
64 import java.util.concurrent.Callable;
65
66 import static jdk.test.lib.Asserts.*;
67 import static jdk.internal.org.objectweb.asm.ClassWriter.*;
68 import static jdk.internal.org.objectweb.asm.Opcodes.*;
69
70 public class StrengthReduceInterfaceCall {
71 public static void main(String[] args) {
72 run(ObjectToString.class);
73 run(ObjectHashCode.class);
74 run(TwoLevelHierarchyLinear.class);
75 run(ThreeLevelHierarchyLinear.class);
678 });
679 assertCompiled();
680
681 shouldThrow(IncompatibleClassChangeError.class, () -> {
682 I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() {}); // super interface
683 test(j);
684 });
685 assertCompiled();
686 }
687 }
688
689 /* =========================================================== */
690
691 interface Action {
692 int run();
693 }
694
695 public static final Unsafe U = Unsafe.getUnsafe();
696
697 interface Test<T> {
698 boolean isCompiled();
699 void assertNotCompiled();
700 void assertCompiled();
701
702 void call(T o);
703 T receiver(int id);
704
705 default Runnable monomophic() {
706 return () -> {
707 call(receiver(0)); // 100%
708 };
709 }
710
711 default Runnable bimorphic() {
712 return () -> {
713 call(receiver(0)); // 50%
714 call(receiver(1)); // 50%
715 };
716 }
717
718 default Runnable polymorphic() {
719 return () -> {
720 for (int i = 0; i < 23; i++) {
721 call(receiver(0)); // 92%
722 }
723 call(receiver(1)); // 4%
724 call(receiver(2)); // 4%
725 };
726 }
727
728 default Runnable megamorphic() {
729 return () -> {
730 call(receiver(0)); // 33%
731 call(receiver(1)); // 33%
732 call(receiver(2)); // 33%
733 };
734 }
735
736 default void compile(Runnable r) {
737 assertNotCompiled();
738 while(!isCompiled()) {
739 r.run();
740 }
741 assertCompiled();
742 }
743
744 default void initialize(Class<?>... cs) {
745 for (Class<?> c : cs) {
746 U.ensureClassInitialized(c);
747 }
748 }
749
750 default void repeat(int cnt, Runnable r) {
751 for (int i = 0; i < cnt; i++) {
752 r.run();
753 }
754 }
755 }
756
757 public static abstract class ATest<T> implements Test<T> {
758 public static final WhiteBox WB = WhiteBox.getWhiteBox();
759
760 public static final Object CORRECT = new Object();
761 public static final Object WRONG = new Object();
762
763 final Method TEST;
772 TEST = compute(() -> this.getClass().getDeclaredMethod("test", declared));
773 }
774
775 @DontInline
776 public abstract Object test(T i);
777
778 public abstract void checkInvalidReceiver();
779
780 public T receiver(int id) {
781 return receivers.computeIfAbsent(id, (i -> {
782 try {
783 MyClassLoader cl = (MyClassLoader) receiver.getClassLoader();
784 Class<?> sub = cl.subclass(receiver, i);
785 return (T)sub.getDeclaredConstructor().newInstance();
786 } catch (Exception e) {
787 throw new Error(e);
788 }
789 }));
790 }
791
792 @Override
793 public boolean isCompiled() { return WB.isMethodCompiled(TEST); }
794
795 @Override
796 public void assertNotCompiled() { assertFalse(isCompiled()); }
797
798 @Override
799 public void assertCompiled() { assertTrue(isCompiled()); }
800
801 @Override
802 public void call(T i) {
803 assertTrue(test(i) != WRONG);
804 }
805 }
806
807 @Retention(value = RetentionPolicy.RUNTIME)
808 public @interface TestCase {}
809
810 static void run(Class<?> test) {
811 try {
812 for (Method m : test.getDeclaredMethods()) {
813 if (m.isAnnotationPresent(TestCase.class)) {
814 System.out.println(m.toString());
815 ClassLoader cl = new MyClassLoader(test);
816 Class<?> c = cl.loadClass(test.getName());
817 c.getMethod(m.getName()).invoke(c.getDeclaredConstructor().newInstance());
818 }
819 }
|
36 * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
37 * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
38 * -Xbatch -XX:+WhiteBoxAPI -Xmixed
39 * -XX:-TieredCompilation
40 * compiler.cha.StrengthReduceInterfaceCall
41 *
42 * @run main/othervm -Xbootclasspath/a:. -XX:+IgnoreUnrecognizedVMOptions -XX:+UnlockDiagnosticVMOptions
43 * -XX:+PrintCompilation -XX:+PrintInlining -XX:+TraceDependencies -verbose:class -XX:CompileCommand=quiet
44 * -XX:CompileCommand=compileonly,*::test -XX:CompileCommand=compileonly,*::m -XX:CompileCommand=dontinline,*::test
45 * -Xbatch -XX:+WhiteBoxAPI -Xmixed
46 * -XX:+TieredCompilation -XX:TieredStopAtLevel=1
47 * compiler.cha.StrengthReduceInterfaceCall
48 */
49 package compiler.cha;
50
51 import jdk.internal.misc.Unsafe;
52 import jdk.internal.org.objectweb.asm.ClassWriter;
53 import jdk.internal.org.objectweb.asm.MethodVisitor;
54 import jdk.internal.vm.annotation.DontInline;
55 import sun.hotspot.WhiteBox;
56 import sun.hotspot.code.NMethod;
57
58 import java.io.IOException;
59 import java.lang.annotation.Retention;
60 import java.lang.annotation.RetentionPolicy;
61 import java.lang.invoke.MethodHandle;
62 import java.lang.invoke.MethodHandles;
63 import java.lang.reflect.Method;
64 import java.util.HashMap;
65 import java.util.concurrent.Callable;
66
67 import static jdk.test.lib.Asserts.*;
68 import static jdk.internal.org.objectweb.asm.ClassWriter.*;
69 import static jdk.internal.org.objectweb.asm.Opcodes.*;
70
71 public class StrengthReduceInterfaceCall {
72 public static void main(String[] args) {
73 run(ObjectToString.class);
74 run(ObjectHashCode.class);
75 run(TwoLevelHierarchyLinear.class);
76 run(ThreeLevelHierarchyLinear.class);
679 });
680 assertCompiled();
681
682 shouldThrow(IncompatibleClassChangeError.class, () -> {
683 I j = (I) unsafeCastMH(I.class).invokeExact((Object)new J2() {}); // super interface
684 test(j);
685 });
686 assertCompiled();
687 }
688 }
689
690 /* =========================================================== */
691
692 interface Action {
693 int run();
694 }
695
696 public static final Unsafe U = Unsafe.getUnsafe();
697
698 interface Test<T> {
699 void call(T o);
700 T receiver(int id);
701
702 default Runnable monomophic() {
703 return () -> {
704 call(receiver(0)); // 100%
705 };
706 }
707
708 default Runnable bimorphic() {
709 return () -> {
710 call(receiver(0)); // 50%
711 call(receiver(1)); // 50%
712 };
713 }
714
715 default Runnable polymorphic() {
716 return () -> {
717 for (int i = 0; i < 23; i++) {
718 call(receiver(0)); // 92%
719 }
720 call(receiver(1)); // 4%
721 call(receiver(2)); // 4%
722 };
723 }
724
725 default Runnable megamorphic() {
726 return () -> {
727 call(receiver(0)); // 33%
728 call(receiver(1)); // 33%
729 call(receiver(2)); // 33%
730 };
731 }
732
733 default void initialize(Class<?>... cs) {
734 for (Class<?> c : cs) {
735 U.ensureClassInitialized(c);
736 }
737 }
738
739 default void repeat(int cnt, Runnable r) {
740 for (int i = 0; i < cnt; i++) {
741 r.run();
742 }
743 }
744 }
745
746 public static abstract class ATest<T> implements Test<T> {
747 public static final WhiteBox WB = WhiteBox.getWhiteBox();
748
749 public static final Object CORRECT = new Object();
750 public static final Object WRONG = new Object();
751
752 final Method TEST;
761 TEST = compute(() -> this.getClass().getDeclaredMethod("test", declared));
762 }
763
764 @DontInline
765 public abstract Object test(T i);
766
767 public abstract void checkInvalidReceiver();
768
769 public T receiver(int id) {
770 return receivers.computeIfAbsent(id, (i -> {
771 try {
772 MyClassLoader cl = (MyClassLoader) receiver.getClassLoader();
773 Class<?> sub = cl.subclass(receiver, i);
774 return (T)sub.getDeclaredConstructor().newInstance();
775 } catch (Exception e) {
776 throw new Error(e);
777 }
778 }));
779 }
780
781
782 public void compile(Runnable r) {
783 while (!WB.isMethodCompiled(TEST)) {
784 for (int i = 0; i < 100; i++) {
785 r.run();
786 }
787 }
788 assertCompiled(); // record nmethod info
789 }
790
791 private NMethod prevNM = null;
792
793 public void assertNotCompiled() {
794 NMethod curNM = NMethod.get(TEST, false);
795 assertTrue(prevNM != null); // was previously compiled
796 assertTrue(curNM == null || prevNM.compile_id != curNM.compile_id); // either no nmethod present or recompiled
797 prevNM = curNM; // update nmethod info
798 }
799
800 public void assertCompiled() {
801 NMethod curNM = NMethod.get(TEST, false);
802 assertTrue(curNM != null); // nmethod is present
803 assertTrue(prevNM == null || prevNM.compile_id == curNM.compile_id); // no recompilations if nmethod present
804 prevNM = curNM; // update nmethod info
805 }
806
807 @Override
808 public void call(T i) {
809 assertTrue(test(i) != WRONG);
810 }
811 }
812
813 @Retention(value = RetentionPolicy.RUNTIME)
814 public @interface TestCase {}
815
816 static void run(Class<?> test) {
817 try {
818 for (Method m : test.getDeclaredMethods()) {
819 if (m.isAnnotationPresent(TestCase.class)) {
820 System.out.println(m.toString());
821 ClassLoader cl = new MyClassLoader(test);
822 Class<?> c = cl.loadClass(test.getName());
823 c.getMethod(m.getName()).invoke(c.getDeclaredConstructor().newInstance());
824 }
825 }
|