aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm/opto/multnode.cpp
diff options
context:
space:
mode:
authorroland <none@none>2013-10-19 12:16:43 +0200
committerroland <none@none>2013-10-19 12:16:43 +0200
commit07b56092c33eeece957448e6703448186e832248 (patch)
treebda1fba3bc1b9a0f26652e60468fb3107b20d8fa /src/share/vm/opto/multnode.cpp
parenta1a245c428f3db760409c12acadaaba20766b901 (diff)
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
Diffstat (limited to 'src/share/vm/opto/multnode.cpp')
-rw-r--r--src/share/vm/opto/multnode.cpp57
1 files changed, 57 insertions, 0 deletions
diff --git a/src/share/vm/opto/multnode.cpp b/src/share/vm/opto/multnode.cpp
index 286f0461b..bb3357abc 100644
--- a/src/share/vm/opto/multnode.cpp
+++ b/src/share/vm/opto/multnode.cpp
@@ -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 @@ const RegMask &ProjNode::out_RegMask() const {
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;
+}