< prev index next >

src/share/vm/opto/valuetypenode.cpp

Print this page

        

*** 367,377 **** --i; imax -= nb; } } } ! uint ValueTypeNode::set_arguments_for_java_call(CallJavaNode* call, int base_input, const GraphKit& kit, ciValueKlass* base_vk, int base_offset) { ciValueKlass* vk = value_klass(); if (base_vk == NULL) { base_vk = vk; } uint edges = 0; --- 367,384 ---- --i; imax -= nb; } } } ! void ValueTypeNode::pass_klass(Node* n, uint pos, const GraphKit& kit) { ! ciValueKlass* vk = value_klass(); ! const TypeKlassPtr* tk = TypeKlassPtr::make(vk); ! Node* arg = kit.makecon(tk); ! n->init_req(pos, arg); ! } ! ! uint ValueTypeNode::pass_fields(Node* n, int base_input, const GraphKit& kit, ciValueKlass* base_vk, int base_offset) { ciValueKlass* vk = value_klass(); if (base_vk == NULL) { base_vk = vk; } uint edges = 0;
*** 379,389 **** ciType* f_type = field_type(i); int offset = base_offset + field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0); Node* arg = field_value(i); if (f_type->is_valuetype()) { ciValueKlass* embedded_vk = f_type->as_value_klass(); ! edges += arg->as_ValueType()->set_arguments_for_java_call(call, base_input, kit, base_vk, offset); } else { int j = 0; int extra = 0; for (; j < base_vk->nof_nonstatic_fields(); j++) { ciField* f = base_vk->nonstatic_field_at(j); if (offset == f->offset()) { --- 386,396 ---- ciType* f_type = field_type(i); int offset = base_offset + field_offset(i) - (base_offset > 0 ? vk->first_field_offset() : 0); Node* arg = field_value(i); if (f_type->is_valuetype()) { ciValueKlass* embedded_vk = f_type->as_value_klass(); ! edges += arg->as_ValueType()->pass_fields(n, base_input, kit, base_vk, offset); } else { int j = 0; int extra = 0; for (; j < base_vk->nof_nonstatic_fields(); j++) { ciField* f = base_vk->nonstatic_field_at(j); if (offset == f->offset()) {
*** 393,407 **** BasicType bt = f->type()->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { extra++; } } ! call->init_req(base_input + j + extra, arg); edges++; BasicType bt = f_type->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { ! call->init_req(base_input + j + extra + 1, kit.top()); edges++; } } } return edges; --- 400,414 ---- BasicType bt = f->type()->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { extra++; } } ! n->init_req(base_input + j + extra, arg); edges++; BasicType bt = f_type->basic_type(); if (bt == T_LONG || bt == T_DOUBLE) { ! n->init_req(base_input + j + extra + 1, kit.top()); edges++; } } } return edges;
*** 425,434 **** --- 432,472 ---- } return NULL; } + // When a call returns multiple values, it has several result + // projections, one per field. Replacing the result of the call by a + // value type node (after late inlining) requires that for each result + // projection, we find the corresponding value type field. + void ValueTypeNode::replace_call_results(Node* call, Compile* C) { + ciValueKlass* vk = value_klass(); + for (DUIterator_Fast imax, i = call->fast_outs(imax); i < imax; i++) { + ProjNode *pn = call->fast_out(i)->as_Proj(); + uint con = pn->_con; + if (con >= TypeFunc::Parms+1) { + uint field_nb = con - (TypeFunc::Parms+1); + int extra = 0; + for (uint j = 0; j < field_nb - extra; j++) { + ciField* f = vk->nonstatic_field_at(j); + BasicType bt = f->type()->basic_type(); + if (bt == T_LONG || bt == T_DOUBLE) { + extra++; + } + } + ciField* f = vk->nonstatic_field_at(field_nb - extra); + Node* field = field_value_by_offset(f->offset(), true); + + C->gvn_replace_by(pn, field); + C->initial_gvn()->hash_delete(pn); + pn->set_req(0, C->top()); + --i; --imax; + } + } + } + + #ifndef PRODUCT void ValueTypeNode::dump_spec(outputStream* st) const { TypeNode::dump_spec(st); }
< prev index next >