2754 // Execute transformation here to avoid barrier generation in such case. |
2754 // Execute transformation here to avoid barrier generation in such case. |
2755 if (_gvn.type(newval) == TypePtr::NULL_PTR) |
2755 if (_gvn.type(newval) == TypePtr::NULL_PTR) |
2756 newval = _gvn.makecon(TypePtr::NULL_PTR); |
2756 newval = _gvn.makecon(TypePtr::NULL_PTR); |
2757 |
2757 |
2758 // Reference stores need a store barrier. |
2758 // Reference stores need a store barrier. |
2759 pre_barrier(true /* do_load*/, |
2759 if (kind == LS_xchg) { |
2760 control(), base, adr, alias_idx, newval, value_type->make_oopptr(), |
2760 // If pre-barrier must execute before the oop store, old value will require do_load here. |
2761 NULL /* pre_val*/, |
2761 if (!can_move_pre_barrier()) { |
2762 T_OBJECT); |
2762 pre_barrier(true /* do_load*/, |
|
2763 control(), base, adr, alias_idx, newval, value_type->make_oopptr(), |
|
2764 NULL /* pre_val*/, |
|
2765 T_OBJECT); |
|
2766 } // Else move pre_barrier to use load_store value, see below. |
|
2767 } else if (kind == LS_cmpxchg) { |
|
2768 // Same as for newval above: |
|
2769 if (_gvn.type(oldval) == TypePtr::NULL_PTR) { |
|
2770 oldval = _gvn.makecon(TypePtr::NULL_PTR); |
|
2771 } |
|
2772 // The only known value which might get overwritten is oldval. |
|
2773 pre_barrier(false /* do_load */, |
|
2774 control(), NULL, NULL, max_juint, NULL, NULL, |
|
2775 oldval /* pre_val */, |
|
2776 T_OBJECT); |
|
2777 } else { |
|
2778 ShouldNotReachHere(); |
|
2779 } |
|
2780 |
2763 #ifdef _LP64 |
2781 #ifdef _LP64 |
2764 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
2782 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
2765 Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); |
2783 Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop())); |
2766 if (kind == LS_xchg) { |
2784 if (kind == LS_xchg) { |
2767 load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr, |
2785 load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr, |
2793 // main role is to prevent LoadStore nodes from being optimized away |
2811 // main role is to prevent LoadStore nodes from being optimized away |
2794 // when their results aren't used. |
2812 // when their results aren't used. |
2795 Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); |
2813 Node* proj = _gvn.transform(new (C) SCMemProjNode(load_store)); |
2796 set_memory(proj, alias_idx); |
2814 set_memory(proj, alias_idx); |
2797 |
2815 |
|
2816 if (type == T_OBJECT && kind == LS_xchg) { |
|
2817 #ifdef _LP64 |
|
2818 if (adr->bottom_type()->is_ptr_to_narrowoop()) { |
|
2819 load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); |
|
2820 } |
|
2821 #endif |
|
2822 if (can_move_pre_barrier()) { |
|
2823 // Don't need to load pre_val. The old value is returned by load_store. |
|
2824 // The pre_barrier can execute after the xchg as long as no safepoint |
|
2825 // gets inserted between them. |
|
2826 pre_barrier(false /* do_load */, |
|
2827 control(), NULL, NULL, max_juint, NULL, NULL, |
|
2828 load_store /* pre_val */, |
|
2829 T_OBJECT); |
|
2830 } |
|
2831 } |
|
2832 |
2798 // Add the trailing membar surrounding the access |
2833 // Add the trailing membar surrounding the access |
2799 insert_mem_bar(Op_MemBarCPUOrder); |
2834 insert_mem_bar(Op_MemBarCPUOrder); |
2800 insert_mem_bar(Op_MemBarAcquire); |
2835 insert_mem_bar(Op_MemBarAcquire); |
2801 |
|
2802 #ifdef _LP64 |
|
2803 if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) { |
|
2804 load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->get_ptr_type())); |
|
2805 } |
|
2806 #endif |
|
2807 |
2836 |
2808 assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match"); |
2837 assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match"); |
2809 set_result(load_store); |
2838 set_result(load_store); |
2810 return true; |
2839 return true; |
2811 } |
2840 } |