Tue, 19 Feb 2019 08:58:55 +0100
8218721: C1's CEE optimization produces safepoint poll with invalid debug information
Summary: Bail out of CEE if one of the gotos is a safepoint but the if is not.
Reviewed-by: vlivanov, mdoerr
1.1 --- a/src/share/vm/c1/c1_Optimizer.cpp Wed Jun 19 09:42:12 2019 +0900 1.2 +++ b/src/share/vm/c1/c1_Optimizer.cpp Tue Feb 19 08:58:55 2019 +0100 1.3 @@ -175,6 +175,12 @@ 1.4 for_each_phi_fun(t_block, phi, return; ); 1.5 for_each_phi_fun(f_block, phi, return; ); 1.6 1.7 + // Only replace safepoint gotos if state_before information is available (if is a safepoint) 1.8 + bool is_safepoint = if_->is_safepoint(); 1.9 + if (!is_safepoint && (t_goto->is_safepoint() || f_goto->is_safepoint())) { 1.10 + return; 1.11 + } 1.12 + 1.13 // 2) substitute conditional expression 1.14 // with an IfOp followed by a Goto 1.15 // cut if_ away and get node before 1.16 @@ -203,7 +209,7 @@ 1.17 1.18 // append Goto to successor 1.19 ValueStack* state_before = if_->state_before(); 1.20 - Goto* goto_ = new Goto(sux, state_before, if_->is_safepoint() || t_goto->is_safepoint() || f_goto->is_safepoint()); 1.21 + Goto* goto_ = new Goto(sux, state_before, is_safepoint); 1.22 1.23 // prepare state for Goto 1.24 ValueStack* goto_state = if_state;
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/test/compiler/c1/TestGotoIf.jasm Tue Feb 19 08:58:55 2019 +0100 2.3 @@ -0,0 +1,171 @@ 2.4 +/* 2.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +public class compiler/c1/TestGotoIf version 52:0 { 2.29 + public Field f1:"I"; 2.30 + public Field f2:"I"; 2.31 + public static Field i:"I"; 2.32 + 2.33 + Method "<init>":"()V" stack 1 locals 1 { 2.34 + aload_0; 2.35 + invokespecial Method java/lang/Object."<init>":"()V"; 2.36 + return; 2.37 + } 2.38 + 2.39 + public Method test1:"()I" stack 3 locals 1 { 2.40 + aload_0; 2.41 + getfield Field f1:"I"; 2.42 + aload_0; 2.43 + getfield Field f2:"I"; 2.44 + iconst_1; 2.45 + isub; 2.46 + // Without the fix, if got eliminated by CEE 2.47 + if_icmpgt Null; 2.48 + iconst_1; 2.49 + Return: stack_frame_type stack1; 2.50 + stack_map int; 2.51 + ireturn; 2.52 + Null: stack_frame_type same; 2.53 + iconst_0; 2.54 + goto Return; // Backbranch (t_goto) with safepoint 2.55 + } 2.56 + 2.57 + public Method test2:"()I" stack 3 locals 1 { 2.58 + aload_0; 2.59 + getfield Field f1:"I"; 2.60 + aload_0; 2.61 + getfield Field f2:"I"; 2.62 + iconst_1; 2.63 + isub; 2.64 + goto Skip; 2.65 + Return: stack_frame_type full; 2.66 + stack_map int; 2.67 + ireturn; 2.68 + Skip: stack_frame_type full; 2.69 + stack_map int, int; 2.70 + // Without the fix, if got eliminated by CEE 2.71 + if_icmpgt Null; 2.72 + iconst_1; 2.73 + goto Return; // Backbranch (f_goto) with safepoint 2.74 + Null: stack_frame_type full; 2.75 + stack_map; 2.76 + iconst_0; 2.77 + goto Return; // Backbranch (t_goto) with safepoint 2.78 + } 2.79 + 2.80 + public Method test3:"()I" stack 3 locals 1 { 2.81 + aload_0; 2.82 + getfield Field f1:"I"; 2.83 + aload_0; 2.84 + getfield Field f2:"I"; 2.85 + iconst_1; 2.86 + isub; 2.87 + goto Skip; 2.88 + Return: stack_frame_type full; 2.89 + stack_map int; 2.90 + ireturn; 2.91 + Null: stack_frame_type full; 2.92 + stack_map; 2.93 + iconst_0; 2.94 + goto Return; // Backbranch (t_goto) with safepoint 2.95 + Skip: stack_frame_type full; 2.96 + stack_map int, int; 2.97 + // If will be eliminated by CEE 2.98 + if_icmpgt Null; // Backbranch (if) with safepoint 2.99 + iconst_1; 2.100 + goto Return; // Backbranch (f_goto) with safepoint 2.101 + } 2.102 + 2.103 + public Method test4:"()I" stack 3 locals 1 { 2.104 + aload_0; 2.105 + getfield Field f1:"I"; 2.106 + aload_0; 2.107 + getfield Field f2:"I"; 2.108 + iconst_1; 2.109 + isub; 2.110 + goto Skip; 2.111 + Null: stack_frame_type full; 2.112 + stack_map; 2.113 + iconst_0; 2.114 + Return: stack_frame_type full; 2.115 + stack_map int; 2.116 + ireturn; 2.117 + Skip: stack_frame_type full; 2.118 + stack_map int, int; 2.119 + // If will be eliminated by CEE 2.120 + if_icmpgt Null; // Backbranch (if) with safepoint 2.121 + iconst_1; 2.122 + goto Return; // Backbranch (f_goto) with safepoint 2.123 + } 2.124 + 2.125 + public Method test5:"()I" stack 3 locals 2 { 2.126 + aload_0; 2.127 + getfield Field f1:"I"; 2.128 + aload_0; 2.129 + getfield Field f2:"I"; 2.130 + iconst_1; 2.131 + isub; 2.132 + goto Skip; 2.133 + Null: stack_frame_type full; 2.134 + stack_map; 2.135 + iconst_0; 2.136 + goto Return; 2.137 + Skip: stack_frame_type full; 2.138 + stack_map int, int; 2.139 + // If will be eliminated by CEE 2.140 + if_icmpgt Null; // Backbranch (if) with safepoint 2.141 + iconst_1; 2.142 + Return: stack_frame_type full; 2.143 + stack_map int; 2.144 + ireturn; 2.145 + } 2.146 + 2.147 + public Method test6:"()I" stack 4 locals 1 { 2.148 + getstatic Field i:"I"; 2.149 + Loop: stack_frame_type full; 2.150 + stack_map int; 2.151 + // Decrement i and exit loop if < 0 2.152 + iconst_0; 2.153 + getstatic Field i:"I"; 2.154 + iconst_1; 2.155 + isub; 2.156 + dup; 2.157 + putstatic Field i:"I"; 2.158 + if_icmpgt Exit; 2.159 + 2.160 + iconst_1; 2.161 + // Without the fix, if got eliminated by CEE 2.162 + if_icmpgt Null; 2.163 + iconst_1; 2.164 + goto Loop; // Backbranch (f_goto) with safepoint 2.165 + Null: stack_frame_type same; 2.166 + iconst_0; 2.167 + goto Loop; // Backbranch (t_goto) with safepoint 2.168 + 2.169 + Exit: stack_frame_type full; 2.170 + stack_map int; 2.171 + iconst_0; 2.172 + ireturn; 2.173 + } 2.174 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/compiler/c1/TestGotoIfMain.java Tue Feb 19 08:58:55 2019 +0100 3.3 @@ -0,0 +1,46 @@ 3.4 +/* 3.5 + * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/* 3.28 + * @test 3.29 + * @bug 8218721 3.30 + * @compile TestGotoIf.jasm 3.31 + * @run main/othervm -XX:TieredStopAtLevel=1 -Xcomp 3.32 + * -XX:CompileCommand=compileonly,compiler.c1.TestGotoIf::test* 3.33 + * compiler.c1.TestGotoIfMain 3.34 + */ 3.35 + 3.36 +package compiler.c1; 3.37 + 3.38 +public class TestGotoIfMain { 3.39 + public static void main(String[] args) { 3.40 + TestGotoIf test = new TestGotoIf(); 3.41 + test.i = 5; 3.42 + test.test1(); 3.43 + test.test2(); 3.44 + test.test3(); 3.45 + test.test4(); 3.46 + test.test5(); 3.47 + test.test6(); 3.48 + } 3.49 +}