< prev index next >

src/hotspot/share/opto/graphKit.cpp

Print this page

        

@@ -47,18 +47,25 @@
 #include "runtime/deoptimization.hpp"
 #include "runtime/sharedRuntime.hpp"
 
 //----------------------------GraphKit-----------------------------------------
 // Main utility constructor.
-GraphKit::GraphKit(JVMState* jvms)
+GraphKit::GraphKit(JVMState* jvms, PhaseGVN* gvn)
   : Phase(Phase::Parser),
     _env(C->env()),
-    _gvn(*C->initial_gvn())
+    _gvn((gvn != NULL) ? *gvn : *C->initial_gvn())
 {
   _exceptions = jvms->map()->next_exception();
   if (_exceptions != NULL)  jvms->map()->set_next_exception(NULL);
   set_jvms(jvms);
+#ifdef ASSERT
+  if (_gvn.is_IterGVN() != NULL) {
+    assert(_gvn.is_IterGVN()->delay_transform(), "Transformation must be delayed if IterGVN is used");
+    // Save the initial size of _for_igvn worklist for verification (see ~GraphKit)
+    _worklist_size = _gvn.C->for_igvn()->size();
+  }
+#endif
 }
 
 // Private constructor for parser.
 GraphKit::GraphKit()
   : Phase(Phase::Parser),

@@ -1381,22 +1388,12 @@
   } else {
     ld = LoadNode::make(_gvn, ctl, mem, adr, adr_type, t, bt, mo, control_dependency, unaligned, mismatched);
   }
   ld = _gvn.transform(ld);
   if (bt == T_VALUETYPE) {
-    // Load non-flattened value type from memory. Add a null check and let the
-    // interpreter take care of initializing the field to the default value type.
-    Node* null_ctl = top();
-    ld = null_check_common(ld, bt, false, &null_ctl, false);
-    if (null_ctl != top()) {
-      assert(!adr_type->isa_aryptr(), "value type array must be initialized");
-      PreserveJVMState pjvms(this);
-      set_control(null_ctl);
-      uncommon_trap(Deoptimization::reason_null_check(false), Deoptimization::Action_maybe_recompile,
-                    t->is_valuetypeptr()->value_type()->value_klass(), "uninitialized non-flattened value type");
-    }
-    ld = ValueTypeNode::make(gvn(), map()->memory(), ld);
+    // Loading a non-flattened value type from memory requires a null check.
+    ld = ValueTypeNode::make(this, ld, true /* null check */);
   } else if (((bt == T_OBJECT) && C->do_escape_analysis()) || C->eliminate_boxing()) {
     // Improve graph before escape analysis and boxing elimination.
     record_for_igvn(ld);
   }
   return ld;

@@ -1533,13 +1530,13 @@
   assert(bt == T_OBJECT || bt == T_VALUETYPE, "sanity");
   assert(val != NULL, "not dead path");
   uint adr_idx = C->get_alias_index(adr_type);
   assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
 
-  if (bt == T_VALUETYPE) {
-    // Allocate value type and store oop
-    val = val->as_ValueType()->allocate(this);
+  if (val->is_ValueType()) {
+    // Allocate value type and get oop
+    val = val->as_ValueType()->allocate(this)->get_oop();
   }
 
   pre_barrier(true /* do_load */,
               control(), obj, adr, adr_idx, val, val_type,
               NULL /* pre_val */,

@@ -1628,31 +1625,31 @@
   for (uint i = TypeFunc::Parms, idx = TypeFunc::Parms; i < nargs; i++) {
     Node* arg = argument(i-TypeFunc::Parms);
     if (ValueTypePassFieldsAsArgs) {
       if (arg->is_ValueType()) {
         ValueTypeNode* vt = arg->as_ValueType();
-        if (domain->field_at(i)->is_valuetypeptr()->klass() != C->env()->___Value_klass()) {
+        if (!domain->field_at(i)->is_valuetypeptr()->is__Value()) {
           // We don't pass value type arguments by reference but instead
           // pass each field of the value type
           idx += vt->pass_fields(call, idx, *this);
           // If a value type argument is passed as fields, attach the Method* to the call site
           // to be able to access the extended signature later via attached_method_before_pc().
           // For example, see CompiledMethod::preserve_callee_argument_oops().
           call->set_override_symbolic_info(true);
         } else {
-          arg = arg->as_ValueType()->allocate(this);
+          arg = arg->as_ValueType()->allocate(this)->get_oop();
           call->init_req(idx, arg);
           idx++;
         }
       } else {
         call->init_req(idx, arg);
         idx++;
       }
     } else {
       if (arg->is_ValueType()) {
         // Pass value type argument via oop to callee
-        arg = arg->as_ValueType()->allocate(this);
+        arg = arg->as_ValueType()->allocate(this)->get_oop();
       }
       call->init_req(i, arg);
     }
   }
 }

@@ -1689,41 +1686,44 @@
 }
 
 Node* GraphKit::set_results_for_java_call(CallJavaNode* call, bool separate_io_proj) {
   if (stopped())  return top();  // maybe the call folded up?
 
+  // Note:  Since any out-of-line call can produce an exception,
+  // we always insert an I_O projection from the call into the result.
+
+  make_slow_call_ex(call, env()->Throwable_klass(), separate_io_proj);
+
+  if (separate_io_proj) {
+    // The caller requested separate projections be used by the fall
+    // through and exceptional paths, so replace the projections for
+    // the fall through path.
+    set_i_o(_gvn.transform( new ProjNode(call, TypeFunc::I_O) ));
+    set_all_memory(_gvn.transform( new ProjNode(call, TypeFunc::Memory) ));
+  }
+
   // Capture the return value, if any.
   Node* ret;
   if (call->method() == NULL ||
-      call->method()->return_type()->basic_type() == T_VOID)
+      call->method()->return_type()->basic_type() == T_VOID) {
         ret = top();
-  else {
+  } else {
     if (!call->tf()->returns_value_type_as_fields()) {
       ret = _gvn.transform(new ProjNode(call, TypeFunc::Parms));
     } else {
       // Return of multiple values (value type fields): we create a
       // ValueType node, each field is a projection from the call.
-      const TypeTuple *range_sig = call->tf()->range_sig();
+      const TypeTuple* range_sig = call->tf()->range_sig();
       const Type* t = range_sig->field_at(TypeFunc::Parms);
       assert(t->isa_valuetypeptr(), "only value types for multiple return values");
       ciValueKlass* vk = t->is_valuetypeptr()->value_type()->value_klass();
-      ret = ValueTypeNode::make(_gvn, call, vk, TypeFunc::Parms+1, false);
+      Node* ctl = control();
+      ret = ValueTypeNode::make(_gvn, ctl, merged_memory(), call, vk, TypeFunc::Parms+1, false);
+      set_control(ctl);
     }
   }
 
-  // Note:  Since any out-of-line call can produce an exception,
-  // we always insert an I_O projection from the call into the result.
-
-  make_slow_call_ex(call, env()->Throwable_klass(), separate_io_proj);
-
-  if (separate_io_proj) {
-    // The caller requested separate projections be used by the fall
-    // through and exceptional paths, so replace the projections for
-    // the fall through path.
-    set_i_o(_gvn.transform( new ProjNode(call, TypeFunc::I_O) ));
-    set_all_memory(_gvn.transform( new ProjNode(call, TypeFunc::Memory) ));
-  }
   return ret;
 }
 
 //--------------------set_predefined_input_for_runtime_call--------------------
 // Reading and setting the memory state is way conservative here.

@@ -3395,11 +3395,11 @@
 //  - deoptimize_on_exception controls how Java exceptions are handled (rethrow vs deoptimize)
 Node* GraphKit::new_instance(Node* klass_node,
                              Node* extra_slow_test,
                              Node* *return_size_val,
                              bool deoptimize_on_exception,
-                             ValueTypeNode* value_node) {
+                             ValueTypeBaseNode* value_node) {
   // Compute size in doublewords
   // The size is always an integral number of doublewords, represented
   // as a positive bytewise size stored in the klass's layout_helper.
   // The layout_helper also encodes (in a low bit) the need for a slow path.
   jint  layout_con = Klass::_lh_neutral_value;

@@ -3691,11 +3691,11 @@
   SafePointNode* loop_map = NULL;
   {
     PreserveJVMState pjvms(this);
     // Create default value type and store it to memory
     Node* oop = ValueTypeNode::make_default(gvn(), vk);
-    oop = oop->as_ValueType()->allocate(this);
+    oop = oop->as_ValueType()->allocate(this)->get_oop();
 
     length = SubI(length, intcon(1));
     add_predicate(nargs);
     RegionNode* loop = new RegionNode(3);
     loop->init_req(1, control());

@@ -4562,11 +4562,11 @@
                                                         /*is_unsigned_load=*/false);
   if (con_type != NULL) {
     Node* con = makecon(con_type);
     if (field->layout_type() == T_VALUETYPE) {
       // Load value type from constant oop
-      con = ValueTypeNode::make(gvn(), map()->memory(), con);
+      con = ValueTypeNode::make(this, con);
     }
     return con;
   }
   return NULL;
 }
< prev index next >