Skip to content
Permalink
Browse files

8240676: Meet not symmetric failure when running lucene on jdk8

Reviewed-by: kvn, thartmann
  • Loading branch information
rwestrel committed Mar 24, 2020
1 parent 7048684 commit 5ff2d7baaa1410566aaa2ac166049859cb3d20f5
@@ -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,50 +810,74 @@ bool Type::interface_vs_oop(const Type *t) const {

#endif

//------------------------------meet-------------------------------------------
// Compute the MEET of two types. NOT virtual. It enforces that meet is
// commutative and the lattice is symmetric.
const Type *Type::meet_helper(const Type *t, bool include_speculative) const {
if (isa_narrowoop() && t->isa_narrowoop()) {
const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative);
return result->make_narrowoop();
}
if (isa_narrowklass() && t->isa_narrowklass()) {
const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative);
return result->make_narrowklass();
}

const Type *this_t = maybe_remove_speculative(include_speculative);
t = t->maybe_remove_speculative(include_speculative);

const Type *mt = this_t->xmeet(t);
if (isa_narrowoop() || t->isa_narrowoop()) return mt;
if (isa_narrowklass() || t->isa_narrowklass()) return mt;
void Type::check_symmetrical(const Type *t, const Type *mt) const {
#ifdef ASSERT
assert(mt == t->xmeet(this_t), "meet not commutative");
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_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_t->_dual) ) {
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= "); this_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= "); this_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.
const Type *Type::meet_helper(const Type *t, bool include_speculative) const {
if (isa_narrowoop() && t->isa_narrowoop()) {
const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative);
return result->make_narrowoop();
}
if (isa_narrowklass() && t->isa_narrowklass()) {
const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative);
return result->make_narrowklass();
}

const Type *this_t = maybe_remove_speculative(include_speculative);
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;
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 @@ class Type {
#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 {
}
}

0 comments on commit 5ff2d7b

Please sign in to comment.