comparison src/share/vm/opto/library_call.cpp @ 12169:29aa8936f03c

8023597: Optimize G1 barriers code for unsafe load_store Summary: Avoid loading old values in G1 pre-barriers for inlined unsafe load_store nodes. Reviewed-by: kvn, tonyp Contributed-by: Martin Doerr <martin.doerr@sap.com>
author kvn
date Wed, 28 Aug 2013 11:22:43 +0200
parents acedd49a1bce
children edb5ab0f3fe5 7944aba7ba41
comparison
equal deleted inserted replaced
12168:7181dd13a6c4 12169:29aa8936f03c
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 }