mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-19 02:24:40 +02:00
8240676: Meet not symmetric failure when running lucene on jdk8
Reviewed-by: kvn, thartmann
This commit is contained in:
parent
7048684ca7
commit
5ff2d7baaa
5 changed files with 126 additions and 25 deletions
|
@ -1009,6 +1009,9 @@ void Compile::Init(int aliaslevel) {
|
||||||
_range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
_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);
|
_opaque4_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8, 0, NULL);
|
||||||
register_library_intrinsics();
|
register_library_intrinsics();
|
||||||
|
#ifdef ASSERT
|
||||||
|
_type_verify_symmetry = true;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------init_start----------------------------------------
|
//---------------------------init_start----------------------------------------
|
||||||
|
|
|
@ -1179,6 +1179,9 @@ class Compile : public Phase {
|
||||||
bool select_24_bit_instr() const { return _select_24_bit_instr; }
|
bool select_24_bit_instr() const { return _select_24_bit_instr; }
|
||||||
bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; }
|
bool in_24_bit_fp_mode() const { return _in_24_bit_fp_mode; }
|
||||||
#endif // IA32
|
#endif // IA32
|
||||||
|
#ifdef ASSERT
|
||||||
|
bool _type_verify_symmetry;
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SHARE_OPTO_COMPILE_HPP
|
#endif // SHARE_OPTO_COMPILE_HPP
|
||||||
|
|
|
@ -810,6 +810,35 @@ bool Type::interface_vs_oop(const Type *t) const {
|
||||||
|
|
||||||
#endif
|
#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-------------------------------------------
|
//------------------------------meet-------------------------------------------
|
||||||
// Compute the MEET of two types. NOT virtual. It enforces that meet is
|
// Compute the MEET of two types. NOT virtual. It enforces that meet is
|
||||||
// commutative and the lattice is symmetric.
|
// 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);
|
t = t->maybe_remove_speculative(include_speculative);
|
||||||
|
|
||||||
const Type *mt = this_t->xmeet(t);
|
const Type *mt = this_t->xmeet(t);
|
||||||
|
#ifdef ASSERT
|
||||||
if (isa_narrowoop() || t->isa_narrowoop()) return mt;
|
if (isa_narrowoop() || t->isa_narrowoop()) return mt;
|
||||||
if (isa_narrowklass() || t->isa_narrowklass()) return mt;
|
if (isa_narrowklass() || t->isa_narrowklass()) return mt;
|
||||||
#ifdef ASSERT
|
Compile* C = Compile::current();
|
||||||
assert(mt == t->xmeet(this_t), "meet not commutative");
|
if (!C->_type_verify_symmetry) {
|
||||||
const Type* dual_join = mt->_dual;
|
return mt;
|
||||||
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" );
|
|
||||||
}
|
}
|
||||||
|
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
|
#endif
|
||||||
return mt;
|
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())) ||
|
(tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
|
||||||
// 'this' is exact and super or unrelated:
|
// 'this' is exact and super or unrelated:
|
||||||
(this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
|
(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);
|
tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
|
||||||
}
|
}
|
||||||
return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
|
return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
|
||||||
|
|
|
@ -166,6 +166,7 @@ private:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const Type *meet_helper(const Type *t, bool include_speculative) const;
|
const Type *meet_helper(const Type *t, bool include_speculative) const;
|
||||||
|
void check_symmetrical(const Type *t, const Type *mt) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Each class of type is also identified by its base.
|
// 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…
Add table
Add a link
Reference in a new issue