< prev index next >

src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp

Print this page
@@ -5029,12 +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);
+   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 +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 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);
  

@@ -5858,14 +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));
-     // 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));
+     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 +5915,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);
- 
+     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, start_offset)));
+     ldr(tmp3, Address(pre(a1, base_offset)));
      subs(zr, cnt1, stubBytesThreshold);
      br(GE, STUB);
-     ldr(tmp4, Address(pre(a2, start_offset)));
+     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 +5958,13 @@
      eor(tmp2, tmp1, tmp2);
      cbnz(tmp2, DONE);
      b(LAST_CHECK);
  
      bind(STUB);
-     ldr(tmp4, Address(pre(a2, start_offset)));
+     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 +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, start_offset));
-     ldr(tmp4, Address(a2, start_offset));
+     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 >