< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page
*** 5029,12 ***
  // Input:
  // src - the oop we want to load the klass from.
  // dst - output narrow klass.
  void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
    assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
!   ldr(dst, Address(src, oopDesc::mark_offset_in_bytes()));
!   lsr(dst, dst, markWord::klass_shift);
  }
  
  void MacroAssembler::load_klass(Register dst, Register src) {
    if (UseCompactObjectHeaders) {
      load_narrow_klass_compact(dst, src);
--- 5029,12 ---
  // Input:
  // src - the oop we want to load the klass from.
  // dst - output narrow klass.
  void MacroAssembler::load_narrow_klass_compact(Register dst, Register src) {
    assert(UseCompactObjectHeaders, "expects UseCompactObjectHeaders");
!   ldrw(dst, Address(src, oopDesc::mark_offset_in_bytes()));
!   lsrw(dst, dst, markWord::klass_shift);
  }
  
  void MacroAssembler::load_klass(Register dst, Register src) {
    if (UseCompactObjectHeaders) {
      load_narrow_klass_compact(dst, src);

*** 5809,26 ***
                                        Register tmp4, Register tmp5, Register result,
                                        Register cnt1, int elem_size) {
    Label DONE, SAME;
    Register tmp1 = rscratch1;
    Register tmp2 = rscratch2;
    int elem_per_word = wordSize/elem_size;
    int log_elem_size = exact_log2(elem_size);
-   int klass_offset  = arrayOopDesc::klass_offset_in_bytes();
    int length_offset = arrayOopDesc::length_offset_in_bytes();
    int base_offset
      = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
-   // When the length offset is not aligned to 8 bytes,
-   // then we align it down. This is valid because the new
-   // offset will always be the klass which is the same
-   // for type arrays.
-   int start_offset = align_down(length_offset, BytesPerWord);
-   int extra_length = base_offset - start_offset;
-   assert(start_offset == length_offset || start_offset == klass_offset,
-          "start offset must be 8-byte-aligned or be the klass offset");
-   assert(base_offset != start_offset, "must include the length field");
-   extra_length = extra_length / elem_size; // We count in elements, not bytes.
    int stubBytesThreshold = 3 * 64 + (UseSIMDForArrayEquals ? 0 : 16);
  
    assert(elem_size == 1 || elem_size == 2, "must be char or byte");
    assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
  
--- 5809,16 ---
                                        Register tmp4, Register tmp5, Register result,
                                        Register cnt1, int elem_size) {
    Label DONE, SAME;
    Register tmp1 = rscratch1;
    Register tmp2 = rscratch2;
+   Register cnt2 = tmp2;  // cnt2 only used in array length compare
    int elem_per_word = wordSize/elem_size;
    int log_elem_size = exact_log2(elem_size);
    int length_offset = arrayOopDesc::length_offset_in_bytes();
    int base_offset
      = arrayOopDesc::base_offset_in_bytes(elem_size == 2 ? T_CHAR : T_BYTE);
    int stubBytesThreshold = 3 * 64 + (UseSIMDForArrayEquals ? 0 : 16);
  
    assert(elem_size == 1 || elem_size == 2, "must be char or byte");
    assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
  

*** 5858,14 ***
      br(EQ, A_MIGHT_BE_NULL);
      // if (a1.length != a2.length)
      //      return false;
      bind(A_IS_NOT_NULL);
      ldrw(cnt1, Address(a1, length_offset));
!     // Increase loop counter by diff between base- and actual start-offset.
!     addw(cnt1, cnt1, extra_length);
!     lea(a1, Address(a1, start_offset));
!     lea(a2, Address(a2, start_offset));
      // Check for short strings, i.e. smaller than wordSize.
      subs(cnt1, cnt1, elem_per_word);
      br(Assembler::LT, SHORT);
      // Main 8 byte comparison loop.
      bind(NEXT_WORD); {
--- 5848,15 ---
      br(EQ, A_MIGHT_BE_NULL);
      // if (a1.length != a2.length)
      //      return false;
      bind(A_IS_NOT_NULL);
      ldrw(cnt1, Address(a1, length_offset));
!     ldrw(cnt2, Address(a2, length_offset));
!     eorw(tmp5, cnt1, cnt2);
!     cbnzw(tmp5, DONE);
!     lea(a1, Address(a1, base_offset));
+     lea(a2, Address(a2, base_offset));
      // Check for short strings, i.e. smaller than wordSize.
      subs(cnt1, cnt1, elem_per_word);
      br(Assembler::LT, SHORT);
      // Main 8 byte comparison loop.
      bind(NEXT_WORD); {

*** 5924,22 ***
          CSET_EQ, LAST_CHECK;
      mov(result, false);
      cbz(a1, DONE);
      ldrw(cnt1, Address(a1, length_offset));
      cbz(a2, DONE);
!     // Increase loop counter by diff between base- and actual start-offset.
-     addw(cnt1, cnt1, extra_length);
- 
      // on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
      // faster to perform another branch before comparing a1 and a2
      cmp(cnt1, (u1)elem_per_word);
      br(LE, SHORT); // short or same
!     ldr(tmp3, Address(pre(a1, start_offset)));
      subs(zr, cnt1, stubBytesThreshold);
      br(GE, STUB);
!     ldr(tmp4, Address(pre(a2, start_offset)));
      sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
  
      // Main 16 byte comparison loop with 2 exits
      bind(NEXT_DWORD); {
        ldr(tmp1, Address(pre(a1, wordSize)));
        ldr(tmp2, Address(pre(a2, wordSize)));
--- 5915,22 ---
          CSET_EQ, LAST_CHECK;
      mov(result, false);
      cbz(a1, DONE);
      ldrw(cnt1, Address(a1, length_offset));
      cbz(a2, DONE);
!     ldrw(cnt2, Address(a2, length_offset));
      // on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
      // faster to perform another branch before comparing a1 and a2
      cmp(cnt1, (u1)elem_per_word);
      br(LE, SHORT); // short or same
!     ldr(tmp3, Address(pre(a1, base_offset)));
      subs(zr, cnt1, stubBytesThreshold);
      br(GE, STUB);
!     ldr(tmp4, Address(pre(a2, base_offset)));
      sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
+     cmp(cnt2, cnt1);
+     br(NE, DONE);
  
      // Main 16 byte comparison loop with 2 exits
      bind(NEXT_DWORD); {
        ldr(tmp1, Address(pre(a1, wordSize)));
        ldr(tmp2, Address(pre(a2, wordSize)));

*** 5967,11 ***
      eor(tmp2, tmp1, tmp2);
      cbnz(tmp2, DONE);
      b(LAST_CHECK);
  
      bind(STUB);
!     ldr(tmp4, Address(pre(a2, start_offset)));
      if (elem_size == 2) { // convert to byte counter
        lsl(cnt1, cnt1, 1);
      }
      eor(tmp5, tmp3, tmp4);
      cbnz(tmp5, DONE);
--- 5958,13 ---
      eor(tmp2, tmp1, tmp2);
      cbnz(tmp2, DONE);
      b(LAST_CHECK);
  
      bind(STUB);
!     ldr(tmp4, Address(pre(a2, base_offset)));
+     cmp(cnt2, cnt1);
+     br(NE, DONE);
      if (elem_size == 2) { // convert to byte counter
        lsl(cnt1, cnt1, 1);
      }
      eor(tmp5, tmp3, tmp4);
      cbnz(tmp5, DONE);

*** 5988,13 ***
      // (a1 != null && a2 == null) || (a1 != null && a2 != null && a1 == a2)
      // so, if a2 == null => return false(0), else return true, so we can return a2
      mov(result, a2);
      b(DONE);
      bind(SHORT);
      sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
!     ldr(tmp3, Address(a1, start_offset));
!     ldr(tmp4, Address(a2, start_offset));
      bind(LAST_CHECK);
      eor(tmp4, tmp3, tmp4);
      lslv(tmp5, tmp4, tmp5);
      cmp(tmp5, zr);
      bind(CSET_EQ);
--- 5981,16 ---
      // (a1 != null && a2 == null) || (a1 != null && a2 != null && a1 == a2)
      // so, if a2 == null => return false(0), else return true, so we can return a2
      mov(result, a2);
      b(DONE);
      bind(SHORT);
+     cmp(cnt2, cnt1);
+     br(NE, DONE);
+     cbz(cnt1, SAME);
      sub(tmp5, zr, cnt1, LSL, 3 + log_elem_size);
!     ldr(tmp3, Address(a1, base_offset));
!     ldr(tmp4, Address(a2, base_offset));
      bind(LAST_CHECK);
      eor(tmp4, tmp3, tmp4);
      lslv(tmp5, tmp4, tmp5);
      cmp(tmp5, zr);
      bind(CSET_EQ);
< prev index next >