< prev index next >

src/share/vm/opto/parse1.cpp

Print this page

        

@@ -779,45 +779,118 @@
     _exits.set_argument(0, ret_phi);  // here is where the parser finds it
     // Note:  ret_phi is not yet pushed, until do_exits.
   }
 }
 
+// Helper function to create a ValueTypeNode from its fields passed as
+// arguments. Fields are passed in order of increasing offsets.
+static Node* create_vt_node(StartNode* start, ciValueKlass* vk, ciValueKlass* base_vk, int base_offset, int base_input, Compile* C) {
+  assert(base_offset >= 0, "");
+  PhaseGVN& gvn = *C->initial_gvn();
+  ValueTypeNode* vt = ValueTypeNode::make(gvn, vk);
+  for (uint i = 0; i < vt->field_count(); i++) {
+    ciType* field_type = vt->get_field_type(i);
+    int offset = base_offset + vt->get_field_offset(i) - (base_offset > 0 ? vk->get_first_field_offset() : 0);
+    if (field_type->is_valuetype()) {
+      ciValueKlass* embedded_vk = field_type->as_value_klass();
+      Node* embedded_vt = create_vt_node(start, embedded_vk, base_vk, offset, base_input, C);
+      vt->set_field_value(i, embedded_vt);
+    } 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()) {
+          assert(f->type() == field_type, "");
+          break;
+        }
+        BasicType bt = f->type()->basic_type();
+        if (bt == T_LONG || bt == T_DOUBLE) {
+          extra++;
+        }
+      }
+      assert(j != base_vk->nof_nonstatic_fields(), "must find");
+      Node* parm = gvn.transform(new ParmNode(start, base_input + j + extra));
+      vt->set_field_value(i, parm);
+      // Record all these guys for later GVN.
+      C->record_for_igvn(parm);
+    }
+  }
+  return gvn.transform(vt);
+}
 
 //----------------------------build_start_state-------------------------------
 // Construct a state which contains only the incoming arguments from an
 // unknown caller.  The method & bci will be NULL & InvocationEntryBci.
 JVMState* Compile::build_start_state(StartNode* start, const TypeFunc* tf) {
-  int        arg_size = tf->domain()->cnt();
-  int        max_size = MAX2(arg_size, (int)tf->range()->cnt());
+  int        arg_size_sig = tf->domain_sig()->cnt();
+  int        max_size = MAX2(arg_size_sig, (int)tf->range()->cnt());
   JVMState*  jvms     = new (this) JVMState(max_size - TypeFunc::Parms);
   SafePointNode* map  = new SafePointNode(max_size, NULL);
   record_for_igvn(map);
-  assert(arg_size == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size");
+  assert(arg_size_sig == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size");
   Node_Notes* old_nn = default_node_notes();
   if (old_nn != NULL && has_method()) {
     Node_Notes* entry_nn = old_nn->clone(this);
     JVMState* entry_jvms = new(this) JVMState(method(), old_nn->jvms());
     entry_jvms->set_offsets(0);
     entry_jvms->set_bci(entry_bci());
     entry_nn->set_jvms(entry_jvms);
     set_default_node_notes(entry_nn);
   }
-  uint i;
-  for (i = 0; i < (uint)arg_size; i++) {
     PhaseGVN& gvn = *initial_gvn();
+  uint j = 0;
+  for (uint i = 0; i < (uint)arg_size_sig; i++) {
+    assert(j >= i, "");
+    if (ValueTypePassFieldsAsArgs) {
+      if (i < TypeFunc::Parms) {
+        assert(i == j, "");
+        Node* parm = gvn.transform(new ParmNode(start, i));
+        map->init_req(i, parm);
+        // Record all these guys for later GVN.
+        record_for_igvn(parm);
+        j++;
+      } else {
+        // Value type arguments are not passed by reference: we get an
+        // argument per field of the value type. Build ValueTypeNodes
+        // from the value type arguments.
+        const Type* t = tf->domain_sig()->field_at(i);
+        if (t->isa_valuetypeptr()) {
+          ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
+          Node* vt = create_vt_node(start, vk, vk, 0, j, C);
+          map->init_req(i, gvn.transform(vt));
+          int extra = 0;
+          for (int k = 0; k < vk->nof_nonstatic_fields(); k++) {
+            ciField* f = vk->nonstatic_field_at(k);
+            BasicType bt = f->type()->basic_type();
+            if (bt == T_LONG || bt == T_DOUBLE) {
+              extra++;
+            }
+          }
+          j += extra + vk->nof_nonstatic_fields();
+        } else {
+          Node* parm = gvn.transform(new ParmNode(start, j));
+          map->init_req(i, parm);
+          // Record all these guys for later GVN.
+          record_for_igvn(parm);
+          j++;
+        }
+      }
+    } else {
     Node* parm = gvn.transform(new ParmNode(start, i));
     // Check if parameter is a value type pointer
     if (gvn.type(parm)->isa_valuetypeptr()) {
       // Create ValueTypeNode from the oop and replace the parameter
       parm = ValueTypeNode::make(gvn, map->memory(), parm);
     }
     map->init_req(i, parm);
     // Record all these guys for later GVN.
     record_for_igvn(parm);
+     j++;
+    }
   }
-  for (; i < map->req(); i++) {
-    map->init_req(i, top());
+  for (; j < map->req(); j++) {
+    map->init_req(j, top());
   }
   assert(jvms->argoff() == TypeFunc::Parms, "parser gets arguments here");
   set_default_node_notes(old_nn);
   map->set_jvms(jvms);
   jvms->set_map(map);

@@ -1152,11 +1225,11 @@
     set_all_memory(reset_memory());
   }
   assert(merged_memory(), "");
 
   // Now add the locals which are initially bound to arguments:
-  uint arg_size = tf()->domain()->cnt();
+  uint arg_size = tf()->domain_sig()->cnt();
   ensure_stack(arg_size - TypeFunc::Parms);  // OSR methods have funny args
   for (i = TypeFunc::Parms; i < arg_size; i++) {
     map()->init_req(i, inmap->argument(_caller, i - TypeFunc::Parms));
   }
 
< prev index next >