< prev index next >

src/cpu/ppc/vm/macroAssembler_ppc.cpp

Print this page
rev 9944 : 8145336: PPC64: fix string intrinsics after CompactStrings change

@@ -3170,53 +3170,52 @@
 
 // Search for a single jchar in an jchar[].
 //
 // Assumes that result differs from all other registers.
 //
-// Haystack, needle are the addresses of jchar-arrays.
-// NeedleChar is needle[0] if it is known at compile time.
-// Haycnt is the length of the haystack. We assume haycnt >=1.
+// 'haystack' is the addresses of a jchar-array.
+// 'needle' is either the character to search for or R0.
+// 'needleChar' is the character to search for if 'needle' == R0..
+// 'haycnt' is the length of the haystack. We assume 'haycnt' >=1.
 //
-// Preserves haystack, haycnt, kills all other registers.
+// Preserves haystack, haycnt, needle and kills all other registers.
 //
 // If needle == R0, we search for the constant needleChar.
 void MacroAssembler::string_indexof_1(Register result, Register haystack, Register haycnt,
                                       Register needle, jchar needleChar,
                                       Register tmp1, Register tmp2) {
 
   assert_different_registers(result, haystack, haycnt, needle, tmp1, tmp2);
 
   Label L_InnerLoop, L_FinalCheck, L_Found1, L_Found2, L_Found3, L_NotFound, L_End;
-  Register needle0 = needle, // Contains needle[0].
-           addr = tmp1,
+  Register addr = tmp1,
            ch1 = tmp2,
            ch2 = R0;
 
-//2 (variable) or 3 (const):
-   if (needle != R0) lhz(needle0, 0, needle); // Preload needle character, needle has len==1.
+//2:
    dcbtct(haystack, 0x00);                        // Indicate R/O access to haystack.
 
    srwi_(tmp2, haycnt, 1);   // Shift right by exact_log2(UNROLL_FACTOR).
    mr(addr, haystack);
    beq(CCR0, L_FinalCheck);
    mtctr(tmp2);              // Move to count register.
 //8:
   bind(L_InnerLoop);             // Main work horse (2x unrolled search loop).
    lhz(ch1, 0, addr);        // Load characters from haystack.
    lhz(ch2, 2, addr);
-   (needle != R0) ? cmpw(CCR0, ch1, needle0) : cmplwi(CCR0, ch1, needleChar);
-   (needle != R0) ? cmpw(CCR1, ch2, needle0) : cmplwi(CCR1, ch2, needleChar);
+   (needle != R0) ? cmpw(CCR0, ch1, needle) : cmplwi(CCR0, ch1, needleChar);
+   (needle != R0) ? cmpw(CCR1, ch2, needle) : cmplwi(CCR1, ch2, needleChar);
    beq(CCR0, L_Found1);   // Did we find the needle?
    beq(CCR1, L_Found2);
    addi(addr, addr, 4);
    bdnz(L_InnerLoop);
 //16:
   bind(L_FinalCheck);
    andi_(R0, haycnt, 1);
    beq(CCR0, L_NotFound);
    lhz(ch1, 0, addr);        // One position left at which we have to compare.
-   (needle != R0) ? cmpw(CCR1, ch1, needle0) : cmplwi(CCR1, ch1, needleChar);
+   (needle != R0) ? cmpw(CCR1, ch1, needle) : cmplwi(CCR1, ch1, needleChar);
    beq(CCR1, L_Found3);
 //21:
   bind(L_NotFound);
    li(result, -1);           // Not found.
    b(L_End);

@@ -3397,11 +3396,19 @@
             limit_reg = cnt1_reg,
             chr1_reg = result_reg,
             chr2_reg = cnt2_reg,
             addr_diff = str2_reg;
 
+   // 'cnt_reg' contains the number of characters in the string's character array for the
+   // pre-CompactStrings strings implementation and the number of bytes in the string's
+   // byte array for the CompactStrings strings implementation.
+   const int HAS_COMPACT_STRING = java_lang_String::has_coder_field() ? 1 : 0; // '1' = byte array, '0' = char array
+
    // Offset 0 should be 32 byte aligned.
+//-6:
+    srawi(cnt1_reg, cnt1_reg, HAS_COMPACT_STRING);
+    srawi(cnt2_reg, cnt2_reg, HAS_COMPACT_STRING);
 //-4:
     dcbtct(str1_reg, 0x00);  // Indicate R/O access to str1.
     dcbtct(str2_reg, 0x00);  // Indicate R/O access to str2.
 //-2:
    // Compute min(cnt1, cnt2) and check if 0 (bail out if we don't need to compare characters).

@@ -3476,18 +3483,25 @@
   // Offset 0 should be 32 byte aligned.
   Label Linit_cbc, Lcbc, Lloop, Ldone_true, Ldone_false;
   Register index_reg = tmp5_reg;
   Register cbc_iter  = tmp4_reg;
 
+  // 'cnt_reg' contains the number of characters in the string's character array for the
+  // pre-CompactStrings strings implementation and the number of bytes in the string's
+  // byte array for the CompactStrings strings implementation.
+  const int HAS_COMPACT_STRING = java_lang_String::has_coder_field() ? 1 : 0; // '1' = byte array, '0' = char array
+
 //-1:
   dcbtct(str1_reg, 0x00);  // Indicate R/O access to str1.
   dcbtct(str2_reg, 0x00);  // Indicate R/O access to str2.
 //1:
-  andi(cbc_iter, cnt_reg, 4-1);            // Remaining iterations after 4 java characters per iteration loop.
+  // cbc_iter: remaining characters after the '4 java characters per iteration' loop.
+  rlwinm(cbc_iter, cnt_reg, 32 - HAS_COMPACT_STRING, 30, 31); // (cnt_reg % (HAS_COMPACT_STRING ? 8 : 4)) >> HAS_COMPACT_STRING
   li(index_reg, 0); // init
   li(result_reg, 0); // assume false
-  srwi_(tmp2_reg, cnt_reg, exact_log2(4)); // Div: 4 java characters per iteration (main loop).
+  // tmp2_reg: units of 4 java characters (i.e. 8 bytes) per iteration (main loop).
+  srwi_(tmp2_reg, cnt_reg, exact_log2(4 << HAS_COMPACT_STRING)); // cnt_reg / (HAS_COMPACT_STRING ? 8 : 4)
 
   cmpwi(CCR1, cbc_iter, 0);             // CCR1 = (cbc_iter==0)
   beq(CCR0, Linit_cbc);                 // too short
     mtctr(tmp2_reg);
 //8:

@@ -3524,10 +3538,15 @@
   assert_different_registers(result_reg, str1_reg, tmp1_reg, tmp2_reg);
   assert_different_registers(result_reg, str2_reg, tmp1_reg, tmp2_reg);
   assert(sizeof(jchar) == 2, "must be");
   assert(cntval >= 0 && ((cntval & 0x7fff) == cntval), "wrong immediate");
 
+  // 'cntval' contains the number of characters in the string's character array for the
+  // pre-CompactStrings strings implementation and the number of bytes in the string's
+  // byte array for the CompactStrings strings implementation.
+  cntval >>= (java_lang_String::has_coder_field() ? 1 : 0); // '1' = byte array strings, '0' = char array strings
+
   Label Ldone_false;
 
   if (cntval < 16) { // short case
     if (cntval != 0) li(result_reg, 0); // assume false
 
< prev index next >