< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page
rev 50099 : 8203157: Object equals abstraction for BarrierSetAssembler


3630     // forms below.
3631     adr = form_address(rscratch2, dst.base(), dst.offset(), LogBytesPerWord);
3632     break;
3633   default:
3634     lea(rscratch2, dst);
3635     adr = Address(rscratch2);
3636     break;
3637   }
3638   ldr(rscratch1, adr);
3639   add(rscratch1, rscratch1, src);
3640   str(rscratch1, adr);
3641 }
3642 
3643 void MacroAssembler::cmpptr(Register src1, Address src2) {
3644   unsigned long offset;
3645   adrp(rscratch1, src2, offset);
3646   ldr(rscratch1, Address(rscratch1, offset));
3647   cmp(src1, rscratch1);
3648 }
3649 





3650 void MacroAssembler::load_klass(Register dst, Register src) {
3651   if (UseCompressedClassPointers) {
3652     ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3653     decode_klass_not_null(dst);
3654   } else {
3655     ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3656   }
3657 }
3658 
3659 // ((OopHandle)result).resolve();
3660 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
3661   // OopHandle::resolve is an indirection.
3662   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
3663   bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
3664                     result, Address(result, 0), tmp, rthread);
3665 }
3666 
3667 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
3668   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3669   ldr(dst, Address(rmethod, Method::const_offset()));


5019   assert(elem_size == 1 || elem_size == 2, "must be char or byte");
5020   assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
5021 
5022 #ifndef PRODUCT
5023   {
5024     const char kind = (elem_size == 2) ? 'U' : 'L';
5025     char comment[64];
5026     snprintf(comment, sizeof comment, "array_equals%c{", kind);
5027     BLOCK_COMMENT(comment);
5028   }
5029 #endif
5030   if (UseSimpleArrayEquals) {
5031     Label NEXT_WORD, SHORT, SAME, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL;
5032     // if (a1==a2)
5033     //     return true;
5034     // if (a==null || a2==null)
5035     //     return false;
5036     // a1 & a2 == 0 means (some-pointer is null) or
5037     // (very-rare-or-even-probably-impossible-pointer-values)
5038     // so, we can save one branch in most cases


5039     eor(rscratch1, a1, a2);
5040     tst(a1, a2);
5041     mov(result, false);
5042     cbz(rscratch1, SAME);
5043     br(EQ, A_MIGHT_BE_NULL);
5044     // if (a1.length != a2.length)
5045     //      return false;
5046     bind(A_IS_NOT_NULL);
5047     ldrw(cnt1, Address(a1, length_offset));
5048     ldrw(cnt2, Address(a2, length_offset));
5049     eorw(tmp5, cnt1, cnt2);
5050     cbnzw(tmp5, DONE);
5051     lea(a1, Address(a1, base_offset));
5052     lea(a2, Address(a2, base_offset));
5053     // Check for short strings, i.e. smaller than wordSize.
5054     subs(cnt1, cnt1, elem_per_word);
5055     br(Assembler::LT, SHORT);
5056     // Main 8 byte comparison loop.
5057     bind(NEXT_WORD); {
5058       ldr(tmp1, Address(post(a1, wordSize)));


5102         ldrb(tmp1, a1);
5103         ldrb(tmp2, a2);
5104         eorw(tmp5, tmp1, tmp2);
5105         cbnzw(tmp5, DONE);
5106       }
5107     }
5108     bind(SAME);
5109     mov(result, true);
5110   } else {
5111     Label NEXT_DWORD, A_IS_NULL, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
5112         CSET_EQ, LAST_CHECK, LEN_IS_ZERO, SAME;
5113     cbz(a1, A_IS_NULL);
5114     ldrw(cnt1, Address(a1, length_offset));
5115     cbz(a2, A_IS_NULL);
5116     ldrw(cnt2, Address(a2, length_offset));
5117     mov(result, false);
5118     // on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
5119     // faster to perform another branch before comparing a1 and a2
5120     cmp(cnt1, elem_per_word);
5121     br(LE, SHORT); // short or same
5122     cmp(a1, a2);
5123     br(EQ, SAME);
5124     ldr(tmp3, Address(pre(a1, base_offset)));
5125     cmp(cnt1, stubBytesThreshold);
5126     br(GE, STUB);
5127     ldr(tmp4, Address(pre(a2, base_offset)));
5128     sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
5129     cmp(cnt2, cnt1);
5130     br(NE, DONE);
5131 
5132     // Main 16 byte comparison loop with 2 exits
5133     bind(NEXT_DWORD); {
5134       ldr(tmp1, Address(pre(a1, wordSize)));
5135       ldr(tmp2, Address(pre(a2, wordSize)));
5136       subs(cnt1, cnt1, 2 * elem_per_word);
5137       br(LE, TAIL);
5138       eor(tmp4, tmp3, tmp4);
5139       cbnz(tmp4, DONE);
5140       ldr(tmp3, Address(pre(a1, wordSize)));
5141       ldr(tmp4, Address(pre(a2, wordSize)));
5142       cmp(cnt1, elem_per_word);




3630     // forms below.
3631     adr = form_address(rscratch2, dst.base(), dst.offset(), LogBytesPerWord);
3632     break;
3633   default:
3634     lea(rscratch2, dst);
3635     adr = Address(rscratch2);
3636     break;
3637   }
3638   ldr(rscratch1, adr);
3639   add(rscratch1, rscratch1, src);
3640   str(rscratch1, adr);
3641 }
3642 
3643 void MacroAssembler::cmpptr(Register src1, Address src2) {
3644   unsigned long offset;
3645   adrp(rscratch1, src2, offset);
3646   ldr(rscratch1, Address(rscratch1, offset));
3647   cmp(src1, rscratch1);
3648 }
3649 
3650 void MacroAssembler::cmpoop(Register obj1, Register obj2) {
3651   BarrierSetAssembler* bs = BarrierSet::barrier_set()->barrier_set_assembler();
3652   bs->obj_equals(this, IN_HEAP, obj1, obj2);
3653 }
3654 
3655 void MacroAssembler::load_klass(Register dst, Register src) {
3656   if (UseCompressedClassPointers) {
3657     ldrw(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3658     decode_klass_not_null(dst);
3659   } else {
3660     ldr(dst, Address(src, oopDesc::klass_offset_in_bytes()));
3661   }
3662 }
3663 
3664 // ((OopHandle)result).resolve();
3665 void MacroAssembler::resolve_oop_handle(Register result, Register tmp) {
3666   // OopHandle::resolve is an indirection.
3667   BarrierSetAssembler *bs = BarrierSet::barrier_set()->barrier_set_assembler();
3668   bs->load_at(this, IN_ROOT | IN_CONCURRENT_ROOT, T_OBJECT,
3669                     result, Address(result, 0), tmp, rthread);
3670 }
3671 
3672 void MacroAssembler::load_mirror(Register dst, Register method, Register tmp) {
3673   const int mirror_offset = in_bytes(Klass::java_mirror_offset());
3674   ldr(dst, Address(rmethod, Method::const_offset()));


5024   assert(elem_size == 1 || elem_size == 2, "must be char or byte");
5025   assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
5026 
5027 #ifndef PRODUCT
5028   {
5029     const char kind = (elem_size == 2) ? 'U' : 'L';
5030     char comment[64];
5031     snprintf(comment, sizeof comment, "array_equals%c{", kind);
5032     BLOCK_COMMENT(comment);
5033   }
5034 #endif
5035   if (UseSimpleArrayEquals) {
5036     Label NEXT_WORD, SHORT, SAME, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL;
5037     // if (a1==a2)
5038     //     return true;
5039     // if (a==null || a2==null)
5040     //     return false;
5041     // a1 & a2 == 0 means (some-pointer is null) or
5042     // (very-rare-or-even-probably-impossible-pointer-values)
5043     // so, we can save one branch in most cases
5044     cmpoop(a1, a2);
5045     br(EQ, SAME);
5046     eor(rscratch1, a1, a2);
5047     tst(a1, a2);
5048     mov(result, false);
5049     cbz(rscratch1, SAME);
5050     br(EQ, A_MIGHT_BE_NULL);
5051     // if (a1.length != a2.length)
5052     //      return false;
5053     bind(A_IS_NOT_NULL);
5054     ldrw(cnt1, Address(a1, length_offset));
5055     ldrw(cnt2, Address(a2, length_offset));
5056     eorw(tmp5, cnt1, cnt2);
5057     cbnzw(tmp5, DONE);
5058     lea(a1, Address(a1, base_offset));
5059     lea(a2, Address(a2, base_offset));
5060     // Check for short strings, i.e. smaller than wordSize.
5061     subs(cnt1, cnt1, elem_per_word);
5062     br(Assembler::LT, SHORT);
5063     // Main 8 byte comparison loop.
5064     bind(NEXT_WORD); {
5065       ldr(tmp1, Address(post(a1, wordSize)));


5109         ldrb(tmp1, a1);
5110         ldrb(tmp2, a2);
5111         eorw(tmp5, tmp1, tmp2);
5112         cbnzw(tmp5, DONE);
5113       }
5114     }
5115     bind(SAME);
5116     mov(result, true);
5117   } else {
5118     Label NEXT_DWORD, A_IS_NULL, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
5119         CSET_EQ, LAST_CHECK, LEN_IS_ZERO, SAME;
5120     cbz(a1, A_IS_NULL);
5121     ldrw(cnt1, Address(a1, length_offset));
5122     cbz(a2, A_IS_NULL);
5123     ldrw(cnt2, Address(a2, length_offset));
5124     mov(result, false);
5125     // on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
5126     // faster to perform another branch before comparing a1 and a2
5127     cmp(cnt1, elem_per_word);
5128     br(LE, SHORT); // short or same
5129     cmpoop(a1, a2);
5130     br(EQ, SAME);
5131     ldr(tmp3, Address(pre(a1, base_offset)));
5132     cmp(cnt1, stubBytesThreshold);
5133     br(GE, STUB);
5134     ldr(tmp4, Address(pre(a2, base_offset)));
5135     sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
5136     cmp(cnt2, cnt1);
5137     br(NE, DONE);
5138 
5139     // Main 16 byte comparison loop with 2 exits
5140     bind(NEXT_DWORD); {
5141       ldr(tmp1, Address(pre(a1, wordSize)));
5142       ldr(tmp2, Address(pre(a2, wordSize)));
5143       subs(cnt1, cnt1, 2 * elem_per_word);
5144       br(LE, TAIL);
5145       eor(tmp4, tmp3, tmp4);
5146       cbnz(tmp4, DONE);
5147       ldr(tmp3, Address(pre(a1, wordSize)));
5148       ldr(tmp4, Address(pre(a2, wordSize)));
5149       cmp(cnt1, elem_per_word);


< prev index next >