< prev index next >
src/share/vm/opto/valuetypenode.cpp
Print this page
@@ -367,11 +367,18 @@
--i; imax -= nb;
}
}
}
-uint ValueTypeNode::set_arguments_for_java_call(CallJavaNode* call, int base_input, const GraphKit& kit, ciValueKlass* base_vk, int base_offset) {
+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,11 +386,11 @@
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);
+ 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,15 +400,15 @@
BasicType bt = f->type()->basic_type();
if (bt == T_LONG || bt == T_DOUBLE) {
extra++;
}
}
- call->init_req(base_input + j + extra, arg);
+ n->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());
+ n->init_req(base_input + j + extra + 1, kit.top());
edges++;
}
}
}
return edges;
@@ -425,10 +432,41 @@
}
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 >