changeset 57862:b53fdc9fd058

8237524: AArch64: String.compareTo() may return incorrect result Reviewed-by: aph
author pli
date Tue, 21 Jan 2020 08:15:33 +0000
parents 9fb094231eee
children eec468f180dd
files src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp test/hotspot/jtreg/compiler/intrinsics/Test8237524.java
diffstat 2 files changed, 64 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Wed Jan 29 11:04:00 2020 +0100
+++ b/src/hotspot/cpu/aarch64/macroAssembler_aarch64.cpp	Tue Jan 21 08:15:33 2020 +0000
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 1997, 2019, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, 2019, Red Hat Inc. All rights reserved.
+ * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2020, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -4977,8 +4977,6 @@
       sub(cnt2, zr, cnt2, LSL, str2_chr_shift);
     } else if (isLU) {
       ldrs(vtmp, Address(str1));
-      cmp(str1, str2);
-      br(Assembler::EQ, DONE);
       ldr(tmp2, Address(str2));
       cmp(cnt2, stub_threshold);
       br(GE, STUB);
@@ -4993,8 +4991,6 @@
       fmovd(tmp1, vtmp);
     } else { // UL case
       ldr(tmp1, Address(str1));
-      cmp(str1, str2);
-      br(Assembler::EQ, DONE);
       ldrs(vtmp, Address(str2));
       cmp(cnt2, stub_threshold);
       br(GE, STUB);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/hotspot/jtreg/compiler/intrinsics/Test8237524.java	Tue Jan 21 08:15:33 2020 +0000
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, Arm Limited. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8237524
+ * @summary String.compareTo() may return incorrect result in this case
+ *
+ * @run main/othervm compiler.intrinsics.Test8237524
+ */
+
+package compiler.intrinsics;
+
+import java.lang.reflect.Constructor;
+
+public class Test8237524 {
+
+  private static int stringCompareTo(String s1, String s2) {
+    return s1.compareTo(s2);
+  }
+
+  public static void main(String[] args) throws Exception {
+    Constructor<String> c = String.class.getDeclaredConstructor(byte[].class, byte.class);
+    c.setAccessible(true);
+
+    byte[] bytes = new byte[] {
+      'Y', 'm', '_', 'l', 'V', 'n', 'W', 'S', 'w', 'm', 'W', 'S'
+    };
+
+    String s1 = c.newInstance(bytes, (byte) 0); // a Latin string
+    String s2 = c.newInstance(bytes, (byte) 1); // a Chinese string
+
+    for (int i = 0; i < 50000; i++) {
+      if (stringCompareTo(s1, s2) >= 0) {
+        System.out.println("FAIL. s1 should be less than s2 according to Java API Spec");
+        System.exit(1);
+      }
+    }
+  }
+}
+