1 /*
2 /*
3 * Copyright (c) 2013, Red Hat Inc.
4 * Copyright (c) 1997, 2012, Oracle and/or its affiliates.
5 * All rights reserved.
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7 *
8 * This code is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License version 2 only, as
10 * published by the Free Software Foundation.
11 *
12 * This code is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 * version 2 for more details (a copy is included in the LICENSE file that
16 * accompanied this code).
17 *
18 * You should have received a copy of the GNU General Public License version
19 * 2 along with this work; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23 * or visit www.oracle.com if you need additional information or have any
24 * questions.
25 *
26 */
27
28 #include <sys/types.h>
29
30 #include "precompiled.hpp"
31 #include "asm/assembler.hpp"
32 #include "asm/assembler.inline.hpp"
33 #include "interpreter/interpreter.hpp"
34
35 #include "compiler/disassembler.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "runtime/biasedLocking.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/sharedRuntime.hpp"
40
41 // #include "gc_interface/collectedHeap.inline.hpp"
42 // #include "interpreter/interpreter.hpp"
43 // #include "memory/cardTableModRefBS.hpp"
44 // #include "prims/methodHandles.hpp"
45 // #include "runtime/biasedLocking.hpp"
46 // #include "runtime/interfaceSupport.hpp"
47 // #include "runtime/objectMonitor.hpp"
48 // #include "runtime/os.hpp"
49 // #include "runtime/sharedRuntime.hpp"
50 // #include "runtime/stubRoutines.hpp"
51
52 #if INCLUDE_ALL_GCS
53 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
54 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
55 #include "gc_implementation/g1/heapRegion.hpp"
56 #endif
57
58 #ifdef COMPILER2
59 #include "opto/node.hpp"
60 #include "opto/compile.hpp"
61 #endif
62
63 #ifdef PRODUCT
64 #define BLOCK_COMMENT(str) /* nothing */
65 #define STOP(error) stop(error)
66 #else
67 #define BLOCK_COMMENT(str) block_comment(str)
68 #define STOP(error) block_comment(error); stop(error)
69 #endif
70
71 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
72
73 // Patch any kind of instruction; there may be several instructions.
74 // Return the total length (in bytes) of the instructions.
75 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
1627 // constant
1628 u_int32_t imm_h[2];
1629 imm_h[0] = imm32 & 0xffff;
1630 imm_h[1] = ((imm32 >> 16) & 0xffff);
1631 if (imm_h[0] == 0) {
1632 movzw(dst, imm_h[1], 16);
1633 } else if (imm_h[0] == 0xffff) {
1634 movnw(dst, imm_h[1] ^ 0xffff, 16);
1635 } else if (imm_h[1] == 0) {
1636 movzw(dst, imm_h[0], 0);
1637 } else if (imm_h[1] == 0xffff) {
1638 movnw(dst, imm_h[0] ^ 0xffff, 0);
1639 } else {
1640 // use a MOVZ and MOVK (makes it easier to debug)
1641 movzw(dst, imm_h[0], 0);
1642 movkw(dst, imm_h[1], 16);
1643 }
1644 }
1645 }
1646
1647 // Form an address from base + offset in Rd. Rd may or may
1648 // not actually be used: you must use the Address that is returned.
1649 // It is up to you to ensure that the shift provided matches the size
1650 // of your data.
1651 Address MacroAssembler::form_address(Register Rd, Register base, long byte_offset, int shift) {
1652 if (Address::offset_ok_for_immed(byte_offset, shift))
1653 // It fits; no need for any heroics
1654 return Address(base, byte_offset);
1655
1656 // Don't do anything clever with negative or misaligned offsets
1657 unsigned mask = (1 << shift) - 1;
1658 if (byte_offset < 0 || byte_offset & mask) {
1659 mov(Rd, byte_offset);
1660 add(Rd, base, Rd);
1661 return Address(Rd);
1662 }
1663
1664 // See if we can do this with two 12-bit offsets
1665 {
1666 unsigned long word_offset = byte_offset >> shift;
2350 tty->print_cr("r22 = 0x%016lx", regs[22]);
2351 tty->print_cr("r23 = 0x%016lx", regs[23]);
2352 tty->print_cr("r24 = 0x%016lx", regs[24]);
2353 tty->print_cr("r25 = 0x%016lx", regs[25]);
2354 tty->print_cr("r26 = 0x%016lx", regs[26]);
2355 tty->print_cr("r27 = 0x%016lx", regs[27]);
2356 tty->print_cr("r28 = 0x%016lx", regs[28]);
2357 tty->print_cr("r30 = 0x%016lx", regs[30]);
2358 tty->print_cr("r31 = 0x%016lx", regs[31]);
2359 BREAKPOINT;
2360 }
2361 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
2362 } else {
2363 ttyLocker ttyl;
2364 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
2365 msg);
2366 assert(false, err_msg("DEBUG MESSAGE: %s", msg));
2367 }
2368 }
2369
2370 void MacroAssembler::push_call_clobbered_registers() {
2371 push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2372
2373 // Push v0-v7, v16-v31.
2374 for (int i = 30; i >= 0; i -= 2) {
2375 if (i <= v7->encoding() || i >= v16->encoding()) {
2376 stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2377 Address(pre(sp, -2 * wordSize)));
2378 }
2379 }
2380 }
2381
2382 void MacroAssembler::pop_call_clobbered_registers() {
2383
2384 for (int i = 0; i < 32; i += 2) {
2385 if (i <= v7->encoding() || i >= v16->encoding()) {
2386 ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
2387 Address(post(sp, 2 * wordSize)));
2388 }
2389 }
2390
2391 pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2392 }
2393
2394 void MacroAssembler::push_CPU_state(bool save_vectors) {
2395 push(0x3fffffff, sp); // integer registers except lr & sp
2396
2397 if (!save_vectors) {
2398 for (int i = 30; i >= 0; i -= 2)
2399 stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2400 Address(pre(sp, -2 * wordSize)));
2401 } else {
2402 for (int i = 30; i >= 0; i -= 2)
2403 stpq(as_FloatRegister(i), as_FloatRegister(i+1),
2404 Address(pre(sp, -4 * wordSize)));
2405 }
2406 }
2407
2408 void MacroAssembler::pop_CPU_state(bool restore_vectors) {
2409 if (!restore_vectors) {
3444 movz(dst, 0xDEAD, 16);
3445 movk(dst, 0xBEEF);
3446 }
3447
3448 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
3449 assert (UseCompressedClassPointers, "should only be used for compressed headers");
3450 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
3451 int index = oop_recorder()->find_index(k);
3452 assert(! Universe::heap()->is_in_reserved(k), "should not be an oop");
3453
3454 InstructionMark im(this);
3455 RelocationHolder rspec = metadata_Relocation::spec(index);
3456 code_section()->relocate(inst_mark(), rspec);
3457 narrowKlass nk = Klass::encode_klass(k);
3458 movz(dst, (nk >> 16), 16);
3459 movk(dst, nk & 0xffff);
3460 }
3461
3462 void MacroAssembler::load_heap_oop(Register dst, Address src)
3463 {
3464 if (UseCompressedOops) {
3465 ldrw(dst, src);
3466 decode_heap_oop(dst);
3467 } else {
3468 ldr(dst, src);
3469 }
3470 }
3471
3472 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
3473 {
3474 if (UseCompressedOops) {
3475 ldrw(dst, src);
3476 decode_heap_oop_not_null(dst);
3477 } else {
3478 ldr(dst, src);
3479 }
3480 }
3481
3482 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3483 if (UseCompressedOops) {
3484 assert(!dst.uses(src), "not enough registers");
3485 encode_heap_oop(src);
3486 strw(src, dst);
3487 } else
3488 str(src, dst);
3489 }
3490
3491 // Used for storing NULLs.
3492 void MacroAssembler::store_heap_oop_null(Address dst) {
3493 if (UseCompressedOops) {
3596 }
3597
3598 /*
3599 * g1_write_barrier_post -- G1GC post-write barrier for store of new_val at
3600 * store_addr
3601 *
3602 * Allocates rscratch1
3603 */
3604 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3605 Register new_val,
3606 Register thread,
3607 Register tmp,
3608 Register tmp2) {
3609 #ifdef _LP64
3610 assert(thread == rthread, "must be");
3611 #endif // _LP64
3612 assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
3613 rscratch1);
3614 assert(store_addr != noreg && new_val != noreg && tmp != noreg
3615 && tmp2 != noreg, "expecting a register");
3616
3617 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3618 PtrQueue::byte_offset_of_index()));
3619 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3620 PtrQueue::byte_offset_of_buf()));
3621
3622 BarrierSet* bs = Universe::heap()->barrier_set();
3623 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3624 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3625
3626 Label done;
3627 Label runtime;
3628
3629 // Does store cross heap regions?
3630
3631 eor(tmp, store_addr, new_val);
3632 lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3633 cbz(tmp, done);
3634
3635 // crosses regions, storing NULL?
|
1 /*
2 * Copyright (c) 2013, Red Hat Inc.
3 * Copyright (c) 1997, 2012, Oracle and/or its affiliates.
4 * All rights reserved.
5 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 *
7 * This code is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 only, as
9 * published by the Free Software Foundation.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 *
25 */
26
27 #include <sys/types.h>
28
29 #include "precompiled.hpp"
30 #include "asm/assembler.hpp"
31 #include "asm/assembler.inline.hpp"
32 #include "interpreter/interpreter.hpp"
33
34 #include "compiler/disassembler.hpp"
35 #include "gc_interface/collectedHeap.inline.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "runtime/biasedLocking.hpp"
38 #include "runtime/interfaceSupport.hpp"
39 #include "runtime/sharedRuntime.hpp"
40
41 // #include "gc_interface/collectedHeap.inline.hpp"
42 // #include "interpreter/interpreter.hpp"
43 // #include "memory/cardTableModRefBS.hpp"
44 // #include "prims/methodHandles.hpp"
45 // #include "runtime/biasedLocking.hpp"
46 // #include "runtime/interfaceSupport.hpp"
47 // #include "runtime/objectMonitor.hpp"
48 // #include "runtime/os.hpp"
49 // #include "runtime/sharedRuntime.hpp"
50 // #include "runtime/stubRoutines.hpp"
51
52 #if INCLUDE_ALL_GCS
53 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
54 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
55 #include "gc_implementation/g1/heapRegion.hpp"
56 #include "shenandoahBarrierSetAssembler_aarch64.hpp"
57 #endif
58
59 #ifdef COMPILER2
60 #include "opto/node.hpp"
61 #include "opto/compile.hpp"
62 #endif
63
64 #ifdef PRODUCT
65 #define BLOCK_COMMENT(str) /* nothing */
66 #define STOP(error) stop(error)
67 #else
68 #define BLOCK_COMMENT(str) block_comment(str)
69 #define STOP(error) block_comment(error); stop(error)
70 #endif
71
72 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
73
74 // Patch any kind of instruction; there may be several instructions.
75 // Return the total length (in bytes) of the instructions.
76 int MacroAssembler::pd_patch_instruction_size(address branch, address target) {
1628 // constant
1629 u_int32_t imm_h[2];
1630 imm_h[0] = imm32 & 0xffff;
1631 imm_h[1] = ((imm32 >> 16) & 0xffff);
1632 if (imm_h[0] == 0) {
1633 movzw(dst, imm_h[1], 16);
1634 } else if (imm_h[0] == 0xffff) {
1635 movnw(dst, imm_h[1] ^ 0xffff, 16);
1636 } else if (imm_h[1] == 0) {
1637 movzw(dst, imm_h[0], 0);
1638 } else if (imm_h[1] == 0xffff) {
1639 movnw(dst, imm_h[0] ^ 0xffff, 0);
1640 } else {
1641 // use a MOVZ and MOVK (makes it easier to debug)
1642 movzw(dst, imm_h[0], 0);
1643 movkw(dst, imm_h[1], 16);
1644 }
1645 }
1646 }
1647
1648 void MacroAssembler::mov(Register dst, address addr) {
1649 assert(Universe::heap() == NULL
1650 || !Universe::heap()->is_in(addr), "use movptr for oop pointers");
1651 mov_immediate64(dst, (uintptr_t)addr);
1652 }
1653
1654 // Form an address from base + offset in Rd. Rd may or may
1655 // not actually be used: you must use the Address that is returned.
1656 // It is up to you to ensure that the shift provided matches the size
1657 // of your data.
1658 Address MacroAssembler::form_address(Register Rd, Register base, long byte_offset, int shift) {
1659 if (Address::offset_ok_for_immed(byte_offset, shift))
1660 // It fits; no need for any heroics
1661 return Address(base, byte_offset);
1662
1663 // Don't do anything clever with negative or misaligned offsets
1664 unsigned mask = (1 << shift) - 1;
1665 if (byte_offset < 0 || byte_offset & mask) {
1666 mov(Rd, byte_offset);
1667 add(Rd, base, Rd);
1668 return Address(Rd);
1669 }
1670
1671 // See if we can do this with two 12-bit offsets
1672 {
1673 unsigned long word_offset = byte_offset >> shift;
2357 tty->print_cr("r22 = 0x%016lx", regs[22]);
2358 tty->print_cr("r23 = 0x%016lx", regs[23]);
2359 tty->print_cr("r24 = 0x%016lx", regs[24]);
2360 tty->print_cr("r25 = 0x%016lx", regs[25]);
2361 tty->print_cr("r26 = 0x%016lx", regs[26]);
2362 tty->print_cr("r27 = 0x%016lx", regs[27]);
2363 tty->print_cr("r28 = 0x%016lx", regs[28]);
2364 tty->print_cr("r30 = 0x%016lx", regs[30]);
2365 tty->print_cr("r31 = 0x%016lx", regs[31]);
2366 BREAKPOINT;
2367 }
2368 ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
2369 } else {
2370 ttyLocker ttyl;
2371 ::tty->print_cr("=============== DEBUG MESSAGE: %s ================\n",
2372 msg);
2373 assert(false, err_msg("DEBUG MESSAGE: %s", msg));
2374 }
2375 }
2376
2377 void MacroAssembler::push_call_clobbered_fp_registers() {
2378 // Push v0-v7, v16-v31.
2379 for (int i = 30; i >= 0; i -= 2) {
2380 if (i <= v7->encoding() || i >= v16->encoding()) {
2381 stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2382 Address(pre(sp, -2 * wordSize)));
2383 }
2384 }
2385 }
2386
2387 void MacroAssembler::pop_call_clobbered_fp_registers() {
2388
2389 for (int i = 0; i < 32; i += 2) {
2390 if (i <= v7->encoding() || i >= v16->encoding()) {
2391 ldpd(as_FloatRegister(i), as_FloatRegister(i+1),
2392 Address(post(sp, 2 * wordSize)));
2393 }
2394 }
2395 }
2396
2397 void MacroAssembler::push_call_clobbered_registers() {
2398 push(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2399
2400 push_call_clobbered_fp_registers();
2401 }
2402
2403 void MacroAssembler::pop_call_clobbered_registers() {
2404
2405 pop_call_clobbered_fp_registers();
2406
2407 pop(RegSet::range(r0, r18) - RegSet::of(rscratch1, rscratch2), sp);
2408 }
2409
2410 void MacroAssembler::push_CPU_state(bool save_vectors) {
2411 push(0x3fffffff, sp); // integer registers except lr & sp
2412
2413 if (!save_vectors) {
2414 for (int i = 30; i >= 0; i -= 2)
2415 stpd(as_FloatRegister(i), as_FloatRegister(i+1),
2416 Address(pre(sp, -2 * wordSize)));
2417 } else {
2418 for (int i = 30; i >= 0; i -= 2)
2419 stpq(as_FloatRegister(i), as_FloatRegister(i+1),
2420 Address(pre(sp, -4 * wordSize)));
2421 }
2422 }
2423
2424 void MacroAssembler::pop_CPU_state(bool restore_vectors) {
2425 if (!restore_vectors) {
3460 movz(dst, 0xDEAD, 16);
3461 movk(dst, 0xBEEF);
3462 }
3463
3464 void MacroAssembler::set_narrow_klass(Register dst, Klass* k) {
3465 assert (UseCompressedClassPointers, "should only be used for compressed headers");
3466 assert (oop_recorder() != NULL, "this assembler needs an OopRecorder");
3467 int index = oop_recorder()->find_index(k);
3468 assert(! Universe::heap()->is_in_reserved(k), "should not be an oop");
3469
3470 InstructionMark im(this);
3471 RelocationHolder rspec = metadata_Relocation::spec(index);
3472 code_section()->relocate(inst_mark(), rspec);
3473 narrowKlass nk = Klass::encode_klass(k);
3474 movz(dst, (nk >> 16), 16);
3475 movk(dst, nk & 0xffff);
3476 }
3477
3478 void MacroAssembler::load_heap_oop(Register dst, Address src)
3479 {
3480 #if INCLUDE_ALL_GCS
3481 if (UseShenandoahGC) {
3482 ShenandoahBarrierSetAssembler::bsasm()->load_heap_oop(this, dst, src);
3483 return;
3484 }
3485 #endif
3486
3487 if (UseCompressedOops) {
3488 ldrw(dst, src);
3489 decode_heap_oop(dst);
3490 } else {
3491 ldr(dst, src);
3492 }
3493 }
3494
3495 void MacroAssembler::load_heap_oop_not_null(Register dst, Address src)
3496 {
3497 #if INCLUDE_ALL_GCS
3498 if (UseShenandoahGC) {
3499 ShenandoahBarrierSetAssembler::bsasm()->load_heap_oop(this, dst, src);
3500 return;
3501 }
3502 #endif
3503
3504 if (UseCompressedOops) {
3505 ldrw(dst, src);
3506 decode_heap_oop_not_null(dst);
3507 } else {
3508 ldr(dst, src);
3509 }
3510 }
3511
3512 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3513 if (UseCompressedOops) {
3514 assert(!dst.uses(src), "not enough registers");
3515 encode_heap_oop(src);
3516 strw(src, dst);
3517 } else
3518 str(src, dst);
3519 }
3520
3521 // Used for storing NULLs.
3522 void MacroAssembler::store_heap_oop_null(Address dst) {
3523 if (UseCompressedOops) {
3626 }
3627
3628 /*
3629 * g1_write_barrier_post -- G1GC post-write barrier for store of new_val at
3630 * store_addr
3631 *
3632 * Allocates rscratch1
3633 */
3634 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3635 Register new_val,
3636 Register thread,
3637 Register tmp,
3638 Register tmp2) {
3639 #ifdef _LP64
3640 assert(thread == rthread, "must be");
3641 #endif // _LP64
3642 assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
3643 rscratch1);
3644 assert(store_addr != noreg && new_val != noreg && tmp != noreg
3645 && tmp2 != noreg, "expecting a register");
3646
3647 if (UseShenandoahGC) {
3648 // No need for this in Shenandoah.
3649 return;
3650 }
3651
3652 assert(UseG1GC, "expect G1 GC");
3653
3654 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3655 PtrQueue::byte_offset_of_index()));
3656 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3657 PtrQueue::byte_offset_of_buf()));
3658
3659 BarrierSet* bs = Universe::heap()->barrier_set();
3660 CardTableModRefBS* ct = (CardTableModRefBS*)bs;
3661 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
3662
3663 Label done;
3664 Label runtime;
3665
3666 // Does store cross heap regions?
3667
3668 eor(tmp, store_addr, new_val);
3669 lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3670 cbz(tmp, done);
3671
3672 // crosses regions, storing NULL?
|