8152554: CompactStrings broken on AArch64
authoraph
Mon, 18 Apr 2016 15:37:29 +0000
changeset 38002 d663151fda81
parent 37508 3bf78337709d
child 38003 f84c8ee82ac8
8152554: CompactStrings broken on AArch64 Summary: Correct the logic for string intrinsics. Reviewed-by: roland
hotspot/src/cpu/aarch64/vm/aarch64.ad
hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/hotspot/src/cpu/aarch64/vm/aarch64.ad	Fri Apr 15 17:17:58 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/aarch64.ad	Mon Apr 18 15:37:29 2016 +0000
@@ -3325,9 +3325,15 @@
 
 const bool Matcher::match_rule_supported(int opcode) {
 
-  // TODO
-  // identify extra cases that we might want to provide match rules for
-  // e.g. Op_StrEquals and other intrinsics
+  switch (opcode) {
+  case Op_StrComp:
+  case Op_StrIndexOf:
+    if (CompactStrings)  return false;
+    break;
+  default:
+    break;
+  }
+
   if (!has_match_rule(opcode)) {
     return false;
   }
@@ -14797,10 +14803,10 @@
   ins_pipe(pipe_class_memory);
 %}
 
-instruct string_compare(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
+instruct string_compareU(iRegP_R1 str1, iRegI_R2 cnt1, iRegP_R3 str2, iRegI_R4 cnt2,
                         iRegI_R0 result, iRegP_R10 tmp1, rFlagsReg cr)
 %{
-  predicate(!CompactStrings);
+  predicate(((StrCompNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrComp (Binary str1 cnt1) (Binary str2 cnt2)));
   effect(KILL tmp1, USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2, KILL cr);
 
@@ -14819,7 +14825,7 @@
 instruct string_indexof(iRegP_R1 str1, iRegI_R4 cnt1, iRegP_R3 str2, iRegI_R2 cnt2,
        iRegI_R0 result, iRegI tmp1, iRegI tmp2, iRegI tmp3, iRegI tmp4, rFlagsReg cr)
 %{
-  predicate(!CompactStrings);
+  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 cnt2)));
   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1, USE_KILL cnt2,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
@@ -14839,7 +14845,7 @@
                  immI_le_4 int_cnt2, iRegI_R0 result, iRegI tmp1, iRegI tmp2,
                  iRegI tmp3, iRegI tmp4, rFlagsReg cr)
 %{
-  predicate(!CompactStrings);
+  predicate(((StrIndexOfNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrIndexOf (Binary str1 cnt1) (Binary str2 int_cnt2)));
   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt1,
          TEMP tmp1, TEMP tmp2, TEMP tmp3, TEMP tmp4, KILL cr);
@@ -14856,10 +14862,27 @@
   ins_pipe(pipe_class_memory);
 %}
 
-instruct string_equals(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
+instruct string_equalsL(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
                         iRegI_R0 result, rFlagsReg cr)
 %{
-  predicate(!CompactStrings);
+  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::LL);
+  match(Set result (StrEquals (Binary str1 str2) cnt));
+  effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
+
+  format %{ "String Equals $str1,$str2,$cnt -> $result" %}
+  ins_encode %{
+    // Count is in 8-bit bytes; non-Compact chars are 16 bits.
+    __ arrays_equals($str1$$Register, $str2$$Register,
+                     $result$$Register, $cnt$$Register,
+                     1, /*is_string*/true);
+  %}
+  ins_pipe(pipe_class_memory);
+%}
+
+instruct string_equalsU(iRegP_R1 str1, iRegP_R3 str2, iRegI_R4 cnt,
+                        iRegI_R0 result, rFlagsReg cr)
+%{
+  predicate(((StrEqualsNode*)n)->encoding() == StrIntrinsicNode::UU);
   match(Set result (StrEquals (Binary str1 str2) cnt));
   effect(USE_KILL str1, USE_KILL str2, USE_KILL cnt, KILL cr);
 
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Apr 15 17:17:58 2016 +0200
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Mon Apr 18 15:37:29 2016 +0000
@@ -4585,7 +4585,16 @@
   assert(elem_size == 1 || elem_size == 2, "must be char or byte");
   assert_different_registers(a1, a2, result, cnt1, rscratch1, rscratch2);
 
-  BLOCK_COMMENT(is_string ? "string_equals {" : "array_equals {");
+#ifndef PRODUCT
+  {
+    const char kind = (elem_size == 2) ? 'U' : 'L';
+    char comment[64];
+    snprintf(comment, sizeof comment, "%s%c%s {",
+             is_string ? "string_equals" : "array_equals",
+             kind, "{");
+    BLOCK_COMMENT(comment);
+  }
+#endif
 
   mov(result, false);