2711 MethodHandles.invoker(myvalue2_mt)); 2712 2713 MethodHandle test102_count = MethodHandles.constant(int.class, 100); 2714 ValueType<?> test102_VT = ValueType.forClass(ValueCapableClass2.class); 2715 MethodHandle test102_init = test102_VT.defaultValueConstant(); 2716 MethodHandle test102_getfield = test102_VT.findGetter(lookup, "u", long.class); 2717 MethodHandle test102_add = lookup.findStatic(Long.class, "sum", MethodType.methodType(long.class, long.class, long.class)); 2718 MethodHandle test102_body = MethodHandles.collectArguments(ValueCapableClass2.FACTORY, 2719 0, 2720 MethodHandles.dropArguments(MethodHandles.collectArguments(MethodHandles.insertArguments(test102_add, 2721 0, 2722 1L), 2723 0, 2724 test102_getfield), 2725 1, 2726 int.class)); 2727 test102_mh = MethodHandles.collectArguments(test102_getfield, 2728 0, 2729 MethodHandles.countedLoop(test102_count, test102_init, test102_body)); 2730 2731 } catch (NoSuchMethodException|IllegalAccessException|NoSuchFieldException e) { 2732 e.printStackTrace(); 2733 throw new RuntimeException("method handle lookup fails"); 2734 } 2735 } 2736 2737 // Return of target1 and target2 merged in a Lambda Form as an 2738 // __Value. Shouldn't cause any allocation 2739 final MyValue3 test99_vt1 = MyValue3.create(); 2740 @ForceInline 2741 MyValue3 test99_target1() { 2742 return test99_vt1; 2743 } 2744 2745 final MyValue3 test99_vt2 = MyValue3.create(); 2746 @ForceInline 2747 MyValue3 test99_target2() { 2748 return test99_vt2; 2749 } 2750 2753 boolean test99_test() { 2754 return test99_bool; 2755 } 2756 2757 static final MethodHandle test99_mh; 2758 2759 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2760 @Test(valid = ValueTypeReturnedAsFieldsOff) 2761 MyValue3 test99() throws Throwable { 2762 return (MyValue3)test99_mh.invokeExact(this); 2763 } 2764 2765 @DontCompile 2766 public void test99_verifier(boolean warmup) throws Throwable { 2767 test99_bool = !test99_bool; 2768 MyValue3 vt = test99(); 2769 vt.verify(test99_bool ? test99_vt1 : test99_vt2); 2770 } 2771 2772 // Similar as above but with the method handle for target1 not 2773 // constant. Shouldn't cause any allocation but does currently. 2774 @ForceInline 2775 static MyValue2 test100_target1() { 2776 return MyValue2.createWithFieldsInline(rI, true); 2777 } 2778 2779 @ForceInline 2780 static MyValue2 test100_target2() { 2781 return MyValue2.createWithFieldsInline(rI+1, false); 2782 } 2783 2784 static boolean test100_bool = true; 2785 @ForceInline 2786 static boolean test100_test() { 2787 return test100_bool; 2788 } 2789 2790 static final MethodHandle test100_mh; 2791 static MethodHandle test100_mh1; 2792 2793 @Test 2794 long test100() throws Throwable { 2795 return ((MyValue2)test100_mh.invokeExact(test100_mh1)).hash(); 2796 } 2797 2798 @DontCompile 2799 public void test100_verifier(boolean warmup) throws Throwable { 2800 test100_bool = !test100_bool; 2801 long hash = test100(); 2802 Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test100_bool ? 0 : 1), test100_bool).hash()); 2803 } 2804 2805 // Same as above but with the method handle for target2 not 2806 // constant. Shouldn't cause any allocation but does currently. 2807 @ForceInline 2808 static MyValue2 test101_target1() { 2809 return MyValue2.createWithFieldsInline(rI, true); 2810 } 2811 2812 @ForceInline 2813 static MyValue2 test101_target2() { 2814 return MyValue2.createWithFieldsInline(rI+1, false); 2815 } 2816 2817 static boolean test101_bool = true; 2818 @ForceInline 2819 static boolean test101_test() { 2820 return test101_bool; 2821 } 2822 2823 static final MethodHandle test101_mh; 2824 static MethodHandle test101_mh2; 2825 2826 @Test 2827 long test101() throws Throwable { 2828 return ((MyValue2)test101_mh.invokeExact(test101_mh2)).hash(); 2829 } 2830 2831 @DontCompile 2832 public void test101_verifier(boolean warmup) throws Throwable { 2833 test101_bool = !test101_bool; 2834 long hash = test101(); 2835 Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test101_bool ? 0 : 1), test101_bool).hash()); 2836 } 2837 2838 // Simple reduction with intermediate result merged in a Lambda 2839 // Form as an __Value. Shouldn't cause any allocations. The entire 2840 // loop should go away as the result is a constant. 2841 static final MethodHandle test102_mh; 2842 2843 @Test(failOn = ALLOC + STORE + LOOP) 2844 long test102() throws Throwable { 2845 return (long)test102_mh.invokeExact(); 2846 } 2847 2848 @DontCompile 2849 public void test102_verifier(boolean warmup) throws Throwable { 2850 long v = test102(); 2851 Asserts.assertEQ(v, 100L); 2852 } 2853 // ========== Test infrastructure ========== 2854 2855 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 2856 private static final int ValueTypePassFieldsAsArgsOn = 0x1; 2857 private static final int ValueTypePassFieldsAsArgsOff = 0x2; 2858 private static final int ValueTypeArrayFlattenOn = 0x4; 2859 private static final int ValueTypeArrayFlattenOff = 0x8; 2860 private static final int ValueTypeReturnedAsFieldsOn = 0x10; 2861 private static final int ValueTypeReturnedAsFieldsOff = 0x20; 2862 static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn; 2863 private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); 2864 private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten"); 2865 private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields"); 2866 private static final int COMP_LEVEL_ANY = -1; 2867 private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; 2868 private static final Hashtable<String, Method> tests = new Hashtable<String, Method>(); 2869 private static final int WARMUP = 251; 2870 private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); 2871 private static boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); 2872 private static boolean XCOMP = Platform.isComp(); | 2711 MethodHandles.invoker(myvalue2_mt)); 2712 2713 MethodHandle test102_count = MethodHandles.constant(int.class, 100); 2714 ValueType<?> test102_VT = ValueType.forClass(ValueCapableClass2.class); 2715 MethodHandle test102_init = test102_VT.defaultValueConstant(); 2716 MethodHandle test102_getfield = test102_VT.findGetter(lookup, "u", long.class); 2717 MethodHandle test102_add = lookup.findStatic(Long.class, "sum", MethodType.methodType(long.class, long.class, long.class)); 2718 MethodHandle test102_body = MethodHandles.collectArguments(ValueCapableClass2.FACTORY, 2719 0, 2720 MethodHandles.dropArguments(MethodHandles.collectArguments(MethodHandles.insertArguments(test102_add, 2721 0, 2722 1L), 2723 0, 2724 test102_getfield), 2725 1, 2726 int.class)); 2727 test102_mh = MethodHandles.collectArguments(test102_getfield, 2728 0, 2729 MethodHandles.countedLoop(test102_count, test102_init, test102_body)); 2730 2731 MethodType test103_mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue3;", ValueTypeTestBench.class.getClassLoader()); 2732 MethodHandle test103_mh1 = lookup.findVirtual(ValueTypeTestBench.class, "test103_target1", test103_mt); 2733 MethodHandle test103_mh2 = lookup.findVirtual(ValueTypeTestBench.class, "test103_target2", test103_mt); 2734 MethodHandle test103_mh3 = lookup.findVirtual(ValueTypeTestBench.class, "test103_target3", test103_mt); 2735 MethodType test103_mt2 = MethodType.methodType(boolean.class); 2736 MethodHandle test103_mh_test1 = lookup.findVirtual(ValueTypeTestBench.class, "test103_test1", test103_mt2); 2737 MethodHandle test103_mh_test2 = lookup.findVirtual(ValueTypeTestBench.class, "test103_test2", test103_mt2); 2738 test103_mh = MethodHandles.guardWithTest(test103_mh_test1, 2739 test103_mh1, 2740 MethodHandles.guardWithTest(test103_mh_test2, test103_mh2, test103_mh3)); 2741 2742 MethodType test104_mt = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue2;", ValueTypeTestBench.class.getClassLoader()); 2743 MethodHandle test104_mh1 = lookup.findStatic(ValueTypeTestBench.class, "test104_target1", test104_mt); 2744 test104_mh2 = lookup.findStatic(ValueTypeTestBench.class, "test104_target2", test104_mt); 2745 test104_mh3 = lookup.findStatic(ValueTypeTestBench.class, "test104_target3", test104_mt); 2746 MethodType test104_mt2 = MethodType.methodType(boolean.class); 2747 MethodType test104_mt3 = MethodType.fromMethodDescriptorString("()Qcompiler/valhalla/valuetypes/MyValue2;", ValueTypeTestBench.class.getClassLoader()); 2748 MethodHandle test104_mh_test1 = lookup.findStatic(ValueTypeTestBench.class, "test104_test1", test104_mt2); 2749 MethodHandle test104_mh_test2 = lookup.findStatic(ValueTypeTestBench.class, "test104_test2", test104_mt2); 2750 test104_mh = MethodHandles.guardWithTest(test104_mh_test1, 2751 MethodHandles.dropArguments(test104_mh1, 0, MethodHandle.class, MethodHandle.class), 2752 MethodHandles.guardWithTest(test104_mh_test2, 2753 MethodHandles.dropArguments(MethodHandles.invoker(test104_mt3), 1, MethodHandle.class), 2754 MethodHandles.dropArguments(MethodHandles.invoker(test104_mt3), 0, MethodHandle.class)) 2755 ); 2756 } catch (NoSuchMethodException|IllegalAccessException|NoSuchFieldException e) { 2757 e.printStackTrace(); 2758 throw new RuntimeException("method handle lookup fails"); 2759 } 2760 } 2761 2762 // Return of target1 and target2 merged in a Lambda Form as an 2763 // __Value. Shouldn't cause any allocation 2764 final MyValue3 test99_vt1 = MyValue3.create(); 2765 @ForceInline 2766 MyValue3 test99_target1() { 2767 return test99_vt1; 2768 } 2769 2770 final MyValue3 test99_vt2 = MyValue3.create(); 2771 @ForceInline 2772 MyValue3 test99_target2() { 2773 return test99_vt2; 2774 } 2775 2778 boolean test99_test() { 2779 return test99_bool; 2780 } 2781 2782 static final MethodHandle test99_mh; 2783 2784 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2785 @Test(valid = ValueTypeReturnedAsFieldsOff) 2786 MyValue3 test99() throws Throwable { 2787 return (MyValue3)test99_mh.invokeExact(this); 2788 } 2789 2790 @DontCompile 2791 public void test99_verifier(boolean warmup) throws Throwable { 2792 test99_bool = !test99_bool; 2793 MyValue3 vt = test99(); 2794 vt.verify(test99_bool ? test99_vt1 : test99_vt2); 2795 } 2796 2797 // Similar as above but with the method handle for target1 not 2798 // constant. Shouldn't cause any allocation. 2799 @ForceInline 2800 static MyValue2 test100_target1() { 2801 return MyValue2.createWithFieldsInline(rI, true); 2802 } 2803 2804 @ForceInline 2805 static MyValue2 test100_target2() { 2806 return MyValue2.createWithFieldsInline(rI+1, false); 2807 } 2808 2809 static boolean test100_bool = true; 2810 @ForceInline 2811 static boolean test100_test() { 2812 return test100_bool; 2813 } 2814 2815 static final MethodHandle test100_mh; 2816 static MethodHandle test100_mh1; 2817 2818 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2819 @Test(valid = ValueTypeReturnedAsFieldsOff) 2820 long test100() throws Throwable { 2821 return ((MyValue2)test100_mh.invokeExact(test100_mh1)).hash(); 2822 } 2823 2824 @DontCompile 2825 public void test100_verifier(boolean warmup) throws Throwable { 2826 test100_bool = !test100_bool; 2827 long hash = test100(); 2828 Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test100_bool ? 0 : 1), test100_bool).hash()); 2829 } 2830 2831 // Same as above but with the method handle for target2 not 2832 // constant. Shouldn't cause any allocation. 2833 @ForceInline 2834 static MyValue2 test101_target1() { 2835 return MyValue2.createWithFieldsInline(rI, true); 2836 } 2837 2838 @ForceInline 2839 static MyValue2 test101_target2() { 2840 return MyValue2.createWithFieldsInline(rI+1, false); 2841 } 2842 2843 static boolean test101_bool = true; 2844 @ForceInline 2845 static boolean test101_test() { 2846 return test101_bool; 2847 } 2848 2849 static final MethodHandle test101_mh; 2850 static MethodHandle test101_mh2; 2851 2852 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2853 @Test(valid = ValueTypeReturnedAsFieldsOff) 2854 long test101() throws Throwable { 2855 return ((MyValue2)test101_mh.invokeExact(test101_mh2)).hash(); 2856 } 2857 2858 @DontCompile 2859 public void test101_verifier(boolean warmup) throws Throwable { 2860 test101_bool = !test101_bool; 2861 long hash = test101(); 2862 Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(rI+(test101_bool ? 0 : 1), test101_bool).hash()); 2863 } 2864 2865 // Simple reduction with intermediate result merged in a Lambda 2866 // Form as an __Value. Shouldn't cause any allocations. The entire 2867 // loop should go away as the result is a constant. 2868 static final MethodHandle test102_mh; 2869 2870 @Test(failOn = ALLOC + STORE + LOOP) 2871 long test102() throws Throwable { 2872 return (long)test102_mh.invokeExact(); 2873 } 2874 2875 @DontCompile 2876 public void test102_verifier(boolean warmup) throws Throwable { 2877 long v = test102(); 2878 Asserts.assertEQ(v, 100L); 2879 } 2880 2881 // Return of target1, target2 and target3 merged in Lambda Forms 2882 // as an __Value. Shouldn't cause any allocation 2883 final MyValue3 test103_vt1 = MyValue3.create(); 2884 @ForceInline 2885 MyValue3 test103_target1() { 2886 return test103_vt1; 2887 } 2888 2889 final MyValue3 test103_vt2 = MyValue3.create(); 2890 @ForceInline 2891 MyValue3 test103_target2() { 2892 return test103_vt2; 2893 } 2894 2895 final MyValue3 test103_vt3 = MyValue3.create(); 2896 @ForceInline 2897 MyValue3 test103_target3() { 2898 return test103_vt3; 2899 } 2900 2901 boolean test103_bool1 = true; 2902 @ForceInline 2903 boolean test103_test1() { 2904 return test103_bool1; 2905 } 2906 2907 boolean test103_bool2 = true; 2908 @ForceInline 2909 boolean test103_test2() { 2910 return test103_bool2; 2911 } 2912 2913 static final MethodHandle test103_mh; 2914 2915 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2916 @Test(valid = ValueTypeReturnedAsFieldsOff) 2917 MyValue3 test103() throws Throwable { 2918 return (MyValue3)test103_mh.invokeExact(this); 2919 } 2920 2921 static int test103_i = 0; 2922 @DontCompile 2923 public void test103_verifier(boolean warmup) throws Throwable { 2924 test103_i++; 2925 test103_bool1 = (test103_i % 2) == 0; 2926 test103_bool2 = (test103_i % 3) == 0; 2927 MyValue3 vt = test103(); 2928 vt.verify(test103_bool1 ? test103_vt1 : (test103_bool2 ? test103_vt2 : test103_vt3)); 2929 } 2930 2931 // Same as above but with non constant target2 and target3 2932 @ForceInline 2933 static MyValue2 test104_target1() { 2934 return MyValue2.createWithFieldsInline(rI, true); 2935 } 2936 2937 @ForceInline 2938 static MyValue2 test104_target2() { 2939 return MyValue2.createWithFieldsInline(rI+1, false); 2940 } 2941 2942 @ForceInline 2943 static MyValue2 test104_target3() { 2944 return MyValue2.createWithFieldsInline(rI+2, true); 2945 } 2946 2947 static boolean test104_bool1 = true; 2948 @ForceInline 2949 static boolean test104_test1() { 2950 return test104_bool1; 2951 } 2952 2953 static boolean test104_bool2 = true; 2954 @ForceInline 2955 static boolean test104_test2() { 2956 return test104_bool2; 2957 } 2958 2959 static final MethodHandle test104_mh; 2960 static MethodHandle test104_mh2; 2961 static MethodHandle test104_mh3; 2962 2963 @Test(valid = ValueTypeReturnedAsFieldsOn, failOn = ALLOC + ALLOCA + STORE) 2964 @Test(valid = ValueTypeReturnedAsFieldsOff) 2965 long test104() throws Throwable { 2966 return ((MyValue2)test104_mh.invokeExact(test104_mh2, test104_mh3)).hash(); 2967 } 2968 2969 static int test104_i = 0; 2970 @DontCompile 2971 public void test104_verifier(boolean warmup) throws Throwable { 2972 test104_i++; 2973 test104_bool1 = (test104_i % 2) == 0; 2974 test104_bool2 = (test104_i % 3) == 0; 2975 long hash = test104(); 2976 int i = rI+(test104_bool1 ? 0 : (test104_bool2 ? 1 : 2)); 2977 boolean b = test104_bool1 ? true : (test104_bool2 ? false : true); 2978 Asserts.assertEQ(hash, MyValue2.createWithFieldsInline(i, b).hash()); 2979 } 2980 2981 // ========== Test infrastructure ========== 2982 2983 private static final WhiteBox WHITE_BOX = WhiteBox.getWhiteBox(); 2984 private static final int ValueTypePassFieldsAsArgsOn = 0x1; 2985 private static final int ValueTypePassFieldsAsArgsOff = 0x2; 2986 private static final int ValueTypeArrayFlattenOn = 0x4; 2987 private static final int ValueTypeArrayFlattenOff = 0x8; 2988 private static final int ValueTypeReturnedAsFieldsOn = 0x10; 2989 private static final int ValueTypeReturnedAsFieldsOff = 0x20; 2990 static final int AllFlags = ValueTypePassFieldsAsArgsOn | ValueTypePassFieldsAsArgsOff | ValueTypeArrayFlattenOn | ValueTypeArrayFlattenOff | ValueTypeReturnedAsFieldsOn; 2991 private static final boolean ValueTypePassFieldsAsArgs = (Boolean)WHITE_BOX.getVMFlag("ValueTypePassFieldsAsArgs"); 2992 private static final boolean ValueTypeArrayFlatten = (Boolean)WHITE_BOX.getVMFlag("ValueArrayFlatten"); 2993 private static final boolean ValueTypeReturnedAsFields = (Boolean)WHITE_BOX.getVMFlag("ValueTypeReturnedAsFields"); 2994 private static final int COMP_LEVEL_ANY = -1; 2995 private static final int COMP_LEVEL_FULL_OPTIMIZATION = 4; 2996 private static final Hashtable<String, Method> tests = new Hashtable<String, Method>(); 2997 private static final int WARMUP = 251; 2998 private static boolean USE_COMPILER = WHITE_BOX.getBooleanVMFlag("UseCompiler"); 2999 private static boolean PRINT_IDEAL = WHITE_BOX.getBooleanVMFlag("PrintIdeal"); 3000 private static boolean XCOMP = Platform.isComp(); |