Mercurial > hg > truffle
diff src/share/vm/opto/escape.cpp @ 163:885ed790ecf0
6695810: null oop passed to encode_heap_oop_not_null
Summary: fix several problems in C2 related to Escape Analysis and Compressed Oops.
Reviewed-by: never, jrose
author | kvn |
---|---|
date | Wed, 21 May 2008 10:45:07 -0700 |
parents | b130b98db9cf |
children | c436414a719e |
line wrap: on
line diff
--- a/src/share/vm/opto/escape.cpp Tue May 20 06:32:58 2008 -0700 +++ b/src/share/vm/opto/escape.cpp Wed May 21 10:45:07 2008 -0700 @@ -888,6 +888,23 @@ record_for_optimizer(n); if (alloc->is_Allocate() && ptn->_scalar_replaceable && (t->isa_instptr() || t->isa_aryptr())) { + + // First, put on the worklist all Field edges from Connection Graph + // which is more accurate then putting immediate users from Ideal Graph. + for (uint e = 0; e < ptn->edge_count(); e++) { + Node *use = _nodes->adr_at(ptn->edge_target(e))->_node; + assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(), + "only AddP nodes are Field edges in CG"); + if (use->outcnt() > 0) { // Don't process dead nodes + Node* addp2 = find_second_addp(use, use->in(AddPNode::Base)); + if (addp2 != NULL) { + assert(alloc->is_AllocateArray(),"array allocation was expected"); + alloc_worklist.append_if_missing(addp2); + } + alloc_worklist.append_if_missing(use); + } + } + // An allocation may have an Initialize which has raw stores. Scan // the users of the raw allocation result and push AddP users // on alloc_worklist. @@ -919,6 +936,8 @@ tinst = igvn->type(base)->isa_oopptr(); } else if (n->is_Phi() || n->is_CheckCastPP() || + n->Opcode() == Op_EncodeP || + n->Opcode() == Op_DecodeN || (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { if (visited.test_set(n->_idx)) { assert(n->is_Phi(), "loops only through Phi's"); @@ -935,13 +954,25 @@ tinst = igvn->type(val)->isa_oopptr(); assert(tinst != NULL && tinst->is_instance() && tinst->instance_id() == elem , "instance type expected."); - const TypeOopPtr *tn_t = igvn->type(tn)->isa_oopptr(); + + const TypeOopPtr *tn_t = NULL; + const Type *tn_type = igvn->type(tn); + if (tn_type->isa_narrowoop()) { + tn_t = tn_type->is_narrowoop()->make_oopptr()->isa_oopptr(); + } else { + tn_t = tn_type->isa_oopptr(); + } if (tn_t != NULL && tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) { + if (tn_type->isa_narrowoop()) { + tn_type = tinst->make_narrowoop(); + } else { + tn_type = tinst; + } igvn->hash_delete(tn); - igvn->set_type(tn, tinst); - tn->set_type(tinst); + igvn->set_type(tn, tn_type); + tn->set_type(tn_type); igvn->hash_insert(tn); record_for_optimizer(n); } @@ -978,6 +1009,8 @@ alloc_worklist.append_if_missing(use); } else if (use->is_Phi() || use->is_CheckCastPP() || + use->Opcode() == Op_EncodeP || + use->Opcode() == Op_DecodeN || (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { alloc_worklist.append_if_missing(use); } @@ -1199,7 +1232,7 @@ void ConnectionGraph::compute_escape() { - // 1. Populate Connection Graph with Ideal nodes. + // 1. Populate Connection Graph (CG) with Ideal nodes. Unique_Node_List worklist_init; worklist_init.map(_compile->unique(), NULL); // preallocate space @@ -1281,11 +1314,13 @@ remove_deferred(ni, &deferred_edges, &visited); if (n->is_AddP()) { // If this AddP computes an address which may point to more that one - // object, nothing the address points to can be scalar replaceable. + // object or more then one field (array's element), nothing the address + // points to can be scalar replaceable. Node *base = get_addp_base(n); ptset.Clear(); PointsTo(ptset, base, igvn); - if (ptset.Size() > 1) { + if (ptset.Size() > 1 || + (ptset.Size() != 0 && ptn->offset() == Type::OffsetBot)) { for( VectorSetI j(&ptset); j.test(); ++j ) { uint pt = j.elem; ptnode_adr(pt)->_scalar_replaceable = false; @@ -1979,6 +2014,11 @@ assert(false, "Op_ConP"); break; } + case Op_ConN: + { + assert(false, "Op_ConN"); + break; + } case Op_CreateEx: { assert(false, "Op_CreateEx");