< prev index next >

src/hotspot/share/opto/escape.cpp

Print this page




2080     if (adr_type->isa_instptr() || adr_type->isa_valuetypeptr()) {
2081       ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2082       if (field != NULL) {
2083         bt = field->layout_type();
2084       } else {
2085         // Check for unsafe oop field access
2086         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2087             n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2088             n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2089           bt = T_OBJECT;
2090           (*unsafe) = true;
2091         }
2092       }
2093     } else if (adr_type->isa_aryptr()) {
2094       if (offset == arrayOopDesc::length_offset_in_bytes()) {
2095         // Ignore array length load.
2096       } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2097         // Ignore first AddP.
2098       } else {
2099         const Type* elemtype = adr_type->isa_aryptr()->elem();
2100         if (elemtype->isa_valuetype()) {
2101           assert(field_offset != Type::OffsetBot, "invalid field offset");
2102           ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
2103           field_offset += vk->first_field_offset();
2104           bt = vk->get_field_by_offset(field_offset, false)->layout_type();
2105         } else {
2106           bt = elemtype->array_element_basic_type();
2107         }
2108       }
2109     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
2110       // Allocation initialization, ThreadLocal field access, unsafe access
2111       if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2112           n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2113           n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2114         bt = T_OBJECT;
2115       }
2116     }
2117   }
2118   return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY);


2119 }
2120 
2121 // Returns unique pointed java object or NULL.
2122 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
2123   assert(!_collecting, "should not call when contructed graph");
2124   // If the node was created after the escape computation we can't answer.
2125   uint idx = n->_idx;
2126   if (idx >= nodes_size()) {
2127     return NULL;
2128   }
2129   PointsToNode* ptn = ptnode_adr(idx);
2130   if (ptn->is_JavaObject()) {
2131     return ptn->as_JavaObject();
2132   }
2133   assert(ptn->is_LocalVar(), "sanity");
2134   // Check all java objects it points to.
2135   JavaObjectNode* jobj = NULL;
2136   for (EdgeIterator i(ptn); i.has_next(); i.next()) {
2137     PointsToNode* e = i.get();
2138     if (e->is_JavaObject()) {


3166       } else if (use->is_Mem()) {
3167         assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path");
3168       } else if (use->is_MergeMem()) {
3169         assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
3170       } else if (use->is_SafePoint()) {
3171         // Look for MergeMem nodes for calls which reference unique allocation
3172         // (through CheckCastPP nodes) even for debug info.
3173         Node* m = use->in(TypeFunc::Memory);
3174         if (m->is_MergeMem()) {
3175           assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist");
3176         }
3177       } else if (use->Opcode() == Op_EncodeISOArray) {
3178         if (use->in(MemNode::Memory) == n || use->in(3) == n) {
3179           // EncodeISOArray overwrites destination array
3180           memnode_worklist.append_if_missing(use);
3181         }
3182       } else if (use->Opcode() == Op_Return) {
3183         assert(_compile->tf()->returns_value_type_as_fields(), "must return a value type");
3184         // Get ValueKlass by removing the tag bit from the metadata pointer
3185         Node* klass = use->in(TypeFunc::Parms);
3186         intptr_t ptr = (intptr_t)igvn->find_intptr_t_con(klass, -1);
3187         clear_nth_bit(ptr, 0);
3188         assert(Metaspace::contains((void*)ptr), "should be klass");
3189         assert(((ValueKlass*)ptr)->contains_oops(), "returned value type must contain a reference field");
3190       } else {
3191         uint op = use->Opcode();
3192         if ((op == Op_StrCompressedCopy || op == Op_StrInflatedCopy) &&
3193             (use->in(MemNode::Memory) == n)) {
3194           // They overwrite memory edge corresponding to destination array,
3195           memnode_worklist.append_if_missing(use);
3196         } else if (!(op == Op_CmpP || op == Op_Conv2B ||
3197               op == Op_CastP2X || op == Op_StoreCM ||
3198               op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
3199               op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
3200               op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar ||
3201               op == Op_ValueType)) {
3202           n->dump();
3203           use->dump();
3204           assert(false, "EA: missing allocation reference path");
3205         }
3206 #endif




2080     if (adr_type->isa_instptr() || adr_type->isa_valuetypeptr()) {
2081       ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2082       if (field != NULL) {
2083         bt = field->layout_type();
2084       } else {
2085         // Check for unsafe oop field access
2086         if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2087             n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2088             n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2089           bt = T_OBJECT;
2090           (*unsafe) = true;
2091         }
2092       }
2093     } else if (adr_type->isa_aryptr()) {
2094       if (offset == arrayOopDesc::length_offset_in_bytes()) {
2095         // Ignore array length load.
2096       } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2097         // Ignore first AddP.
2098       } else {
2099         const Type* elemtype = adr_type->isa_aryptr()->elem();
2100         if (elemtype->isa_valuetype() && field_offset != Type::OffsetBot) {

2101           ciValueKlass* vk = elemtype->is_valuetype()->value_klass();
2102           field_offset += vk->first_field_offset();
2103           bt = vk->get_field_by_offset(field_offset, false)->layout_type();
2104         } else {
2105           bt = elemtype->array_element_basic_type();
2106         }
2107       }
2108     } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
2109       // Allocation initialization, ThreadLocal field access, unsafe access
2110       if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2111           n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2112           n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2113         bt = T_OBJECT;
2114       }
2115     }
2116   }
2117   // TODO enable when using T_VALUETYPEPTR
2118   //assert(bt != T_VALUETYPE, "should not have valuetype here");
2119   return (bt == T_OBJECT || bt == T_VALUETYPE || bt == T_VALUETYPEPTR || bt == T_NARROWOOP || bt == T_ARRAY);
2120 }
2121 
2122 // Returns unique pointed java object or NULL.
2123 JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
2124   assert(!_collecting, "should not call when contructed graph");
2125   // If the node was created after the escape computation we can't answer.
2126   uint idx = n->_idx;
2127   if (idx >= nodes_size()) {
2128     return NULL;
2129   }
2130   PointsToNode* ptn = ptnode_adr(idx);
2131   if (ptn->is_JavaObject()) {
2132     return ptn->as_JavaObject();
2133   }
2134   assert(ptn->is_LocalVar(), "sanity");
2135   // Check all java objects it points to.
2136   JavaObjectNode* jobj = NULL;
2137   for (EdgeIterator i(ptn); i.has_next(); i.next()) {
2138     PointsToNode* e = i.get();
2139     if (e->is_JavaObject()) {


3167       } else if (use->is_Mem()) {
3168         assert(use->in(MemNode::Address) != n, "EA: missing allocation reference path");
3169       } else if (use->is_MergeMem()) {
3170         assert(_mergemem_worklist.contains(use->as_MergeMem()), "EA: missing MergeMem node in the worklist");
3171       } else if (use->is_SafePoint()) {
3172         // Look for MergeMem nodes for calls which reference unique allocation
3173         // (through CheckCastPP nodes) even for debug info.
3174         Node* m = use->in(TypeFunc::Memory);
3175         if (m->is_MergeMem()) {
3176           assert(_mergemem_worklist.contains(m->as_MergeMem()), "EA: missing MergeMem node in the worklist");
3177         }
3178       } else if (use->Opcode() == Op_EncodeISOArray) {
3179         if (use->in(MemNode::Memory) == n || use->in(3) == n) {
3180           // EncodeISOArray overwrites destination array
3181           memnode_worklist.append_if_missing(use);
3182         }
3183       } else if (use->Opcode() == Op_Return) {
3184         assert(_compile->tf()->returns_value_type_as_fields(), "must return a value type");
3185         // Get ValueKlass by removing the tag bit from the metadata pointer
3186         Node* klass = use->in(TypeFunc::Parms);
3187         intptr_t ptr = igvn->type(klass)->isa_rawptr()->get_con();
3188         clear_nth_bit(ptr, 0);
3189         assert(Metaspace::contains((void*)ptr), "should be klass");
3190         assert(((ValueKlass*)ptr)->contains_oops(), "returned value type must contain a reference field");
3191       } else {
3192         uint op = use->Opcode();
3193         if ((op == Op_StrCompressedCopy || op == Op_StrInflatedCopy) &&
3194             (use->in(MemNode::Memory) == n)) {
3195           // They overwrite memory edge corresponding to destination array,
3196           memnode_worklist.append_if_missing(use);
3197         } else if (!(op == Op_CmpP || op == Op_Conv2B ||
3198               op == Op_CastP2X || op == Op_StoreCM ||
3199               op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || op == Op_HasNegatives ||
3200               op == Op_StrCompressedCopy || op == Op_StrInflatedCopy ||
3201               op == Op_StrEquals || op == Op_StrIndexOf || op == Op_StrIndexOfChar ||
3202               op == Op_ValueType)) {
3203           n->dump();
3204           use->dump();
3205           assert(false, "EA: missing allocation reference path");
3206         }
3207 #endif


< prev index next >