< prev index next >

src/share/vm/opto/escape.cpp

Print this page

        

*** 2050,2061 **** dst->set_arraycopy_dst(); } bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) { const Type* adr_type = n->as_AddP()->bottom_type(); BasicType bt = T_INT; ! if (offset == Type::OffsetBot) { // Check only oop fields. if (!adr_type->isa_aryptr() || (adr_type->isa_aryptr()->klass() == NULL) || adr_type->isa_aryptr()->klass()->is_obj_array_klass()) { // OffsetBot is used to reference array's element. Ignore first AddP. --- 2050,2062 ---- dst->set_arraycopy_dst(); } bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) { const Type* adr_type = n->as_AddP()->bottom_type(); + int field_offset = adr_type->isa_aryptr() ? adr_type->isa_aryptr()->field_offset().get() : Type::OffsetBot; BasicType bt = T_INT; ! if (offset == Type::OffsetBot && field_offset == Type::OffsetBot) { // Check only oop fields. if (!adr_type->isa_aryptr() || (adr_type->isa_aryptr()->klass() == NULL) || adr_type->isa_aryptr()->klass()->is_obj_array_klass()) { // OffsetBot is used to reference array's element. Ignore first AddP.
*** 2080,2091 **** --- 2081,2099 ---- // Ignore array length load. } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) { // Ignore first AddP. } else { const Type* elemtype = adr_type->isa_aryptr()->elem(); + if (elemtype->isa_valuetype()) { + assert(field_offset != Type::OffsetBot, "invalid field offset"); + ciValueKlass* vk = elemtype->is_valuetype()->value_klass(); + field_offset += vk->first_field_offset(); + bt = vk->get_field_by_offset(field_offset, false)->layout_type(); + } else { bt = elemtype->array_element_basic_type(); } + } } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) { // Allocation initialization, ThreadLocal field access, unsafe access if (n->has_out_with(Op_StoreP, Op_LoadP, Op_StoreN, Op_LoadN)) { bt = T_OBJECT; }
*** 2403,2413 **** } const TypePtr* tinst = base_t->add_offset(t->offset()); if (tinst->isa_aryptr() && t->isa_aryptr()) { // In the case of a flattened value type array, each field has its // own slice so we need to keep track of the field being accessed. ! tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset()); } // Do NOT remove the next line: ensure a new alias index is allocated // for the instance type. Note: C++ will not remove it since the call // has side effect. --- 2411,2421 ---- } const TypePtr* tinst = base_t->add_offset(t->offset()); if (tinst->isa_aryptr() && t->isa_aryptr()) { // In the case of a flattened value type array, each field has its // own slice so we need to keep track of the field being accessed. ! tinst = tinst->is_aryptr()->with_field_offset(t->is_aryptr()->field_offset().get()); } // Do NOT remove the next line: ensure a new alias index is allocated // for the instance type. Note: C++ will not remove it since the call // has side effect.
< prev index next >