Mercurial > hg > truffle
comparison src/share/vm/opto/macro.cpp @ 3754:642c68c75db9
7050280: assert(u->as_Unlock()->is_eliminated()) failed: sanity
Summary: Mark all associated (same box and obj) lock and unlock nodes for elimination if some of them marked already.
Reviewed-by: iveresov, never
author | kvn |
---|---|
date | Sat, 04 Jun 2011 10:36:22 -0700 |
parents | bad7ecd0b6ed |
children | e3cbc9ddd434 |
comparison
equal
deleted
inserted
replaced
3753:cba7b5c2d53f | 3754:642c68c75db9 |
---|---|
1691 expand_allocate_common(alloc, length, | 1691 expand_allocate_common(alloc, length, |
1692 OptoRuntime::new_array_Type(), | 1692 OptoRuntime::new_array_Type(), |
1693 OptoRuntime::new_array_Java()); | 1693 OptoRuntime::new_array_Java()); |
1694 } | 1694 } |
1695 | 1695 |
1696 | 1696 //-----------------------mark_eliminated_locking_nodes----------------------- |
1697 // we have determined that this lock/unlock can be eliminated, we simply | 1697 // During EA obj may point to several objects but after few ideal graph |
1698 // eliminate the node without expanding it. | 1698 // transformations (CCP) it may point to only one non escaping object |
1699 // | 1699 // (but still using phi), corresponding locks and unlocks will be marked |
1700 // Note: The membar's associated with the lock/unlock are currently not | 1700 // for elimination. Later obj could be replaced with a new node (new phi) |
1701 // eliminated. This should be investigated as a future enhancement. | 1701 // and which does not have escape information. And later after some graph |
1702 // | 1702 // reshape other locks and unlocks (which were not marked for elimination |
1703 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { | 1703 // before) are connected to this new obj (phi) but they still will not be |
1704 | 1704 // marked for elimination since new obj has no escape information. |
1705 // Mark all associated (same box and obj) lock and unlock nodes for | |
1706 // elimination if some of them marked already. | |
1707 void PhaseMacroExpand::mark_eliminated_locking_nodes(AbstractLockNode *alock) { | |
1705 if (!alock->is_eliminated()) { | 1708 if (!alock->is_eliminated()) { |
1706 return false; | 1709 return; |
1707 } | 1710 } |
1708 if (alock->is_Lock() && !alock->is_coarsened()) { | 1711 if (!alock->is_coarsened()) { // Eliminated by EA |
1709 // Create new "eliminated" BoxLock node and use it | 1712 // Create new "eliminated" BoxLock node and use it |
1710 // in monitor debug info for the same object. | 1713 // in monitor debug info for the same object. |
1711 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); | 1714 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); |
1712 Node* obj = alock->obj_node(); | 1715 Node* obj = alock->obj_node(); |
1713 if (!oldbox->is_eliminated()) { | 1716 if (!oldbox->is_eliminated()) { |
1714 BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); | 1717 BoxLockNode* newbox = oldbox->clone()->as_BoxLock(); |
1718 // Note: BoxLock node is marked eliminated only here | |
1719 // and it is used to indicate that all associated lock | |
1720 // and unlock nodes are marked for elimination. | |
1715 newbox->set_eliminated(); | 1721 newbox->set_eliminated(); |
1716 transform_later(newbox); | 1722 transform_later(newbox); |
1717 // Replace old box node with new box for all users | 1723 // Replace old box node with new box for all users |
1718 // of the same object. | 1724 // of the same object. |
1719 for (uint i = 0; i < oldbox->outcnt();) { | 1725 for (uint i = 0; i < oldbox->outcnt();) { |
1720 | 1726 |
1721 bool next_edge = true; | 1727 bool next_edge = true; |
1722 Node* u = oldbox->raw_out(i); | 1728 Node* u = oldbox->raw_out(i); |
1723 if (u == alock) { | 1729 if (u->is_AbstractLock() && |
1724 i++; | 1730 u->as_AbstractLock()->obj_node() == obj && |
1725 continue; // It will be removed below | 1731 u->as_AbstractLock()->box_node() == oldbox) { |
1726 } | 1732 // Mark all associated locks and unlocks. |
1727 if (u->is_Lock() && | 1733 u->as_AbstractLock()->set_eliminated(); |
1728 u->as_Lock()->obj_node() == obj && | |
1729 // oldbox could be referenced in debug info also | |
1730 u->as_Lock()->box_node() == oldbox) { | |
1731 assert(u->as_Lock()->is_eliminated(), "sanity"); | |
1732 _igvn.hash_delete(u); | 1734 _igvn.hash_delete(u); |
1733 u->set_req(TypeFunc::Parms + 1, newbox); | 1735 u->set_req(TypeFunc::Parms + 1, newbox); |
1734 next_edge = false; | 1736 next_edge = false; |
1735 #ifdef ASSERT | |
1736 } else if (u->is_Unlock() && u->as_Unlock()->obj_node() == obj) { | |
1737 assert(u->as_Unlock()->is_eliminated(), "sanity"); | |
1738 #endif | |
1739 } | 1737 } |
1740 // Replace old box in monitor debug info. | 1738 // Replace old box in monitor debug info. |
1741 if (u->is_SafePoint() && u->as_SafePoint()->jvms()) { | 1739 if (u->is_SafePoint() && u->as_SafePoint()->jvms()) { |
1742 SafePointNode* sfn = u->as_SafePoint(); | 1740 SafePointNode* sfn = u->as_SafePoint(); |
1743 JVMState* youngest_jvms = sfn->jvms(); | 1741 JVMState* youngest_jvms = sfn->jvms(); |
1759 } // for (int depth = 1; | 1757 } // for (int depth = 1; |
1760 } // if (u->is_SafePoint() | 1758 } // if (u->is_SafePoint() |
1761 if (next_edge) i++; | 1759 if (next_edge) i++; |
1762 } // for (uint i = 0; i < oldbox->outcnt();) | 1760 } // for (uint i = 0; i < oldbox->outcnt();) |
1763 } // if (!oldbox->is_eliminated()) | 1761 } // if (!oldbox->is_eliminated()) |
1764 } // if (alock->is_Lock() && !lock->is_coarsened()) | 1762 } // if (!alock->is_coarsened()) |
1765 | 1763 } |
1764 | |
1765 // we have determined that this lock/unlock can be eliminated, we simply | |
1766 // eliminate the node without expanding it. | |
1767 // | |
1768 // Note: The membar's associated with the lock/unlock are currently not | |
1769 // eliminated. This should be investigated as a future enhancement. | |
1770 // | |
1771 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { | |
1772 | |
1773 if (!alock->is_eliminated()) { | |
1774 return false; | |
1775 } | |
1776 #ifdef ASSERT | |
1777 if (alock->is_Lock() && !alock->is_coarsened()) { | |
1778 // Check that new "eliminated" BoxLock node is created. | |
1779 BoxLockNode* oldbox = alock->box_node()->as_BoxLock(); | |
1780 assert(oldbox->is_eliminated(), "should be done already"); | |
1781 } | |
1782 #endif | |
1766 CompileLog* log = C->log(); | 1783 CompileLog* log = C->log(); |
1767 if (log != NULL) { | 1784 if (log != NULL) { |
1768 log->head("eliminate_lock lock='%d'", | 1785 log->head("eliminate_lock lock='%d'", |
1769 alock->is_Lock()); | 1786 alock->is_Lock()); |
1770 JVMState* p = alock->jvms(); | 1787 JVMState* p = alock->jvms(); |
2143 // Returns true if a failure occurred. | 2160 // Returns true if a failure occurred. |
2144 bool PhaseMacroExpand::expand_macro_nodes() { | 2161 bool PhaseMacroExpand::expand_macro_nodes() { |
2145 if (C->macro_count() == 0) | 2162 if (C->macro_count() == 0) |
2146 return false; | 2163 return false; |
2147 // First, attempt to eliminate locks | 2164 // First, attempt to eliminate locks |
2165 int cnt = C->macro_count(); | |
2166 for (int i=0; i < cnt; i++) { | |
2167 Node *n = C->macro_node(i); | |
2168 if (n->is_AbstractLock()) { // Lock and Unlock nodes | |
2169 // Before elimination mark all associated (same box and obj) | |
2170 // lock and unlock nodes. | |
2171 mark_eliminated_locking_nodes(n->as_AbstractLock()); | |
2172 } | |
2173 } | |
2148 bool progress = true; | 2174 bool progress = true; |
2149 while (progress) { | 2175 while (progress) { |
2150 progress = false; | 2176 progress = false; |
2151 for (int i = C->macro_count(); i > 0; i--) { | 2177 for (int i = C->macro_count(); i > 0; i--) { |
2152 Node * n = C->macro_node(i-1); | 2178 Node * n = C->macro_node(i-1); |