Fri, 29 Apr 2016 00:06:10 +0800
Added MIPS 64-bit port.
1 /*
2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
3 * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 *
6 * This code is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License version 2 only, as
8 * published by the Free Software Foundation.
9 *
10 * This code is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * version 2 for more details (a copy is included in the LICENSE file that
14 * accompanied this code).
15 *
16 * You should have received a copy of the GNU General Public License version
17 * 2 along with this work; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *
20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21 * or visit www.oracle.com if you need additional information or have any
22 * questions.
23 *
24 */
26 #include "precompiled.hpp"
27 #include "c1/c1_MacroAssembler.hpp"
28 #include "c1/c1_Runtime1.hpp"
29 #include "classfile/systemDictionary.hpp"
30 #include "gc_interface/collectedHeap.hpp"
31 #include "interpreter/interpreter.hpp"
32 #include "oops/arrayOop.hpp"
33 #include "oops/markOop.hpp"
34 #include "runtime/basicLock.hpp"
35 #include "runtime/biasedLocking.hpp"
36 #include "runtime/os.hpp"
37 #include "runtime/stubRoutines.hpp"
39 int C1_MacroAssembler::lock_object(Register hdr, Register obj, Register disp_hdr,Register scratch, Label& slow_case) {
40 const int aligned_mask = BytesPerWord -1;
41 const int hdr_offset = oopDesc::mark_offset_in_bytes();
43 // hdr is just a temperary register, it cannot be AT, however
44 if ( hdr == NOREG ) {
45 hdr = T8;
46 }
48 assert_different_registers(hdr, obj, disp_hdr);
49 Label done;
50 // The following move must be the first instruction of emitted since debug
51 // information may be generated for it.
52 // Load object header
53 int null_check_offset = -1;
54 verify_oop(obj);
56 // save object being locked into the BasicObjectLock
57 st_ptr(obj, disp_hdr, BasicObjectLock::obj_offset_in_bytes());
58 if (UseBiasedLocking) {
59 assert(scratch != noreg, "should have scratch register at this point");
60 null_check_offset = biased_locking_enter(disp_hdr, obj, hdr, scratch, false,
61 done, &slow_case);
62 } else {
63 null_check_offset = offset();
64 }
66 // Load object header
67 ld_ptr(hdr, obj, hdr_offset);
68 // and mark it as unlocked
69 ori(hdr, hdr, markOopDesc::unlocked_value);
70 // save unlocked object header into the displaced header location on the stack
71 sd(hdr, disp_hdr, 0);
73 // test if object header is still the same (i.e. unlocked), and if so, store the
74 // displaced header address in the object header - if it is not the same, get the
75 // object header instead
76 //if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg!
77 cmpxchg(disp_hdr, Address(obj, hdr_offset), hdr);
78 // if the object header was the same, we're done
79 if (PrintBiasedLockingStatistics) {
80 //cond_incl(Assembler::equal,
81 //Address((int) BiasedLocking::fast_path_entry_count_addr(), relocInfo::none));
82 // cond_incl(Assembler::equal,
83 // Address((int) BiasedLocking::fast_path_entry_count_addr(), relocInfo::none));
85 }
88 bne(AT, R0, done);
89 delayed()->nop();
90 // if the object header was not the same, it is now in the hdr register
91 // => test if it is a stack pointer into the same stack (recursive locking), i.e.:
92 //
93 // 1) (hdr & aligned_mask) == 0
94 // 2) SP <= hdr
95 // 3) hdr <= SP + page_size
96 //
97 // these 3 tests can be done by evaluating the following expression:
98 //
99 // (hdr - SP) & (aligned_mask - page_size)
100 //
101 // assuming both the stack pointer and page_size have their least
102 // significant 2 bits cleared and page_size is a power of 2
103 sub(hdr, hdr, SP);
104 move(AT, aligned_mask - os::vm_page_size());
105 andr(hdr, hdr, AT);
106 // for recursive locking, the result is zero => save it in the displaced header
107 // location (NULL in the displaced hdr location indicates recursive locking)
108 st_ptr(hdr, disp_hdr, 0);
109 // otherwise we don't care about the result and handle locking via runtime call
110 bne_far(hdr, R0, slow_case);
111 delayed()->nop();
112 // done
113 bind(done);
114 return null_check_offset;
115 }
118 void C1_MacroAssembler::unlock_object(Register hdr, Register obj, Register disp_hdr, Label& slow_case) {
119 const int aligned_mask = BytesPerWord -1;
120 const int hdr_offset = oopDesc::mark_offset_in_bytes();
122 // hdr is just a temparay register, however, it cannot be AT
123 if ( hdr == NOREG ) {
124 hdr = T8;
125 }
127 assert_different_registers(hdr, obj, disp_hdr);
128 assert(BytesPerWord == 8, "adjust aligned_mask and code");
129 Label done;
130 if (UseBiasedLocking) {
131 // load object
132 ld_ptr(obj, Address(disp_hdr, BasicObjectLock::obj_offset_in_bytes()));
133 biased_locking_exit(obj, hdr, done);
134 }
138 // load displaced header
139 ld_ptr(hdr, disp_hdr, 0);
140 // if the loaded hdr is NULL we had recursive locking
141 // if we had recursive locking, we are done
142 beq(hdr, R0, done);
143 delayed()->nop();
144 // load object
145 if(!UseBiasedLocking){
146 ld_ptr(obj, disp_hdr, BasicObjectLock::obj_offset_in_bytes());
147 }
149 verify_oop(obj);
150 // test if object header is pointing to the displaced header, and if so, restore
151 // the displaced header in the object - if the object header is not pointing to
152 // the displaced header, get the object header instead
153 //if (os::is_MP()) MacroAssembler::lock(); // must be immediately before cmpxchg!
154 cmpxchg(hdr, Address(obj, hdr_offset), disp_hdr);
155 // if the object header was not pointing to the displaced header,
156 // we do unlocking via runtime call
157 beq_far(AT, R0, slow_case);
158 delayed()->nop();
159 // done
160 bind(done);
161 }
165 // Defines obj, preserves var_size_in_bytes
166 void C1_MacroAssembler::try_allocate(Register obj, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2, Label& slow_case) {
167 if (UseTLAB) {
168 tlab_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
169 } else {
170 eden_allocate(obj, var_size_in_bytes, con_size_in_bytes, t1, t2, slow_case);
171 }
172 }
174 void C1_MacroAssembler::initialize_header(Register obj, Register klass, Register len, Register t1 , Register t2) {
175 assert_different_registers(obj, klass, len, AT);
177 if (UseBiasedLocking && !len->is_valid()) {
178 assert_different_registers(obj, klass, len, t1, t2);
179 ld_ptr(t1, klass, in_bytes(Klass::prototype_header_offset()));
180 st_ptr(t1, obj, oopDesc::mark_offset_in_bytes());
181 } else {
182 li(AT, (intptr_t)markOopDesc::prototype());
183 st_ptr(AT, obj, oopDesc::mark_offset_in_bytes());
184 }
185 //st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
186 #ifdef _LP64
187 if (UseCompressedOops) {
188 move(AT, klass);
189 store_klass(obj, AT);
190 } else
191 #endif
192 {
193 st_ptr(klass, obj, oopDesc::klass_offset_in_bytes());
194 }
196 if (len->is_valid()) {
197 sw(len, obj, arrayOopDesc::length_offset_in_bytes());
198 }
199 #ifdef _LP64
200 else if (UseCompressedOops) {
201 store_klass_gap(obj, R0);
202 }
204 #endif
205 }
207 // preserves obj, destroys len_in_bytes
208 void C1_MacroAssembler::initialize_body(Register obj, Register len_in_bytes, int hdr_size_in_bytes, Register t1) {
209 Label done;
210 Register ptr = t1;
211 assert_different_registers(obj, ptr, len_in_bytes);
212 assert((hdr_size_in_bytes & (BytesPerWord - 1)) == 0,
213 "header size is not a multiple of BytesPerWord");
214 Register index = len_in_bytes;
216 //tty->print_cr("C1_MacroAssembler::initialize_body LEN=0x%x, hdr_size=0x%x", len_in_bytes, hdr_size_in_bytes);
217 assert(is_simm16(hdr_size_in_bytes), "change this code");
218 addi(index, index, - hdr_size_in_bytes);
219 beq(index, R0, done);
220 delayed();
222 // initialize topmost word, divide index by 2, check if odd and test if zero
223 // note: for the remaining code to work, index must be a multiple of BytesPerWord
224 #ifdef ASSERT
225 {
226 Label L;
227 andi(AT, index, BytesPerWord - 1);
228 beq(AT, R0, L);
229 delayed()->nop();
230 stop("index is not a multiple of BytesPerWord");
231 bind(L);
232 }
233 #endif
234 // index could have been not a multiple of 8 (i.e., bit 2 was set)
235 {
236 Label even;
237 // note: if index was a multiple of 8, than it cannot
238 // be 0 now otherwise it must have been 0 before
239 // => if it is even, we don't need to check for 0 again
240 #ifdef _LP64
241 andi(AT, index, 8);
242 shr(index, 4);
243 shl(index, 4);
244 #else
245 andi(AT, index, 4);
246 shr(index, 3);
247 shl(index, 3);
248 #endif
249 beq(AT, R0, even);
250 delayed()->add(ptr, obj, index);
251 // clear topmost word (no jump needed if conditional assignment would work here)
252 st_ptr(R0, ptr, hdr_size_in_bytes);
253 // index could be 0 now, need to check again
254 beq(index, R0, done);
255 delayed()->nop();
256 bind(even);
257 }
258 // initialize remaining object fields: edx is a multiple of 2 now
259 {
260 Label loop;
261 bind(loop);
262 st_ptr(R0, ptr, hdr_size_in_bytes - 1*BytesPerWord);
263 st_ptr(R0, ptr, hdr_size_in_bytes - 2*BytesPerWord);
265 addi(index, index, - 2 * wordSize);
266 bne(index, R0, loop);
267 delayed()->addi(ptr, ptr, - 2 * wordSize);
268 }
270 // done
271 bind(done);
272 }
274 void C1_MacroAssembler::allocate_object(Register obj, Register t1, Register t2, int header_size, int object_size, Register klass, Label& slow_case) {
275 //assert(obj == rax, "obj must be in rax, for cmpxchg");
276 assert(obj != t1 && obj != t2 && t1 != t2, "registers must be different"); // XXX really?
277 assert(header_size >= 0 && object_size >= header_size, "illegal sizes");
279 try_allocate(obj, noreg, object_size * BytesPerWord, t1, t2, slow_case);
281 initialize_object(obj, klass, noreg, object_size * HeapWordSize, t1, t2);
282 }
284 void C1_MacroAssembler::initialize_object(Register obj, Register klass, Register var_size_in_bytes, int con_size_in_bytes, Register t1, Register t2) {
285 assert((con_size_in_bytes & MinObjAlignmentInBytesMask) == 0,
286 "con_size_in_bytes is not multiple of alignment");
287 //Merged from b25
288 const int hdr_size_in_bytes = instanceOopDesc::header_size() * HeapWordSize;
290 // initialize_header(obj, klass, NOREG);
291 initialize_header(obj, klass, NOREG,t1,t2);
293 // clear rest of allocated space
294 const Register index = t2;
295 //FIXME, x86 changed the value in jdk6
296 // const int threshold = hdr_size_in_bytes + 36;
297 // // approximate break even point for code size (see comments below)
298 const int threshold = 6 * BytesPerWord;
299 // approximate break even point for code size (see comments below)
300 if (var_size_in_bytes != NOREG) {
301 move(index, var_size_in_bytes);
302 initialize_body(obj, index, hdr_size_in_bytes, t1);
303 } else if (con_size_in_bytes <= threshold) {
304 // use explicit null stores
305 // code size = 4*n bytes (n = number of fields to clear)
307 for (int i = hdr_size_in_bytes; i < con_size_in_bytes; i += BytesPerWord) {
308 st_ptr(R0, obj, i);
309 }
313 } else if(con_size_in_bytes > hdr_size_in_bytes) {
314 // use loop to null out the fields
315 // code size = 32 bytes for even n (n = number of fields to clear)
316 // initialize last object field first if odd number of fields
317 assert( ((con_size_in_bytes - hdr_size_in_bytes) >> 3)!=0, "change code here");
319 #ifdef _LP64
320 move(index, (con_size_in_bytes - hdr_size_in_bytes) >> 4);
321 sll(t1, index, 4);
322 #else
323 move(index, (con_size_in_bytes - hdr_size_in_bytes) >> 3);
324 sll(t1, index, 3);
325 #endif
326 add(t1, obj, t1);
328 // initialize last object field if constant size is odd
329 #ifdef _LP64
330 if (! UseCompressedOops)
331 {
332 if (((con_size_in_bytes - hdr_size_in_bytes) & 8) != 0) {
333 sd(R0, t1, hdr_size_in_bytes);
334 }
335 } else if (UseCompressedOops) {
336 int extra = (con_size_in_bytes - hdr_size_in_bytes) % 16;
337 while (extra != 0) {
338 sw(R0, t1, hdr_size_in_bytes + extra - 4);
339 extra -= 4;
340 }
341 }
342 #else
343 if (((con_size_in_bytes - hdr_size_in_bytes) & 4) != 0) {
344 sw(R0, t1, hdr_size_in_bytes);
345 }
346 #endif
347 // initialize remaining object fields: edx is a multiple of 2
348 {
349 Label loop;
350 bind(loop);
351 st_ptr(R0, t1, hdr_size_in_bytes - (1*BytesPerWord));
352 st_ptr(R0, t1, hdr_size_in_bytes - (2*BytesPerWord));
353 addi(index, index, -1);
354 bne(index, R0, loop);
355 delayed()->addi(t1, t1, - 2 * wordSize);
356 }
357 }
359 if (DTraceAllocProbes) {
360 //assert(obj == eax, "must be");
361 call(CAST_FROM_FN_PTR(address,
362 Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)), relocInfo::runtime_call_type);
363 delayed()->nop();
364 }
365 verify_oop(obj);
366 }
368 void C1_MacroAssembler::allocate_array(Register obj, Register len, Register t1, Register t2, Register t3,int header_size,
369 int scale, Register klass, Label& slow_case) {
370 assert(obj == V0, "obj must be in V0 for cmpxchg");
371 assert_different_registers(obj, len, t1, t2, t3,klass, AT);
373 // determine alignment mask
374 assert(BytesPerWord == 8, "must be a multiple of 2 for masking code to work");
376 // check for negative or excessive length
377 //const int max_length = 0x00FFFFFF;
378 // move(AT, max_length);
379 move(AT, max_array_allocation_length);
380 sltu(AT, AT, len);
381 bne_far(AT, R0, slow_case);
382 delayed()->nop();
384 const Register arr_size = t3;
385 // align object end
386 move(arr_size, header_size * BytesPerWord + MinObjAlignmentInBytesMask);
387 sll(AT, len, scale);
388 add(arr_size, arr_size, AT);
389 move(AT, ~MinObjAlignmentInBytesMask);
390 andr(arr_size, arr_size, AT);
392 try_allocate(obj, arr_size, 0, t1, t2, slow_case);
394 initialize_header(obj, klass, len,t1,t2);
396 // clear rest of allocated space
397 const Register len_zero = len;
398 initialize_body(obj, arr_size, header_size * BytesPerWord, len_zero);
399 if (DTraceAllocProbes) {
400 // assert(obj == eax, "must be");
401 call(CAST_FROM_FN_PTR(address,
402 Runtime1::entry_for(Runtime1::dtrace_object_alloc_id)),
403 relocInfo::runtime_call_type);
404 delayed()->nop();
405 }
407 verify_oop(obj);
408 }
411 void C1_MacroAssembler::inline_cache_check(Register receiver, Register iCache) {
412 verify_oop(receiver);
413 // explicit NULL check not needed since load from [klass_offset] causes a trap
414 // check against inline cache
415 assert(!MacroAssembler::needs_explicit_null_check(oopDesc::klass_offset_in_bytes()), "must add explicit null check");
416 ///cmpl(iCache, Address(receiver, oopDesc::klass_offset_in_bytes()));
417 // if icache check fails, then jump to runtime routine
418 // Note: RECEIVER must still contain the receiver!
419 Label L;
420 #ifdef _LP64
421 //ld_ptr(AT, receiver, oopDesc::klass_offset_in_bytes());
422 //add for compressedoops
423 load_klass(AT, receiver);
424 #else
425 lw(AT, receiver, oopDesc::klass_offset_in_bytes());
426 #endif
427 beq(AT, iCache, L);
428 delayed()->nop();
429 // jmp(Runtime1::entry_for(Runtime1::handle_ic_miss_id), relocInfo::runtime_call_type);
430 jmp(SharedRuntime::get_ic_miss_stub(), relocInfo::runtime_call_type);
431 delayed()->nop();
432 bind(L);
433 // assert(UseCompressedOops, "check alignment in emit_method_entry");
434 }
435 /*
436 void C1_MacroAssembler::method_exit(bool restore_frame) {
437 if (restore_frame) {
438 leave();
439 }
440 jr(RA);
441 delayed()->nop();
442 }*/
445 void C1_MacroAssembler::build_frame(int frame_size_in_bytes, int bang_size_in_bytes) {
446 // Make sure there is enough stack space for this method's activation.
447 // Note that we do this before doing an enter(). This matches the
448 // ordering of C2's stack overflow check / esp decrement and allows
449 // the SharedRuntime stack overflow handling to be consistent
450 // between the two compilers.
451 generate_stack_overflow_check(frame_size_in_bytes);
453 enter();
454 //FIXME
455 #ifdef TIERED
456 // c2 leaves fpu stack dirty. Clean it on entry
457 // if (UseSSE < 2 ) {
458 empty_FPU_stack();
459 // }
460 #endif // TIERED
462 decrement(SP, frame_size_in_bytes); // does not emit code for frame_size == 0
463 }
465 void C1_MacroAssembler::unverified_entry(Register receiver, Register ic_klass) {
466 if (C1Breakpoint) int3();
467 inline_cache_check(receiver, ic_klass);
468 }
471 void C1_MacroAssembler::verified_entry() {
472 if (C1Breakpoint)int3();
473 // build frame
474 verify_FPU(0, "method_entry");
475 }
478 #ifndef PRODUCT
479 void C1_MacroAssembler::verify_stack_oop(int stack_offset) {
480 if (!VerifyOops) return;
481 // verify_oop_addr(Address(esp, stack_offset));
482 verify_oop_addr(Address(SP, stack_offset));
483 }
485 void C1_MacroAssembler::verify_not_null_oop(Register r) {
486 if (!VerifyOops) return;
487 Label not_null;
488 // testl(r, r);
489 //jcc(Assembler::notZero, not_null);
490 bne(r,R0,not_null);
491 delayed()->nop();
492 stop("non-null oop required");
493 bind(not_null);
494 verify_oop(r);
495 }
497 void C1_MacroAssembler::invalidate_registers(bool inv_v0, bool inv_v1, bool inv_t3, bool inv_t7, bool inv_s0, bool inv_s7) {
498 #ifdef ASSERT
499 /* if (inv_eax) movl(eax, 0xDEAD);
500 if (inv_ebx) movl(ebx, 0xDEAD);
501 if (inv_ecx) movl(ecx, 0xDEAD);
502 if (inv_edx) movl(edx, 0xDEAD);
503 if (inv_esi) movl(esi, 0xDEAD);
504 if (inv_edi) movl(edi, 0xDEAD);
505 */
506 //if (inv_v0) move(V0, 0xDEAD);
507 //if (inv_v1) move(V1, 0xDEAD);
508 //if (inv_t3) move(T3, 0xDEAD);
509 //if (inv_t7) move(T7, 0xDEAD);
510 //if (inv_s0) move(S0, 0xDEAD);
511 //if (inv_s7) move(S7, 0xDEAD);
512 #endif
513 }
514 #endif // ifndef PRODUCT