< prev index next >
src/hotspot/share/opto/memnode.cpp
Print this page
@@ -3172,41 +3172,79 @@
leading->_pair_idx = leading->_idx;
#endif
}
MemBarNode* MemBarNode::trailing_membar() const {
+ ResourceMark rm;
Node* trailing = (Node*)this;
VectorSet seen(Thread::current()->resource_area());
- while (!trailing->is_MemBar() || !trailing->as_MemBar()->trailing()) {
- if (seen.test_set(trailing->_idx)) {
- // Dying subgraph?
- return NULL;
+ Node_Stack multis(0);
+ do {
+ Node* c = trailing;
+ uint i = 0;
+ do {
+ trailing = NULL;
+ for (; i < c->outcnt(); i++) {
+ Node* next = c->raw_out(i);
+ if (next != c && next->is_CFG()) {
+ if (c->is_MultiBranch()) {
+ if (multis.node() == c) {
+ multis.set_index(i+1);
+ } else {
+ multis.push(c, i+1);
+ }
}
- for (DUIterator_Fast jmax, j = trailing->fast_outs(jmax); j < jmax; j++) {
- Node* next = trailing->fast_out(j);
- if (next != trailing && next->is_CFG()) {
trailing = next;
break;
}
}
+ if (trailing != NULL && !seen.test_set(trailing->_idx)) {
+ break;
+ }
+ while (multis.size() > 0) {
+ c = multis.node();
+ i = multis.index();
+ if (i < c->req()) {
+ break;
+ }
+ multis.pop();
}
+ } while (multis.size() > 0);
+ } while (!trailing->is_MemBar() || !trailing->as_MemBar()->trailing());
+
MemBarNode* mb = trailing->as_MemBar();
assert((mb->_kind == TrailingStore && _kind == LeadingStore) ||
(mb->_kind == TrailingLoadStore && _kind == LeadingLoadStore), "bad trailing membar");
assert(mb->_pair_idx == _pair_idx, "bad trailing membar");
return mb;
}
MemBarNode* MemBarNode::leading_membar() const {
+ ResourceMark rm;
VectorSet seen(Thread::current()->resource_area());
+ Node_Stack regions(0);
Node* leading = in(0);
while (leading != NULL && (!leading->is_MemBar() || !leading->as_MemBar()->leading())) {
- if (seen.test_set(leading->_idx)) {
- // Dying subgraph?
+ while (leading == NULL || leading->is_top() || seen.test_set(leading->_idx)) {
+ leading = NULL;
+ while (regions.size() > 0) {
+ Node* r = regions.node();
+ uint i = regions.index();
+ if (i < r->req()) {
+ leading = r->in(i);
+ regions.set_index(i+1);
+ } else {
+ regions.pop();
+ }
+ }
+ if (leading == NULL) {
+ assert(regions.size() == 0, "all paths should have been tried");
return NULL;
}
+ }
if (leading->is_Region()) {
+ regions.push(leading, 2);
leading = leading->in(1);
} else {
leading = leading->in(0);
}
}
< prev index next >