diff --git a/src/share/vm/opto/cfgnode.cpp b/src/share/vm/opto/cfgnode.cpp index fdee151f1e995cd1ef134b7041b77028a74e8e5c..e29cc0d58e39930ba030e0e33c2ee16b7deca085 100644 --- a/src/share/vm/opto/cfgnode.cpp +++ b/src/share/vm/opto/cfgnode.cpp @@ -858,12 +858,18 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { // convert the one to the other. const TypePtr* ttp = _type->make_ptr(); const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL; + const TypeKlassPtr* ttkp = (ttp != NULL) ? ttp->isa_klassptr() : NULL; bool is_intf = false; if (ttip != NULL) { ciKlass* k = ttip->klass(); if (k->is_loaded() && k->is_interface()) is_intf = true; } + if (ttkp != NULL) { + ciKlass* k = ttkp->klass(); + if (k->is_loaded() && k->is_interface()) + is_intf = true; + } // Default case: merge all inputs const Type *t = Type::TOP; // Merged type starting value @@ -921,6 +927,8 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { // uplift the type. if( !t->empty() && ttip && ttip->is_loaded() && ttip->klass()->is_interface() ) { assert(ft == _type, ""); } // Uplift to interface + else if( !t->empty() && ttkp && ttkp->is_loaded() && ttkp->klass()->is_interface() ) + { assert(ft == _type, ""); } // Uplift to interface // Otherwise it's something stupid like non-overlapping int ranges // found on dying counted loops. else @@ -936,6 +944,7 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { // because the type system doesn't interact well with interfaces. const TypePtr *jtp = jt->make_ptr(); const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL; + const TypeKlassPtr *jtkp = (jtp != NULL) ? jtp->isa_klassptr() : NULL; if( jtip && ttip ) { if( jtip->is_loaded() && jtip->klass()->is_interface() && ttip->is_loaded() && !ttip->klass()->is_interface() ) { @@ -945,6 +954,14 @@ const Type *PhiNode::Value( PhaseTransform *phase ) const { jt = ft; } } + if( jtkp && ttkp ) { + if( jtkp->is_loaded() && jtkp->klass()->is_interface() && + ttkp->is_loaded() && !ttkp->klass()->is_interface() ) { + assert(ft == ttkp->cast_to_ptr_type(jtkp->ptr()) || + ft->isa_narrowoop() && ft->make_ptr() == ttkp->cast_to_ptr_type(jtkp->ptr()), ""); + jt = ft; + } + } if (jt != ft && jt->base() == ft->base()) { if (jt->isa_int() && jt->is_int()->_lo == ft->is_int()->_lo && diff --git a/src/share/vm/opto/type.cpp b/src/share/vm/opto/type.cpp index f433a125535037715d25abd0361d2f1e05982345..37c895b82e5871f0aacc18a75b5cb3e55799ad2b 100644 --- a/src/share/vm/opto/type.cpp +++ b/src/share/vm/opto/type.cpp @@ -2471,6 +2471,8 @@ const Type *TypeOopPtr::filter( const Type *kills ) const { const Type* ft = join(kills); const TypeInstPtr* ftip = ft->isa_instptr(); const TypeInstPtr* ktip = kills->isa_instptr(); + const TypeKlassPtr* ftkp = ft->isa_klassptr(); + const TypeKlassPtr* ktkp = kills->isa_klassptr(); if (ft->empty()) { // Check for evil case of 'this' being a class and 'kills' expecting an @@ -2484,6 +2486,8 @@ const Type *TypeOopPtr::filter( const Type *kills ) const { // uplift the type. if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) return kills; // Uplift to interface + if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface()) + return kills; // Uplift to interface return Type::TOP; // Canonical empty value } @@ -2499,6 +2503,12 @@ const Type *TypeOopPtr::filter( const Type *kills ) const { // Happens in a CTW of rt.jar, 320-341, no extra flags return ktip->cast_to_ptr_type(ftip->ptr()); } + if (ftkp != NULL && ktkp != NULL && + ftkp->is_loaded() && ftkp->klass()->is_interface() && + ktkp->is_loaded() && !ktkp->klass()->is_interface()) { + // Happens in a CTW of rt.jar, 320-341, no extra flags + return ktkp->cast_to_ptr_type(ftkp->ptr()); + } return ft; } diff --git a/src/share/vm/opto/type.hpp b/src/share/vm/opto/type.hpp index 3d3f3ddd883f74aa132e0fb8aaae62b1ec53cbf3..493b622a28e809d199f3655b7764a1fea1ca2ca7 100644 --- a/src/share/vm/opto/type.hpp +++ b/src/share/vm/opto/type.hpp @@ -882,6 +882,8 @@ class TypeKlassPtr : public TypeOopPtr { public: ciSymbol* name() const { return _klass->name(); } + bool is_loaded() const { return _klass->is_loaded(); } + // ptr to klass 'k' static const TypeKlassPtr *make( ciKlass* k ) { return make( TypePtr::Constant, k, 0); } // ptr to klass 'k' with offset