3672 adr = Address(rscratch2);
3673 break;
3674 }
3675 ldr(rscratch1, adr);
3676 add(rscratch1, rscratch1, src);
3677 str(rscratch1, adr);
3678 }
3679
3680 void MacroAssembler::cmpptr(Register src1, Address src2) {
3681 unsigned long offset;
3682 adrp(rscratch1, src2, offset);
3683 ldr(rscratch1, Address(rscratch1, offset));
3684 cmp(src1, rscratch1);
3685 }
3686
3687 void MacroAssembler::cmpoop(Register obj1, Register obj2) {
3688 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
3689 bs->obj_equals(this, obj1, obj2);
3690 }
3691
3692 void MacroAssembler::load_method_holder(Register holder, Register method) {
3693 ldr(holder, Address(method, Method::const_offset())); // ConstMethod*
3694 ldr(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool*
3695 ldr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
3696 }
3697
3698 void MacroAssembler::load_klass(Register dst, Register src) {
3699 if (UseCompressedClassPointers) {
3700 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3701 decode_klass_not_null(dst);
3702 } else {
3703 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3704 }
3705 }
3706
3707 // ((OopHandle)result).resolve();
3708 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
3709 // OopHandle::resolve is an indirection.
3710 access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp, noreg);
3711 }
3712
3713 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
3714 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3715 ldr(dst, Address(rmethod, Method::const_offset()));
3716 ldr(dst, Address(dst, ConstMethod::constants_offset()));
3717 ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
3718 ldr(dst, Address(dst, mirror_offset));
3719 resolve_oop_handle(dst, tmp);
3720 }
3721
3722 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
3723 if (UseCompressedClassPointers) {
3724 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
3725 if (CompressedKlassPointers::base() == NULL) {
3726 cmp(trial_klass, tmp, LSL, CompressedKlassPointers::shift());
3727 return;
3728 } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
3729 && CompressedKlassPointers::shift() == 0) {
3730 // Only the bottom 32 bits matter
3731 cmpw(trial_klass, tmp);
3732 return;
4087 }
4088
4089 void MacroAssembler::store_heap_oop(Address dst, Register src, Register tmp1,
4090 Register thread_tmp, DecoratorSet decorators) {
4091 access_store_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
4092 }
4093
4094 // Used for storing NULLs.
4095 void MacroAssembler::store_heap_oop_null(Address dst) {
4096 access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg);
4097 }
4098
4099 Address MacroAssembler::allocate_metadata_address(Metadata* obj) {
4100 assert(oop_recorder() != NULL, "this assembler needs a Recorder");
4101 int index = oop_recorder()->allocate_metadata_index(obj);
4102 RelocationHolder rspec = metadata_Relocation::spec(index);
4103 return Address((address)obj, rspec);
4104 }
4105
4106 // Move an oop into a register. immediate is true if we want
4107 // immediate instrcutions, i.e. we are not going to patch this
4108 // instruction while the code is being executed by another thread. In
4109 // that case we can use move immediates rather than the constant pool.
4110 void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) {
4111 int oop_index;
4112 if (obj == NULL) {
4113 oop_index = oop_recorder()->allocate_oop_index(obj);
4114 } else {
4115 #ifdef ASSERT
4116 {
4117 ThreadInVMfromUnknown tiv;
4118 assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop");
4119 }
4120 #endif
4121 oop_index = oop_recorder()->find_index(obj);
4122 }
4123 RelocationHolder rspec = oop_Relocation::spec(oop_index);
4124 if (! immediate) {
4125 address dummy = address(uintptr_t(pc()) & -wordSize); // A nearby aligned address
4126 ldr_constant(dst, Address(dummy, rspec));
4127 } else
4128 mov(dst, Address((address)obj, rspec));
4129 }
4130
4131 // Move a metadata address into a register.
4132 void MacroAssembler::mov_metadata(Register dst, Metadata* obj) {
4133 int oop_index;
4134 if (obj == NULL) {
4135 oop_index = oop_recorder()->allocate_metadata_index(obj);
4136 } else {
4137 oop_index = oop_recorder()->find_index(obj);
4138 }
4139 RelocationHolder rspec = metadata_Relocation::spec(oop_index);
4140 mov(dst, Address((address)obj, rspec));
4141 }
4142
4143 Address MacroAssembler::constant_oop_address(jobject obj) {
4144 #ifdef ASSERT
|
3672 adr = Address(rscratch2);
3673 break;
3674 }
3675 ldr(rscratch1, adr);
3676 add(rscratch1, rscratch1, src);
3677 str(rscratch1, adr);
3678 }
3679
3680 void MacroAssembler::cmpptr(Register src1, Address src2) {
3681 unsigned long offset;
3682 adrp(rscratch1, src2, offset);
3683 ldr(rscratch1, Address(rscratch1, offset));
3684 cmp(src1, rscratch1);
3685 }
3686
3687 void MacroAssembler::cmpoop(Register obj1, Register obj2) {
3688 BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
3689 bs->obj_equals(this, obj1, obj2);
3690 }
3691
3692 void MacroAssembler::load_method_holder_cld(Register rresult, Register rmethod) {
3693 load_method_holder(rresult, rmethod);
3694 ldr(rresult, Address(rresult, InstanceKlass::class_loader_data_offset()));
3695 }
3696
3697 void MacroAssembler::load_method_holder(Register holder, Register method) {
3698 ldr(holder, Address(method, Method::const_offset())); // ConstMethod*
3699 ldr(holder, Address(holder, ConstMethod::constants_offset())); // ConstantPool*
3700 ldr(holder, Address(holder, ConstantPool::pool_holder_offset_in_bytes())); // InstanceKlass*
3701 }
3702
3703 void MacroAssembler::load_klass(Register dst, Register src) {
3704 if (UseCompressedClassPointers) {
3705 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3706 decode_klass_not_null(dst);
3707 } else {
3708 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3709 }
3710 }
3711
3712 // ((OopHandle)result).resolve();
3713 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
3714 // OopHandle::resolve is an indirection.
3715 access_load_at(T_OBJECT, IN_NATIVE, result, Address(result, 0), tmp, noreg);
3716 }
3717
3718 // ((WeakHandle)result).resolve();
3719 void MacroAssembler::resolve_weak_handle(Register rresult, Register rtmp) {
3720 assert_different_registers(rresult, rtmp);
3721 Label resolved;
3722
3723 // A null weak handle resolves to null.
3724 cbz(rresult, resolved);
3725
3726 // Only 64 bit platforms support GCs that require a tmp register
3727 // Only IN_HEAP loads require a thread_tmp register
3728 // WeakHandle::resolve is an indirection like jweak.
3729 access_load_at(T_OBJECT, IN_NATIVE | ON_PHANTOM_OOP_REF,
3730 rresult, Address(rresult), rtmp, /*tmp_thread*/noreg);
3731 bind(resolved);
3732 }
3733
3734 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
3735 const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3736 ldr(dst, Address(rmethod, Method::const_offset()));
3737 ldr(dst, Address(dst, ConstMethod::constants_offset()));
3738 ldr(dst, Address(dst, ConstantPool::pool_holder_offset_in_bytes()));
3739 ldr(dst, Address(dst, mirror_offset));
3740 resolve_oop_handle(dst, tmp);
3741 }
3742
3743 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) {
3744 if (UseCompressedClassPointers) {
3745 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes()));
3746 if (CompressedKlassPointers::base() == NULL) {
3747 cmp(trial_klass, tmp, LSL, CompressedKlassPointers::shift());
3748 return;
3749 } else if (((uint64_t)CompressedKlassPointers::base() & 0xffffffff) == 0
3750 && CompressedKlassPointers::shift() == 0) {
3751 // Only the bottom 32 bits matter
3752 cmpw(trial_klass, tmp);
3753 return;
4108 }
4109
4110 void MacroAssembler::store_heap_oop(Address dst, Register src, Register tmp1,
4111 Register thread_tmp, DecoratorSet decorators) {
4112 access_store_at(T_OBJECT, IN_HEAP | decorators, dst, src, tmp1, thread_tmp);
4113 }
4114
4115 // Used for storing NULLs.
4116 void MacroAssembler::store_heap_oop_null(Address dst) {
4117 access_store_at(T_OBJECT, IN_HEAP, dst, noreg, noreg, noreg);
4118 }
4119
4120 Address MacroAssembler::allocate_metadata_address(Metadata* obj) {
4121 assert(oop_recorder() != NULL, "this assembler needs a Recorder");
4122 int index = oop_recorder()->allocate_metadata_index(obj);
4123 RelocationHolder rspec = metadata_Relocation::spec(index);
4124 return Address((address)obj, rspec);
4125 }
4126
4127 // Move an oop into a register. immediate is true if we want
4128 // immediate instructions and nmethod entry barriers are not enabled.
4129 // i.e. we are not going to patch this instruction while the code is being
4130 // executed by another thread.
4131 void MacroAssembler::movoop(Register dst, jobject obj, bool immediate) {
4132 int oop_index;
4133 if (obj == NULL) {
4134 oop_index = oop_recorder()->allocate_oop_index(obj);
4135 } else {
4136 #ifdef ASSERT
4137 {
4138 ThreadInVMfromUnknown tiv;
4139 assert(Universe::heap()->is_in(JNIHandles::resolve(obj)), "should be real oop");
4140 }
4141 #endif
4142 oop_index = oop_recorder()->find_index(obj);
4143 }
4144 RelocationHolder rspec = oop_Relocation::spec(oop_index);
4145
4146 // nmethod entry barrier necessitate using the constant pool. They have to be
4147 // ordered with respected to oop accesses.
4148 // Using immediate literals would necessitate ISBs.
4149 if (BarrierSet::barrier_set()->barrier_set_nmethod() != NULL || !immediate) {
4150 address dummy = address(uintptr_t(pc()) & -wordSize); // A nearby aligned address
4151 ldr_constant(dst, Address(dummy, rspec));
4152 } else
4153 mov(dst, Address((address)obj, rspec));
4154 }
4155
4156 // Move a metadata address into a register.
4157 void MacroAssembler::mov_metadata(Register dst, Metadata* obj) {
4158 int oop_index;
4159 if (obj == NULL) {
4160 oop_index = oop_recorder()->allocate_metadata_index(obj);
4161 } else {
4162 oop_index = oop_recorder()->find_index(obj);
4163 }
4164 RelocationHolder rspec = metadata_Relocation::spec(oop_index);
4165 mov(dst, Address((address)obj, rspec));
4166 }
4167
4168 Address MacroAssembler::constant_oop_address(jobject obj) {
4169 #ifdef ASSERT
|