826 // eliminate the node without expanding it. |
826 // eliminate the node without expanding it. |
827 // |
827 // |
828 // Note: The membar's associated with the lock/unlock are currently not |
828 // Note: The membar's associated with the lock/unlock are currently not |
829 // eliminated. This should be investigated as a future enhancement. |
829 // eliminated. This should be investigated as a future enhancement. |
830 // |
830 // |
831 void PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { |
831 bool PhaseMacroExpand::eliminate_locking_node(AbstractLockNode *alock) { |
832 Node* mem = alock->in(TypeFunc::Memory); |
832 |
|
833 if (!alock->is_eliminated()) { |
|
834 return false; |
|
835 } |
|
836 // Mark the box lock as eliminated if all correspondent locks are eliminated |
|
837 // to construct correct debug info. |
|
838 BoxLockNode* box = alock->box_node()->as_BoxLock(); |
|
839 if (!box->is_eliminated()) { |
|
840 bool eliminate = true; |
|
841 for (DUIterator_Fast imax, i = box->fast_outs(imax); i < imax; i++) { |
|
842 Node *lck = box->fast_out(i); |
|
843 if (lck->is_Lock() && !lck->as_AbstractLock()->is_eliminated()) { |
|
844 eliminate = false; |
|
845 break; |
|
846 } |
|
847 } |
|
848 if (eliminate) |
|
849 box->set_eliminated(); |
|
850 } |
|
851 |
|
852 #ifndef PRODUCT |
|
853 if (PrintEliminateLocks) { |
|
854 if (alock->is_Lock()) { |
|
855 tty->print_cr("++++ Eliminating: %d Lock", alock->_idx); |
|
856 } else { |
|
857 tty->print_cr("++++ Eliminating: %d Unlock", alock->_idx); |
|
858 } |
|
859 } |
|
860 #endif |
|
861 |
|
862 Node* mem = alock->in(TypeFunc::Memory); |
|
863 Node* ctrl = alock->in(TypeFunc::Control); |
|
864 |
|
865 extract_call_projections(alock); |
|
866 // There are 2 projections from the lock. The lock node will |
|
867 // be deleted when its last use is subsumed below. |
|
868 assert(alock->outcnt() == 2 && |
|
869 _fallthroughproj != NULL && |
|
870 _memproj_fallthrough != NULL, |
|
871 "Unexpected projections from Lock/Unlock"); |
|
872 |
|
873 Node* fallthroughproj = _fallthroughproj; |
|
874 Node* memproj_fallthrough = _memproj_fallthrough; |
833 |
875 |
834 // The memory projection from a lock/unlock is RawMem |
876 // The memory projection from a lock/unlock is RawMem |
835 // The input to a Lock is merged memory, so extract its RawMem input |
877 // The input to a Lock is merged memory, so extract its RawMem input |
836 // (unless the MergeMem has been optimized away.) |
878 // (unless the MergeMem has been optimized away.) |
837 if (alock->is_Lock()) { |
879 if (alock->is_Lock()) { |
838 if (mem->is_MergeMem()) |
880 // Seach for MemBarAcquire node and delete it also. |
839 mem = mem->as_MergeMem()->in(Compile::AliasIdxRaw); |
881 MemBarNode* membar = fallthroughproj->unique_ctrl_out()->as_MemBar(); |
840 } |
882 assert(membar != NULL && membar->Opcode() == Op_MemBarAcquire, ""); |
841 |
883 Node* ctrlproj = membar->proj_out(TypeFunc::Control); |
842 extract_call_projections(alock); |
884 Node* memproj = membar->proj_out(TypeFunc::Memory); |
843 // There are 2 projections from the lock. The lock node will |
885 _igvn.hash_delete(ctrlproj); |
844 // be deleted when its last use is subsumed below. |
886 _igvn.subsume_node(ctrlproj, fallthroughproj); |
845 assert(alock->outcnt() == 2 && _fallthroughproj != NULL && |
887 _igvn.hash_delete(memproj); |
846 _memproj_fallthrough != NULL, "Unexpected projections from Lock/Unlock"); |
888 _igvn.subsume_node(memproj, memproj_fallthrough); |
847 _igvn.hash_delete(_fallthroughproj); |
889 } |
848 _igvn.subsume_node(_fallthroughproj, alock->in(TypeFunc::Control)); |
890 |
849 _igvn.hash_delete(_memproj_fallthrough); |
891 // Seach for MemBarRelease node and delete it also. |
850 _igvn.subsume_node(_memproj_fallthrough, mem); |
892 if (alock->is_Unlock() && ctrl != NULL && ctrl->is_Proj() && |
851 return; |
893 ctrl->in(0)->is_MemBar()) { |
|
894 MemBarNode* membar = ctrl->in(0)->as_MemBar(); |
|
895 assert(membar->Opcode() == Op_MemBarRelease && |
|
896 mem->is_Proj() && membar == mem->in(0), ""); |
|
897 _igvn.hash_delete(fallthroughproj); |
|
898 _igvn.subsume_node(fallthroughproj, ctrl); |
|
899 _igvn.hash_delete(memproj_fallthrough); |
|
900 _igvn.subsume_node(memproj_fallthrough, mem); |
|
901 fallthroughproj = ctrl; |
|
902 memproj_fallthrough = mem; |
|
903 ctrl = membar->in(TypeFunc::Control); |
|
904 mem = membar->in(TypeFunc::Memory); |
|
905 } |
|
906 |
|
907 _igvn.hash_delete(fallthroughproj); |
|
908 _igvn.subsume_node(fallthroughproj, ctrl); |
|
909 _igvn.hash_delete(memproj_fallthrough); |
|
910 _igvn.subsume_node(memproj_fallthrough, mem); |
|
911 return true; |
852 } |
912 } |
853 |
913 |
854 |
914 |
855 //------------------------------expand_lock_node---------------------- |
915 //------------------------------expand_lock_node---------------------- |
856 void PhaseMacroExpand::expand_lock_node(LockNode *lock) { |
916 void PhaseMacroExpand::expand_lock_node(LockNode *lock) { |
|
917 |
|
918 if (eliminate_locking_node(lock)) { |
|
919 return; |
|
920 } |
857 |
921 |
858 Node* ctrl = lock->in(TypeFunc::Control); |
922 Node* ctrl = lock->in(TypeFunc::Control); |
859 Node* mem = lock->in(TypeFunc::Memory); |
923 Node* mem = lock->in(TypeFunc::Memory); |
860 Node* obj = lock->obj_node(); |
924 Node* obj = lock->obj_node(); |
861 Node* box = lock->box_node(); |
925 Node* box = lock->box_node(); |
862 Node *flock = lock->fastlock_node(); |
926 Node* flock = lock->fastlock_node(); |
863 |
|
864 if (lock->is_eliminated()) { |
|
865 eliminate_locking_node(lock); |
|
866 return; |
|
867 } |
|
868 |
927 |
869 // Make the merge point |
928 // Make the merge point |
870 Node *region = new (C, 3) RegionNode(3); |
929 Node *region = new (C, 3) RegionNode(3); |
871 |
930 |
872 Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne)); |
931 Node *bol = transform_later(new (C, 2) BoolNode(flock,BoolTest::ne)); |