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 */
25
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "asm/assembler.hpp"
30 #include "asm/assembler.inline.hpp"
31 #include "gc/shared/cardTable.hpp"
32 #include "gc/shared/cardTableModRefBS.hpp"
33 #include "interpreter/interpreter.hpp"
34 #include "compiler/disassembler.hpp"
35 #include "memory/resourceArea.hpp"
36 #include "nativeInst_aarch64.hpp"
37 #include "oops/klass.inline.hpp"
38 #include "oops/oop.inline.hpp"
39 #include "opto/compile.hpp"
40 #include "opto/intrinsicnode.hpp"
41 #include "opto/node.hpp"
42 #include "prims/jvm.h"
43 #include "runtime/biasedLocking.hpp"
44 #include "runtime/icache.hpp"
45 #include "runtime/interfaceSupport.hpp"
46 #include "runtime/sharedRuntime.hpp"
47 #include "runtime/thread.hpp"
48
49 #if INCLUDE_ALL_GCS
50 #include "gc/g1/g1CardTable.hpp"
51 #include "gc/g1/g1CollectedHeap.inline.hpp"
1985 return count;
1986 }
1987 #ifdef ASSERT
1988 void MacroAssembler::verify_heapbase(const char* msg) {
1989 #if 0
1990 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
1991 assert (Universe::heap() != NULL, "java heap should be initialized");
1992 if (CheckCompressedOops) {
1993 Label ok;
1994 push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
1995 cmpptr(rheapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
1996 br(Assembler::EQ, ok);
1997 stop(msg);
1998 bind(ok);
1999 pop(1 << rscratch1->encoding(), sp);
2000 }
2001 #endif
2002 }
2003 #endif
2004
2005 void MacroAssembler::stop(const char* msg) {
2006 address ip = pc();
2007 pusha();
2008 mov(c_rarg0, (address)msg);
2009 mov(c_rarg1, (address)ip);
2010 mov(c_rarg2, sp);
2011 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2012 // call(c_rarg3);
2013 blrt(c_rarg3, 3, 0, 1);
2014 hlt(0);
2015 }
2016
2017 void MacroAssembler::unimplemented(const char* what) {
2018 char* b = new char[1024];
2019 jio_snprintf(b, 1024, "unimplemented: %s", what);
2020 stop(b);
2021 }
2022
2023 // If a constant does not fit in an immediate field, generate some
2024 // number of MOV instructions and then perform the operation.
3218 // forms below.
3219 adr = form_address(rscratch2, dst.base(), dst.offset(), LogBytesPerWord);
3220 break;
3221 default:
3222 lea(rscratch2, dst);
3223 adr = Address(rscratch2);
3224 break;
3225 }
3226 ldr(rscratch1, adr);
3227 add(rscratch1, rscratch1, src);
3228 str(rscratch1, adr);
3229 }
3230
3231 void MacroAssembler::cmpptr(Register src1, Address src2) {
3232 unsigned long offset;
3233 adrp(rscratch1, src2, offset);
3234 ldr(rscratch1, Address(rscratch1, offset));
3235 cmp(src1, rscratch1);
3236 }
3237
3238 void MacroAssembler::store_check(Register obj, Address dst) {
3239 store_check(obj);
3240 }
3241
3242 void MacroAssembler::store_check(Register obj) {
3243 // Does a store check for the oop in register obj. The content of
3244 // register obj is destroyed afterwards.
3245
3246 BarrierSet* bs = Universe::heap()->barrier_set();
3247 assert(bs->kind() == BarrierSet::CardTableModRef,
3248 "Wrong barrier set kind");
3249
3250 CardTableModRefBS* ctbs = barrier_set_cast<CardTableModRefBS>(bs);
3251 CardTable* ct = ctbs->card_table();
3252 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
3253
3254 lsr(obj, obj, CardTable::card_shift);
3255
3256 assert(CardTable::dirty_card_val() == 0, "must be");
3257
3258 load_byte_map_base(rscratch1);
3259
3260 if (UseCondCardMark) {
3261 Label L_already_dirty;
3262 membar(StoreLoad);
3263 ldrb(rscratch2, Address(obj, rscratch1));
3264 cbz(rscratch2, L_already_dirty);
3265 strb(zr, Address(obj, rscratch1));
3266 bind(L_already_dirty);
3267 } else {
3268 if (UseConcMarkSweepGC && CMSPrecleaningEnabled) {
3269 membar(StoreStore);
3270 }
3271 strb(zr, Address(obj, rscratch1));
3272 }
3273 }
3274
3275 void MacroAssembler::load_klass(Register dst, Register src) {
3276 if (UseCompressedClassPointers) {
3277 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3278 decode_klass_not_null(dst);
3279 } else {
3280 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3281 }
3282 }
3283
3284 // ((OopHandle)result).resolve();
3285 void MacroAssembler::resolve_oop_handle(Register result) {
3286 // OopHandle::resolve is an indirection.
3287 ldr(result, Address(result, 0));
3288 }
3289
3290 void MacroAssembler::load_mirror(Register dst, Register method) {
3291 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3292 ldr(dst, Address(rmethod, Method::const_offset()));
3293 ldr(dst, Address(dst, ConstMethod::constants_offset()));
3294 ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
3614 }
3615 }
3616
3617 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3618 if (UseCompressedOops) {
3619 assert(!dst.uses(src), "not enough registers");
3620 encode_heap_oop(src);
3621 strw(src, dst);
3622 } else
3623 str(src, dst);
3624 }
3625
3626 // Used for storing NULLs.
3627 void MacroAssembler::store_heap_oop_null(Address dst) {
3628 if (UseCompressedOops) {
3629 strw(zr, dst);
3630 } else
3631 str(zr, dst);
3632 }
3633
3634 #if INCLUDE_ALL_GCS
3635 /*
3636 * g1_write_barrier_pre -- G1GC pre-write barrier for store of new_val at
3637 * store_addr.
3638 *
3639 * Allocates rscratch1
3640 */
3641 void MacroAssembler::g1_write_barrier_pre(Register obj,
3642 Register pre_val,
3643 Register thread,
3644 Register tmp,
3645 bool tosca_live,
3646 bool expand_call) {
3647 // If expand_call is true then we expand the call_VM_leaf macro
3648 // directly to skip generating the check by
3649 // InterpreterMacroAssembler::call_VM_leaf_base that checks _last_sp.
3650
3651 assert(thread == rthread, "must be");
3652
3653 Label done;
3654 Label runtime;
3655
3656 assert_different_registers(obj, pre_val, tmp, rscratch1);
3657 assert(pre_val != noreg && tmp != noreg, "expecting a register");
3658
3659 Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3660 SATBMarkQueue::byte_offset_of_active()));
3661 Address index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3662 SATBMarkQueue::byte_offset_of_index()));
3663 Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
3664 SATBMarkQueue::byte_offset_of_buf()));
3665
3666
3667 // Is marking active?
3668 if (in_bytes(SATBMarkQueue::byte_width_of_active()) == 4) {
3669 ldrw(tmp, in_progress);
3670 } else {
3671 assert(in_bytes(SATBMarkQueue::byte_width_of_active()) == 1, "Assumption");
3672 ldrb(tmp, in_progress);
3673 }
3674 cbzw(tmp, done);
3675
3676 // Do we need to load the previous value?
3677 if (obj != noreg) {
3678 load_heap_oop(pre_val, Address(obj, 0));
3679 }
3680
3681 // Is the previous value null?
3682 cbz(pre_val, done);
3683
3684 // Can we store original value in the thread's buffer?
3685 // Is index == 0?
3686 // (The index field is typed as size_t.)
3687
3688 ldr(tmp, index); // tmp := *index_adr
3689 cbz(tmp, runtime); // tmp == 0?
3690 // If yes, goto runtime
3691
3692 sub(tmp, tmp, wordSize); // tmp := tmp - wordSize
3693 str(tmp, index); // *index_adr := tmp
3694 ldr(rscratch1, buffer);
3695 add(tmp, tmp, rscratch1); // tmp := tmp + *buffer_adr
3696
3697 // Record the previous value
3698 str(pre_val, Address(tmp, 0));
3699 b(done);
3700
3701 bind(runtime);
3702 // save the live input values
3703 push(r0->bit(tosca_live) | obj->bit(obj != noreg) | pre_val->bit(true), sp);
3704
3705 // Calling the runtime using the regular call_VM_leaf mechanism generates
3706 // code (generated by InterpreterMacroAssember::call_VM_leaf_base)
3707 // that checks that the *(rfp+frame::interpreter_frame_last_sp) == NULL.
3708 //
3709 // If we care generating the pre-barrier without a frame (e.g. in the
3710 // intrinsified Reference.get() routine) then ebp might be pointing to
3711 // the caller frame and so this check will most likely fail at runtime.
3712 //
3713 // Expanding the call directly bypasses the generation of the check.
3714 // So when we do not have have a full interpreter frame on the stack
3715 // expand_call should be passed true.
3716
3717 if (expand_call) {
3718 assert(pre_val != c_rarg1, "smashed arg");
3719 pass_arg1(this, thread);
3720 pass_arg0(this, pre_val);
3721 MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), 2);
3722 } else {
3723 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_pre), pre_val, thread);
3724 }
3725
3726 pop(r0->bit(tosca_live) | obj->bit(obj != noreg) | pre_val->bit(true), sp);
3727
3728 bind(done);
3729 }
3730
3731 /*
3732 * g1_write_barrier_post -- G1GC post-write barrier for store of new_val at
3733 * store_addr
3734 *
3735 * Allocates rscratch1
3736 */
3737 void MacroAssembler::g1_write_barrier_post(Register store_addr,
3738 Register new_val,
3739 Register thread,
3740 Register tmp,
3741 Register tmp2) {
3742 assert(thread == rthread, "must be");
3743 assert_different_registers(store_addr, new_val, thread, tmp, tmp2,
3744 rscratch1);
3745 assert(store_addr != noreg && new_val != noreg && tmp != noreg
3746 && tmp2 != noreg, "expecting a register");
3747
3748 Address queue_index(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3749 DirtyCardQueue::byte_offset_of_index()));
3750 Address buffer(thread, in_bytes(JavaThread::dirty_card_queue_offset() +
3751 DirtyCardQueue::byte_offset_of_buf()));
3752
3753 BarrierSet* bs = Universe::heap()->barrier_set();
3754 CardTableModRefBS* ctbs = barrier_set_cast<CardTableModRefBS>(bs);
3755 CardTable* ct = ctbs->card_table();
3756 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
3757
3758 Label done;
3759 Label runtime;
3760
3761 // Does store cross heap regions?
3762
3763 eor(tmp, store_addr, new_val);
3764 lsr(tmp, tmp, HeapRegion::LogOfHRGrainBytes);
3765 cbz(tmp, done);
3766
3767 // crosses regions, storing NULL?
3768
3769 cbz(new_val, done);
3770
3771 // storing region crossing non-NULL, is card already dirty?
3772
3773 ExternalAddress cardtable((address) ct->byte_map_base());
3774 assert(sizeof(*ct->byte_map_base()) == sizeof(jbyte), "adjust this code");
3775 const Register card_addr = tmp;
3776
3777 lsr(card_addr, store_addr, CardTable::card_shift);
3778
3779 // get the address of the card
3780 load_byte_map_base(tmp2);
3781 add(card_addr, card_addr, tmp2);
3782 ldrb(tmp2, Address(card_addr));
3783 cmpw(tmp2, (int)G1CardTable::g1_young_card_val());
3784 br(Assembler::EQ, done);
3785
3786 assert((int)CardTable::dirty_card_val() == 0, "must be 0");
3787
3788 membar(Assembler::StoreLoad);
3789
3790 ldrb(tmp2, Address(card_addr));
3791 cbzw(tmp2, done);
3792
3793 // storing a region crossing, non-NULL oop, card is clean.
3794 // dirty card and log.
3795
3796 strb(zr, Address(card_addr));
3797
3798 ldr(rscratch1, queue_index);
3799 cbz(rscratch1, runtime);
3800 sub(rscratch1, rscratch1, wordSize);
3801 str(rscratch1, queue_index);
3802
3803 ldr(tmp2, buffer);
3804 str(card_addr, Address(tmp2, rscratch1));
3805 b(done);
3806
3807 bind(runtime);
3808 // save the live input values
3809 push(store_addr->bit(true) | new_val->bit(true), sp);
3810 call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::g1_wb_post), card_addr, thread);
3811 pop(store_addr->bit(true) | new_val->bit(true), sp);
3812
3813 bind(done);
3814 }
3815
3816 #endif // INCLUDE_ALL_GCS
3817
3818 Address MacroAssembler::allocate_metadata_address(Metadata* obj) {
3819 assert(oop_recorder() != NULL, "this assembler needs a Recorder");
3820 int index = oop_recorder()->allocate_metadata_index(obj);
3821 RelocationHolder rspec = metadata_Relocation::spec(index);
3822 return Address((address)obj, rspec);
3823 }
3824
3825 // Move an oop into a register. immediate is true if we want
3826 // immediate instrcutions, i.e. we are not going to patch this
3827 // instruction while the code is being executed by another thread. In
3828 // that case we can use move immediates rather than the constant pool.
3829 void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) {
3830 int oop_index;
3831 if (obj == NULL) {
3832 oop_index = oop_recorder()->allocate_oop_index(obj);
3833 } else {
3834 oop_index = oop_recorder()->find_index(obj);
3835 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
3836 }
3837 RelocationHolder rspec = oop_Relocation::spec(oop_index);
4224
4225 InstructionMark im(this);
4226 code_section()->relocate(inst_mark(), dest.rspec());
4227 // 8143067: Ensure that the adrp can reach the dest from anywhere within
4228 // the code cache so that if it is relocated we know it will still reach
4229 if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
4230 _adrp(reg1, dest.target());
4231 } else {
4232 unsigned long target = (unsigned long)dest.target();
4233 unsigned long adrp_target
4234 = (target & 0xffffffffUL) | ((unsigned long)pc() & 0xffff00000000UL);
4235
4236 _adrp(reg1, (address)adrp_target);
4237 movk(reg1, target >> 32, 32);
4238 }
4239 byte_offset = (unsigned long)dest.target() & 0xfff;
4240 }
4241
4242 void MacroAssembler::load_byte_map_base(Register reg) {
4243 jbyte *byte_map_base =
4244 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->byte_map_base;
4245
4246 if (is_valid_AArch64_address((address)byte_map_base)) {
4247 // Strictly speaking the byte_map_base isn't an address at all,
4248 // and it might even be negative.
4249 unsigned long offset;
4250 adrp(reg, ExternalAddress((address)byte_map_base), offset);
4251 // We expect offset to be zero with most collectors.
4252 if (offset != 0) {
4253 add(reg, reg, offset);
4254 }
4255 } else {
4256 mov(reg, (uint64_t)byte_map_base);
4257 }
4258 }
4259
4260 void MacroAssembler::build_frame(int framesize) {
4261 assert(framesize > 0, "framesize must be > 0");
4262 if (framesize < ((1 << 9) + 2 * wordSize)) {
4263 sub(sp, sp, framesize);
4264 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
4265 if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
|
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 */
25
26 #include <sys/types.h>
27
28 #include "precompiled.hpp"
29 #include "asm/assembler.hpp"
30 #include "asm/assembler.inline.hpp"
31 #include "gc/shared/cardTable.hpp"
32 #include "gc/shared/barrierSetCodeGen.hpp"
33 #include "gc/shared/cardTableModRefBS.hpp"
34 #include "interpreter/interpreter.hpp"
35 #include "compiler/disassembler.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "nativeInst_aarch64.hpp"
38 #include "oops/klass.inline.hpp"
39 #include "oops/oop.inline.hpp"
40 #include "opto/compile.hpp"
41 #include "opto/intrinsicnode.hpp"
42 #include "opto/node.hpp"
43 #include "prims/jvm.h"
44 #include "runtime/biasedLocking.hpp"
45 #include "runtime/icache.hpp"
46 #include "runtime/interfaceSupport.hpp"
47 #include "runtime/sharedRuntime.hpp"
48 #include "runtime/thread.hpp"
49
50 #if INCLUDE_ALL_GCS
51 #include "gc/g1/g1CardTable.hpp"
52 #include "gc/g1/g1CollectedHeap.inline.hpp"
1986 return count;
1987 }
1988 #ifdef ASSERT
1989 void MacroAssembler::verify_heapbase(const char* msg) {
1990 #if 0
1991 assert (UseCompressedOops || UseCompressedClassPointers, "should be compressed");
1992 assert (Universe::heap() != NULL, "java heap should be initialized");
1993 if (CheckCompressedOops) {
1994 Label ok;
1995 push(1 << rscratch1->encoding(), sp); // cmpptr trashes rscratch1
1996 cmpptr(rheapbase, ExternalAddress((address)Universe::narrow_ptrs_base_addr()));
1997 br(Assembler::EQ, ok);
1998 stop(msg);
1999 bind(ok);
2000 pop(1 << rscratch1->encoding(), sp);
2001 }
2002 #endif
2003 }
2004 #endif
2005
2006 void MacroAssembler::resolve_jobject(Register value, Register thread, Register tmp) {
2007 BarrierSetCodeGen *code_gen = Universe::heap()->barrier_set()->code_gen();
2008 Label done, not_weak;
2009 cbz(value, done); // Use NULL as-is.
2010
2011 STATIC_ASSERT(JNIHandles::weak_tag_mask == 1u);
2012 tbz(r0, 0, not_weak); // Test for jweak tag.
2013
2014 // Resolve jweak.
2015 code_gen->load_at(this, ACCESS_IN_ROOT | ACCESS_ON_PHANTOM_OOP_REF, T_OBJECT,
2016 value, Address(value, -JNIHandles::weak_tag_value), tmp, thread);
2017 verify_oop(value);
2018 b(done);
2019
2020 bind(not_weak);
2021 // Resolve (untagged) jobject.
2022 code_gen->load_at(this, ACCESS_IN_ROOT | ACCESS_ON_STRONG_OOP_REF, T_OBJECT,
2023 value, Address(value, 0), tmp, thread);
2024 verify_oop(value);
2025 bind(done);
2026 }
2027
2028 void MacroAssembler::stop(const char* msg) {
2029 address ip = pc();
2030 pusha();
2031 mov(c_rarg0, (address)msg);
2032 mov(c_rarg1, (address)ip);
2033 mov(c_rarg2, sp);
2034 mov(c_rarg3, CAST_FROM_FN_PTR(address, MacroAssembler::debug64));
2035 // call(c_rarg3);
2036 blrt(c_rarg3, 3, 0, 1);
2037 hlt(0);
2038 }
2039
2040 void MacroAssembler::unimplemented(const char* what) {
2041 char* b = new char[1024];
2042 jio_snprintf(b, 1024, "unimplemented: %s", what);
2043 stop(b);
2044 }
2045
2046 // If a constant does not fit in an immediate field, generate some
2047 // number of MOV instructions and then perform the operation.
3241 // forms below.
3242 adr = form_address(rscratch2, dst.base(), dst.offset(), LogBytesPerWord);
3243 break;
3244 default:
3245 lea(rscratch2, dst);
3246 adr = Address(rscratch2);
3247 break;
3248 }
3249 ldr(rscratch1, adr);
3250 add(rscratch1, rscratch1, src);
3251 str(rscratch1, adr);
3252 }
3253
3254 void MacroAssembler::cmpptr(Register src1, Address src2) {
3255 unsigned long offset;
3256 adrp(rscratch1, src2, offset);
3257 ldr(rscratch1, Address(rscratch1, offset));
3258 cmp(src1, rscratch1);
3259 }
3260
3261 void MacroAssembler::load_klass(Register dst, Register src) {
3262 if (UseCompressedClassPointers) {
3263 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3264 decode_klass_not_null(dst);
3265 } else {
3266 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3267 }
3268 }
3269
3270 // ((OopHandle)result).resolve();
3271 void MacroAssembler::resolve_oop_handle(Register result) {
3272 // OopHandle::resolve is an indirection.
3273 ldr(result, Address(result, 0));
3274 }
3275
3276 void MacroAssembler::load_mirror(Register dst, Register method) {
3277 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3278 ldr(dst, Address(rmethod, Method::const_offset()));
3279 ldr(dst, Address(dst, ConstMethod::constants_offset()));
3280 ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
3600 }
3601 }
3602
3603 void MacroAssembler::store_heap_oop(Address dst, Register src) {
3604 if (UseCompressedOops) {
3605 assert(!dst.uses(src), "not enough registers");
3606 encode_heap_oop(src);
3607 strw(src, dst);
3608 } else
3609 str(src, dst);
3610 }
3611
3612 // Used for storing NULLs.
3613 void MacroAssembler::store_heap_oop_null(Address dst) {
3614 if (UseCompressedOops) {
3615 strw(zr, dst);
3616 } else
3617 str(zr, dst);
3618 }
3619
3620 Address MacroAssembler::allocate_metadata_address(Metadata* obj) {
3621 assert(oop_recorder() != NULL, "this assembler needs a Recorder");
3622 int index = oop_recorder()->allocate_metadata_index(obj);
3623 RelocationHolder rspec = metadata_Relocation::spec(index);
3624 return Address((address)obj, rspec);
3625 }
3626
3627 // Move an oop into a register. immediate is true if we want
3628 // immediate instrcutions, i.e. we are not going to patch this
3629 // instruction while the code is being executed by another thread. In
3630 // that case we can use move immediates rather than the constant pool.
3631 void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) {
3632 int oop_index;
3633 if (obj == NULL) {
3634 oop_index = oop_recorder()->allocate_oop_index(obj);
3635 } else {
3636 oop_index = oop_recorder()->find_index(obj);
3637 assert(Universe::heap()->is_in_reserved(JNIHandles::resolve(obj)), "should be real oop");
3638 }
3639 RelocationHolder rspec = oop_Relocation::spec(oop_index);
4026
4027 InstructionMark im(this);
4028 code_section()->relocate(inst_mark(), dest.rspec());
4029 // 8143067: Ensure that the adrp can reach the dest from anywhere within
4030 // the code cache so that if it is relocated we know it will still reach
4031 if (offset_high >= -(1<<20) && offset_low < (1<<20)) {
4032 _adrp(reg1, dest.target());
4033 } else {
4034 unsigned long target = (unsigned long)dest.target();
4035 unsigned long adrp_target
4036 = (target & 0xffffffffUL) | ((unsigned long)pc() & 0xffff00000000UL);
4037
4038 _adrp(reg1, (address)adrp_target);
4039 movk(reg1, target >> 32, 32);
4040 }
4041 byte_offset = (unsigned long)dest.target() & 0xfff;
4042 }
4043
4044 void MacroAssembler::load_byte_map_base(Register reg) {
4045 jbyte *byte_map_base =
4046 ((CardTableModRefBS*)(Universe::heap()->barrier_set()))->card_table()->byte_map_base();
4047 if (is_valid_AArch64_address((address)byte_map_base)) {
4048 // Strictly speaking the byte_map_base isn't an address at all,
4049 // and it might even be negative.
4050 unsigned long offset;
4051 adrp(reg, ExternalAddress((address)byte_map_base), offset);
4052 // We expect offset to be zero with most collectors.
4053 if (offset != 0) {
4054 add(reg, reg, offset);
4055 }
4056 } else {
4057 mov(reg, (uint64_t)byte_map_base);
4058 }
4059 }
4060
4061 void MacroAssembler::build_frame(int framesize) {
4062 assert(framesize > 0, "framesize must be > 0");
4063 if (framesize < ((1 << 9) + 2 * wordSize)) {
4064 sub(sp, sp, framesize);
4065 stp(rfp, lr, Address(sp, framesize - 2 * wordSize));
4066 if (PreserveFramePointer) add(rfp, sp, framesize - 2 * wordSize);
|