mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 18:33:41 +00:00
8240676: Meet not symmetric failure when running lucene on jdk8
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
7048684ca7
commit
5ff2d7baaa
@ -1009,6 +1009,9 @@ void Compile::Init(int aliaslevel) {
|
||||
_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----------------------------------------
|
||||
|
||||
@ -1179,6 +1179,9 @@ class Compile : public Phase {
|
||||
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
|
||||
|
||||
@ -810,6 +810,35 @@ bool Type::interface_vs_oop(const Type *t) const {
|
||||
|
||||
#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 @@ const Type *Type::meet_helper(const Type *t, bool include_speculative) const {
|
||||
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 @@ const Type *TypeAryPtr::xmeet_helper(const Type *t) const {
|
||||
(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);
|
||||
|
||||
@ -166,6 +166,7 @@ private:
|
||||
#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.
|
||||
|
||||
@ -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 {
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user