# HG changeset patch # User iveresov # Date 1304709149 25200 # Node ID d4c1fbc3de9525c8ec3a9a9737be917ef3a57c90 # Parent f879eafd583539726edfeb95f1af234adc159379 7042153: guarantee(x_compare_res != Constant::not_comparable) failed: incomparable constants in IfOp Summary: Handle IfOps folding properly in case of unloaded constant oop arguments Reviewed-by: kvn, never diff -r f879eafd5835 -r d4c1fbc3de95 src/share/vm/c1/c1_InstructionPrinter.cpp --- a/src/share/vm/c1/c1_InstructionPrinter.cpp Thu May 05 21:06:14 2011 -0700 +++ b/src/share/vm/c1/c1_InstructionPrinter.cpp Fri May 06 12:12:29 2011 -0700 @@ -132,17 +132,22 @@ if (value->is_null_object()) { output()->print("null"); } else if (!value->is_loaded()) { - output()->print("", value); + output()->print("", value); } else if (value->is_method()) { ciMethod* m = (ciMethod*)value; output()->print("", m->holder()->name()->as_utf8(), m->name()->as_utf8()); } else { - output()->print("", value->constant_encoding()); + output()->print("", value->constant_encoding()); } } else if (type->as_InstanceConstant() != NULL) { - output()->print("", type->as_InstanceConstant()->value()->constant_encoding()); + ciInstance* value = type->as_InstanceConstant()->value(); + if (value->is_loaded()) { + output()->print("", value->constant_encoding()); + } else { + output()->print("", value); + } } else if (type->as_ArrayConstant() != NULL) { - output()->print("", type->as_ArrayConstant()->value()->constant_encoding()); + output()->print("", type->as_ArrayConstant()->value()->constant_encoding()); } else if (type->as_ClassConstant() != NULL) { ciInstanceKlass* klass = type->as_ClassConstant()->value(); if (!klass->is_loaded()) { diff -r f879eafd5835 -r d4c1fbc3de95 src/share/vm/c1/c1_Optimizer.cpp --- a/src/share/vm/c1/c1_Optimizer.cpp Thu May 05 21:06:14 2011 -0700 +++ b/src/share/vm/c1/c1_Optimizer.cpp Fri May 06 12:12:29 2011 -0700 @@ -252,26 +252,28 @@ Constant::CompareResult t_compare_res = x_tval_const->compare(cond, y_const); Constant::CompareResult f_compare_res = x_fval_const->compare(cond, y_const); - guarantee(t_compare_res != Constant::not_comparable && f_compare_res != Constant::not_comparable, "incomparable constants in IfOp"); - - Value new_tval = t_compare_res == Constant::cond_true ? tval : fval; - Value new_fval = f_compare_res == Constant::cond_true ? tval : fval; + // not_comparable here is a valid return in case we're comparing unloaded oop constants + if (t_compare_res != Constant::not_comparable && f_compare_res != Constant::not_comparable) { + Value new_tval = t_compare_res == Constant::cond_true ? tval : fval; + Value new_fval = f_compare_res == Constant::cond_true ? tval : fval; - _ifop_count++; - if (new_tval == new_fval) { - return new_tval; - } else { - return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval); + _ifop_count++; + if (new_tval == new_fval) { + return new_tval; + } else { + return new IfOp(x_ifop->x(), x_ifop_cond, x_ifop->y(), new_tval, new_fval); + } } } } else { Constant* x_const = x->as_Constant(); if (x_const != NULL) { // x and y are constants Constant::CompareResult x_compare_res = x_const->compare(cond, y_const); - guarantee(x_compare_res != Constant::not_comparable, "incomparable constants in IfOp"); - - _ifop_count++; - return x_compare_res == Constant::cond_true ? tval : fval; + // not_comparable here is a valid return in case we're comparing unloaded oop constants + if (x_compare_res != Constant::not_comparable) { + _ifop_count++; + return x_compare_res == Constant::cond_true ? tval : fval; + } } } } diff -r f879eafd5835 -r d4c1fbc3de95 test/compiler/7042153/Test7042153.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/compiler/7042153/Test7042153.java Fri May 06 12:12:29 2011 -0700 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/** + * @test + * @bug 7042153 + * @summary Bad folding of IfOps with unloaded constant arguments in C1 + * + * @run main/othervm -Xcomp Test7042153 + */ + +import java.lang.reflect.*; + +public class Test7042153 { + static public class Bar { } + static public class Foo { } + + static volatile boolean z; + public static void main(String [] args) { + Class cx = Bar.class; + Class cy = Foo.class; + z = (cx == cy); + } +}