2063 // Add edge from destination object to arraycopy node.
2064 (void)add_edge(dst, ptadr);
2065 dst->set_arraycopy_dst();
2066 }
2067
2068 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
2069 const Type* adr_type = n->as_AddP()->bottom_type();
2070 int field_offset = adr_type->isa_aryptr() ? adr_type->isa_aryptr()->field_offset().get() : Type::OffsetBot;
2071 BasicType bt = T_INT;
2072 if (offset == Type::OffsetBot && field_offset == Type::OffsetBot) {
2073 // Check only oop fields.
2074 if (!adr_type->isa_aryptr() ||
2075 (adr_type->isa_aryptr()->klass() == NULL) ||
2076 adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
2077 // OffsetBot is used to reference array's element. Ignore first AddP.
2078 if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
2079 bt = T_OBJECT;
2080 }
2081 }
2082 } else if (offset != oopDesc::klass_offset_in_bytes()) {
2083 if (adr_type->isa_instptr() || adr_type->isa_valuetypeptr()) {
2084 ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2085 if (field != NULL) {
2086 bt = field->layout_type();
2087 } else {
2088 // Check for unsafe oop field access
2089 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2090 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2091 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2092 bt = T_OBJECT;
2093 (*unsafe) = true;
2094 }
2095 }
2096 } else if (adr_type->isa_aryptr()) {
2097 if (offset == arrayOopDesc::length_offset_in_bytes()) {
2098 // Ignore array length load.
2099 } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2100 // Ignore first AddP.
2101 } else {
2102 const Type* elemtype = adr_type->isa_aryptr()->elem();
2103 if (elemtype->isa_valuetype() && field_offset != Type::OffsetBot) {
3024 }
3025 if (alloc->is_CallStaticJava()) {
3026 // Set the scalar_replaceable flag for boxing method
3027 // so it could be eliminated.
3028 alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
3029 }
3030 set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
3031 // in order for an object to be scalar-replaceable, it must be:
3032 // - a direct allocation (not a call returning an object)
3033 // - non-escaping
3034 // - eligible to be a unique type
3035 // - not determined to be ineligible by escape analysis
3036 set_map(alloc, n);
3037 set_map(n, alloc);
3038 const TypeOopPtr* tinst = t->cast_to_instance_id(ni);
3039 igvn->hash_delete(n);
3040 igvn->set_type(n, tinst);
3041 n->raise_bottom_type(tinst);
3042 igvn->hash_insert(n);
3043 record_for_optimizer(n);
3044 if (alloc->is_Allocate() && (t->isa_instptr() || t->isa_aryptr() || t->isa_valuetypeptr())) {
3045
3046 // First, put on the worklist all Field edges from Connection Graph
3047 // which is more accurate than putting immediate users from Ideal Graph.
3048 for (EdgeIterator e(ptn); e.has_next(); e.next()) {
3049 PointsToNode* tgt = e.get();
3050 if (tgt->is_Arraycopy()) {
3051 continue;
3052 }
3053 Node* use = tgt->ideal_node();
3054 assert(tgt->is_Field() && use->is_AddP(),
3055 "only AddP nodes are Field edges in CG");
3056 if (use->outcnt() > 0) { // Don't process dead nodes
3057 Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
3058 if (addp2 != NULL) {
3059 assert(alloc->is_AllocateArray(),"array allocation was expected");
3060 alloc_worklist.append_if_missing(addp2);
3061 }
3062 alloc_worklist.append_if_missing(use);
3063 }
3064 }
|
2063 // Add edge from destination object to arraycopy node.
2064 (void)add_edge(dst, ptadr);
2065 dst->set_arraycopy_dst();
2066 }
2067
2068 bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
2069 const Type* adr_type = n->as_AddP()->bottom_type();
2070 int field_offset = adr_type->isa_aryptr() ? adr_type->isa_aryptr()->field_offset().get() : Type::OffsetBot;
2071 BasicType bt = T_INT;
2072 if (offset == Type::OffsetBot && field_offset == Type::OffsetBot) {
2073 // Check only oop fields.
2074 if (!adr_type->isa_aryptr() ||
2075 (adr_type->isa_aryptr()->klass() == NULL) ||
2076 adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
2077 // OffsetBot is used to reference array's element. Ignore first AddP.
2078 if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
2079 bt = T_OBJECT;
2080 }
2081 }
2082 } else if (offset != oopDesc::klass_offset_in_bytes()) {
2083 if (adr_type->isa_instptr()) {
2084 ciField* field = _compile->alias_type(adr_type->is_ptr())->field();
2085 if (field != NULL) {
2086 bt = field->layout_type();
2087 } else {
2088 // Check for unsafe oop field access
2089 if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN) ||
2090 n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) ||
2091 n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
2092 bt = T_OBJECT;
2093 (*unsafe) = true;
2094 }
2095 }
2096 } else if (adr_type->isa_aryptr()) {
2097 if (offset == arrayOopDesc::length_offset_in_bytes()) {
2098 // Ignore array length load.
2099 } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
2100 // Ignore first AddP.
2101 } else {
2102 const Type* elemtype = adr_type->isa_aryptr()->elem();
2103 if (elemtype->isa_valuetype() && field_offset != Type::OffsetBot) {
3024 }
3025 if (alloc->is_CallStaticJava()) {
3026 // Set the scalar_replaceable flag for boxing method
3027 // so it could be eliminated.
3028 alloc->as_CallStaticJava()->_is_scalar_replaceable = true;
3029 }
3030 set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
3031 // in order for an object to be scalar-replaceable, it must be:
3032 // - a direct allocation (not a call returning an object)
3033 // - non-escaping
3034 // - eligible to be a unique type
3035 // - not determined to be ineligible by escape analysis
3036 set_map(alloc, n);
3037 set_map(n, alloc);
3038 const TypeOopPtr* tinst = t->cast_to_instance_id(ni);
3039 igvn->hash_delete(n);
3040 igvn->set_type(n, tinst);
3041 n->raise_bottom_type(tinst);
3042 igvn->hash_insert(n);
3043 record_for_optimizer(n);
3044 if (alloc->is_Allocate() && (t->isa_instptr() || t->isa_aryptr())) {
3045
3046 // First, put on the worklist all Field edges from Connection Graph
3047 // which is more accurate than putting immediate users from Ideal Graph.
3048 for (EdgeIterator e(ptn); e.has_next(); e.next()) {
3049 PointsToNode* tgt = e.get();
3050 if (tgt->is_Arraycopy()) {
3051 continue;
3052 }
3053 Node* use = tgt->ideal_node();
3054 assert(tgt->is_Field() && use->is_AddP(),
3055 "only AddP nodes are Field edges in CG");
3056 if (use->outcnt() > 0) { // Don't process dead nodes
3057 Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
3058 if (addp2 != NULL) {
3059 assert(alloc->is_AllocateArray(),"array allocation was expected");
3060 alloc_worklist.append_if_missing(addp2);
3061 }
3062 alloc_worklist.append_if_missing(use);
3063 }
3064 }
|