66 load_klass(hdr, obj);
67 lbu(hdr, Address(hdr, Klass::misc_flags_offset()));
68 test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class));
69 bnez(temp, slow_case, true /* is_far */);
70 }
71
72 if (LockingMode == LM_LIGHTWEIGHT) {
73 lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
74 } else if (LockingMode == LM_LEGACY) {
75 Label done;
76 // Load object header
77 ld(hdr, Address(obj, hdr_offset));
78 // and mark it as unlocked
79 ori(hdr, hdr, markWord::unlocked_value);
80 // save unlocked object header into the displaced header location on the stack
81 sd(hdr, Address(disp_hdr, 0));
82 // test if object header is still the same (i.e. unlocked), and if so, store the
83 // displaced header address in the object header - if it is not the same, get the
84 // object header instead
85 la(temp, Address(obj, hdr_offset));
86 cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
87 // if the object header was the same, we're done
88 // if the object header was not the same, it is now in the hdr register
89 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
90 //
91 // 1) (hdr & aligned_mask) == 0
92 // 2) sp <= hdr
93 // 3) hdr <= sp + page_size
94 //
95 // these 3 tests can be done by evaluating the following expression:
96 //
97 // (hdr -sp) & (aligned_mask - page_size)
98 //
99 // assuming both the stack pointer and page_size have their least
100 // significant 2 bits cleared and page_size is a power of 2
101 sub(hdr, hdr, sp);
102 mv(temp, aligned_mask - (int)os::vm_page_size());
103 andr(hdr, hdr, temp);
104 // for recursive locking, the result is zero => save it in the displaced header
105 // location (null in the displaced hdr location indicates recursive locking)
106 sd(hdr, Address(disp_hdr, 0));
107 // otherwise we don't care about the result and handle locking via runtime call
108 bnez(hdr, slow_case, /* is_far */ true);
109 // done
110 bind(done);
111 }
112
113 increment(Address(xthread, JavaThread::held_monitor_count_offset()));
114 return null_check_offset;
115 }
116
117 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
118 const int aligned_mask = BytesPerWord - 1;
119 const int hdr_offset = oopDesc::mark_offset_in_bytes();
120 assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
121 Label done;
122
123 if (LockingMode != LM_LIGHTWEIGHT) {
124 // load displaced header
125 ld(hdr, Address(disp_hdr, 0));
126 // if the loaded hdr is null we had recursive locking
127 // if we had recursive locking, we are done
128 beqz(hdr, done);
129 }
130
131 // load object
132 ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
133 verify_oop(obj);
134
135 if (LockingMode == LM_LIGHTWEIGHT) {
136 lightweight_unlock(obj, hdr, temp, t1, slow_case);
137 } else if (LockingMode == LM_LEGACY) {
138 // test if object header is pointing to the displaced header, and if so, restore
139 // the displaced header in the object - if the object header is not pointing to
140 // the displaced header, get the object header instead
141 // if the object header was not pointing to the displaced header,
142 // we do unlocking via runtime call
143 if (hdr_offset) {
144 la(temp, Address(obj, hdr_offset));
145 cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
146 } else {
147 cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
148 }
149 // done
150 bind(done);
151 }
152
153 decrement(Address(xthread, JavaThread::held_monitor_count_offset()));
154 }
155
156 // Defines obj, preserves var_size_in_bytes
157 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) {
158 if (UseTLAB) {
159 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, /* is_far */ true);
160 } else {
161 j(slow_case);
162 }
163 }
164
165 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
166 assert_different_registers(obj, klass, len, tmp1, tmp2);
167 // This assumes that all prototype bits fitr in an int32_t
168 mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value());
169 sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
170
171 if (UseCompressedClassPointers) { // Take care not to kill klass
172 encode_klass_not_null(tmp1, klass, tmp2);
173 sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
|
66 load_klass(hdr, obj);
67 lbu(hdr, Address(hdr, Klass::misc_flags_offset()));
68 test_bit(temp, hdr, exact_log2(KlassFlags::_misc_is_value_based_class));
69 bnez(temp, slow_case, true /* is_far */);
70 }
71
72 if (LockingMode == LM_LIGHTWEIGHT) {
73 lightweight_lock(disp_hdr, obj, hdr, temp, t1, slow_case);
74 } else if (LockingMode == LM_LEGACY) {
75 Label done;
76 // Load object header
77 ld(hdr, Address(obj, hdr_offset));
78 // and mark it as unlocked
79 ori(hdr, hdr, markWord::unlocked_value);
80 // save unlocked object header into the displaced header location on the stack
81 sd(hdr, Address(disp_hdr, 0));
82 // test if object header is still the same (i.e. unlocked), and if so, store the
83 // displaced header address in the object header - if it is not the same, get the
84 // object header instead
85 la(temp, Address(obj, hdr_offset));
86 // if the object header was the same, we're done
87 cmpxchgptr(hdr, disp_hdr, temp, t1, done, /*fallthough*/nullptr);
88 // if the object header was not the same, it is now in the hdr register
89 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
90 //
91 // 1) (hdr & aligned_mask) == 0
92 // 2) sp <= hdr
93 // 3) hdr <= sp + page_size
94 //
95 // these 3 tests can be done by evaluating the following expression:
96 //
97 // (hdr -sp) & (aligned_mask - page_size)
98 //
99 // assuming both the stack pointer and page_size have their least
100 // significant 2 bits cleared and page_size is a power of 2
101 sub(hdr, hdr, sp);
102 mv(temp, aligned_mask - (int)os::vm_page_size());
103 andr(hdr, hdr, temp);
104 // for recursive locking, the result is zero => save it in the displaced header
105 // location (null in the displaced hdr location indicates recursive locking)
106 sd(hdr, Address(disp_hdr, 0));
107 // otherwise we don't care about the result and handle locking via runtime call
108 bnez(hdr, slow_case, /* is_far */ true);
109
110 // done
111 bind(done);
112 inc_held_monitor_count();
113 }
114
115 return null_check_offset;
116 }
117
118 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Register temp, Label& slow_case) {
119 const int aligned_mask = BytesPerWord - 1;
120 const int hdr_offset = oopDesc::mark_offset_in_bytes();
121 assert_different_registers(hdr, obj, disp_hdr, temp, t0, t1);
122 Label done;
123
124 if (LockingMode != LM_LIGHTWEIGHT) {
125 // load displaced header
126 ld(hdr, Address(disp_hdr, 0));
127 // if the loaded hdr is null we had recursive locking
128 // if we had recursive locking, we are done
129 beqz(hdr, done);
130 }
131
132 // load object
133 ld(obj, Address(disp_hdr, BasicObjectLock::obj_offset()));
134 verify_oop(obj);
135
136 if (LockingMode == LM_LIGHTWEIGHT) {
137 lightweight_unlock(obj, hdr, temp, t1, slow_case);
138 } else if (LockingMode == LM_LEGACY) {
139 // test if object header is pointing to the displaced header, and if so, restore
140 // the displaced header in the object - if the object header is not pointing to
141 // the displaced header, get the object header instead
142 // if the object header was not pointing to the displaced header,
143 // we do unlocking via runtime call
144 if (hdr_offset) {
145 la(temp, Address(obj, hdr_offset));
146 cmpxchgptr(disp_hdr, hdr, temp, t1, done, &slow_case);
147 } else {
148 cmpxchgptr(disp_hdr, hdr, obj, t1, done, &slow_case);
149 }
150
151 // done
152 bind(done);
153 dec_held_monitor_count();
154 }
155 }
156
157 // Defines obj, preserves var_size_in_bytes
158 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register tmp1, Register tmp2, Label& slow_case) {
159 if (UseTLAB) {
160 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, tmp1, tmp2, slow_case, /* is_far */ true);
161 } else {
162 j(slow_case);
163 }
164 }
165
166 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register tmp1, Register tmp2) {
167 assert_different_registers(obj, klass, len, tmp1, tmp2);
168 // This assumes that all prototype bits fitr in an int32_t
169 mv(tmp1, (int32_t)(intptr_t)markWord::prototype().value());
170 sd(tmp1, Address(obj, oopDesc::mark_offset_in_bytes()));
171
172 if (UseCompressedClassPointers) { // Take care not to kill klass
173 encode_klass_not_null(tmp1, klass, tmp2);
174 sw(tmp1, Address(obj, oopDesc::klass_offset_in_bytes()));
|