Blame SOURCES/8174164-pr3334-rh1417266.patch

0ad01d
# HG changeset patch
0ad01d
# User roland
0ad01d
# Date 1487208397 28800
0ad01d
#      Wed Feb 15 17:26:37 2017 -0800
0ad01d
# Node ID a9cbaff50d3d7e3a1d2dbdc0121c470142b87270
0ad01d
# Parent  15922b2f31db4857ec84efdf533c41b19e68030b
0ad01d
8174164, PR3334, RH1417266: SafePointNode::_replaced_nodes breaks with irreducible loops
0ad01d
Reviewed-by: kvn
0ad01d
0ad01d
diff --git a/src/share/vm/opto/callnode.hpp b/src/share/vm/opto/callnode.hpp
0ad01d
--- openjdk/hotspot/src/share/vm/opto/callnode.hpp
0ad01d
+++ openjdk/hotspot/src/share/vm/opto/callnode.hpp
0ad01d
@@ -449,8 +449,8 @@
0ad01d
   void delete_replaced_nodes() {
0ad01d
     _replaced_nodes.reset();
0ad01d
   }
0ad01d
-  void apply_replaced_nodes() {
0ad01d
-    _replaced_nodes.apply(this);
0ad01d
+  void apply_replaced_nodes(uint idx) {
0ad01d
+    _replaced_nodes.apply(this, idx);
0ad01d
   }
0ad01d
   void merge_replaced_nodes_with(SafePointNode* sfpt) {
0ad01d
     _replaced_nodes.merge_with(sfpt->_replaced_nodes);
0ad01d
diff --git a/src/share/vm/opto/parse1.cpp b/src/share/vm/opto/parse1.cpp
0ad01d
--- openjdk/hotspot/src/share/vm/opto/parse1.cpp
0ad01d
+++ openjdk/hotspot/src/share/vm/opto/parse1.cpp
0ad01d
@@ -1048,7 +1048,7 @@
0ad01d
         kit.make_dtrace_method_exit(method());
0ad01d
       }
0ad01d
       if (_replaced_nodes_for_exceptions) {
0ad01d
-        kit.map()->apply_replaced_nodes();
0ad01d
+        kit.map()->apply_replaced_nodes(_new_idx);
0ad01d
       }
0ad01d
       // Done with exception-path processing.
0ad01d
       ex_map = kit.make_exception_state(ex_oop);
0ad01d
@@ -1069,7 +1069,7 @@
0ad01d
       _exits.add_exception_state(ex_map);
0ad01d
     }
0ad01d
   }
0ad01d
-  _exits.map()->apply_replaced_nodes();
0ad01d
+  _exits.map()->apply_replaced_nodes(_new_idx);
0ad01d
 }
0ad01d
 
0ad01d
 //-----------------------------create_entry_map-------------------------------
0ad01d
diff --git a/src/share/vm/opto/replacednodes.cpp b/src/share/vm/opto/replacednodes.cpp
0ad01d
--- openjdk/hotspot/src/share/vm/opto/replacednodes.cpp
0ad01d
+++ openjdk/hotspot/src/share/vm/opto/replacednodes.cpp
0ad01d
@@ -91,13 +91,17 @@
0ad01d
 }
0ad01d
 
0ad01d
 // Perfom node replacement (used when returning to caller)
0ad01d
-void ReplacedNodes::apply(Node* n) {
0ad01d
+void ReplacedNodes::apply(Node* n, uint idx) {
0ad01d
   if (is_empty()) {
0ad01d
     return;
0ad01d
   }
0ad01d
   for (int i = 0; i < _replaced_nodes->length(); i++) {
0ad01d
     ReplacedNode replaced = _replaced_nodes->at(i);
0ad01d
-    n->replace_edge(replaced.initial(), replaced.improved());
0ad01d
+    // Only apply if improved node was created in a callee to avoid
0ad01d
+    // issues with irreducible loops in the caller
0ad01d
+    if (replaced.improved()->_idx >= idx) {
0ad01d
+      n->replace_edge(replaced.initial(), replaced.improved());
0ad01d
+    }
0ad01d
   }
0ad01d
 }
0ad01d
 
0ad01d
diff --git a/src/share/vm/opto/replacednodes.hpp b/src/share/vm/opto/replacednodes.hpp
0ad01d
--- openjdk/hotspot/src/share/vm/opto/replacednodes.hpp
0ad01d
+++ openjdk/hotspot/src/share/vm/opto/replacednodes.hpp
0ad01d
@@ -71,7 +71,7 @@
0ad01d
   void record(Node* initial, Node* improved);
0ad01d
   void transfer_from(const ReplacedNodes& other, uint idx);
0ad01d
   void reset();
0ad01d
-  void apply(Node* n);
0ad01d
+  void apply(Node* n, uint idx);
0ad01d
   void merge_with(const ReplacedNodes& other);
0ad01d
   bool is_empty() const;
0ad01d
   void dump(outputStream *st) const;