40
40
int C1_MacroAssembler::lock_object (Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
41
41
const int aligned_mask = BytesPerWord -1 ;
42
42
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 );
44
44
int null_check_offset = -1 ;
45
- Label done;
46
45
47
46
verify_oop (obj);
48
47
@@ -61,39 +60,44 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr
61
60
62
61
// Load object header
63
62
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
+ }
97
101
increment (Address (TREG, JavaThread::held_monitor_count_offset ()), 1 );
98
102
return null_check_offset;
99
103
}
@@ -104,27 +108,39 @@ void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_
104
108
assert (hdr != obj && hdr != disp_hdr && obj != disp_hdr, " registers must be different" );
105
109
Label done;
106
110
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
+
112
119
// load object
113
120
ld_d (obj, Address (disp_hdr, BasicObjectLock::obj_offset_in_bytes ()));
114
121
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);
125
143
}
126
- // done
127
- bind (done);
128
144
decrement (Address (TREG, JavaThread::held_monitor_count_offset ()), 1 );
129
145
}
130
146
0 commit comments