Merge
This commit is contained in:
commit
26949087c0
@ -487,6 +487,23 @@ bool Type::is_nan() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
//----------------------interface_vs_oop---------------------------------------
|
||||
#ifdef ASSERT
|
||||
bool Type::interface_vs_oop(const Type *t) const {
|
||||
bool result = false;
|
||||
|
||||
const TypeInstPtr* this_inst = this->isa_instptr();
|
||||
const TypeInstPtr* t_inst = t->isa_instptr();
|
||||
if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) {
|
||||
bool this_interface = this_inst->klass()->is_interface();
|
||||
bool t_interface = t_inst->klass()->is_interface();
|
||||
result = this_interface ^ t_interface;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------meet-------------------------------------------
|
||||
// Compute the MEET of two types. NOT virtual. It enforces that meet is
|
||||
// commutative and the lattice is symmetric.
|
||||
@ -507,16 +524,8 @@ const Type *Type::meet( const Type *t ) const {
|
||||
// Interface meet Oop is Not Symmetric:
|
||||
// Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull
|
||||
// Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull
|
||||
const TypeInstPtr* this_inst = this->isa_instptr();
|
||||
const TypeInstPtr* t_inst = t->isa_instptr();
|
||||
bool interface_vs_oop = false;
|
||||
if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) {
|
||||
bool this_interface = this_inst->klass()->is_interface();
|
||||
bool t_interface = t_inst->klass()->is_interface();
|
||||
interface_vs_oop = this_interface ^ t_interface;
|
||||
}
|
||||
|
||||
if( !interface_vs_oop && (t2t != t->_dual || t2this != _dual) ) {
|
||||
if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != _dual) ) {
|
||||
tty->print_cr("=== Meet Not Symmetric ===");
|
||||
tty->print("t = "); t->dump(); tty->cr();
|
||||
tty->print("this= "); dump(); tty->cr();
|
||||
@ -1800,6 +1809,17 @@ int TypeAry::hash(void) const {
|
||||
return (intptr_t)_elem + (intptr_t)_size;
|
||||
}
|
||||
|
||||
//----------------------interface_vs_oop---------------------------------------
|
||||
#ifdef ASSERT
|
||||
bool TypeAry::interface_vs_oop(const Type *t) const {
|
||||
const TypeAry* t_ary = t->is_ary();
|
||||
if (t_ary) {
|
||||
return _elem->interface_vs_oop(t_ary->_elem);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
@ -3389,6 +3409,17 @@ const Type *TypeAryPtr::xdual() const {
|
||||
return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
|
||||
}
|
||||
|
||||
//----------------------interface_vs_oop---------------------------------------
|
||||
#ifdef ASSERT
|
||||
bool TypeAryPtr::interface_vs_oop(const Type *t) const {
|
||||
const TypeAryPtr* t_aryptr = t->isa_aryptr();
|
||||
if (t_aryptr) {
|
||||
return _ary->interface_vs_oop(t_aryptr->_ary);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------dump2------------------------------------------
|
||||
#ifndef PRODUCT
|
||||
void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const {
|
||||
|
@ -190,6 +190,11 @@ public:
|
||||
// Currently, it also works around limitations involving interface types.
|
||||
virtual const Type *filter( const Type *kills ) const;
|
||||
|
||||
#ifdef ASSERT
|
||||
// One type is interface, the other is oop
|
||||
virtual bool interface_vs_oop(const Type *t) const;
|
||||
#endif
|
||||
|
||||
// Returns true if this pointer points at memory which contains a
|
||||
// compressed oop references.
|
||||
bool is_ptr_to_narrowoop() const;
|
||||
@ -546,6 +551,10 @@ public:
|
||||
virtual const Type *xmeet( const Type *t ) const;
|
||||
virtual const Type *xdual() const; // Compute dual right now.
|
||||
bool ary_must_be_exact() const; // true if arrays of such are never generic
|
||||
#ifdef ASSERT
|
||||
// One type is interface, the other is oop
|
||||
virtual bool interface_vs_oop(const Type *t) const;
|
||||
#endif
|
||||
#ifndef PRODUCT
|
||||
virtual void dump2( Dict &d, uint, outputStream *st ) const; // Specialized per-Type dumping
|
||||
#endif
|
||||
@ -867,6 +876,10 @@ public:
|
||||
}
|
||||
static const TypeAryPtr *_array_body_type[T_CONFLICT+1];
|
||||
// sharpen the type of an int which is used as an array size
|
||||
#ifdef ASSERT
|
||||
// One type is interface, the other is oop
|
||||
virtual bool interface_vs_oop(const Type *t) const;
|
||||
#endif
|
||||
#ifndef PRODUCT
|
||||
virtual void dump2( Dict &d, uint depth, outputStream *st ) const; // Specialized per-Type dumping
|
||||
#endif
|
||||
|
94
hotspot/test/compiler/6837094/Test.java
Normal file
94
hotspot/test/compiler/6837094/Test.java
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright 2009 Sun Microsystems, 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
|
||||
* CA 95054 USA or visit www.sun.com if you need additional information or
|
||||
* have any questions.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @bug 6837094
|
||||
* @summary False positive for "meet not symmetric" failure
|
||||
*
|
||||
* @run main/othervm -Xbatch -XX:CompileOnly=Test.collectIs,Test$Factory$1.getArray,Test$Factory$2.getArray Test
|
||||
*/
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class Test {
|
||||
|
||||
private interface Factory<M extends Interface> {
|
||||
Factory<Child0> Zero = new Factory<Child0>() {
|
||||
public Child0[] getArray() { return new Child0[1]; }
|
||||
};
|
||||
|
||||
Factory<Child1> One = new Factory<Child1>() {
|
||||
public Child1[] getArray() { return new Child1[1]; }
|
||||
};
|
||||
|
||||
M[] getArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* C2 asserts when compiling this method. Bimorphic inlining happens at
|
||||
* getArray call site. A Phi in the catch block tries to join the meet type
|
||||
* from he inline site (Parent[]) with the type expected by CI (Interface[]).
|
||||
*
|
||||
* C2 throws an assert when it doesn't need to.
|
||||
*/
|
||||
private static <I extends Interface> void collectIs(
|
||||
Factory<I> factory, Set<Interface> s) {
|
||||
for (I i : factory.getArray()) {
|
||||
try {
|
||||
s.add(i);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public void main(String argv[]) {
|
||||
Set<Interface> s = new HashSet();
|
||||
|
||||
for (int i = 0; i < 25000; i++) {
|
||||
collectIs(Factory.Zero, s);
|
||||
collectIs(Factory.One, s);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Establish necessary class hierarchy
|
||||
*/
|
||||
|
||||
interface Interface {
|
||||
}
|
||||
|
||||
class Parent {
|
||||
}
|
||||
|
||||
class Child0 extends Parent implements Interface {
|
||||
}
|
||||
|
||||
class Child1 extends Parent implements Interface {
|
||||
}
|
||||
|
||||
class Child2 extends Parent implements Interface {
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user