< prev index next > src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp
Print this page
// 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);
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);
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); {
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)));
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);
// (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 >