From 399491d1fb47d8484bf24aaff6ab5c7bcde10c84 Mon Sep 17 00:00:00 2001 From: roland Date: Wed, 15 Feb 2017 17:26:37 -0800 Subject: [PATCH] 8174164: SafePointNode::_replaced_nodes breaks with irreducible loops Reviewed-by: kvn --- src/share/vm/opto/callnode.hpp | 4 ++-- src/share/vm/opto/parse1.cpp | 4 ++-- src/share/vm/opto/replacednodes.cpp | 8 ++++++-- src/share/vm/opto/replacednodes.hpp | 2 +- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/share/vm/opto/callnode.hpp b/src/share/vm/opto/callnode.hpp index 26f5c6ba7..9544264ee 100644 --- a/src/share/vm/opto/callnode.hpp +++ b/src/share/vm/opto/callnode.hpp @@ -449,8 +449,8 @@ public: void delete_replaced_nodes() { _replaced_nodes.reset(); } - void apply_replaced_nodes() { - _replaced_nodes.apply(this); + void apply_replaced_nodes(uint idx) { + _replaced_nodes.apply(this, idx); } void merge_replaced_nodes_with(SafePointNode* sfpt) { _replaced_nodes.merge_with(sfpt->_replaced_nodes); diff --git a/src/share/vm/opto/parse1.cpp b/src/share/vm/opto/parse1.cpp index 87557847c..2d6daa159 100644 --- a/src/share/vm/opto/parse1.cpp +++ b/src/share/vm/opto/parse1.cpp @@ -1048,7 +1048,7 @@ void Parse::do_exits() { kit.make_dtrace_method_exit(method()); } if (_replaced_nodes_for_exceptions) { - kit.map()->apply_replaced_nodes(); + kit.map()->apply_replaced_nodes(_new_idx); } // Done with exception-path processing. ex_map = kit.make_exception_state(ex_oop); @@ -1069,7 +1069,7 @@ void Parse::do_exits() { _exits.add_exception_state(ex_map); } } - _exits.map()->apply_replaced_nodes(); + _exits.map()->apply_replaced_nodes(_new_idx); } //-----------------------------create_entry_map------------------------------- diff --git a/src/share/vm/opto/replacednodes.cpp b/src/share/vm/opto/replacednodes.cpp index d4cb3b1e2..f4aac43b1 100644 --- a/src/share/vm/opto/replacednodes.cpp +++ b/src/share/vm/opto/replacednodes.cpp @@ -91,13 +91,17 @@ void ReplacedNodes::reset() { } // Perfom node replacement (used when returning to caller) -void ReplacedNodes::apply(Node* n) { +void ReplacedNodes::apply(Node* n, uint idx) { if (is_empty()) { return; } for (int i = 0; i < _replaced_nodes->length(); i++) { ReplacedNode replaced = _replaced_nodes->at(i); - n->replace_edge(replaced.initial(), replaced.improved()); + // Only apply if improved node was created in a callee to avoid + // issues with irreducible loops in the caller + if (replaced.improved()->_idx >= idx) { + n->replace_edge(replaced.initial(), replaced.improved()); + } } } diff --git a/src/share/vm/opto/replacednodes.hpp b/src/share/vm/opto/replacednodes.hpp index 0f68fe986..3c31d0de9 100644 --- a/src/share/vm/opto/replacednodes.hpp +++ b/src/share/vm/opto/replacednodes.hpp @@ -71,7 +71,7 @@ class ReplacedNodes VALUE_OBJ_CLASS_SPEC { void record(Node* initial, Node* improved); void transfer_from(const ReplacedNodes& other, uint idx); void reset(); - void apply(Node* n); + void apply(Node* n, uint idx); void merge_with(const ReplacedNodes& other); bool is_empty() const; void dump(outputStream *st) const; -- GitLab