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