hotspot/src/share/vm/opto/escape.cpp
changeset 46525 3a5c833a43de
parent 40094 b6bc61803957
child 46630 75aa3e39d02c
--- a/hotspot/src/share/vm/opto/escape.cpp	Tue Jun 06 17:07:42 2017 +0200
+++ b/hotspot/src/share/vm/opto/escape.cpp	Mon May 29 18:17:49 2017 +0200
@@ -2302,20 +2302,34 @@
   //       | |
   //       AddP  ( base == address )
   //
+  // case #9. Mixed unsafe access
+  //    {instance}
+  //        |
+  //      CheckCastPP (raw)
+  //  top   |
+  //     \  |
+  //     AddP  ( base == top )
+  //
   Node *base = addp->in(AddPNode::Base);
-  if (base->uncast()->is_top()) { // The AddP case #3 and #6.
+  if (base->uncast()->is_top()) { // The AddP case #3 and #6 and #9.
     base = addp->in(AddPNode::Address);
     while (base->is_AddP()) {
       // Case #6 (unsafe access) may have several chained AddP nodes.
       assert(base->in(AddPNode::Base)->uncast()->is_top(), "expected unsafe access address only");
       base = base->in(AddPNode::Address);
     }
-    Node* uncast_base = base->uncast();
-    int opcode = uncast_base->Opcode();
-    assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
-           opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
-           (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
-           (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
+    if (base->Opcode() == Op_CheckCastPP &&
+        base->bottom_type()->isa_rawptr() &&
+        _igvn->type(base->in(1))->isa_oopptr()) {
+      base = base->in(1); // Case #9
+    } else {
+      Node* uncast_base = base->uncast();
+      int opcode = uncast_base->Opcode();
+      assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
+             opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
+             (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
+             (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
+    }
   }
   return base;
 }