1
2 /*
3 /*
4 * Copyright (c) 2013, Red Hat Inc.
5 * Copyright (c) 1997, 2012, Oracle and/or its affiliates.
6 * All rights reserved.
7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 *
9 * This code is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License version 2 only, as
11 * published by the Free Software Foundation.
12 *
13 * This code is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * version 2 for more details (a copy is included in the LICENSE file that
17 * accompanied this code).
18 *
19 * You should have received a copy of the GNU General Public License version
20 * 2 along with this work; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
22 *
23 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
24 * or visit www.oracle.com if you need additional information or have any
25 * questions.
26 *
27 */
28
29 #include <sys/types.h>
30
31 #include "precompiled.hpp"
32 #include "asm/assembler.hpp"
33 #include "asm/assembler.inline.hpp"
34 #include "interpreter/interpreter.hpp"
35
36 #include "compiler/disassembler.hpp"
37 #include "gc_interface/collectedHeap.inline.hpp"
38 #include "gc_implementation/shenandoah/brooksPointer.hpp"
39 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
40 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
41 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
42 #include "memory/resourceArea.hpp"
43 #include "runtime/biasedLocking.hpp"
44 #include "runtime/interfaceSupport.hpp"
45 #include "runtime/sharedRuntime.hpp"
46
47 // #include "gc_interface/collectedHeap.inline.hpp"
48 // #include "interpreter/interpreter.hpp"
49 // #include "memory/cardTableModRefBS.hpp"
50 // #include "prims/methodHandles.hpp"
51 // #include "runtime/biasedLocking.hpp"
52 // #include "runtime/interfaceSupport.hpp"
53 // #include "runtime/objectMonitor.hpp"
54 // #include "runtime/os.hpp"
55 // #include "runtime/sharedRuntime.hpp"
56 // #include "runtime/stubRoutines.hpp"
57
58 #if INCLUDE_ALL_GCS
1417
1418 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) {
1419 assert(arg_0 != c_rarg3, "smashed arg");
1420 assert(arg_1 != c_rarg3, "smashed arg");
1421 assert(arg_2 != c_rarg3, "smashed arg");
1422 pass_arg3(this, arg_3);
1423 assert(arg_0 != c_rarg2, "smashed arg");
1424 assert(arg_1 != c_rarg2, "smashed arg");
1425 pass_arg2(this, arg_2);
1426 assert(arg_0 != c_rarg1, "smashed arg");
1427 pass_arg1(this, arg_1);
1428 pass_arg0(this, arg_0);
1429 MacroAssembler::call_VM_leaf_base(entry_point, 4);
1430 }
1431
1432 void MacroAssembler::null_check(Register reg, int offset) {
1433 if (needs_explicit_null_check(offset)) {
1434 // provoke OS NULL exception if reg = NULL by
1435 // accessing M[reg] w/o changing any registers
1436 // NOTE: this is plenty to provoke a segv
1437
1438 ldr(zr, Address(reg));
1439 } else {
1440 // nothing to do, (later) access of M[reg + offset]
1441 // will provoke OS NULL exception if reg = NULL
1442 }
1443 }
1444
1445 // MacroAssembler protected routines needed to implement
1446 // public methods
1447
1448 void MacroAssembler::mov(Register r, Address dest) {
1449 code_section()->relocate(pc(), dest.rspec());
1450 u_int64_t imm64 = (u_int64_t)dest.target();
1451 movptr(r, imm64);
1452 }
1453
1454 // Move a constant pointer into r. In AArch64 mode the virtual
1455 // address space is 48 bits in size, so we only need three
1456 // instructions to create a patchable instruction sequence that can
1457 // reach anywhere.
2003 return count;
2004 }
2005 #ifdef ASSERT
2006 void MacroAssembler::verify_heapbase(const char* msg) {
2007 #if 0
2008 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
2009 assert (Universe::heap() != NULL, "java heap should be initialized");
2010 if (CheckCompressedOops) {
2011 Label ok;
2012 push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
2013 cmpptr(rheapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
2014 br(Assembler::EQ, ok);
2015 stop(msg);
2016 bind(ok);
2017 pop(1 << rscratch1->encoding(), sp);
2018 }
2019 #endif
2020 }
2021 #endif
2022
2023 void MacroAssembler::stop(const char* msg, Label *l) {
2024 address ip = pc();
2025 pusha();
2026 // We use movptr rather than mov here because we need code size not
2027 // to depend on the pointer value of msg otherwise C2 can observe
2028 // the same node with different sizes when emitted in a scratch
2029 // buffer and later when emitted for good.
2030 movptr(c_rarg0, (uintptr_t)msg);
2031 if (! l) {
2032 adr(c_rarg1, (address)ip);
2033 } else {
2034 adr(c_rarg1, *l);
2035 }
2036 mov(c_rarg2, sp);
2037 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2038 // call(c_rarg3);
2039 blrt(c_rarg3, 3, 0, 1);
2040 hlt(0);
2041 }
2042
2043 // If a constant does not fit in an immediate field, generate some
2044 // number of MOV instructions and then perform the operation.
2045 void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
2046 add_sub_imm_insn insn1,
2047 add_sub_reg_insn insn2) {
2048 assert(Rd != zr, "Rd = zr and not setting flags?");
2049 if (operand_valid_for_add_sub_immediate((int)imm)) {
2050 (this->*insn1)(Rd, Rn, imm);
2051 } else {
2052 if (uabs(imm) < (1 << 24)) {
2053 (this->*insn1)(Rd, Rn, imm & -(1 << 12));
2054 (this->*insn1)(Rd, Rd, imm & ((1 << 12)-1));
2055 } else {
2377 str(t1, Address(thread, in_bytes(JavaThread::allocated_bytes_offset())));
2378 }
2379
2380 #ifndef PRODUCT
2381 extern "C" void findpc(intptr_t x);
2382 #endif
2383
2384 void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[])
2385 {
2386 // In order to get locks to work, we need to fake a in_VM state
2387 if (ShowMessageBoxOnError ) {
2388 JavaThread* thread = JavaThread::current();
2389 JavaThreadState saved_state = thread->thread_state();
2390 thread->set_thread_state(_thread_in_vm);
2391 #ifndef PRODUCT
2392 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
2393 ttyLocker ttyl;
2394 BytecodeCounter::print();
2395 }
2396 #endif
2397
2398 if (os::message_box(msg, "Execution stopped, print registers?")) {
2399 ttyLocker ttyl;
2400 tty->print_cr(" pc = 0x%016lx", pc);
2401 #ifndef PRODUCT
2402 tty->cr();
2403 findpc(pc);
2404 tty->cr();
2405 #endif
2406 tty->print_cr(" r0 = 0x%016lx", regs[0]);
2407 tty->print_cr(" r1 = 0x%016lx", regs[1]);
2408 tty->print_cr(" r2 = 0x%016lx", regs[2]);
2409 tty->print_cr(" r3 = 0x%016lx", regs[3]);
2410 tty->print_cr(" r4 = 0x%016lx", regs[4]);
2411 tty->print_cr(" r5 = 0x%016lx", regs[5]);
2412 tty->print_cr(" r6 = 0x%016lx", regs[6]);
2413 tty->print_cr(" r7 = 0x%016lx", regs[7]);
2414 tty->print_cr(" r8 = 0x%016lx", regs[8]);
2415 tty->print_cr(" r9 = 0x%016lx", regs[9]);
2416 tty->print_cr("r10 = 0x%016lx", regs[10]);
2417 tty->print_cr("r11 = 0x%016lx", regs[11]);
3805
3806 bind(done);
3807 }
3808
3809 void MacroAssembler::shenandoah_write_barrier(Register dst) {
3810 assert(UseShenandoahGC && ShenandoahWriteBarrier, "Should be enabled");
3811 assert(dst != rscratch1, "need rscratch1");
3812 assert(dst != rscratch2, "need rscratch2");
3813
3814 Label done;
3815
3816 Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset()));
3817 ldrb(rscratch1, gc_state);
3818
3819 // Check for heap stability
3820 mov(rscratch2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION);
3821 tst(rscratch1, rscratch2);
3822 br(Assembler::EQ, done);
3823
3824 // Heap is unstable, need to perform the read-barrier even if WB is inactive
3825 if (ShenandoahWriteBarrierRB) {
3826 ldr(dst, Address(dst, BrooksPointer::byte_offset()));
3827 }
3828
3829 // Check for evacuation-in-progress and jump to WB slow-path if needed
3830 mov(rscratch2, ShenandoahHeap::EVACUATION);
3831 tst(rscratch1, rscratch2);
3832 br(Assembler::EQ, done);
3833
3834 RegSet to_save = RegSet::of(r0);
3835 if (dst != r0) {
3836 push(to_save, sp);
3837 mov(r0, dst);
3838 }
3839
3840 assert(StubRoutines::aarch64::shenandoah_wb() != NULL, "need write barrier stub");
3841 far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::aarch64::shenandoah_wb())));
3842
3843 if (dst != r0) {
3844 mov(dst, r0);
3845 pop(to_save, sp);
3846 }
3847 block_comment("} Shenandoah write barrier");
|
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 "gc_interface/collectedHeap.inline.hpp"
37 #include "gc_implementation/shenandoah/shenandoahBrooksPointer.hpp"
38 #include "gc_implementation/shenandoah/shenandoahHeap.hpp"
39 #include "gc_implementation/shenandoah/shenandoahHeap.inline.hpp"
40 #include "gc_implementation/shenandoah/shenandoahHeapRegion.hpp"
41 #include "memory/resourceArea.hpp"
42 #include "runtime/biasedLocking.hpp"
43 #include "runtime/interfaceSupport.hpp"
44 #include "runtime/sharedRuntime.hpp"
45
46 // #include "gc_interface/collectedHeap.inline.hpp"
47 // #include "interpreter/interpreter.hpp"
48 // #include "memory/cardTableModRefBS.hpp"
49 // #include "prims/methodHandles.hpp"
50 // #include "runtime/biasedLocking.hpp"
51 // #include "runtime/interfaceSupport.hpp"
52 // #include "runtime/objectMonitor.hpp"
53 // #include "runtime/os.hpp"
54 // #include "runtime/sharedRuntime.hpp"
55 // #include "runtime/stubRoutines.hpp"
56
57 #if INCLUDE_ALL_GCS
1416
1417 void MacroAssembler::super_call_VM_leaf(address entry_point, Register arg_0, Register arg_1, Register arg_2, Register arg_3) {
1418 assert(arg_0 != c_rarg3, "smashed arg");
1419 assert(arg_1 != c_rarg3, "smashed arg");
1420 assert(arg_2 != c_rarg3, "smashed arg");
1421 pass_arg3(this, arg_3);
1422 assert(arg_0 != c_rarg2, "smashed arg");
1423 assert(arg_1 != c_rarg2, "smashed arg");
1424 pass_arg2(this, arg_2);
1425 assert(arg_0 != c_rarg1, "smashed arg");
1426 pass_arg1(this, arg_1);
1427 pass_arg0(this, arg_0);
1428 MacroAssembler::call_VM_leaf_base(entry_point, 4);
1429 }
1430
1431 void MacroAssembler::null_check(Register reg, int offset) {
1432 if (needs_explicit_null_check(offset)) {
1433 // provoke OS NULL exception if reg = NULL by
1434 // accessing M[reg] w/o changing any registers
1435 // NOTE: this is plenty to provoke a segv
1436 ldr(zr, Address(reg));
1437 } else {
1438 // nothing to do, (later) access of M[reg + offset]
1439 // will provoke OS NULL exception if reg = NULL
1440 }
1441 }
1442
1443 // MacroAssembler protected routines needed to implement
1444 // public methods
1445
1446 void MacroAssembler::mov(Register r, Address dest) {
1447 code_section()->relocate(pc(), dest.rspec());
1448 u_int64_t imm64 = (u_int64_t)dest.target();
1449 movptr(r, imm64);
1450 }
1451
1452 // Move a constant pointer into r. In AArch64 mode the virtual
1453 // address space is 48 bits in size, so we only need three
1454 // instructions to create a patchable instruction sequence that can
1455 // reach anywhere.
2001 return count;
2002 }
2003 #ifdef ASSERT
2004 void MacroAssembler::verify_heapbase(const char* msg) {
2005 #if 0
2006 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
2007 assert (Universe::heap() != NULL, "java heap should be initialized");
2008 if (CheckCompressedOops) {
2009 Label ok;
2010 push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
2011 cmpptr(rheapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
2012 br(Assembler::EQ, ok);
2013 stop(msg);
2014 bind(ok);
2015 pop(1 << rscratch1->encoding(), sp);
2016 }
2017 #endif
2018 }
2019 #endif
2020
2021 void MacroAssembler::stop(const char* msg) {
2022 address ip = pc();
2023 pusha();
2024 mov(c_rarg0, (address)msg);
2025 mov(c_rarg1, (address)ip);
2026 mov(c_rarg2, sp);
2027 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2028 // call(c_rarg3);
2029 blrt(c_rarg3, 3, 0, 1);
2030 hlt(0);
2031 }
2032
2033 // If a constant does not fit in an immediate field, generate some
2034 // number of MOV instructions and then perform the operation.
2035 void MacroAssembler::wrap_add_sub_imm_insn(Register Rd, Register Rn, unsigned imm,
2036 add_sub_imm_insn insn1,
2037 add_sub_reg_insn insn2) {
2038 assert(Rd != zr, "Rd = zr and not setting flags?");
2039 if (operand_valid_for_add_sub_immediate((int)imm)) {
2040 (this->*insn1)(Rd, Rn, imm);
2041 } else {
2042 if (uabs(imm) < (1 << 24)) {
2043 (this->*insn1)(Rd, Rn, imm & -(1 << 12));
2044 (this->*insn1)(Rd, Rd, imm & ((1 << 12)-1));
2045 } else {
2367 str(t1, Address(thread, in_bytes(JavaThread::allocated_bytes_offset())));
2368 }
2369
2370 #ifndef PRODUCT
2371 extern "C" void findpc(intptr_t x);
2372 #endif
2373
2374 void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[])
2375 {
2376 // In order to get locks to work, we need to fake a in_VM state
2377 if (ShowMessageBoxOnError ) {
2378 JavaThread* thread = JavaThread::current();
2379 JavaThreadState saved_state = thread->thread_state();
2380 thread->set_thread_state(_thread_in_vm);
2381 #ifndef PRODUCT
2382 if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
2383 ttyLocker ttyl;
2384 BytecodeCounter::print();
2385 }
2386 #endif
2387 if (os::message_box(msg, "Execution stopped, print registers?")) {
2388 ttyLocker ttyl;
2389 tty->print_cr(" pc = 0x%016lx", pc);
2390 #ifndef PRODUCT
2391 tty->cr();
2392 findpc(pc);
2393 tty->cr();
2394 #endif
2395 tty->print_cr(" r0 = 0x%016lx", regs[0]);
2396 tty->print_cr(" r1 = 0x%016lx", regs[1]);
2397 tty->print_cr(" r2 = 0x%016lx", regs[2]);
2398 tty->print_cr(" r3 = 0x%016lx", regs[3]);
2399 tty->print_cr(" r4 = 0x%016lx", regs[4]);
2400 tty->print_cr(" r5 = 0x%016lx", regs[5]);
2401 tty->print_cr(" r6 = 0x%016lx", regs[6]);
2402 tty->print_cr(" r7 = 0x%016lx", regs[7]);
2403 tty->print_cr(" r8 = 0x%016lx", regs[8]);
2404 tty->print_cr(" r9 = 0x%016lx", regs[9]);
2405 tty->print_cr("r10 = 0x%016lx", regs[10]);
2406 tty->print_cr("r11 = 0x%016lx", regs[11]);
3794
3795 bind(done);
3796 }
3797
3798 void MacroAssembler::shenandoah_write_barrier(Register dst) {
3799 assert(UseShenandoahGC && ShenandoahWriteBarrier, "Should be enabled");
3800 assert(dst != rscratch1, "need rscratch1");
3801 assert(dst != rscratch2, "need rscratch2");
3802
3803 Label done;
3804
3805 Address gc_state(rthread, in_bytes(JavaThread::gc_state_offset()));
3806 ldrb(rscratch1, gc_state);
3807
3808 // Check for heap stability
3809 mov(rscratch2, ShenandoahHeap::HAS_FORWARDED | ShenandoahHeap::EVACUATION);
3810 tst(rscratch1, rscratch2);
3811 br(Assembler::EQ, done);
3812
3813 // Heap is unstable, need to perform the read-barrier even if WB is inactive
3814 ldr(dst, Address(dst, ShenandoahBrooksPointer::byte_offset()));
3815
3816 // Check for evacuation-in-progress and jump to WB slow-path if needed
3817 mov(rscratch2, ShenandoahHeap::EVACUATION);
3818 tst(rscratch1, rscratch2);
3819 br(Assembler::EQ, done);
3820
3821 RegSet to_save = RegSet::of(r0);
3822 if (dst != r0) {
3823 push(to_save, sp);
3824 mov(r0, dst);
3825 }
3826
3827 assert(StubRoutines::aarch64::shenandoah_wb() != NULL, "need write barrier stub");
3828 far_call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::aarch64::shenandoah_wb())));
3829
3830 if (dst != r0) {
3831 mov(dst, r0);
3832 pop(to_save, sp);
3833 }
3834 block_comment("} Shenandoah write barrier");
|