< prev index next >

src/hotspot/share/opto/escape.cpp

Print this page

3425   (void)add_edge(ptadr, src);
3426   src->set_arraycopy_src();
3427   // Add edge from destination object to arraycopy node.
3428   (void)add_edge(dst, ptadr);
3429   dst->set_arraycopy_dst();
3430 }
3431 
3432 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
3433   const Type* adr_type = n->as_AddP()->bottom_type();
3434   BasicType bt = T_INT;
3435   if (offset == Type::OffsetBot) {
3436     // Check only oop fields.
3437     if (!adr_type->isa_aryptr() ||
3438         adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3439         adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3440       // OffsetBot is used to reference array's element. Ignore first AddP.
3441       if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3442         bt = T_OBJECT;
3443       }
3444     }
3445   } else if (offset != oopDesc::klass_offset_in_bytes()) {
3446     if (adr_type->isa_instptr()) {
3447       ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3448       if (field != nullptr) {
3449         bt = field->layout_type();
3450       } else {
3451         // Check for unsafe oop field access
3452         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3453             n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3454             n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3455             BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3456           bt = T_OBJECT;
3457           (*unsafe) = true;
3458         }
3459       }
3460     } else if (adr_type->isa_aryptr()) {
3461       if (offset == arrayOopDesc::length_offset_in_bytes()) {
3462         // Ignore array length load.
3463       } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3464         // Ignore first AddP.
3465       } else {

4424         alloc->as_Allocate()->_is_scalar_replaceable = true;
4425       }
4426       set_escape_state(ptnode_adr(n->_idx), es NOT_PRODUCT(COMMA trace_propagate_message(ptn))); // CheckCastPP escape state
4427       // in order for an object to be scalar-replaceable, it must be:
4428       //   - a direct allocation (not a call returning an object)
4429       //   - non-escaping
4430       //   - eligible to be a unique type
4431       //   - not determined to be ineligible by escape analysis
4432       set_map(alloc, n);
4433       set_map(n, alloc);
4434       const TypeOopPtr* tinst = t->cast_to_instance_id(ni);
4435       igvn->hash_delete(n);
4436       igvn->set_type(n,  tinst);
4437       n->raise_bottom_type(tinst);
4438       igvn->hash_insert(n);
4439       record_for_optimizer(n);
4440       // Allocate an alias index for the header fields. Accesses to
4441       // the header emitted during macro expansion wouldn't have
4442       // correct memory state otherwise.
4443       _compile->get_alias_index(tinst->add_offset(oopDesc::mark_offset_in_bytes()));
4444       _compile->get_alias_index(tinst->add_offset(oopDesc::klass_offset_in_bytes()));
4445       if (alloc->is_Allocate() && (t->isa_instptr() || t->isa_aryptr())) {
4446 
4447         // First, put on the worklist all Field edges from Connection Graph
4448         // which is more accurate than putting immediate users from Ideal Graph.
4449         for (EdgeIterator e(ptn); e.has_next(); e.next()) {
4450           PointsToNode* tgt = e.get();
4451           if (tgt->is_Arraycopy()) {
4452             continue;
4453           }
4454           Node* use = tgt->ideal_node();
4455           assert(tgt->is_Field() && use->is_AddP(),
4456                  "only AddP nodes are Field edges in CG");
4457           if (use->outcnt() > 0) { // Don't process dead nodes
4458             Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
4459             if (addp2 != nullptr) {
4460               assert(alloc->is_AllocateArray(),"array allocation was expected");
4461               alloc_worklist.append_if_missing(addp2);
4462             }
4463             alloc_worklist.append_if_missing(use);
4464           }

3425   (void)add_edge(ptadr, src);
3426   src->set_arraycopy_src();
3427   // Add edge from destination object to arraycopy node.
3428   (void)add_edge(dst, ptadr);
3429   dst->set_arraycopy_dst();
3430 }
3431 
3432 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
3433   const Type* adr_type = n->as_AddP()->bottom_type();
3434   BasicType bt = T_INT;
3435   if (offset == Type::OffsetBot) {
3436     // Check only oop fields.
3437     if (!adr_type->isa_aryptr() ||
3438         adr_type->isa_aryptr()->elem() == Type::BOTTOM ||
3439         adr_type->isa_aryptr()->elem()->make_oopptr() != nullptr) {
3440       // OffsetBot is used to reference array's element. Ignore first AddP.
3441       if (find_second_addp(n, n->in(AddPNode::Base)) == nullptr) {
3442         bt = T_OBJECT;
3443       }
3444     }
3445   } else if (offset != Type::klass_offset()) {
3446     if (adr_type->isa_instptr()) {
3447       ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
3448       if (field != nullptr) {
3449         bt = field->layout_type();
3450       } else {
3451         // Check for unsafe oop field access
3452         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
3453             n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
3454             n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN) ||
3455             BarrierSet::barrier_set()->barrier_set_c2()->escape_has_out_with_unsafe_object(n)) {
3456           bt = T_OBJECT;
3457           (*unsafe) = true;
3458         }
3459       }
3460     } else if (adr_type->isa_aryptr()) {
3461       if (offset == arrayOopDesc::length_offset_in_bytes()) {
3462         // Ignore array length load.
3463       } else if (find_second_addp(n, n->in(AddPNode::Base)) != nullptr) {
3464         // Ignore first AddP.
3465       } else {

4424         alloc->as_Allocate()->_is_scalar_replaceable = true;
4425       }
4426       set_escape_state(ptnode_adr(n->_idx), es NOT_PRODUCT(COMMA trace_propagate_message(ptn))); // CheckCastPP escape state
4427       // in order for an object to be scalar-replaceable, it must be:
4428       //   - a direct allocation (not a call returning an object)
4429       //   - non-escaping
4430       //   - eligible to be a unique type
4431       //   - not determined to be ineligible by escape analysis
4432       set_map(alloc, n);
4433       set_map(n, alloc);
4434       const TypeOopPtr* tinst = t->cast_to_instance_id(ni);
4435       igvn->hash_delete(n);
4436       igvn->set_type(n,  tinst);
4437       n->raise_bottom_type(tinst);
4438       igvn->hash_insert(n);
4439       record_for_optimizer(n);
4440       // Allocate an alias index for the header fields. Accesses to
4441       // the header emitted during macro expansion wouldn't have
4442       // correct memory state otherwise.
4443       _compile->get_alias_index(tinst->add_offset(oopDesc::mark_offset_in_bytes()));
4444       _compile->get_alias_index(tinst->add_offset(Type::klass_offset()));
4445       if (alloc->is_Allocate() && (t->isa_instptr() || t->isa_aryptr())) {
4446 
4447         // First, put on the worklist all Field edges from Connection Graph
4448         // which is more accurate than putting immediate users from Ideal Graph.
4449         for (EdgeIterator e(ptn); e.has_next(); e.next()) {
4450           PointsToNode* tgt = e.get();
4451           if (tgt->is_Arraycopy()) {
4452             continue;
4453           }
4454           Node* use = tgt->ideal_node();
4455           assert(tgt->is_Field() && use->is_AddP(),
4456                  "only AddP nodes are Field edges in CG");
4457           if (use->outcnt() > 0) { // Don't process dead nodes
4458             Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
4459             if (addp2 != nullptr) {
4460               assert(alloc->is_AllocateArray(),"array allocation was expected");
4461               alloc_worklist.append_if_missing(addp2);
4462             }
4463             alloc_worklist.append_if_missing(use);
4464           }
< prev index next >