1 |
# HG changeset patch |
2 |
# User roland |
3 |
# Date 1487208397 28800 |
4 |
# Wed Feb 15 17:26:37 2017 -0800 |
5 |
# Node ID a9cbaff50d3d7e3a1d2dbdc0121c470142b87270 |
6 |
# Parent 15922b2f31db4857ec84efdf533c41b19e68030b |
7 |
8174164, PR3334, RH1417266: SafePointNode::_replaced_nodes breaks with irreducible loops |
8 |
Reviewed-by: kvn |
9 |
|
10 |
diff --git a/src/share/vm/opto/callnode.hpp b/src/share/vm/opto/callnode.hpp |
11 |
--- openjdk/hotspot/src/share/vm/opto/callnode.hpp |
12 |
+++ openjdk/hotspot/src/share/vm/opto/callnode.hpp |
13 |
@@ -449,8 +449,8 @@ |
14 |
void delete_replaced_nodes() { |
15 |
_replaced_nodes.reset(); |
16 |
} |
17 |
- void apply_replaced_nodes() { |
18 |
- _replaced_nodes.apply(this); |
19 |
+ void apply_replaced_nodes(uint idx) { |
20 |
+ _replaced_nodes.apply(this, idx); |
21 |
} |
22 |
void merge_replaced_nodes_with(SafePointNode* sfpt) { |
23 |
_replaced_nodes.merge_with(sfpt->_replaced_nodes); |
24 |
diff --git a/src/share/vm/opto/parse1.cpp b/src/share/vm/opto/parse1.cpp |
25 |
--- openjdk/hotspot/src/share/vm/opto/parse1.cpp |
26 |
+++ openjdk/hotspot/src/share/vm/opto/parse1.cpp |
27 |
@@ -1048,7 +1048,7 @@ |
28 |
kit.make_dtrace_method_exit(method()); |
29 |
} |
30 |
if (_replaced_nodes_for_exceptions) { |
31 |
- kit.map()->apply_replaced_nodes(); |
32 |
+ kit.map()->apply_replaced_nodes(_new_idx); |
33 |
} |
34 |
// Done with exception-path processing. |
35 |
ex_map = kit.make_exception_state(ex_oop); |
36 |
@@ -1069,7 +1069,7 @@ |
37 |
_exits.add_exception_state(ex_map); |
38 |
} |
39 |
} |
40 |
- _exits.map()->apply_replaced_nodes(); |
41 |
+ _exits.map()->apply_replaced_nodes(_new_idx); |
42 |
} |
43 |
|
44 |
//-----------------------------create_entry_map------------------------------- |
45 |
diff --git a/src/share/vm/opto/replacednodes.cpp b/src/share/vm/opto/replacednodes.cpp |
46 |
--- openjdk/hotspot/src/share/vm/opto/replacednodes.cpp |
47 |
+++ openjdk/hotspot/src/share/vm/opto/replacednodes.cpp |
48 |
@@ -91,13 +91,17 @@ |
49 |
} |
50 |
|
51 |
// Perfom node replacement (used when returning to caller) |
52 |
-void ReplacedNodes::apply(Node* n) { |
53 |
+void ReplacedNodes::apply(Node* n, uint idx) { |
54 |
if (is_empty()) { |
55 |
return; |
56 |
} |
57 |
for (int i = 0; i < _replaced_nodes->length(); i++) { |
58 |
ReplacedNode replaced = _replaced_nodes->at(i); |
59 |
- n->replace_edge(replaced.initial(), replaced.improved()); |
60 |
+ // Only apply if improved node was created in a callee to avoid |
61 |
+ // issues with irreducible loops in the caller |
62 |
+ if (replaced.improved()->_idx >= idx) { |
63 |
+ n->replace_edge(replaced.initial(), replaced.improved()); |
64 |
+ } |
65 |
} |
66 |
} |
67 |
|
68 |
diff --git a/src/share/vm/opto/replacednodes.hpp b/src/share/vm/opto/replacednodes.hpp |
69 |
--- openjdk/hotspot/src/share/vm/opto/replacednodes.hpp |
70 |
+++ openjdk/hotspot/src/share/vm/opto/replacednodes.hpp |
71 |
@@ -71,7 +71,7 @@ |
72 |
void record(Node* initial, Node* improved); |
73 |
void transfer_from(const ReplacedNodes& other, uint idx); |
74 |
void reset(); |
75 |
- void apply(Node* n); |
76 |
+ void apply(Node* n, uint idx); |
77 |
void merge_with(const ReplacedNodes& other); |
78 |
bool is_empty() const; |
79 |
void dump(outputStream *st) const; |