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