4040int C1_MacroAssembler::lock_object (Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
4141 const int aligned_mask = BytesPerWord -1 ;
4242 const int hdr_offset = oopDesc::mark_offset_in_bytes ();
43- assert (hdr != obj && hdr != disp_hdr && obj != disp_hdr, " registers must be different " );
43+ assert_different_registers (hdr, obj, disp_hdr );
4444 int null_check_offset = -1 ;
45- Label done;
4645
4746 verify_oop (obj);
4847
@@ -61,39 +60,44 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
6160
6261 // Load object header
6362 ld_d (hdr, Address (obj, hdr_offset));
64- // and mark it as unlocked
65- ori (hdr, hdr, markWord::unlocked_value);
66- // save unlocked object header into the displaced header location on the stack
67- st_d (hdr, Address (disp_hdr, 0 ));
68- // test if object header is still the same (i.e. unlocked), and if so, store the
69- // displaced header address in the object header - if it is not the same, get the
70- // object header instead
71- lea (SCR2, Address (obj, hdr_offset));
72- cmpxchg (Address (SCR2, 0 ), hdr, disp_hdr, SCR1, true , false , done);
73- // if the object header was the same, we're done
74- // if the object header was not the same, it is now in the hdr register
75- // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
76- //
77- // 1) (hdr & aligned_mask) == 0
78- // 2) sp <= hdr
79- // 3) hdr <= sp + page_size
80- //
81- // these 3 tests can be done by evaluating the following expression:
82- //
83- // (hdr - sp) & (aligned_mask - page_size)
84- //
85- // assuming both the stack pointer and page_size have their least
86- // significant 2 bits cleared and page_size is a power of 2
87- sub_d (hdr, hdr, SP);
88- li (SCR1, aligned_mask - os::vm_page_size ());
89- andr (hdr, hdr, SCR1);
90- // for recursive locking, the result is zero => save it in the displaced header
91- // location (null in the displaced hdr location indicates recursive locking)
92- st_d (hdr, Address (disp_hdr, 0 ));
93- // otherwise we don't care about the result and handle locking via runtime call
94- bnez (hdr, slow_case);
95- // done
96- bind (done);
63+ if (LockingMode == LM_LIGHTWEIGHT) {
64+ fast_lock (obj, hdr, SCR1, SCR2, slow_case);
65+ } else if (LockingMode == LM_LEGACY) {
66+ Label done;
67+ // and mark it as unlocked
68+ ori (hdr, hdr, markWord::unlocked_value);
69+ // save unlocked object header into the displaced header location on the stack
70+ st_d (hdr, Address (disp_hdr, 0 ));
71+ // test if object header is still the same (i.e. unlocked), and if so, store the
72+ // displaced header address in the object header - if it is not the same, get the
73+ // object header instead
74+ lea (SCR2, Address (obj, hdr_offset));
75+ cmpxchg (Address (SCR2, 0 ), hdr, disp_hdr, SCR1, true , false , done);
76+ // if the object header was the same, we're done
77+ // if the object header was not the same, it is now in the hdr register
78+ // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
79+ //
80+ // 1) (hdr & aligned_mask) == 0
81+ // 2) sp <= hdr
82+ // 3) hdr <= sp + page_size
83+ //
84+ // these 3 tests can be done by evaluating the following expression:
85+ //
86+ // (hdr - sp) & (aligned_mask - page_size)
87+ //
88+ // assuming both the stack pointer and page_size have their least
89+ // significant 2 bits cleared and page_size is a power of 2
90+ sub_d (hdr, hdr, SP);
91+ li (SCR1, aligned_mask - os::vm_page_size ());
92+ andr (hdr, hdr, SCR1);
93+ // for recursive locking, the result is zero => save it in the displaced header
94+ // location (null in the displaced hdr location indicates recursive locking)
95+ st_d (hdr, Address (disp_hdr, 0 ));
96+ // otherwise we don't care about the result and handle locking via runtime call
97+ bnez (hdr, slow_case);
98+ // done
99+ bind (done);
100+ }
97101 increment (Address (TREG, JavaThread::held_monitor_count_offset ()), 1 );
98102 return null_check_offset;
99103}
@@ -104,27 +108,39 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
104108 assert (hdr != obj && hdr != disp_hdr && obj != disp_hdr, " registers must be different" );
105109 Label done;
106110
107- // load displaced header
108- ld_d (hdr, Address (disp_hdr, 0 ));
109- // if the loaded hdr is null we had recursive locking
110- // if we had recursive locking, we are done
111- beqz (hdr, done);
111+ if (LockingMode != LM_LIGHTWEIGHT) {
112+ // load displaced header
113+ ld_d (hdr, Address (disp_hdr, 0 ));
114+ // if the loaded hdr is null we had recursive locking
115+ // if we had recursive locking, we are done
116+ beqz (hdr, done);
117+ }
118+
112119 // load object
113120 ld_d (obj, Address (disp_hdr, BasicObjectLock::obj_offset_in_bytes ()));
114121 verify_oop (obj);
115- // test if object header is pointing to the displaced header, and if so, restore
116- // the displaced header in the object - if the object header is not pointing to
117- // the displaced header, get the object header instead
118- // if the object header was not pointing to the displaced header,
119- // we do unlocking via runtime call
120- if (hdr_offset) {
121- lea (SCR1, Address (obj, hdr_offset));
122- cmpxchg (Address (SCR1, 0 ), disp_hdr, hdr, SCR2, false , false , done, &slow_case);
123- } else {
124- cmpxchg (Address (obj, 0 ), disp_hdr, hdr, SCR2, false , false , done, &slow_case);
122+ if (LockingMode == LM_LIGHTWEIGHT) {
123+ ld_d (hdr, Address (obj, oopDesc::mark_offset_in_bytes ()));
124+ // We cannot use tbnz here, the target might be too far away and cannot
125+ // be encoded.
126+ andi (AT, hdr, markWord::monitor_value);
127+ bnez (AT, slow_case);
128+ fast_unlock (obj, hdr, SCR1, SCR2, slow_case);
129+ } else if (LockingMode == LM_LEGACY) {
130+ // test if object header is pointing to the displaced header, and if so, restore
131+ // the displaced header in the object - if the object header is not pointing to
132+ // the displaced header, get the object header instead
133+ // if the object header was not pointing to the displaced header,
134+ // we do unlocking via runtime call
135+ if (hdr_offset) {
136+ lea (SCR1, Address (obj, hdr_offset));
137+ cmpxchg (Address (SCR1, 0 ), disp_hdr, hdr, SCR2, false , false , done, &slow_case);
138+ } else {
139+ cmpxchg (Address (obj, 0 ), disp_hdr, hdr, SCR2, false , false , done, &slow_case);
140+ }
141+ // done
142+ bind (done);
125143 }
126- // done
127- bind (done);
128144 decrement (Address (TREG, JavaThread::held_monitor_count_offset ()), 1 );
129145}
130146
0 commit comments