提交 8b6132ac 编写于 作者: K kvn

6716441: error in meet with +DoEscapeAnalysis

Summary: Set instance_id to InstanceBot for InstPtr->meet(AryPtr) when types are not related.
Reviewed-by: jrose, never
上级 c57cc0fc
......@@ -632,7 +632,7 @@ bool CallNode::may_modify(const TypePtr *addr_t, PhaseTransform *phase) {
const TypeOopPtr *adrInst_t = addr_t->isa_oopptr();
// if not an InstPtr or not an instance type, assume the worst
if (adrInst_t == NULL || !adrInst_t->is_instance_field()) {
if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) {
return true;
}
Compile *C = phase->C;
......
......@@ -708,12 +708,12 @@ PhiNode* PhiNode::slice_memory(const TypePtr* adr_type) const {
// Split out an instance type from a bottom phi.
PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
const TypeOopPtr *t_oop = at->isa_oopptr();
assert(t_oop != NULL && t_oop->is_instance(), "expecting instance oopptr");
assert(t_oop != NULL && t_oop->is_known_instance(), "expecting instance oopptr");
const TypePtr *t = adr_type();
assert(type() == Type::MEMORY &&
(t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop),
t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop),
"bottom or raw memory required");
// Check if an appropriate node already exists.
......
......@@ -129,7 +129,7 @@ public:
};
PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,
const int iid = TypeOopPtr::UNKNOWN_INSTANCE,
const int iid = TypeOopPtr::InstanceTop,
const int iidx = Compile::AliasIdxTop,
const int ioffs = Type::OffsetTop )
: TypeNode(t,r->req()),
......
......@@ -1069,7 +1069,7 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
// No constant oop pointers (such as Strings); they alias with
// unknown strings.
tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
} else if( to->is_instance_field() ) {
} else if( to->is_known_instance_field() ) {
tj = to; // Keep NotNull and klass_is_exact for instance type
} else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
// During the 2nd round of IterGVN, NotNull castings are removed.
......@@ -1190,8 +1190,8 @@ void Compile::AliasType::Init(int i, const TypePtr* at) {
_field = NULL;
_is_rewritable = true; // default
const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
if (atoop != NULL && atoop->is_instance()) {
const TypeOopPtr *gt = atoop->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
if (atoop != NULL && atoop->is_known_instance()) {
const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot);
_general_index = Compile::current()->get_alias_index(gt);
} else {
_general_index = 0;
......
......@@ -483,7 +483,7 @@ static Node* find_second_addp(Node* addp, Node* n) {
//
void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
assert(base_t != NULL && base_t->is_instance(), "expecting instance oopptr");
assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
if (t == NULL) {
// We are computing a raw address for a store captured by an Initialize
......@@ -494,8 +494,8 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
assert(offs != Type::OffsetBot, "offset must be a constant");
t = base_t->add_offset(offs)->is_oopptr();
}
uint inst_id = base_t->instance_id();
assert(!t->is_instance() || t->instance_id() == inst_id,
int inst_id = base_t->instance_id();
assert(!t->is_known_instance() || t->instance_id() == inst_id,
"old type must be non-instance or match new type");
const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
// Do NOT remove the next call: ensure an new alias index is allocated
......@@ -509,7 +509,7 @@ void ConnectionGraph::split_AddP(Node *addp, Node *base, PhaseGVN *igvn) {
Node *adr = addp->in(AddPNode::Address);
const TypeOopPtr *atype = igvn->type(adr)->isa_oopptr();
if (atype != NULL && atype->instance_id() != inst_id) {
assert(!atype->is_instance(), "no conflicting instances");
assert(!atype->is_known_instance(), "no conflicting instances");
const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
acast->set_req(0, adr->in(0));
......@@ -663,7 +663,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
return orig_mem;
Compile* C = phase->C;
const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
bool is_instance = (tinst != NULL) && tinst->is_instance();
bool is_instance = (tinst != NULL) && tinst->is_known_instance();
Node *prev = NULL;
Node *result = orig_mem;
while (prev != result) {
......@@ -693,7 +693,7 @@ Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArra
AllocateNode* alloc = proj_in->as_Initialize()->allocation();
// Stop if this is the initialization for the object instance which
// which contains this memory slice, otherwise skip over it.
if (alloc == NULL || alloc->_idx != tinst->instance_id()) {
if (alloc == NULL || alloc->_idx != (uint)tinst->instance_id()) {
result = proj_in->in(TypeFunc::Memory);
}
} else if (proj_in->is_MemBar()) {
......@@ -887,7 +887,7 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
if (t == NULL)
continue; // not a TypeInstPtr
tinst = t->cast_to_instance(ni);
tinst = t->cast_to_instance_id(ni);
igvn->hash_delete(n);
igvn->set_type(n, tinst);
n->raise_bottom_type(tinst);
......@@ -959,14 +959,19 @@ void ConnectionGraph::split_unique_types(GrowableArray<Node *> &alloc_worklist)
Node *val = get_map(elem); // CheckCastPP node
TypeNode *tn = n->as_Type();
tinst = igvn->type(val)->isa_oopptr();
assert(tinst != NULL && tinst->is_instance() &&
tinst->instance_id() == elem , "instance type expected.");
assert(tinst != NULL && tinst->is_known_instance() &&
(uint)tinst->instance_id() == elem , "instance type expected.");
const Type *tn_type = igvn->type(tn);
const TypeOopPtr *tn_t = tn_type->make_ptr()->isa_oopptr();
const TypeOopPtr *tn_t;
if (tn_type->isa_narrowoop()) {
tn_t = tn_type->make_ptr()->isa_oopptr();
} else {
tn_t = tn_type->isa_oopptr();
}
if (tn_t != NULL &&
tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
tinst->cast_to_instance_id(TypeOopPtr::InstanceBot)->higher_equal(tn_t)) {
if (tn_type->isa_narrowoop()) {
tn_type = tinst->make_narrowoop();
} else {
......
......@@ -41,7 +41,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
const Type* type = n->bottom_type();
const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
Node *phi;
if( t_oop != NULL && t_oop->is_instance_field() ) {
if( t_oop != NULL && t_oop->is_known_instance_field() ) {
int iid = t_oop->instance_id();
int index = C->get_alias_index(t_oop);
int offset = t_oop->offset();
......
......@@ -320,9 +320,9 @@ Node *PhaseMacroExpand::value_from_mem_phi(Node *mem, BasicType ft, const Type *
// Search the last value stored into the object's field.
Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) {
assert(adr_t->is_instance_field(), "instance required");
uint instance_id = adr_t->instance_id();
assert(instance_id == alloc->_idx, "wrong allocation");
assert(adr_t->is_known_instance_field(), "instance required");
int instance_id = adr_t->instance_id();
assert((uint)instance_id == alloc->_idx, "wrong allocation");
int alias_idx = C->get_alias_index(adr_t);
int offset = adr_t->offset();
......@@ -354,7 +354,7 @@ Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type
const TypeOopPtr* atype = mem->as_Store()->adr_type()->isa_oopptr();
assert(atype != NULL, "address type must be oopptr");
assert(C->get_alias_index(atype) == alias_idx &&
atype->is_instance_field() && atype->offset() == offset &&
atype->is_known_instance_field() && atype->offset() == offset &&
atype->instance_id() == instance_id, "store is correct memory slice");
done = true;
} else if (mem->is_Phi()) {
......
......@@ -91,7 +91,7 @@ extern void print_alias_types();
Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
const TypeOopPtr *tinst = t_adr->isa_oopptr();
if (tinst == NULL || !tinst->is_instance_field())
if (tinst == NULL || !tinst->is_known_instance_field())
return mchain; // don't try to optimize non-instance types
uint instance_id = tinst->instance_id();
Node *prev = NULL;
......@@ -125,7 +125,7 @@ Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr,
Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
const TypeOopPtr *t_oop = t_adr->isa_oopptr();
bool is_instance = (t_oop != NULL) && t_oop->is_instance_field();
bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
PhaseIterGVN *igvn = phase->is_IterGVN();
Node *result = mchain;
result = optimize_simple_memory_chain(result, t_adr, phase);
......@@ -134,8 +134,8 @@ Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGV
assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
const TypePtr *t = mphi->adr_type();
if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop) {
t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
// clone the Phi with our address type
result = mphi->split_out_instance(t_adr, igvn);
} else {
......@@ -470,7 +470,7 @@ Node* MemNode::find_previous_store(PhaseTransform* phase) {
return mem; // let caller handle steps (c), (d)
}
} else if (addr_t != NULL && addr_t->is_instance_field()) {
} else if (addr_t != NULL && addr_t->is_known_instance_field()) {
// Can't use optimize_simple_memory_chain() since it needs PhaseGVN.
if (mem->is_Proj() && mem->in(0)->is_Call()) {
CallNode *call = mem->in(0)->as_Call();
......@@ -916,7 +916,7 @@ bool LoadNode::is_instance_field_load_with_local_phi(Node* ctrl) {
in(MemNode::Address)->is_AddP() ) {
const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
// Only instances.
if( t_oop != NULL && t_oop->is_instance_field() &&
if( t_oop != NULL && t_oop->is_known_instance_field() &&
t_oop->offset() != Type::OffsetBot &&
t_oop->offset() != Type::OffsetTop) {
return true;
......@@ -1139,7 +1139,7 @@ Node *LoadNode::split_through_phi(PhaseGVN *phase) {
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
assert(mem->is_Phi() && (t_oop != NULL) &&
t_oop->is_instance_field(), "invalide conditions");
t_oop->is_known_instance_field(), "invalide conditions");
Node *region = mem->in(0);
if (region == NULL) {
......@@ -1307,7 +1307,7 @@ Node *LoadNode::Ideal(PhaseGVN *phase, bool can_reshape) {
}
const TypeOopPtr *t_oop = addr_t->isa_oopptr();
if (can_reshape && opt_mem->is_Phi() &&
(t_oop != NULL) && t_oop->is_instance_field()) {
(t_oop != NULL) && t_oop->is_known_instance_field()) {
// Split instance field load through Phi.
Node* result = split_through_phi(phase);
if (result != NULL) return result;
......@@ -1542,7 +1542,7 @@ const Type *LoadNode::Value( PhaseTransform *phase ) const {
}
const TypeOopPtr *tinst = tp->isa_oopptr();
if (tinst != NULL && tinst->is_instance_field()) {
if (tinst != NULL && tinst->is_known_instance_field()) {
// If we have an instance type and our memory input is the
// programs's initial memory state, there is no matching store,
// so just return a zero of the appropriate type
......@@ -2137,7 +2137,7 @@ bool StoreNode::value_never_loaded( PhaseTransform *phase) const {
const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr();
if (adr_oop == NULL)
return false;
if (!adr_oop->is_instance_field())
if (!adr_oop->is_known_instance_field())
return false; // if not a distinct instance, there may be aliases of the address
for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
Node *use = adr->fast_out(i);
......
此差异已折叠。
......@@ -654,7 +654,8 @@ public:
virtual int hash() const; // Type specific hashing
virtual bool singleton(void) const; // TRUE if type is a singleton
enum {
UNKNOWN_INSTANCE = 0
InstanceTop = -1, // undefined instance
InstanceBot = 0 // any possible instance
};
protected:
......@@ -667,14 +668,15 @@ protected:
bool _klass_is_exact;
bool _is_ptr_to_narrowoop;
int _instance_id; // if not UNKNOWN_INSTANCE, indicates that this is a particular instance
// of this type which is distinct. This is the the node index of the
// node creating this instance
// If not InstanceTop or InstanceBot, indicates that this is
// a particular instance of this type which is distinct.
// This is the the node index of the allocation node creating this instance.
int _instance_id;
static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
int dual_instance() const { return -_instance_id; }
int meet_instance(int uid) const;
int dual_instance_id() const;
int meet_instance_id(int uid) const;
public:
// Creates a type given a klass. Correctly handles multi-dimensional arrays
......@@ -707,9 +709,9 @@ public:
// compressed oop references.
bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
bool is_instance() const { return _instance_id != UNKNOWN_INSTANCE; }
uint instance_id() const { return _instance_id; }
bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; }
bool is_known_instance() const { return _instance_id > 0; }
int instance_id() const { return _instance_id; }
bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
virtual intptr_t get_con() const;
......@@ -717,7 +719,7 @@ public:
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
// corresponding pointer to klass, for a given instance
const TypeKlassPtr* as_klass_type() const;
......@@ -778,7 +780,7 @@ class TypeInstPtr : public TypeOopPtr {
}
// Make a pointer to an oop.
static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = 0 );
static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
// If this is a java.lang.Class constant, return the type for it or NULL.
// Pass to Type::get_const_type to turn it to a type, which will usually
......@@ -789,7 +791,7 @@ class TypeInstPtr : public TypeOopPtr {
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypePtr *add_offset( int offset ) const;
......@@ -823,9 +825,9 @@ public:
const Type* elem() const { return _ary->_elem; }
const TypeInt* size() const { return _ary->_size; }
static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Constant pointer to array
static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
// Convenience
static const TypeAryPtr *make(ciObject* o);
......@@ -835,7 +837,7 @@ public:
virtual const Type *cast_to_exactness(bool klass_is_exact) const;
virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册