diff src/share/vm/opto/multnode.cpp @ 12956:3213ba4d3dff

8024069: replace_in_map() should operate on parent maps Summary: type information gets lost because replace_in_map() doesn't update parent maps Reviewed-by: kvn, twisti
author roland
date Sat, 19 Oct 2013 12:16:43 +0200
parents c9ccd7b85f20
children de6a9e811145
line wrap: on
line diff
--- a/src/share/vm/opto/multnode.cpp	Fri Oct 18 12:15:32 2013 -0700
+++ b/src/share/vm/opto/multnode.cpp	Sat Oct 19 12:16:43 2013 +0200
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "opto/callnode.hpp"
+#include "opto/cfgnode.hpp"
 #include "opto/matcher.hpp"
 #include "opto/mathexactnode.hpp"
 #include "opto/multnode.hpp"
@@ -150,3 +151,59 @@
 uint ProjNode::ideal_reg() const {
   return bottom_type()->ideal_reg();
 }
+
+//-------------------------------is_uncommon_trap_proj----------------------------
+// Return true if proj is the form of "proj->[region->..]call_uct"
+bool ProjNode::is_uncommon_trap_proj(Deoptimization::DeoptReason reason) {
+  int path_limit = 10;
+  Node* out = this;
+  for (int ct = 0; ct < path_limit; ct++) {
+    out = out->unique_ctrl_out();
+    if (out == NULL)
+      return false;
+    if (out->is_CallStaticJava()) {
+      int req = out->as_CallStaticJava()->uncommon_trap_request();
+      if (req != 0) {
+        Deoptimization::DeoptReason trap_reason = Deoptimization::trap_request_reason(req);
+        if (trap_reason == reason || reason == Deoptimization::Reason_none) {
+           return true;
+        }
+      }
+      return false; // don't do further after call
+    }
+    if (out->Opcode() != Op_Region)
+      return false;
+  }
+  return false;
+}
+
+//-------------------------------is_uncommon_trap_if_pattern-------------------------
+// Return true  for "if(test)-> proj -> ...
+//                          |
+//                          V
+//                      other_proj->[region->..]call_uct"
+//
+// "must_reason_predicate" means the uct reason must be Reason_predicate
+bool ProjNode::is_uncommon_trap_if_pattern(Deoptimization::DeoptReason reason) {
+  Node *in0 = in(0);
+  if (!in0->is_If()) return false;
+  // Variation of a dead If node.
+  if (in0->outcnt() < 2)  return false;
+  IfNode* iff = in0->as_If();
+
+  // we need "If(Conv2B(Opaque1(...)))" pattern for reason_predicate
+  if (reason != Deoptimization::Reason_none) {
+    if (iff->in(1)->Opcode() != Op_Conv2B ||
+       iff->in(1)->in(1)->Opcode() != Op_Opaque1) {
+      return false;
+    }
+  }
+
+  ProjNode* other_proj = iff->proj_out(1-_con)->as_Proj();
+  if (other_proj->is_uncommon_trap_proj(reason)) {
+    assert(reason == Deoptimization::Reason_none ||
+           Compile::current()->is_predicate_opaq(iff->in(1)->in(1)), "should be on the list");
+    return true;
+  }
+  return false;
+}