2871 SkipIfEqual::SkipIfEqual( 2872 MacroAssembler* masm, const bool* flag_addr, bool value) { 2873 _masm = masm; 2874 unsigned long offset; 2875 _masm->adrp(rscratch1, ExternalAddress((address)flag_addr), offset); 2876 _masm->ldrb(rscratch1, Address(rscratch1, offset)); 2877 _masm->cbzw(rscratch1, _label); 2878 } 2879 2880 SkipIfEqual::~SkipIfEqual() { 2881 _masm->bind(_label); 2882 } 2883 2884 void MacroAssembler::cmpptr(Register src1, Address src2) { 2885 unsigned long offset; 2886 adrp(rscratch1, src2, offset); 2887 ldr(rscratch1, Address(rscratch1, offset)); 2888 cmp(src1, rscratch1); 2889 } 2890 2891 void MacroAssembler::store_check(Register obj) { 2892 // Does a store check for the oop in register obj. The content of 2893 // register obj is destroyed afterwards. 2894 store_check_part_1(obj); 2895 store_check_part_2(obj); 2896 } 2897 2898 void MacroAssembler::store_check(Register obj, Address dst) { 2899 store_check(obj); 2900 } 2901 2902 2903 // split the store check operation so that other instructions can be scheduled inbetween 2904 void MacroAssembler::store_check_part_1(Register obj) { 2905 BarrierSet* bs = Universe::heap()->barrier_set(); 2906 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); 2907 lsr(obj, obj, CardTableModRefBS::card_shift); 2908 } 2909 2910 void MacroAssembler::store_check_part_2(Register obj) { 2911 BarrierSet* bs = Universe::heap()->barrier_set(); 2912 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); 2913 CardTableModRefBS* ct = (CardTableModRefBS*)bs; 2914 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 2915 2916 // The calculation for byte_map_base is as follows: 2917 // byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift); 2918 // So this essentially converts an address to a displacement and 2919 // it will never need to be relocated. 2920 2921 // FIXME: It's not likely that disp will fit into an offset so we 2922 // don't bother to check, but it could save an instruction. 2923 intptr_t disp = (intptr_t) ct->byte_map_base; 2924 mov(rscratch1, disp); 2925 strb(zr, Address(obj, rscratch1)); 2926 } 2927 2928 void MacroAssembler::load_klass(Register dst, Register src) { 2929 if (UseCompressedClassPointers) { 2930 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes())); 2931 decode_klass_not_null(dst); 2932 } else { 2933 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes())); 2934 } 2935 } 2936 2937 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) { 2938 if (UseCompressedClassPointers) { 2939 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes())); 2940 if (Universe::narrow_klass_base() == NULL) { 2941 cmp(trial_klass, tmp, LSL, Universe::narrow_klass_shift()); 2942 return; 2943 } else if (((uint64_t)Universe::narrow_klass_base() & 0xffffffff) == 0 2944 && Universe::narrow_klass_shift() == 0) { 2945 // Only the bottom 32 bits matter | 2871 SkipIfEqual::SkipIfEqual( 2872 MacroAssembler* masm, const bool* flag_addr, bool value) { 2873 _masm = masm; 2874 unsigned long offset; 2875 _masm->adrp(rscratch1, ExternalAddress((address)flag_addr), offset); 2876 _masm->ldrb(rscratch1, Address(rscratch1, offset)); 2877 _masm->cbzw(rscratch1, _label); 2878 } 2879 2880 SkipIfEqual::~SkipIfEqual() { 2881 _masm->bind(_label); 2882 } 2883 2884 void MacroAssembler::cmpptr(Register src1, Address src2) { 2885 unsigned long offset; 2886 adrp(rscratch1, src2, offset); 2887 ldr(rscratch1, Address(rscratch1, offset)); 2888 cmp(src1, rscratch1); 2889 } 2890 2891 void MacroAssembler::store_check(Register obj, Address dst) { 2892 store_check(obj); 2893 } 2894 2895 void MacroAssembler::store_check(Register obj) { 2896 // Does a store check for the oop in register obj. The content of 2897 // register obj is destroyed afterwards. 2898 2899 BarrierSet* bs = Universe::heap()->barrier_set(); 2900 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); 2901 2902 CardTableModRefBS* ct = barrier_set_cast<CardTableModRefBS>(bs); 2903 assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code"); 2904 2905 lsr(obj, obj, CardTableModRefBS::card_shift); 2906 2907 assert(CardTableModRefBS::dirty_card_val() == 0, "must be"); 2908 2909 { 2910 ExternalAddress cardtable((address) ct->byte_map_base); 2911 unsigned long offset; 2912 adrp(rscratch1, cardtable, offset); 2913 assert(offset == 0, "byte_map_base is misaligned"); 2914 } 2915 2916 if (UseCondCardMark) { 2917 Label L_already_dirty; 2918 ldrb(rscratch2, Address(obj, rscratch1)); 2919 cbz(rscratch2, L_already_dirty); 2920 strb(zr, Address(obj, rscratch1)); 2921 bind(L_already_dirty); 2922 } else { 2923 strb(zr, Address(obj, rscratch1)); 2924 } 2925 } 2926 2927 void MacroAssembler::load_klass(Register dst, Register src) { 2928 if (UseCompressedClassPointers) { 2929 ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes())); 2930 decode_klass_not_null(dst); 2931 } else { 2932 ldr(dst, Address(src, oopDesc::klass_offset_in_bytes())); 2933 } 2934 } 2935 2936 void MacroAssembler::cmp_klass(Register oop, Register trial_klass, Register tmp) { 2937 if (UseCompressedClassPointers) { 2938 ldrw(tmp, Address(oop, oopDesc::klass_offset_in_bytes())); 2939 if (Universe::narrow_klass_base() == NULL) { 2940 cmp(trial_klass, tmp, LSL, Universe::narrow_klass_shift()); 2941 return; 2942 } else if (((uint64_t)Universe::narrow_klass_base() & 0xffffffff) == 0 2943 && Universe::narrow_klass_shift() == 0) { 2944 // Only the bottom 32 bits matter |