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);