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
|