OpenJDK / jdk / jdk
changeset 58577:6ccf082f50d4
8240676: Meet not symmetric failure when running lucene on jdk8
Reviewed-by: kvn, thartmann
author | roland |
---|---|
date | Tue, 24 Mar 2020 11:06:26 +0100 |
parents | b7933e5c5ce9 |
children | 4327d2c64129 |
files | src/hotspot/share/opto/compile.cpp src/hotspot/share/opto/compile.hpp src/hotspot/share/opto/type.cpp src/hotspot/share/opto/type.hpp test/hotspot/jtreg/compiler/types/TestArrayMeetNotSymmetrical.java |
diffstat | 5 files changed, 126 insertions(+), 25 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/share/opto/compile.cpp Fri Mar 27 09:44:53 2020 +0100 +++ b/src/hotspot/share/opto/compile.cpp Tue Mar 24 11:06:26 2020 +0100 @@ -1009,6 +1009,9 @@ _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); _opaque4_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL); register_library_intrinsics(); +#ifdef ASSERT + _type_verify_symmetry = true; +#endif } //---------------------------init_start----------------------------------------
--- a/src/hotspot/share/opto/compile.hpp Fri Mar 27 09:44:53 2020 +0100 +++ b/src/hotspot/share/opto/compile.hpp Tue Mar 24 11:06:26 2020 +0100 @@ -1179,6 +1179,9 @@ bool select_24_bit_instr() const { return _select_24_bit_instr; } bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; } #endif // IA32 +#ifdef ASSERT + bool _type_verify_symmetry; +#endif }; #endif // SHARE_OPTO_COMPILE_HPP
--- a/src/hotspot/share/opto/type.cpp Fri Mar 27 09:44:53 2020 +0100 +++ b/src/hotspot/share/opto/type.cpp Tue Mar 24 11:06:26 2020 +0100 @@ -810,6 +810,35 @@ #endif +void Type::check_symmetrical(const Type *t, const Type *mt) const { +#ifdef ASSERT + assert(mt == t->xmeet(this), "meet not commutative"); + const Type* dual_join = mt->_dual; + const Type *t2t = dual_join->xmeet(t->_dual); + const Type *t2this = dual_join->xmeet(this->_dual); + + // Interface meet Oop is Not Symmetric: + // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull + // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull + + if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this->_dual) ) { + tty->print_cr("=== Meet Not Symmetric ==="); + tty->print("t = "); t->dump(); tty->cr(); + tty->print("this= "); dump(); tty->cr(); + tty->print("mt=(t meet this)= "); mt->dump(); tty->cr(); + + tty->print("t_dual= "); t->_dual->dump(); tty->cr(); + tty->print("this_dual= "); _dual->dump(); tty->cr(); + tty->print("mt_dual= "); mt->_dual->dump(); tty->cr(); + + tty->print("mt_dual meet t_dual= "); t2t ->dump(); tty->cr(); + tty->print("mt_dual meet this_dual= "); t2this ->dump(); tty->cr(); + + fatal("meet not symmetric" ); + } +#endif +} + //------------------------------meet------------------------------------------- // Compute the MEET of two types. NOT virtual. It enforces that meet is // commutative and the lattice is symmetric. @@ -827,33 +856,28 @@ t = t->maybe_remove_speculative(include_speculative); const Type *mt = this_t->xmeet(t); +#ifdef ASSERT if (isa_narrowoop() || t->isa_narrowoop()) return mt; if (isa_narrowklass() || t->isa_narrowklass()) return mt; -#ifdef ASSERT - assert(mt == t->xmeet(this_t), "meet not commutative"); - const Type* dual_join = mt->_dual; - const Type *t2t = dual_join->xmeet(t->_dual); - const Type *t2this = dual_join->xmeet(this_t->_dual); - - // Interface meet Oop is Not Symmetric: - // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull - // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull - - if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) { - tty->print_cr("=== Meet Not Symmetric ==="); - tty->print("t = "); t->dump(); tty->cr(); - tty->print("this= "); this_t->dump(); tty->cr(); - tty->print("mt=(t meet this)= "); mt->dump(); tty->cr(); - - tty->print("t_dual= "); t->_dual->dump(); tty->cr(); - tty->print("this_dual= "); this_t->_dual->dump(); tty->cr(); - tty->print("mt_dual= "); mt->_dual->dump(); tty->cr(); - - tty->print("mt_dual meet t_dual= "); t2t ->dump(); tty->cr(); - tty->print("mt_dual meet this_dual= "); t2this ->dump(); tty->cr(); - - fatal("meet not symmetric" ); + Compile* C = Compile::current(); + if (!C->_type_verify_symmetry) { + return mt; } + this_t->check_symmetrical(t, mt); + // In the case of an array, computing the meet above, caused the + // computation of the meet of the elements which at verification + // time caused the computation of the meet of the dual of the + // elements. Computing the meet of the dual of the arrays here + // causes the meet of the dual of the elements to be computed which + // would cause the meet of the dual of the dual of the elements, + // that is the meet of the elements already computed above to be + // computed. Avoid redundant computations by requesting no + // verification. + C->_type_verify_symmetry = false; + const Type *mt_dual = this_t->_dual->xmeet(t->_dual); + this_t->_dual->check_symmetrical(t->_dual, mt_dual); + assert(!C->_type_verify_symmetry, "shouldn't have changed"); + C->_type_verify_symmetry = true; #endif return mt; } @@ -4315,7 +4339,7 @@ (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || // 'this' is exact and super or unrelated: (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { - if (above_centerline(ptr)) { + if (above_centerline(ptr) || (tary->_elem->make_ptr() && above_centerline(tary->_elem->make_ptr()->_ptr))) { tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); } return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
--- a/src/hotspot/share/opto/type.hpp Fri Mar 27 09:44:53 2020 +0100 +++ b/src/hotspot/share/opto/type.hpp Tue Mar 24 11:06:26 2020 +0100 @@ -166,6 +166,7 @@ #endif const Type *meet_helper(const Type *t, bool include_speculative) const; + void check_symmetrical(const Type *t, const Type *mt) const; protected: // Each class of type is also identified by its base.
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/hotspot/jtreg/compiler/types/TestArrayMeetNotSymmetrical.java Tue Mar 24 11:06:26 2020 +0100 @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2020, Red Hat, Inc. 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 8240676 + * @summary Meet not symmetric failure when running lucene on jdk8 + * + * @run main/othervm -XX:-BackgroundCompilation TestArrayMeetNotSymmetrical + * + */ + +public class TestArrayMeetNotSymmetrical { + private static final Object field = new Object[0]; + private static final Object field2 = new A[0]; + + public static void main(String[] args) { + Object array = new A[10]; + for (int i = 0; i < 20_000; i++) { + test1(true, 10); + test1(false, 10); + test2(true); + test2(false); + } + } + + private static Object test1(boolean flag, int len) { + Object o; + if (flag) { + o = field; + } else { + o = new A[len]; + } + return o; + } + + private static Object test2(boolean flag) { + Object o; + if (flag) { + o = field; + } else { + o = field2; + } + return o; + } + + + private static class A { + } +}