Mercurial > hg > truffle
comparison src/cpu/sparc/vm/assembler_sparc.cpp @ 420:a1980da045cc
6462850: generate biased locking code in C2 ideal graph
Summary: Inline biased locking code in C2 ideal graph during macro nodes expansion
Reviewed-by: never
author | kvn |
---|---|
date | Fri, 07 Nov 2008 09:29:38 -0800 |
parents | 1ee8caae33af |
children | 56aae7be60d4 |
comparison
equal
deleted
inserted
replaced
419:0bf25c4807f9 | 420:a1980da045cc |
---|---|
2613 | 2613 |
2614 restore(); | 2614 restore(); |
2615 } | 2615 } |
2616 } | 2616 } |
2617 | 2617 |
2618 void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, Register temp_reg, | 2618 void MacroAssembler::biased_locking_enter(Register obj_reg, Register mark_reg, |
2619 Register temp_reg, | |
2619 Label& done, Label* slow_case, | 2620 Label& done, Label* slow_case, |
2620 BiasedLockingCounters* counters) { | 2621 BiasedLockingCounters* counters) { |
2621 assert(UseBiasedLocking, "why call this otherwise?"); | 2622 assert(UseBiasedLocking, "why call this otherwise?"); |
2622 | 2623 |
2623 if (PrintBiasedLockingStatistics) { | 2624 if (PrintBiasedLockingStatistics) { |
2689 // don't accidentally blow away another thread's valid bias. | 2690 // don't accidentally blow away another thread's valid bias. |
2690 delayed()->and3(mark_reg, | 2691 delayed()->and3(mark_reg, |
2691 markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place, | 2692 markOopDesc::biased_lock_mask_in_place | markOopDesc::age_mask_in_place | markOopDesc::epoch_mask_in_place, |
2692 mark_reg); | 2693 mark_reg); |
2693 or3(G2_thread, mark_reg, temp_reg); | 2694 or3(G2_thread, mark_reg, temp_reg); |
2694 casx_under_lock(mark_addr.base(), mark_reg, temp_reg, | 2695 casn(mark_addr.base(), mark_reg, temp_reg); |
2695 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); | |
2696 // If the biasing toward our thread failed, this means that | 2696 // If the biasing toward our thread failed, this means that |
2697 // another thread succeeded in biasing it toward itself and we | 2697 // another thread succeeded in biasing it toward itself and we |
2698 // need to revoke that bias. The revocation will occur in the | 2698 // need to revoke that bias. The revocation will occur in the |
2699 // interpreter runtime in the slow case. | 2699 // interpreter runtime in the slow case. |
2700 cmp(mark_reg, temp_reg); | 2700 cmp(mark_reg, temp_reg); |
2719 // FIXME: due to a lack of registers we currently blow away the age | 2719 // FIXME: due to a lack of registers we currently blow away the age |
2720 // bits in this situation. Should attempt to preserve them. | 2720 // bits in this situation. Should attempt to preserve them. |
2721 load_klass(obj_reg, temp_reg); | 2721 load_klass(obj_reg, temp_reg); |
2722 ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); | 2722 ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); |
2723 or3(G2_thread, temp_reg, temp_reg); | 2723 or3(G2_thread, temp_reg, temp_reg); |
2724 casx_under_lock(mark_addr.base(), mark_reg, temp_reg, | 2724 casn(mark_addr.base(), mark_reg, temp_reg); |
2725 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); | |
2726 // If the biasing toward our thread failed, this means that | 2725 // If the biasing toward our thread failed, this means that |
2727 // another thread succeeded in biasing it toward itself and we | 2726 // another thread succeeded in biasing it toward itself and we |
2728 // need to revoke that bias. The revocation will occur in the | 2727 // need to revoke that bias. The revocation will occur in the |
2729 // interpreter runtime in the slow case. | 2728 // interpreter runtime in the slow case. |
2730 cmp(mark_reg, temp_reg); | 2729 cmp(mark_reg, temp_reg); |
2750 // | 2749 // |
2751 // FIXME: due to a lack of registers we currently blow away the age | 2750 // FIXME: due to a lack of registers we currently blow away the age |
2752 // bits in this situation. Should attempt to preserve them. | 2751 // bits in this situation. Should attempt to preserve them. |
2753 load_klass(obj_reg, temp_reg); | 2752 load_klass(obj_reg, temp_reg); |
2754 ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); | 2753 ld_ptr(Address(temp_reg, 0, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()), temp_reg); |
2755 casx_under_lock(mark_addr.base(), mark_reg, temp_reg, | 2754 casn(mark_addr.base(), mark_reg, temp_reg); |
2756 (address)StubRoutines::Sparc::atomic_memory_operation_lock_addr()); | |
2757 // Fall through to the normal CAS-based lock, because no matter what | 2755 // Fall through to the normal CAS-based lock, because no matter what |
2758 // the result of the above CAS, some thread must have succeeded in | 2756 // the result of the above CAS, some thread must have succeeded in |
2759 // removing the bias bit from the object's header. | 2757 // removing the bias bit from the object's header. |
2760 if (counters != NULL) { | 2758 if (counters != NULL) { |
2761 cmp(mark_reg, temp_reg); | 2759 cmp(mark_reg, temp_reg); |
2813 // and compiler_unlock_object. Critically, the key factor is code size, not path | 2811 // and compiler_unlock_object. Critically, the key factor is code size, not path |
2814 // length. (Simply experiments to pad CLO with unexecuted NOPs demonstrte the | 2812 // length. (Simply experiments to pad CLO with unexecuted NOPs demonstrte the |
2815 // effect). | 2813 // effect). |
2816 | 2814 |
2817 | 2815 |
2818 void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch, | 2816 void MacroAssembler::compiler_lock_object(Register Roop, Register Rmark, |
2819 BiasedLockingCounters* counters) { | 2817 Register Rbox, Register Rscratch, |
2818 BiasedLockingCounters* counters, | |
2819 bool try_bias) { | |
2820 Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); | 2820 Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); |
2821 | 2821 |
2822 verify_oop(Roop); | 2822 verify_oop(Roop); |
2823 Label done ; | 2823 Label done ; |
2824 | 2824 |
2836 if (EmitSync & 2) { | 2836 if (EmitSync & 2) { |
2837 | 2837 |
2838 // Fetch object's markword | 2838 // Fetch object's markword |
2839 ld_ptr(mark_addr, Rmark); | 2839 ld_ptr(mark_addr, Rmark); |
2840 | 2840 |
2841 if (UseBiasedLocking) { | 2841 if (try_bias) { |
2842 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); | 2842 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); |
2843 } | 2843 } |
2844 | 2844 |
2845 // Save Rbox in Rscratch to be used for the cas operation | 2845 // Save Rbox in Rscratch to be used for the cas operation |
2846 mov(Rbox, Rscratch); | 2846 mov(Rbox, Rscratch); |
2879 if (EmitSync & 256) { | 2879 if (EmitSync & 256) { |
2880 Label IsInflated ; | 2880 Label IsInflated ; |
2881 | 2881 |
2882 ld_ptr (mark_addr, Rmark); // fetch obj->mark | 2882 ld_ptr (mark_addr, Rmark); // fetch obj->mark |
2883 // Triage: biased, stack-locked, neutral, inflated | 2883 // Triage: biased, stack-locked, neutral, inflated |
2884 if (UseBiasedLocking) { | 2884 if (try_bias) { |
2885 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); | 2885 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); |
2886 // Invariant: if control reaches this point in the emitted stream | 2886 // Invariant: if control reaches this point in the emitted stream |
2887 // then Rmark has not been modified. | 2887 // then Rmark has not been modified. |
2888 } | 2888 } |
2889 | 2889 |
2943 // prefetch (mark_addr, Assembler::severalWritesAndPossiblyReads) ; | 2943 // prefetch (mark_addr, Assembler::severalWritesAndPossiblyReads) ; |
2944 | 2944 |
2945 ld_ptr (mark_addr, Rmark); // fetch obj->mark | 2945 ld_ptr (mark_addr, Rmark); // fetch obj->mark |
2946 // Triage: biased, stack-locked, neutral, inflated | 2946 // Triage: biased, stack-locked, neutral, inflated |
2947 | 2947 |
2948 if (UseBiasedLocking) { | 2948 if (try_bias) { |
2949 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); | 2949 biased_locking_enter(Roop, Rmark, Rscratch, done, NULL, counters); |
2950 // Invariant: if control reaches this point in the emitted stream | 2950 // Invariant: if control reaches this point in the emitted stream |
2951 // then Rmark has not been modified. | 2951 // then Rmark has not been modified. |
2952 } | 2952 } |
2953 andcc (Rmark, 2, G0) ; | 2953 andcc (Rmark, 2, G0) ; |
3037 } | 3037 } |
3038 | 3038 |
3039 bind (done) ; | 3039 bind (done) ; |
3040 } | 3040 } |
3041 | 3041 |
3042 void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, Register Rbox, Register Rscratch) { | 3042 void MacroAssembler::compiler_unlock_object(Register Roop, Register Rmark, |
3043 Register Rbox, Register Rscratch, | |
3044 bool try_bias) { | |
3043 Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); | 3045 Address mark_addr(Roop, 0, oopDesc::mark_offset_in_bytes()); |
3044 | 3046 |
3045 Label done ; | 3047 Label done ; |
3046 | 3048 |
3047 if (EmitSync & 4) { | 3049 if (EmitSync & 4) { |
3048 cmp (SP, G0) ; | 3050 cmp (SP, G0) ; |
3049 return ; | 3051 return ; |
3050 } | 3052 } |
3051 | 3053 |
3052 if (EmitSync & 8) { | 3054 if (EmitSync & 8) { |
3053 if (UseBiasedLocking) { | 3055 if (try_bias) { |
3054 biased_locking_exit(mark_addr, Rscratch, done); | 3056 biased_locking_exit(mark_addr, Rscratch, done); |
3055 } | 3057 } |
3056 | 3058 |
3057 // Test first if it is a fast recursive unlock | 3059 // Test first if it is a fast recursive unlock |
3058 ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark); | 3060 ld_ptr(Rbox, BasicLock::displaced_header_offset_in_bytes(), Rmark); |
3075 // is too large performance rolls abruptly off a cliff. | 3077 // is too large performance rolls abruptly off a cliff. |
3076 // This could be related to inlining policies, code cache management, or | 3078 // This could be related to inlining policies, code cache management, or |
3077 // I$ effects. | 3079 // I$ effects. |
3078 Label LStacked ; | 3080 Label LStacked ; |
3079 | 3081 |
3080 if (UseBiasedLocking) { | 3082 if (try_bias) { |
3081 // TODO: eliminate redundant LDs of obj->mark | 3083 // TODO: eliminate redundant LDs of obj->mark |
3082 biased_locking_exit(mark_addr, Rscratch, done); | 3084 biased_locking_exit(mark_addr, Rscratch, done); |
3083 } | 3085 } |
3084 | 3086 |
3085 ld_ptr (Roop, oopDesc::mark_offset_in_bytes(), Rmark) ; | 3087 ld_ptr (Roop, oopDesc::mark_offset_in_bytes(), Rmark) ; |