Merge
authoriveresov
Wed, 03 Aug 2016 15:55:40 -0700
changeset 40337 0e9a027b0f8a
parent 40333 0dc2e9be4855 (current diff)
parent 40336 4f31bb2b0a5a (diff)
child 40338 d92668bfe3e8
child 40340 e12d8c4d181e
child 40342 708dedd4f894
child 40344 e73c2f13704d
Merge
hotspot/src/cpu/sparc/vm/frame_sparc.cpp
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Wed Aug 03 13:56:27 2016 -0700
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp	Wed Aug 03 15:55:40 2016 -0700
@@ -339,12 +339,6 @@
     _cb = CodeCache::find_blob(_pc);
   }
   _deopt_state = unknown;
-#ifdef ASSERT
-  if ( _cb != NULL && _cb->is_compiled()) {
-    // Without a valid unextended_sp() we can't convert the pc to "original"
-    assert(!((CompiledMethod*)_cb)->is_deopt_pc(_pc), "invariant broken");
-  }
-#endif // ASSERT
 }
 
 frame::frame(intptr_t* sp, unpatchable_t, address pc, CodeBlob* cb) {
@@ -516,6 +510,7 @@
 
 
 void frame::patch_pc(Thread* thread, address pc) {
+  vmassert(_deopt_state != unknown, "frame is unpatchable");
   if(thread == Thread::current()) {
    StubRoutines::Sparc::flush_callers_register_windows_func()();
   }
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Aug 03 13:56:27 2016 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Aug 03 15:55:40 2016 -0700
@@ -1703,29 +1703,51 @@
     }
 
     if (uncasted) {
-      // Add a cast node between the phi to be removed and its unique input.
+      // Add cast nodes between the phi to be removed and its unique input.
       // Wait until after parsing for the type information to propagate from the casts.
       assert(can_reshape, "Invalid during parsing");
       const Type* phi_type = bottom_type();
       assert(phi_type->isa_int() || phi_type->isa_ptr(), "bad phi type");
-      int opcode;
-      // Determine the type of cast to be added.
+      // Add casts to carry the control dependency of the Phi that is
+      // going away
+      Node* cast = NULL;
       if (phi_type->isa_int()) {
-        opcode = Op_CastII;
+        cast = ConstraintCastNode::make_cast(Op_CastII, r, uin, phi_type, true);
       } else {
         const Type* uin_type = phase->type(uin);
-        if ((phi_type->join(TypePtr::NOTNULL) == uin_type->join(TypePtr::NOTNULL)) ||
-            (!phi_type->isa_oopptr() && !uin_type->isa_oopptr())) {
-          opcode = Op_CastPP;
+        if (!phi_type->isa_oopptr() && !uin_type->isa_oopptr()) {
+          cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
         } else {
-          opcode = Op_CheckCastPP;
+          // Use a CastPP for a cast to not null and a CheckCastPP for
+          // a cast to a new klass (and both if both null-ness and
+          // klass change).
+
+          // If the type of phi is not null but the type of uin may be
+          // null, uin's type must be casted to not null
+          if (phi_type->join(TypePtr::NOTNULL) == phi_type->remove_speculative() &&
+              uin_type->join(TypePtr::NOTNULL) != uin_type->remove_speculative()) {
+            cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, TypePtr::NOTNULL, true);
+          }
+
+          // If the type of phi and uin, both casted to not null,
+          // differ the klass of uin must be (check)cast'ed to match
+          // that of phi
+          if (phi_type->join_speculative(TypePtr::NOTNULL) != uin_type->join_speculative(TypePtr::NOTNULL)) {
+            Node* n = uin;
+            if (cast != NULL) {
+              cast = phase->transform(cast);
+              n = cast;
+            }
+            cast = ConstraintCastNode::make_cast(Op_CheckCastPP, r, n, phi_type, true);
+          }
+          if (cast == NULL) {
+            cast = ConstraintCastNode::make_cast(Op_CastPP, r, uin, phi_type, true);
+          }
         }
       }
-      // Add a cast to carry the control dependency of the Phi that is
-      // going away
-      Node* cast = ConstraintCastNode::make_cast(opcode, r, uin, phi_type, true);
+      assert(cast != NULL, "cast should be set");
       cast = phase->transform(cast);
-      // set all inputs to the new cast so the Phi is removed by Identity
+      // set all inputs to the new cast(s) so the Phi is removed by Identity
       PhaseIterGVN* igvn = phase->is_IterGVN();
       for (uint i = 1; i < req(); i++) {
         set_req_X(i, cast, igvn);