128 // Defines obj, preserves var_size_in_bytes
129 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
130 if (UseTLAB) {
131 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
132 } else {
133 eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
134 }
135 }
136
137
138 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
139 assert_different_registers(obj, klass, len);
140 if (UseBiasedLocking && !len->is_valid()) {
141 assert_different_registers(obj, klass, len, t1, t2);
142 movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
143 movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
144 } else {
145 // This assumes that all prototype bits fit in an int32_t
146 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
147 }
148
149 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
150 if (len->is_valid()) {
151 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
152 }
153 }
154
155
156 // preserves obj, destroys len_in_bytes
157 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
158 Label done;
159 assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
160 assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
161 Register index = len_in_bytes;
162 // index is positive and ptr sized
163 subptr(index, hdr_size_in_bytes);
164 jcc(Assembler::zero, done);
165 // initialize topmost word, divide index by 2, check if odd and test if zero
166 // note: for the remaining code to work, index must be a multiple of BytesPerWord
167 #ifdef ASSERT
168 { Label L;
169 testptr(index, BytesPerWord - 1);
170 jcc(Assembler::zero, L);
171 stop("index is not a multiple of BytesPerWord");
172 bind(L);
203 }
204
205 // done
206 bind(done);
207 }
208
209
210 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
211 assert(obj == rax, "obj must be in rax, for cmpxchg");
212 assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
213 assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
214
215 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
216
217 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
218 }
219
220 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
221 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
222 "con_size_in_bytes is not multiple of alignment");
223 const int hdr_size_in_bytes = instanceOopDesc::base_offset_in_bytes();
224
225 initialize_header(obj, klass, noreg, t1, t2);
226
227 // clear rest of allocated space
228 const Register t1_zero = t1;
229 const Register index = t2;
230 const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below)
231 if (var_size_in_bytes != noreg) {
232 mov(index, var_size_in_bytes);
233 initialize_body(obj, index, hdr_size_in_bytes, t1_zero);
234 } else if (con_size_in_bytes <= threshold) {
235 // use explicit null stores
236 // code size = 2 + 3*n bytes (n = number of fields to clear)
237 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
238 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
239 movptr(Address(obj, i), t1_zero);
240 } else if (con_size_in_bytes > hdr_size_in_bytes) {
241 // use loop to null out the fields
242 // code size = 16 bytes for even n (n = number of fields to clear)
243 // initialize last object field first if odd number of fields
290 // clear rest of allocated space
291 const Register len_zero = len;
292 initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
293
294 if (CURRENT_ENV->dtrace_alloc_probes()) {
295 assert(obj == rax, "must be");
296 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
297 }
298
299 verify_oop(obj);
300 }
301
302
303
304 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
305 verify_oop(receiver);
306 // explicit NULL check not needed since load from [klass_offset] causes a trap
307 // check against inline cache
308 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
309 int start_offset = offset();
310 cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
311 // if icache check fails, then jump to runtime routine
312 // Note: RECEIVER must still contain the receiver!
313 jump_cc(Assembler::notEqual,
314 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
315 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
316 assert(offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
317 }
318
319
320 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
321 // Make sure there is enough stack space for this method's activation.
322 // Note that we do this before doing an enter(). This matches the
323 // ordering of C2's stack overflow check / rsp decrement and allows
324 // the SharedRuntime stack overflow handling to be consistent
325 // between the two compilers.
326 generate_stack_overflow_check(frame_size_in_bytes);
327
328 push(rbp);
329 #ifdef TIERED
330 // c2 leaves fpu stack dirty. Clean it on entry
331 if (UseSSE < 2 ) {
332 empty_FPU_stack();
333 }
334 #endif // TIERED
335 decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
336 }
|
128 // Defines obj, preserves var_size_in_bytes
129 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
130 if (UseTLAB) {
131 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
132 } else {
133 eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, slow_case);
134 }
135 }
136
137
138 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1, Register t2) {
139 assert_different_registers(obj, klass, len);
140 if (UseBiasedLocking && !len->is_valid()) {
141 assert_different_registers(obj, klass, len, t1, t2);
142 movptr(t1, Address(klass, Klass::prototype_header_offset_in_bytes() + klassOopDesc::klass_part_offset_in_bytes()));
143 movptr(Address(obj, oopDesc::mark_offset_in_bytes()), t1);
144 } else {
145 // This assumes that all prototype bits fit in an int32_t
146 movptr(Address(obj, oopDesc::mark_offset_in_bytes ()), (int32_t)(intptr_t)markOopDesc::prototype());
147 }
148 #ifdef _LP64
149 if (UseCompressedOops) { // Take care not to kill klass
150 movptr(t1, klass);
151 encode_heap_oop_not_null(t1);
152 movl(Address(obj, oopDesc::klass_offset_in_bytes()), t1);
153 } else
154 #endif
155 {
156 movptr(Address(obj, oopDesc::klass_offset_in_bytes()), klass);
157 }
158
159 if (len->is_valid()) {
160 movl(Address(obj, arrayOopDesc::length_offset_in_bytes()), len);
161 }
162 #ifdef _LP64
163 else if (UseCompressedOops) {
164 xorptr(t1, t1);
165 store_klass_gap(obj, t1);
166 }
167 #endif // _LP64
168 }
169
170
171 // preserves obj, destroys len_in_bytes
172 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
173 Label done;
174 assert(obj != len_in_bytes && obj != t1 && t1 != len_in_bytes, "registers must be different");
175 assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0, "header size is not a multiple of BytesPerWord");
176 Register index = len_in_bytes;
177 // index is positive and ptr sized
178 subptr(index, hdr_size_in_bytes);
179 jcc(Assembler::zero, done);
180 // initialize topmost word, divide index by 2, check if odd and test if zero
181 // note: for the remaining code to work, index must be a multiple of BytesPerWord
182 #ifdef ASSERT
183 { Label L;
184 testptr(index, BytesPerWord - 1);
185 jcc(Assembler::zero, L);
186 stop("index is not a multiple of BytesPerWord");
187 bind(L);
218 }
219
220 // done
221 bind(done);
222 }
223
224
225 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
226 assert(obj == rax, "obj must be in rax, for cmpxchg");
227 assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
228 assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
229
230 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
231
232 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
233 }
234
235 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
236 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
237 "con_size_in_bytes is not multiple of alignment");
238 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
239
240 initialize_header(obj, klass, noreg, t1, t2);
241
242 // clear rest of allocated space
243 const Register t1_zero = t1;
244 const Register index = t2;
245 const int threshold = 6 * BytesPerWord; // approximate break even point for code size (see comments below)
246 if (var_size_in_bytes != noreg) {
247 mov(index, var_size_in_bytes);
248 initialize_body(obj, index, hdr_size_in_bytes, t1_zero);
249 } else if (con_size_in_bytes <= threshold) {
250 // use explicit null stores
251 // code size = 2 + 3*n bytes (n = number of fields to clear)
252 xorptr(t1_zero, t1_zero); // use t1_zero reg to clear memory (shorter code)
253 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord)
254 movptr(Address(obj, i), t1_zero);
255 } else if (con_size_in_bytes > hdr_size_in_bytes) {
256 // use loop to null out the fields
257 // code size = 16 bytes for even n (n = number of fields to clear)
258 // initialize last object field first if odd number of fields
305 // clear rest of allocated space
306 const Register len_zero = len;
307 initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
308
309 if (CURRENT_ENV->dtrace_alloc_probes()) {
310 assert(obj == rax, "must be");
311 call(RuntimeAddress(Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)));
312 }
313
314 verify_oop(obj);
315 }
316
317
318
319 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
320 verify_oop(receiver);
321 // explicit NULL check not needed since load from [klass_offset] causes a trap
322 // check against inline cache
323 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
324 int start_offset = offset();
325 #ifdef _LP64
326 if (UseCompressedOops) {
327 load_klass(rscratch1, receiver);
328 cmpptr(rscratch1, iCache);
329 } else
330 #endif
331 cmpptr(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
332 // if icache check fails, then jump to runtime routine
333 // Note: RECEIVER must still contain the receiver!
334 jump_cc(Assembler::notEqual,
335 RuntimeAddress(SharedRuntime::get_ic_miss_stub()));
336 const int ic_cmp_size = LP64_ONLY(10) NOT_LP64(9);
337 assert(UseCompressedOops || offset() - start_offset == ic_cmp_size, "check alignment in emit_method_entry");
338 }
339
340
341 void C1_MacroAssembler::build_frame(int frame_size_in_bytes) {
342 // Make sure there is enough stack space for this method's activation.
343 // Note that we do this before doing an enter(). This matches the
344 // ordering of C2's stack overflow check / rsp decrement and allows
345 // the SharedRuntime stack overflow handling to be consistent
346 // between the two compilers.
347 generate_stack_overflow_check(frame_size_in_bytes);
348
349 push(rbp);
350 #ifdef TIERED
351 // c2 leaves fpu stack dirty. Clean it on entry
352 if (UseSSE < 2 ) {
353 empty_FPU_stack();
354 }
355 #endif // TIERED
356 decrement(rsp, frame_size_in_bytes); // does not emit code for frame_size == 0
357 }
|