Merge
authorplevart
Fri, 22 Jun 2018 18:18:05 +0200
changeset 50720 c55b1386f119
parent 50719 106dc156ce6b (current diff)
parent 50717 365e137617ff (diff)
child 50721 e541c1b68b89
Merge
--- a/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri Jun 22 17:56:55 2018 +0200
+++ b/src/hotspot/cpu/aarch64/assembler_aarch64.hpp	Fri Jun 22 18:18:05 2018 +0200
@@ -1638,12 +1638,14 @@
 #undef INSN
 
   // Conditional compare (both kinds)
-  void conditional_compare(unsigned op, int o2, int o3,
+  void conditional_compare(unsigned op, int o1, int o2, int o3,
                            Register Rn, unsigned imm5, unsigned nzcv,
                            unsigned cond) {
+    starti;
     f(op, 31, 29);
     f(0b11010010, 28, 21);
     f(cond, 15, 12);
+    f(o1, 11);
     f(o2, 10);
     f(o3, 4);
     f(nzcv, 3, 0);
@@ -1652,15 +1654,12 @@
 
 #define INSN(NAME, op)                                                  \
   void NAME(Register Rn, Register Rm, int imm, Condition cond) {        \
-    starti;                                                             \
-    f(0, 11);                                                           \
-    conditional_compare(op, 0, 0, Rn, (uintptr_t)Rm, imm, cond);        \
+    int regNumber = (Rm == zr ? 31 : (uintptr_t)Rm);                    \
+    conditional_compare(op, 0, 0, 0, Rn, regNumber, imm, cond);         \
   }                                                                     \
                                                                         \
-  void NAME(Register Rn, int imm5, int imm, Condition cond) {   \
-    starti;                                                             \
-    f(1, 11);                                                           \
-    conditional_compare(op, 0, 0, Rn, imm5, imm, cond);                 \
+  void NAME(Register Rn, int imm5, int imm, Condition cond) {           \
+    conditional_compare(op, 1, 0, 0, Rn, imm5, imm, cond);              \
   }
 
   INSN(ccmnw, 0b001);
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Fri Jun 22 17:56:55 2018 +0200
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Fri Jun 22 18:18:05 2018 +0200
@@ -4928,9 +4928,8 @@
 
 void MacroAssembler::arrays_equals(Register a1, Register a2, Register tmp3,
                                    Register tmp4, Register tmp5, Register result,
-                                   Register cnt1, int elem_size)
-{
-  Label DONE;
+                                   Register cnt1, int elem_size) {
+  Label DONE, SAME;
   Register tmp1 = rscratch1;
   Register tmp2 = rscratch2;
   Register cnt2 = tmp2;  // cnt2 only used in array length compare
@@ -4952,21 +4951,21 @@
     BLOCK_COMMENT(comment);
   }
 #endif
+
+  // if (a1 == a2)
+  //     return true;
+  cmpoop(a1, a2); // May have read barriers for a1 and a2.
+  br(EQ, SAME);
+
   if (UseSimpleArrayEquals) {
-    Label NEXT_WORD, SHORT, SAME, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL;
-    // if (a1==a2)
-    //     return true;
-    // if (a==null || a2==null)
+    Label NEXT_WORD, SHORT, TAIL03, TAIL01, A_MIGHT_BE_NULL, A_IS_NOT_NULL;
+    // if (a1 == null || a2 == null)
     //     return false;
     // a1 & a2 == 0 means (some-pointer is null) or
     // (very-rare-or-even-probably-impossible-pointer-values)
     // so, we can save one branch in most cases
-    cmpoop(a1, a2);
-    br(EQ, SAME);
-    eor(rscratch1, a1, a2);
     tst(a1, a2);
     mov(result, false);
-    cbz(rscratch1, SAME);
     br(EQ, A_MIGHT_BE_NULL);
     // if (a1.length != a2.length)
     //      return false;
@@ -5032,22 +5031,18 @@
         cbnzw(tmp5, DONE);
       }
     }
-    bind(SAME);
-    mov(result, true);
   } else {
-    Label NEXT_DWORD, A_IS_NULL, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
-        CSET_EQ, LAST_CHECK, LEN_IS_ZERO, SAME;
-    cbz(a1, A_IS_NULL);
+    Label NEXT_DWORD, SHORT, TAIL, TAIL2, STUB, EARLY_OUT,
+        CSET_EQ, LAST_CHECK;
+    mov(result, false);
+    cbz(a1, DONE);
     ldrw(cnt1, Address(a1, length_offset));
-    cbz(a2, A_IS_NULL);
+    cbz(a2, DONE);
     ldrw(cnt2, Address(a2, length_offset));
-    mov(result, false);
     // 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, elem_per_word);
     br(LE, SHORT); // short or same
-    cmpoop(a1, a2);
-    br(EQ, SAME);
     ldr(tmp3, Address(pre(a1, base_offset)));
     cmp(cnt1, stubBytesThreshold);
     br(GE, STUB);
@@ -5099,23 +5094,15 @@
     trampoline_call(stub);
     b(DONE);
 
-    bind(SAME);
-    mov(result, true);
-    b(DONE);
-    bind(A_IS_NULL);
-    // a1 or a2 is null. if a2 == a2 then return true. else return false
-    cmp(a1, a2);
-    b(CSET_EQ);
     bind(EARLY_OUT);
     // (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(LEN_IS_ZERO);
-    cmp(cnt2, zr);
-    b(CSET_EQ);
     bind(SHORT);
-    cbz(cnt1, LEN_IS_ZERO);
+    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));
@@ -5125,8 +5112,11 @@
     cmp(tmp5, zr);
     bind(CSET_EQ);
     cset(result, EQ);
+    b(DONE);
   }
 
+  bind(SAME);
+  mov(result, true);
   // That's it.
   bind(DONE);