8240676: Meet not symmetric failure when running lucene on jdk8

Tue, 30 Jun 2020 18:05:34 +0200

author
roland
date
Tue, 30 Jun 2020 18:05:34 +0200
changeset 9985
8712be1ae49a
parent 9984
63dafc005680
child 9986
85e682d8ab91

8240676: Meet not symmetric failure when running lucene on jdk8
Reviewed-by: kvn, thartmann

src/share/vm/opto/compile.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/compile.hpp file | annotate | diff | comparison | revisions
src/share/vm/opto/type.cpp file | annotate | diff | comparison | revisions
src/share/vm/opto/type.hpp file | annotate | diff | comparison | revisions
test/compiler/types/TestArrayMeetNotSymmetrical.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/opto/compile.cpp	Fri Aug 21 09:07:53 2020 +0200
     1.2 +++ b/src/share/vm/opto/compile.cpp	Tue Jun 30 18:05:34 2020 +0200
     1.3 @@ -1162,6 +1162,9 @@
     1.4    _expensive_nodes = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
     1.5    _range_check_casts = new(comp_arena()) GrowableArray<Node*>(comp_arena(), 8,  0, NULL);
     1.6    register_library_intrinsics();
     1.7 +#ifdef ASSERT
     1.8 +  _type_verify_symmetry = true;
     1.9 +#endif
    1.10  }
    1.11  
    1.12  //---------------------------init_start----------------------------------------
     2.1 --- a/src/share/vm/opto/compile.hpp	Fri Aug 21 09:07:53 2020 +0200
     2.2 +++ b/src/share/vm/opto/compile.hpp	Tue Jun 30 18:05:34 2020 +0200
     2.3 @@ -1224,6 +1224,9 @@
     2.4  
     2.5    // Auxiliary method for randomized fuzzing/stressing
     2.6    static bool randomized_select(int count);
     2.7 +#ifdef ASSERT
     2.8 +  bool _type_verify_symmetry;
     2.9 +#endif
    2.10  };
    2.11  
    2.12  #endif // SHARE_VM_OPTO_COMPILE_HPP
     3.1 --- a/src/share/vm/opto/type.cpp	Fri Aug 21 09:07:53 2020 +0200
     3.2 +++ b/src/share/vm/opto/type.cpp	Tue Jun 30 18:05:34 2020 +0200
     3.3 @@ -668,6 +668,35 @@
     3.4  
     3.5  #endif
     3.6  
     3.7 +void Type::check_symmetrical(const Type *t, const Type *mt) const {
     3.8 +#ifdef ASSERT
     3.9 +  assert(mt == t->xmeet(this), "meet not commutative");
    3.10 +  const Type* dual_join = mt->_dual;
    3.11 +  const Type *t2t    = dual_join->xmeet(t->_dual);
    3.12 +  const Type *t2this = dual_join->xmeet(this->_dual);
    3.13 +
    3.14 +  // Interface meet Oop is Not Symmetric:
    3.15 +  // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
    3.16 +  // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
    3.17 +
    3.18 +  if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this->_dual) ) {
    3.19 +    tty->print_cr("=== Meet Not Symmetric ===");
    3.20 +    tty->print("t   =                   ");              t->dump(); tty->cr();
    3.21 +    tty->print("this=                   ");                 dump(); tty->cr();
    3.22 +    tty->print("mt=(t meet this)=       ");             mt->dump(); tty->cr();
    3.23 +
    3.24 +    tty->print("t_dual=                 ");       t->_dual->dump(); tty->cr();
    3.25 +    tty->print("this_dual=              ");          _dual->dump(); tty->cr();
    3.26 +    tty->print("mt_dual=                ");      mt->_dual->dump(); tty->cr();
    3.27 +
    3.28 +    tty->print("mt_dual meet t_dual=    "); t2t           ->dump(); tty->cr();
    3.29 +    tty->print("mt_dual meet this_dual= "); t2this        ->dump(); tty->cr();
    3.30 +
    3.31 +    fatal("meet not symmetric" );
    3.32 +  }
    3.33 +#endif
    3.34 +}
    3.35 +
    3.36  //------------------------------meet-------------------------------------------
    3.37  // Compute the MEET of two types.  NOT virtual.  It enforces that meet is
    3.38  // commutative and the lattice is symmetric.
    3.39 @@ -685,33 +714,28 @@
    3.40    t = t->maybe_remove_speculative(include_speculative);
    3.41  
    3.42    const Type *mt = this_t->xmeet(t);
    3.43 +#ifdef ASSERT
    3.44    if (isa_narrowoop() || t->isa_narrowoop()) return mt;
    3.45    if (isa_narrowklass() || t->isa_narrowklass()) return mt;
    3.46 -#ifdef ASSERT
    3.47 -  assert(mt == t->xmeet(this_t), "meet not commutative");
    3.48 -  const Type* dual_join = mt->_dual;
    3.49 -  const Type *t2t    = dual_join->xmeet(t->_dual);
    3.50 -  const Type *t2this = dual_join->xmeet(this_t->_dual);
    3.51 -
    3.52 -  // Interface meet Oop is Not Symmetric:
    3.53 -  // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
    3.54 -  // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
    3.55 -
    3.56 -  if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) {
    3.57 -    tty->print_cr("=== Meet Not Symmetric ===");
    3.58 -    tty->print("t   =                   ");              t->dump(); tty->cr();
    3.59 -    tty->print("this=                   ");         this_t->dump(); tty->cr();
    3.60 -    tty->print("mt=(t meet this)=       ");             mt->dump(); tty->cr();
    3.61 -
    3.62 -    tty->print("t_dual=                 ");       t->_dual->dump(); tty->cr();
    3.63 -    tty->print("this_dual=              ");  this_t->_dual->dump(); tty->cr();
    3.64 -    tty->print("mt_dual=                ");      mt->_dual->dump(); tty->cr();
    3.65 -
    3.66 -    tty->print("mt_dual meet t_dual=    "); t2t           ->dump(); tty->cr();
    3.67 -    tty->print("mt_dual meet this_dual= "); t2this        ->dump(); tty->cr();
    3.68 -
    3.69 -    fatal("meet not symmetric" );
    3.70 +  Compile* C = Compile::current();
    3.71 +  if (!C->_type_verify_symmetry) {
    3.72 +    return mt;
    3.73    }
    3.74 +  this_t->check_symmetrical(t, mt);
    3.75 +  // In the case of an array, computing the meet above, caused the
    3.76 +  // computation of the meet of the elements which at verification
    3.77 +  // time caused the computation of the meet of the dual of the
    3.78 +  // elements. Computing the meet of the dual of the arrays here
    3.79 +  // causes the meet of the dual of the elements to be computed which
    3.80 +  // would cause the meet of the dual of the dual of the elements,
    3.81 +  // that is the meet of the elements already computed above to be
    3.82 +  // computed. Avoid redundant computations by requesting no
    3.83 +  // verification.
    3.84 +  C->_type_verify_symmetry = false;
    3.85 +  const Type *mt_dual = this_t->_dual->xmeet(t->_dual);
    3.86 +  this_t->_dual->check_symmetrical(t->_dual, mt_dual);
    3.87 +  assert(!C->_type_verify_symmetry, "shouldn't have changed");
    3.88 +  C->_type_verify_symmetry = true;
    3.89  #endif
    3.90    return mt;
    3.91  }
    3.92 @@ -3966,10 +3990,10 @@
    3.93             (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) ||
    3.94             // 'this' is exact and super or unrelated:
    3.95             (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) {
    3.96 -      if (above_centerline(ptr)) {
    3.97 +      if (above_centerline(ptr) || (tary->_elem->make_ptr() && above_centerline(tary->_elem->make_ptr()->_ptr))) {
    3.98          tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable);
    3.99        }
   3.100 -      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot);
   3.101 +      return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot, speculative, depth);
   3.102      }
   3.103  
   3.104      bool xk = false;
     4.1 --- a/src/share/vm/opto/type.hpp	Fri Aug 21 09:07:53 2020 +0200
     4.2 +++ b/src/share/vm/opto/type.hpp	Tue Jun 30 18:05:34 2020 +0200
     4.3 @@ -165,6 +165,7 @@
     4.4  #endif
     4.5  
     4.6    const Type *meet_helper(const Type *t, bool include_speculative) const;
     4.7 +  void check_symmetrical(const Type *t, const Type *mt) const;
     4.8  
     4.9  protected:
    4.10    // Each class of type is also identified by its base.
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/test/compiler/types/TestArrayMeetNotSymmetrical.java	Tue Jun 30 18:05:34 2020 +0200
     5.3 @@ -0,0 +1,70 @@
     5.4 +/*
     5.5 + * Copyright (c) 2020, Red Hat, Inc. All rights reserved.
     5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5.7 + *
     5.8 + * This code is free software; you can redistribute it and/or modify it
     5.9 + * under the terms of the GNU General Public License version 2 only, as
    5.10 + * published by the Free Software Foundation.
    5.11 + *
    5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    5.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    5.15 + * version 2 for more details (a copy is included in the LICENSE file that
    5.16 + * accompanied this code).
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License version
    5.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    5.21 + *
    5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    5.23 + * or visit www.oracle.com if you need additional information or have any
    5.24 + * questions.
    5.25 + */
    5.26 +
    5.27 +/**
    5.28 + * @test
    5.29 + * @bug 8240676
    5.30 + * @summary Meet not symmetric failure when running lucene on jdk8
    5.31 + *
    5.32 + * @run main/othervm -XX:-BackgroundCompilation TestArrayMeetNotSymmetrical
    5.33 + *
    5.34 + */
    5.35 +
    5.36 +public class TestArrayMeetNotSymmetrical {
    5.37 +    private static final Object field = new Object[0];
    5.38 +    private static final Object field2 = new A[0];
    5.39 +
    5.40 +    public static void main(String[] args) {
    5.41 +        Object array = new A[10];
    5.42 +        for (int i = 0; i < 20_000; i++) {
    5.43 +            test1(true, 10);
    5.44 +            test1(false, 10);
    5.45 +            test2(true);
    5.46 +            test2(false);
    5.47 +        }
    5.48 +    }
    5.49 +
    5.50 +    private static Object test1(boolean flag, int len) {
    5.51 +        Object o;
    5.52 +        if (flag) {
    5.53 +            o = field;
    5.54 +        } else {
    5.55 +            o = new A[len];
    5.56 +        }
    5.57 +        return o;
    5.58 +    }
    5.59 +
    5.60 +    private static Object test2(boolean flag) {
    5.61 +        Object o;
    5.62 +        if (flag) {
    5.63 +            o = field;
    5.64 +        } else {
    5.65 +            o = field2;
    5.66 +        }
    5.67 +        return o;
    5.68 +    }
    5.69 +
    5.70 +
    5.71 +    private static class A {
    5.72 +    }
    5.73 +}

mercurial