< prev index next >

src/share/vm/opto/escape.cpp

Print this page




2035   assert(!src->is_Field() && !dst->is_Field(), "only for JavaObject and LocalVar");
2036   assert((src != null_obj) && (dst != null_obj), "not for ConP NULL");
2037   PointsToNode* ptadr = _nodes.at(n->_idx);
2038   if (ptadr != NULL) {
2039     assert(ptadr->is_Arraycopy() && ptadr->ideal_node() == n, "sanity");
2040     return;
2041   }
2042   Compile* C = _compile;
2043   ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
2044   _nodes.at_put(n->_idx, ptadr);
2045   // Add edge from arraycopy node to source object.
2046   (void)add_edge(ptadr, src);
2047   src->set_arraycopy_src();
2048   // Add edge from destination object to arraycopy node.
2049   (void)add_edge(dst, ptadr);
2050   dst->set_arraycopy_dst();
2051 }
2052 
2053 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
2054   const Type* adr_type = n->as_AddP()->bottom_type();

2055   BasicType bt = T_INT;
2056   if (offset == Type::OffsetBot) {
2057     // Check only oop fields.
2058     if (!adr_type->isa_aryptr() ||
2059         (adr_type->isa_aryptr()->klass() == NULL) ||
2060          adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
2061       // OffsetBot is used to reference array's element. Ignore first AddP.
2062       if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
2063         bt = T_OBJECT;
2064       }
2065     }
2066   } else if (offset != oopDesc::klass_offset_in_bytes()) {
2067     if (adr_type->isa_instptr() || adr_type->isa_valuetypeptr()) {
2068       ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2069       if (field != NULL) {
2070         bt = field->layout_type();
2071       } else {
2072         // Check for unsafe oop field access
2073         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
2074           bt = T_OBJECT;
2075           (*unsafe) = true;
2076         }
2077       }
2078     } else if (adr_type->isa_aryptr()) {
2079       if (offset == arrayOopDesc::length_offset_in_bytes()) {
2080         // Ignore array length load.
2081       } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2082         // Ignore first AddP.
2083       } else {
2084         const Type* elemtype = adr_type->isa_aryptr()->elem();






2085         bt = elemtype->array_element_basic_type();
2086       }

2087     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
2088       // Allocation initialization, ThreadLocal field access, unsafe access
2089       if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
2090         bt = T_OBJECT;
2091       }
2092     }
2093   }
2094   return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY);
2095 }
2096 
2097 // Returns unique pointed java object or NULL.
2098 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
2099   assert(!_collecting, "should not call when contructed graph");
2100   // If the node was created after the escape computation we can't answer.
2101   uint idx = n->_idx;
2102   if (idx >= nodes_size()) {
2103     return NULL;
2104   }
2105   PointsToNode* ptn = ptnode_adr(idx);
2106   if (ptn->is_JavaObject()) {


2388   //
2389   // It could happened on subclass's branch (from the type profiling
2390   // inlining) which was not eliminated during parsing since the exactness
2391   // of the allocation type was not propagated to the subclass type check.
2392   //
2393   // Or the type 't' could be not related to 'base_t' at all.
2394   // It could happened when CHA type is different from MDO type on a dead path
2395   // (for example, from instanceof check) which is not collapsed during parsing.
2396   //
2397   // Do nothing for such AddP node and don't process its users since
2398   // this code branch will go away.
2399   //
2400   if (!t->is_known_instance() &&
2401       !base_t->klass()->is_subtype_of(t->klass())) {
2402      return false; // bail out
2403   }
2404   const TypePtr* tinst = base_t->add_offset(t->offset());
2405   if (tinst->isa_aryptr() && t->isa_aryptr()) {
2406     // In the case of a flattened value type array, each field has its
2407     // own slice so we need to keep track of the field being accessed.
2408     tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset());
2409   }
2410 
2411   // Do NOT remove the next line: ensure a new alias index is allocated
2412   // for the instance type. Note: C++ will not remove it since the call
2413   // has side effect.
2414   int alias_idx = _compile->get_alias_index(tinst);
2415   igvn->set_type(addp, tinst);
2416   // record the allocation in the node map
2417   set_map(addp, get_map(base->_idx));
2418   // Set addp's Base and Address to 'base'.
2419   Node *abase = addp->in(AddPNode::Base);
2420   Node *adr   = addp->in(AddPNode::Address);
2421   if (adr->is_Proj() && adr->in(0)->is_Allocate() &&
2422       adr->in(0)->_idx == (uint)inst_id) {
2423     // Skip AddP cases #3 and #5.
2424   } else {
2425     assert(!abase->is_top(), "sanity"); // AddP case #3
2426     if (abase != base) {
2427       igvn->hash_delete(addp);
2428       addp->set_req(AddPNode::Base, base);




2035   assert(!src->is_Field() && !dst->is_Field(), "only for JavaObject and LocalVar");
2036   assert((src != null_obj) && (dst != null_obj), "not for ConP NULL");
2037   PointsToNode* ptadr = _nodes.at(n->_idx);
2038   if (ptadr != NULL) {
2039     assert(ptadr->is_Arraycopy() && ptadr->ideal_node() == n, "sanity");
2040     return;
2041   }
2042   Compile* C = _compile;
2043   ptadr = new (C->comp_arena()) ArraycopyNode(this, n, es);
2044   _nodes.at_put(n->_idx, ptadr);
2045   // Add edge from arraycopy node to source object.
2046   (void)add_edge(ptadr, src);
2047   src->set_arraycopy_src();
2048   // Add edge from destination object to arraycopy node.
2049   (void)add_edge(dst, ptadr);
2050   dst->set_arraycopy_dst();
2051 }
2052 
2053 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
2054   const Type* adr_type = n->as_AddP()->bottom_type();
2055   int field_offset = adr_type->isa_aryptr() ? adr_type->isa_aryptr()->field_offset().get() : Type::OffsetBot;
2056   BasicType bt = T_INT;
2057   if (offset == Type::OffsetBot && field_offset == Type::OffsetBot) {
2058     // Check only oop fields.
2059     if (!adr_type->isa_aryptr() ||
2060         (adr_type->isa_aryptr()->klass() == NULL) ||
2061          adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
2062       // OffsetBot is used to reference array's element. Ignore first AddP.
2063       if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
2064         bt = T_OBJECT;
2065       }
2066     }
2067   } else if (offset != oopDesc::klass_offset_in_bytes()) {
2068     if (adr_type->isa_instptr() || adr_type->isa_valuetypeptr()) {
2069       ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2070       if (field != NULL) {
2071         bt = field->layout_type();
2072       } else {
2073         // Check for unsafe oop field access
2074         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
2075           bt = T_OBJECT;
2076           (*unsafe) = true;
2077         }
2078       }
2079     } else if (adr_type->isa_aryptr()) {
2080       if (offset == arrayOopDesc::length_offset_in_bytes()) {
2081         // Ignore array length load.
2082       } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2083         // Ignore first AddP.
2084       } else {
2085         const Type* elemtype = adr_type->isa_aryptr()->elem();
2086         if (elemtype->isa_valuetype()) {
2087           assert(field_offset != Type::OffsetBot, "invalid field offset");
2088           ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
2089           field_offset += vk->first_field_offset();
2090           bt = vk->get_field_by_offset(field_offset, false)->layout_type();
2091         } else {
2092           bt = elemtype->array_element_basic_type();
2093         }
2094       }
2095     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
2096       // Allocation initialization, ThreadLocal field access, unsafe access
2097       if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) {
2098         bt = T_OBJECT;
2099       }
2100     }
2101   }
2102   return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY);
2103 }
2104 
2105 // Returns unique pointed java object or NULL.
2106 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
2107   assert(!_collecting, "should not call when contructed graph");
2108   // If the node was created after the escape computation we can't answer.
2109   uint idx = n->_idx;
2110   if (idx >= nodes_size()) {
2111     return NULL;
2112   }
2113   PointsToNode* ptn = ptnode_adr(idx);
2114   if (ptn->is_JavaObject()) {


2396   //
2397   // It could happened on subclass's branch (from the type profiling
2398   // inlining) which was not eliminated during parsing since the exactness
2399   // of the allocation type was not propagated to the subclass type check.
2400   //
2401   // Or the type 't' could be not related to 'base_t' at all.
2402   // It could happened when CHA type is different from MDO type on a dead path
2403   // (for example, from instanceof check) which is not collapsed during parsing.
2404   //
2405   // Do nothing for such AddP node and don't process its users since
2406   // this code branch will go away.
2407   //
2408   if (!t->is_known_instance() &&
2409       !base_t->klass()->is_subtype_of(t->klass())) {
2410      return false; // bail out
2411   }
2412   const TypePtr* tinst = base_t->add_offset(t->offset());
2413   if (tinst->isa_aryptr() && t->isa_aryptr()) {
2414     // In the case of a flattened value type array, each field has its
2415     // own slice so we need to keep track of the field being accessed.
2416     tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset().get());
2417   }
2418 
2419   // Do NOT remove the next line: ensure a new alias index is allocated
2420   // for the instance type. Note: C++ will not remove it since the call
2421   // has side effect.
2422   int alias_idx = _compile->get_alias_index(tinst);
2423   igvn->set_type(addp, tinst);
2424   // record the allocation in the node map
2425   set_map(addp, get_map(base->_idx));
2426   // Set addp's Base and Address to 'base'.
2427   Node *abase = addp->in(AddPNode::Base);
2428   Node *adr   = addp->in(AddPNode::Address);
2429   if (adr->is_Proj() && adr->in(0)->is_Allocate() &&
2430       adr->in(0)->_idx == (uint)inst_id) {
2431     // Skip AddP cases #3 and #5.
2432   } else {
2433     assert(!abase->is_top(), "sanity"); // AddP case #3
2434     if (abase != base) {
2435       igvn->hash_delete(addp);
2436       addp->set_req(AddPNode::Base, base);


< prev index next >