@@ -5583,12 +5583,22 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
5583
5583
Label DONE, SAME;
5584
5584
Register tmp1 = rscratch1;
5585
5585
Register tmp2 = rscratch2;
5586
- Register cnt2 = tmp2; // cnt2 only used in array length compare
5587
5586
int elem_per_word = wordSize/elem_size;
5588
5587
int log_elem_size = exact_log2 (elem_size);
5588
+ int klass_offset = arrayOopDesc::klass_offset_in_bytes ();
5589
5589
int length_offset = arrayOopDesc::length_offset_in_bytes ();
5590
5590
int base_offset
5591
5591
= arrayOopDesc::base_offset_in_bytes (elem_size == 2 ? T_CHAR : T_BYTE);
5592
+ // When the length offset is not aligned to 8 bytes,
5593
+ // then we align it down. This is valid because the new
5594
+ // offset will always be the klass which is the same
5595
+ // for type arrays.
5596
+ int start_offset = align_down (length_offset, BytesPerWord);
5597
+ int extra_length = base_offset - start_offset;
5598
+ assert (start_offset == length_offset || start_offset == klass_offset,
5599
+ " start offset must be 8-byte-aligned or be the klass offset" );
5600
+ assert (base_offset != start_offset, " must include the length field" );
5601
+ extra_length = extra_length / elem_size; // We count in elements, not bytes.
5592
5602
int stubBytesThreshold = 3 * 64 + (UseSIMDForArrayEquals ? 0 : 16 );
5593
5603
5594
5604
assert (elem_size == 1 || elem_size == 2 , " must be char or byte" );
@@ -5622,11 +5632,10 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
5622
5632
// return false;
5623
5633
bind (A_IS_NOT_NULL);
5624
5634
ldrw (cnt1, Address (a1, length_offset));
5625
- ldrw (cnt2, Address (a2, length_offset));
5626
- eorw (tmp5, cnt1, cnt2);
5627
- cbnzw (tmp5, DONE);
5628
- lea (a1, Address (a1, base_offset));
5629
- lea (a2, Address (a2, base_offset));
5635
+ // Increase loop counter by diff between base- and actual start-offset.
5636
+ addw (cnt1, cnt1, extra_length);
5637
+ lea (a1, Address (a1, start_offset));
5638
+ lea (a2, Address (a2, start_offset));
5630
5639
// Check for short strings, i.e. smaller than wordSize.
5631
5640
subs (cnt1, cnt1, elem_per_word);
5632
5641
br (Assembler::LT, SHORT);
@@ -5689,18 +5698,18 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
5689
5698
cbz (a1, DONE);
5690
5699
ldrw (cnt1, Address (a1, length_offset));
5691
5700
cbz (a2, DONE);
5692
- ldrw (cnt2, Address (a2, length_offset));
5701
+ // Increase loop counter by diff between base- and actual start-offset.
5702
+ addw (cnt1, cnt1, extra_length);
5703
+
5693
5704
// on most CPUs a2 is still "locked"(surprisingly) in ldrw and it's
5694
5705
// faster to perform another branch before comparing a1 and a2
5695
5706
cmp (cnt1, (u1)elem_per_word);
5696
5707
br (LE, SHORT); // short or same
5697
- ldr (tmp3, Address (pre (a1, base_offset )));
5708
+ ldr (tmp3, Address (pre (a1, start_offset )));
5698
5709
subs (zr, cnt1, stubBytesThreshold);
5699
5710
br (GE, STUB);
5700
- ldr (tmp4, Address (pre (a2, base_offset )));
5711
+ ldr (tmp4, Address (pre (a2, start_offset )));
5701
5712
sub (tmp5, zr, cnt1, LSL, 3 + log_elem_size);
5702
- cmp (cnt2, cnt1);
5703
- br (NE, DONE);
5704
5713
5705
5714
// Main 16 byte comparison loop with 2 exits
5706
5715
bind (NEXT_DWORD); {
@@ -5732,9 +5741,7 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
5732
5741
b (LAST_CHECK);
5733
5742
5734
5743
bind (STUB);
5735
- ldr (tmp4, Address (pre (a2, base_offset)));
5736
- cmp (cnt2, cnt1);
5737
- br (NE, DONE);
5744
+ ldr (tmp4, Address (pre (a2, start_offset)));
5738
5745
if (elem_size == 2 ) { // convert to byte counter
5739
5746
lsl (cnt1, cnt1, 1 );
5740
5747
}
@@ -5755,12 +5762,9 @@ address MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
5755
5762
mov (result, a2);
5756
5763
b (DONE);
5757
5764
bind (SHORT);
5758
- cmp (cnt2, cnt1);
5759
- br (NE, DONE);
5760
- cbz (cnt1, SAME);
5761
5765
sub (tmp5, zr, cnt1, LSL, 3 + log_elem_size);
5762
- ldr (tmp3, Address (a1, base_offset ));
5763
- ldr (tmp4, Address (a2, base_offset ));
5766
+ ldr (tmp3, Address (a1, start_offset ));
5767
+ ldr (tmp4, Address (a2, start_offset ));
5764
5768
bind (LAST_CHECK);
5765
5769
eor (tmp4, tmp3, tmp4);
5766
5770
lslv (tmp5, tmp4, tmp5);
0 commit comments