< prev index next >

src/share/vm/opto/escape.cpp

Print this page

        

*** 882,892 **** // it's fields will be marked as NoEscape at least. add_java_object(call, PointsToNode::NoEscape); ptnode_adr(call_idx)->set_scalar_replaceable(false); } else { // Determine whether any arguments are returned. ! const TypeTuple* d = call->tf()->domain_sig(); bool ret_arg = false; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { if (d->field_at(i)->isa_ptr() != NULL && call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { ret_arg = true; --- 882,892 ---- // it's fields will be marked as NoEscape at least. add_java_object(call, PointsToNode::NoEscape); ptnode_adr(call_idx)->set_scalar_replaceable(false); } else { // Determine whether any arguments are returned. ! const TypeTuple* d = call->tf()->domain_cc(); bool ret_arg = false; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { if (d->field_at(i)->isa_ptr() != NULL && call_analyzer->is_arg_returned(i - TypeFunc::Parms)) { ret_arg = true;
*** 1057,1076 **** } BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL; // fall-through if not a Java method or no analyzer information if (call_analyzer != NULL) { PointsToNode* call_ptn = ptnode_adr(call->_idx); ! const TypeTuple* d = call->tf()->domain_sig(); ! int extra = 0; for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); - if (at->isa_valuetypeptr()) { - extra += at->is_valuetypeptr()->value_type()->value_klass()->field_count() - 1; - continue; - } int k = i - TypeFunc::Parms; ! Node* arg = call->in(i + extra); PointsToNode* arg_ptn = ptnode_adr(arg->_idx); if (at->isa_ptr() != NULL && call_analyzer->is_arg_returned(k)) { // The call returns arguments. if (call_ptn != NULL) { // Is call's result used? --- 1057,1071 ---- } BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL; // fall-through if not a Java method or no analyzer information if (call_analyzer != NULL) { PointsToNode* call_ptn = ptnode_adr(call->_idx); ! const TypeTuple* d = call->tf()->domain_cc(); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); int k = i - TypeFunc::Parms; ! Node* arg = call->in(i); PointsToNode* arg_ptn = ptnode_adr(arg->_idx); if (at->isa_ptr() != NULL && call_analyzer->is_arg_returned(k)) { // The call returns arguments. if (call_ptn != NULL) { // Is call's result used?
*** 1106,1116 **** } default: { // Fall-through here if not a Java method or no analyzer information // or some other type of call, assume the worst case: all arguments // globally escape. ! const TypeTuple* d = call->tf()->domain_sig(); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); if (at->isa_oopptr() != NULL) { Node* arg = call->in(i); if (arg->is_AddP()) { --- 1101,1111 ---- } default: { // Fall-through here if not a Java method or no analyzer information // or some other type of call, assume the worst case: all arguments // globally escape. ! const TypeTuple* d = call->tf()->domain_cc(); for (uint i = TypeFunc::Parms; i < d->cnt(); i++) { const Type* at = d->field_at(i); if (at->isa_oopptr() != NULL) { Node* arg = call->in(i); if (arg->is_AddP()) {
*** 2052,2063 **** 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. --- 2047,2059 ---- 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.
*** 2084,2095 **** --- 2080,2098 ---- // 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) || n->has_out_with(Op_GetAndSetP, Op_GetAndSetN, Op_CompareAndExchangeP, Op_CompareAndExchangeN) || n->has_out_with(Op_CompareAndSwapP, Op_CompareAndSwapN, Op_WeakCompareAndSwapP, Op_WeakCompareAndSwapN)) {
*** 2409,2419 **** } 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. --- 2412,2422 ---- } 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 >