< 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 >