1 /*
   2  * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2016 SAP SE. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  */
  24 
  25 /*
  26  * @test
  27  * @bug 8145336
  28  * @summary PPC64: fix string intrinsics after CompactStrings change
  29  * @modules java.base/jdk.internal.misc
  30  * @library /test/lib
  31  *
  32  * @build sun.hotspot.WhiteBox
  33  * @run driver ClassFileInstaller sun.hotspot.WhiteBox
  34  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  35  *
  36  * @run main/othervm
  37  *        -Xbootclasspath/a:.
  38  *        -Xmixed
  39  *        -XX:+UnlockDiagnosticVMOptions
  40  *        -XX:+WhiteBoxAPI
  41  *        -XX:MaxInlineSize=70
  42  *        -XX:MinInliningThreshold=0
  43  *        compiler.intrinsics.string.TestStringIntrinsics2
  44  */
  45 
  46 package compiler.intrinsics.string;
  47 
  48 import sun.hotspot.WhiteBox;
  49 
  50 import java.lang.annotation.ElementType;
  51 import java.lang.annotation.Retention;
  52 import java.lang.annotation.RetentionPolicy;
  53 import java.lang.annotation.Target;
  54 import java.util.Arrays;
  55 import java.util.function.Consumer;
  56 
  57 import static jdk.test.lib.Asserts.assertEquals;
  58 import static jdk.test.lib.Asserts.assertFalse;
  59 import static jdk.test.lib.Asserts.assertTrue;
  60 
  61 public class TestStringIntrinsics2 {
  62     // ------------------------------------------------------------------------
  63     //
  64     // We test the following cases:
  65     // - no match in string.  Do we miss the end condition? Will crash if we read
  66     //   past the string.
  67     // - no match in string, but after the string there is a match.
  68     //   Do we incorrectly report this match?  We had a case where we stepped
  69     //   a few chars past the string, this test would report that error. The
  70     //   one above would not.
  71     // - The needle is exactly at the end of the string.
  72     // - The needle spans the end of the string
  73     //
  74     // A special case are needles of length 1. For these we test:
  75     // - needle is first char
  76     // - needle is last char
  77     // - no match
  78     // - match behind string.
  79     //
  80     // We test all these for an unknown needle, and needles known to the compiler
  81     // of lengths 5, 2 and 1.
  82 
  83 
  84     private static final WhiteBox WB = WhiteBox.getWhiteBox();
  85 
  86     public enum Role {
  87         TEST_ENTRY,
  88         TEST_HELPER
  89     }
  90 
  91     @Retention(RetentionPolicy.RUNTIME)
  92     @Target(ElementType.METHOD)
  93     @interface Test {
  94         Role role();
  95         int compileAt() default 0;
  96         int warmup() default 0;
  97         String[] warmupArgs() default {};
  98     }
  99 
 100     // All this mess is needed to avoid try/catch inside the lambdas below.
 101     // See: http://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams
 102     @SuppressWarnings ("unchecked")
 103     private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
 104         throw (E)exception;
 105     }
 106     @FunctionalInterface
 107     public interface Consumer_WithExceptions<T, E extends Exception> {
 108         void accept(T t) throws E;
 109     }
 110     public static <T, E extends Exception> Consumer<T> rethrowConsumer(Consumer_WithExceptions<T, E> consumer) {
 111         return t -> {
 112             try { consumer.accept(t); }
 113             catch (Exception exception) { throwAsUnchecked(exception); }
 114         };
 115     }
 116 
 117     public static void main(String[] args) throws Exception {
 118 
 119         // Warmup helper methods
 120         Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
 121             .filter(m -> m.isAnnotationPresent(Test.class))
 122             .filter(m -> m.getAnnotation(Test.class).warmup() > 0)
 123             .forEach(rethrowConsumer(m -> {
 124                         Test a = m.getAnnotation(Test.class);
 125                         System.out.println("Warming up " + m + " " + a.warmup() + " time(s) ");
 126                         for (int i=0; i < a.warmup(); i++) {
 127                             m.invoke(null, (Object[])a.warmupArgs());
 128                         }
 129                     }));
 130 
 131         // Compile helper methods
 132         Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
 133             .filter(m -> m.isAnnotationPresent(Test.class))
 134             .filter(m -> m.getAnnotation(Test.class).compileAt() > 0)
 135             .forEach(rethrowConsumer(m -> {
 136                         Test a = m.getAnnotation(Test.class);
 137                         if (WB.isMethodCompilable(m, a.compileAt())) {
 138                             WB.enqueueMethodForCompilation(m, a.compileAt());
 139                             while (WB.isMethodQueuedForCompilation(m)) Thread.sleep(10);
 140                             System.out.println(m + " compiled at " + WB.getMethodCompilationLevel(m));
 141                         } else {
 142                             System.out.println("Can't compile " + m + " at level " + a.compileAt());
 143                         }
 144                     }));
 145 
 146         // Run test methods
 147         Arrays.stream(TestStringIntrinsics2.class.getDeclaredMethods())
 148             .filter(m -> m.isAnnotationPresent(Test.class))
 149             .filter(m -> m.getAnnotation(Test.class).role() == Role.TEST_ENTRY)
 150             .forEach(rethrowConsumer(m -> {
 151                         System.out.print("Executing " + m);
 152                         m.invoke(null, (Object[])null);
 153                         System.out.println(" - OK");
 154                     }));
 155     }
 156 
 157     static String text = "<t><t><t><t><t><t>\n" + "<hit>";
 158     static String text2 = "<t><t><t><t><t><t><t>\n" + "<hit>";
 159     static String[] ss = text.split("\n");
 160     static String[] ss2 = null;
 161     static String needle = "<miss>";
 162 
 163     @Test(role = Role.TEST_ENTRY)
 164     public static void test_indexOf_no_match() {
 165         int res = indexOf_no_match_unknown_needle(ss[0], "<miss>");
 166         assertEquals(res, -1, "test_indexOf_no_match_unknown_needle matched at: " + res);
 167         res = indexOf_no_match_imm_needle(ss[0]);
 168         assertEquals(res, -1, "test_indexOf_no_match_imm_needle matched at: " + res);
 169         res = indexOf_no_match_imm2_needle(ss[0]);
 170         assertEquals(res, -1, "test_indexOf_no_match_imm2_needle matched at: " + res);
 171 
 172         if (ss2 == null) ss2 = text.split("\n");
 173         res = indexOf_no_match_unknown_needle(ss2[0], "<miss>");
 174         assertEquals(res, -1, "test_indexOf_no_match_unknown_needle matched at: " + res);
 175         res = indexOf_no_match_imm_needle(ss2[0]);
 176         assertEquals(res, -1, "test_indexOf_no_match_imm_needle matched at: " + res);
 177         res = indexOf_no_match_imm2_needle(ss2[0]);
 178         assertEquals(res, -1, "test_indexOf_no_match_imm2_needle matched at: " + res);
 179         res = indexOf_no_match_imm1_needle(ss2[0]);
 180         assertEquals(res, -1, "test_indexOf_no_match_imm1_needle matched at: " + res);
 181     }
 182 
 183     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>", "<miss>" })
 184     static int indexOf_no_match_unknown_needle(String s, String needle) {
 185         int index = s.indexOf(needle);
 186         return index;
 187     }
 188 
 189     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 190     static int indexOf_no_match_imm_needle(String s) {
 191         int index = s.indexOf("<hitt>");
 192         return index;
 193     }
 194 
 195     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 196     static int indexOf_no_match_imm2_needle(String s) {
 197         int index = s.indexOf("<m");
 198         return index;
 199     }
 200 
 201     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 202     static int indexOf_no_match_imm1_needle(String s) {
 203         int index = s.indexOf("m");
 204         return index;
 205     }
 206 
 207     @Test(role = Role.TEST_ENTRY)
 208     public static void test_indexOf_reads_past_string() {
 209         if (ss == null) ss = text.split("\n");
 210         String res = indexOf_reads_past_string_unknown_needle(ss[0], "<hit>");
 211         assertEquals(res, null, "test_indexOf_reads_past_string_unknown_needle " + res);
 212         res = indexOf_reads_past_string_imm_needle(ss[0]);
 213         assertEquals(res, null, "test_indexOf_reads_past_string_imm_needle " + res);
 214         res = indexOf_reads_past_string_imm2_needle(ss[0]);
 215         assertEquals(res, null, "test_indexOf_reads_past_string_imm2_needle " + res);
 216         res = indexOf_reads_past_string_imm1_needle(ss[0]);
 217         assertEquals(res, null, "test_indexOf_reads_past_string_imm1_needle " + res);
 218     }
 219 
 220     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>", "<hit>" })
 221     static String indexOf_reads_past_string_unknown_needle(String s, String needle) {
 222         int index = s.indexOf(needle);
 223         if (index > s.length()) {
 224             return "Found needle \"" + needle + "\" behind string of length " + s.length()
 225                 + " at position " + index + ".";
 226         }
 227         return null;
 228     }
 229 
 230     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 231     static String indexOf_reads_past_string_imm_needle(String s) {
 232         int index = s.indexOf("<hit>");
 233         if (index > s.length()) {
 234             return "Found needle \"<hit>\" behind string of length " + s.length() + " at position " + index + ".";
 235         }
 236         return null;
 237     }
 238 
 239     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 240     static String indexOf_reads_past_string_imm2_needle(String s) {
 241         int index = s.indexOf("<h");
 242         if (index > s.length()) {
 243             return "Found needle \"<h\" behind string of length " + s.length() + " at position " + index + ".";
 244         }
 245         return null;
 246     }
 247 
 248     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t>" })
 249     static String indexOf_reads_past_string_imm1_needle(String s) {
 250         int index = s.indexOf("h");
 251         if (index > s.length()) {
 252             return "Found needle \"<h\" behind string of length " + s.length() + " at position " + index + ".";
 253         }
 254         return null;
 255     }
 256 
 257     static String text3 =    "<t><hi><t><h><hit<t><hit>";
 258     static String text4 =   "a<t><hi><t><h><hit<t><hit>";
 259     static String text5 =  "gg<t><hi><t><h><hit<t><hit>";
 260     static String text6 = "ccc<t><hi><t><h><hit<t><hit>";
 261     static int len3 = text3.length();
 262     static int len4 = text4.length();
 263     static int len5 = text5.length();
 264     static int len6 = text6.length();
 265 
 266     static String text7  =    "<t><t><t><t><t<t><h";
 267     static String text8  =   "a<t><t><t><t><t<t><h";
 268     static String text9  =  "gg<t><t><t><t><t<t><h";
 269     static String text10 = "ccc<t><t><t><t><t<t><h";
 270 
 271     @Test(role = Role.TEST_ENTRY)
 272     public static void test_indexOf_match_at_end_of_string() {
 273         String testname = "test_indexOf_match_at_end_of_string";
 274         int res = 0;
 275         res = indexOf_match_at_end_of_string_unknown_needle(text3, "<hit>");
 276         assertEquals(len3, res + 5, testname);
 277         res = indexOf_match_at_end_of_string_unknown_needle(text4, "<hit>");
 278         assertEquals(len4, res + 5, testname);
 279         res = indexOf_match_at_end_of_string_unknown_needle(text5, "<hit>");
 280         assertEquals(len5, res + 5, testname);
 281         res = indexOf_match_at_end_of_string_unknown_needle(text6, "<hit>");
 282         assertEquals(len6, res + 5, testname);
 283 
 284         res = indexOf_match_at_end_of_string_imm_needle(text3);
 285         assertEquals(len3, res + 5, testname);
 286         res = indexOf_match_at_end_of_string_imm_needle(text4);
 287         assertEquals(len4, res + 5, testname);
 288         res = indexOf_match_at_end_of_string_imm_needle(text5);
 289         assertEquals(len5, res + 5, testname);
 290         res = indexOf_match_at_end_of_string_imm_needle(text6);
 291         assertEquals(len6, res + 5, testname);
 292 
 293         res = indexOf_match_at_end_of_string_imm2_needle(text7);
 294         assertEquals(text7.length(),  res + 2, testname);
 295         res = indexOf_match_at_end_of_string_imm2_needle(text8);
 296         assertEquals(text8.length(),  res + 2, testname);
 297         res = indexOf_match_at_end_of_string_imm2_needle(text9);
 298         assertEquals(text9.length(),  res + 2, testname);
 299         res = indexOf_match_at_end_of_string_imm2_needle(text10);
 300         assertEquals(text10.length(), res + 2, testname);
 301 
 302         res = indexOf_match_at_end_of_string_imm1_needle(text7);
 303         assertEquals(text7.length(),  res + 1, testname);
 304         res = indexOf_match_at_end_of_string_imm1_needle(text8);
 305         assertEquals(text8.length(),  res + 1, testname);
 306         res = indexOf_match_at_end_of_string_imm1_needle(text9);
 307         assertEquals(text9.length(),  res + 1, testname);
 308         res = indexOf_match_at_end_of_string_imm1_needle(text10);
 309         assertEquals(text10.length(), res + 1, testname);
 310     }
 311 
 312     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>", "<hit>" })
 313     static int indexOf_match_at_end_of_string_unknown_needle(String s, String needle) {
 314         int index = s.indexOf(needle);
 315         return index;
 316     }
 317 
 318     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
 319     static int indexOf_match_at_end_of_string_imm_needle(String s) {
 320         int index = s.indexOf("<hit>");
 321         return index;
 322     }
 323 
 324     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
 325     static int indexOf_match_at_end_of_string_imm2_needle(String s) {
 326         int index = s.indexOf("<h");
 327         return index;
 328     }
 329 
 330     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit>" })
 331     static int indexOf_match_at_end_of_string_imm1_needle(String s) {
 332         int index = s.indexOf("h");
 333         return index;
 334     }
 335 
 336     static String s0_1 = text3.substring(0, len3-1);
 337     static String s0_2 = text3.substring(0, len3-2);
 338     static String s0_3 = text3.substring(0, len3-3);
 339     static String s0_4 = text3.substring(0, len3-4);
 340     static String s1_1 = text4.substring(0, len4-1);
 341     static String s1_2 = text4.substring(0, len4-2);
 342     static String s1_3 = text4.substring(0, len4-3);
 343     static String s1_4 = text4.substring(0, len4-4);
 344     static String s2_1 = text5.substring(0, len5-1);
 345     static String s2_2 = text5.substring(0, len5-2);
 346     static String s2_3 = text5.substring(0, len5-3);
 347     static String s2_4 = text5.substring(0, len5-4);
 348     static String s3_1 = text6.substring(0, len6-1);
 349     static String s3_2 = text6.substring(0, len6-2);
 350     static String s3_3 = text6.substring(0, len6-3);
 351     static String s3_4 = text6.substring(0, len6-4);
 352 
 353     static String s0_1x = text7 .substring(0, text7 .length()-1);
 354     static String s1_1x = text8 .substring(0, text8 .length()-1);
 355     static String s2_1x = text9 .substring(0, text9 .length()-1);
 356     static String s3_1x = text10.substring(0, text10.length()-1);
 357 
 358     @Test(role = Role.TEST_ENTRY)
 359     public static void test_indexOf_match_spans_end_of_string() {
 360         String res = null;
 361         res = indexOf_match_spans_end_of_string_unknown_needle(s0_1, "<hit>");
 362         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_1 " + res);
 363         res = indexOf_match_spans_end_of_string_unknown_needle(s0_2, "<hit>");
 364         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_2 " + res);
 365         res = indexOf_match_spans_end_of_string_unknown_needle(s0_3, "<hit>");
 366         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_3 " + res);
 367         res = indexOf_match_spans_end_of_string_unknown_needle(s0_4, "<hit>");
 368         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s0_4 " + res);
 369         res = indexOf_match_spans_end_of_string_unknown_needle(s1_1, "<hit>");
 370         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_1 " + res);
 371         res = indexOf_match_spans_end_of_string_unknown_needle(s1_2, "<hit>");
 372         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_2 " + res);
 373         res = indexOf_match_spans_end_of_string_unknown_needle(s1_3, "<hit>");
 374         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_3 " + res);
 375         res = indexOf_match_spans_end_of_string_unknown_needle(s1_4, "<hit>");
 376         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s1_4 " + res);
 377         res = indexOf_match_spans_end_of_string_unknown_needle(s2_1, "<hit>");
 378         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_1 " + res);
 379         res = indexOf_match_spans_end_of_string_unknown_needle(s2_2, "<hit>");
 380         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_2 " + res);
 381         res = indexOf_match_spans_end_of_string_unknown_needle(s2_3, "<hit>");
 382         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_3 " + res);
 383         res = indexOf_match_spans_end_of_string_unknown_needle(s2_4, "<hit>");
 384         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s2_4 " + res);
 385         res = indexOf_match_spans_end_of_string_unknown_needle(s3_1, "<hit>");
 386         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_1 " + res);
 387         res = indexOf_match_spans_end_of_string_unknown_needle(s3_2, "<hit>");
 388         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_2 " + res);
 389         res = indexOf_match_spans_end_of_string_unknown_needle(s3_3, "<hit>");
 390         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_3 " + res);
 391         res = indexOf_match_spans_end_of_string_unknown_needle(s3_4, "<hit>");
 392         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_unknown_needle s3_4 " + res);
 393 
 394         res = indexOf_match_spans_end_of_string_imm_needle(s0_1);
 395         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_1 " + res);
 396         res = indexOf_match_spans_end_of_string_imm_needle(s0_2);
 397         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_2 " + res);
 398         res = indexOf_match_spans_end_of_string_imm_needle(s0_3);
 399         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_3 " + res);
 400         res = indexOf_match_spans_end_of_string_imm_needle(s0_4);
 401         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s0_4 " + res);
 402         res = indexOf_match_spans_end_of_string_imm_needle(s1_1);
 403         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_1 " + res);
 404         res = indexOf_match_spans_end_of_string_imm_needle(s1_2);
 405         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_2 " + res);
 406         res = indexOf_match_spans_end_of_string_imm_needle(s1_3);
 407         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_3 " + res);
 408         res = indexOf_match_spans_end_of_string_imm_needle(s1_4);
 409         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s1_4 " + res);
 410         res = indexOf_match_spans_end_of_string_imm_needle(s2_1);
 411         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_1 " + res);
 412         res = indexOf_match_spans_end_of_string_imm_needle(s2_2);
 413         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_2 " + res);
 414         res = indexOf_match_spans_end_of_string_imm_needle(s2_3);
 415         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_3 " + res);
 416         res = indexOf_match_spans_end_of_string_imm_needle(s2_4);
 417         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s2_4 " + res);
 418         res = indexOf_match_spans_end_of_string_imm_needle(s3_1);
 419         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_1 " + res);
 420         res = indexOf_match_spans_end_of_string_imm_needle(s3_2);
 421         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_2 " + res);
 422         res = indexOf_match_spans_end_of_string_imm_needle(s3_3);
 423         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_3 " + res);
 424         res = indexOf_match_spans_end_of_string_imm_needle(s3_4);
 425         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm_needle s3_4 " + res);
 426 
 427         res = indexOf_match_spans_end_of_string_imm2_needle(s0_1x);
 428         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s0_1x " + res);
 429         res = indexOf_match_spans_end_of_string_imm2_needle(s1_1x);
 430         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s1_1x " + res);
 431         res = indexOf_match_spans_end_of_string_imm2_needle(s2_1x);
 432         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s2_1x " + res);
 433         res = indexOf_match_spans_end_of_string_imm2_needle(s3_1x);
 434         assertEquals(res, null, "test_indexOf_match_spans_end_of_string_imm2_needle s3_1x " + res);
 435     }
 436 
 437     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit", "<hit>" })
 438     static String indexOf_match_spans_end_of_string_unknown_needle(String s, String needle) {
 439         int index = s.indexOf(needle);
 440         if (index > -1) {
 441             return "Found needle \"" + needle + "\" that is spanning the end of the string: " + s + ".";
 442         }
 443         return null;
 444     }
 445 
 446     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><hi><t><h><hit<t><hit" })
 447     static String indexOf_match_spans_end_of_string_imm_needle(String s) {
 448         int index = s.indexOf("<hit>");
 449         if (index > -1) {
 450             return "Found needle \"<hit>\" that is spanning the end of the string: " + s + ".";
 451         }
 452         return null;
 453     }
 454 
 455     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "<t><t><t><t><t<t><" })
 456     static String indexOf_match_spans_end_of_string_imm2_needle(String s) {
 457         int index = s.indexOf("<h");
 458         if (index > -1) {
 459             return "Found needle \"<h\" that is spanning the end of the string: " + s + ".";
 460         }
 461         return null;
 462     }
 463 
 464     static String text16 = "ooooooo";
 465     static String text11 = "1ooooooo";
 466     static String text12 = "ooooooo1";
 467     static String text13 = "oooooooo1";
 468     static String text14 = "ooooooooo1";
 469     static String text15 = "oooooooooo1";
 470     static int len12 = text12.length();
 471     static int len13 = text13.length();
 472     static int len14 = text14.length();
 473     static int len15 = text15.length();
 474 
 475     static String text12_1 = text12.substring(0, len12-1);
 476     static String text13_1 = text13.substring(0, len13-1);
 477     static String text14_1 = text14.substring(0, len14-1);
 478     static String text15_1 = text15.substring(0, len15-1);
 479 
 480     @Test(role = Role.TEST_ENTRY)
 481     public static void test_indexOf_imm1_needle() {
 482         assertEquals(     -1, indexOf_imm1_needle(text16), "test_indexOf_imm1_needle no_match");
 483 
 484         assertEquals(      0, indexOf_imm1_needle(text11), "test_indexOf_imm1_needle first_matches");
 485 
 486         assertEquals(len12-1, indexOf_imm1_needle(text12), "test_indexOf_imm1_needle last_matches");
 487         assertEquals(len13-1, indexOf_imm1_needle(text13), "test_indexOf_imm1_needle last_matches");
 488         assertEquals(len14-1, indexOf_imm1_needle(text14), "test_indexOf_imm1_needle last_matches");
 489         assertEquals(len15-1, indexOf_imm1_needle(text15), "test_indexOf_imm1_needle last_matches");
 490 
 491         assertEquals(     -1, indexOf_imm1_needle(text12_1), "test_indexOf_imm1_needle walked_past");
 492         assertEquals(     -1, indexOf_imm1_needle(text13_1), "test_indexOf_imm1_needle walked_past");
 493         assertEquals(     -1, indexOf_imm1_needle(text14_1), "test_indexOf_imm1_needle walked_past");
 494         assertEquals(     -1, indexOf_imm1_needle(text15_1), "test_indexOf_imm1_needle walked_past");
 495     }
 496 
 497     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "ooooooo1" })
 498     static int indexOf_imm1_needle(String s) {
 499         return s.indexOf("1");
 500     }
 501 
 502     static String text1UTF16 = "A" + "\u05d0" + "\u05d1" + "B";
 503 
 504     @Test(role = Role.TEST_ENTRY)
 505     public static void test_indexOf_immUTF16() {
 506         assertEquals(      3, indexOf_imm1Latin1_needle(text1UTF16), "test_indexOf_immUTF16");
 507         assertEquals(      1, indexOf_imm1UTF16_needle(text1UTF16), "test_indexOf_immUTF16");
 508         assertEquals(      1, indexOf_immUTF16_needle(text1UTF16), "test_indexOf_immUTF16");
 509     }
 510 
 511     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "A" + "\u05d0" + "\u05d1" + "B" })
 512     static int indexOf_imm1Latin1_needle(String s) {
 513         return s.indexOf("B");
 514     }
 515 
 516     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "A" + "\u05d0" + "\u05d1" + "B" })
 517     static int indexOf_imm1UTF16_needle(String s) {
 518         return s.indexOf("\u05d0");
 519     }
 520 
 521     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "A" + "\u05d0" + "\u05d1" + "B" })
 522     static int indexOf_immUTF16_needle(String s) {
 523         return s.indexOf("\u05d0" + "\u05d1");
 524     }
 525 
 526     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "abc", "abcd" })
 527     public static int asmStringCompareTo(String a, String b) {
 528         return a.compareTo(b);
 529     }
 530 
 531     @Test(role = Role.TEST_ENTRY)
 532     public static void test_asmStringCompareTo() {
 533         // null
 534         try {
 535             asmStringCompareTo("not null", null);
 536             assertTrue(false,
 537                        "TestOther.asmStringCompareTo(\"not null\", null) doesn't throw exception");
 538         } catch (NullPointerException e) {
 539             assertEquals("java.lang.String.compareTo",
 540                          e.getStackTrace()[0].getClassName() + "." +
 541                          e.getStackTrace()[0].getMethodName(),
 542                          "TestOther.asmStringCompareTo(\"not null\", null) throws exception");
 543         }
 544 
 545         // ==0
 546         {
 547             // check length 0 optimization
 548             assertEquals(0, asmStringCompareTo("", ""),
 549                          "TestOther.asmStringCompareTo(\"\", \"\")");
 550 
 551             // check first character optimization
 552             assertEquals(0, asmStringCompareTo("A", "A"),
 553                          "TestOther.asmStringCompareTo(\"A\", \"A\")");
 554 
 555             // check real comparisons
 556             assertEquals(0, asmStringCompareTo(new String("eq") + new String("ual"), "equal"),
 557                          "TestOther.asmStringCompareTo(\"equal\", \"equal\")");
 558             assertEquals(0, asmStringCompareTo("textABC", "textABC"),
 559                          "TestOther.asmStringCompareTo(\"textABC\", \"textABC\")");
 560             assertEquals(0,
 561                          asmStringCompareTo(new String("abcdefgh01234") +
 562                                             new String("56abcdefgh0123456abcdefgh0123456"),
 563                                             "abcdefgh0123456abcdefgh0123456abcdefgh0123456"),
 564                          "TestOther.asmStringCompareTo(\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\", " +
 565                          "\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\")");
 566         }
 567 
 568         // <0
 569         {
 570             // check first character optimization
 571             assertEquals(-1, asmStringCompareTo("4", "5"),
 572                          "TestOther.asmStringCompareTo(\"4\", \"5\")");
 573 
 574             // check real comparisons
 575             assertEquals(-1, asmStringCompareTo("diff4", "diff5"),
 576                          "TestOther.asmStringCompareTo(\"diff4\", \"diff5\")");
 577             assertEquals(-10, asmStringCompareTo("", "123456789A"),
 578                          "TestOther.asmStringCompareTo(\"\", \"123456789A\")");
 579             assertEquals(-10, asmStringCompareTo("ZYX", "ZYX123456789A"),
 580                          "TestOther.asmStringCompareTo(\"ZYX\", \"ZYX123456789A\")");
 581         }
 582 
 583         // >0
 584         {
 585             // check first character optimization
 586             assertEquals(1, asmStringCompareTo("5", "4"),
 587                          "TestOther.asmStringCompareTo(\"5\", \"4\")");
 588 
 589             // check real comparisons
 590             assertEquals(1, asmStringCompareTo("diff5", "diff4"),
 591                          "TestOther.asmStringCompareTo(\"diff5\", \"diff4\")");
 592             assertEquals(10, asmStringCompareTo("123456789A", ""),
 593                          "TestOther.asmStringCompareTo(\"123456789A\", \"\")");
 594             assertEquals(10, asmStringCompareTo("ZYX123456789A", "ZYX"),
 595                          "TestOther.asmStringCompareTo(\"ZYX123456789A\", \"ZYX\")");
 596         }
 597 
 598         // very long strings (100k)
 599         {
 600             char[] ac = new char[(100 * 1024)];
 601             for (int i = 0; i < (100 * 1024); i += 315)
 602                 ac[i] = (char) ((i % 12) + 'a');
 603             char[] bc = new char[(100 * 1024)];
 604             for (int i = 0; i < (100 * 1024); i += 315)
 605                 bc[i] = (char) ((i % 12) + 'a');
 606 
 607             ac[(100 * 1024) - 1] = '2';
 608             bc[(100 * 1024) - 1] = '2';
 609             String a1 = new String(ac);
 610             String b1 = new String(bc);
 611             assertEquals(0, asmStringCompareTo(a1, b1),
 612                          "TestOther.asmStringCompareTo(very_long_strings_1)");
 613 
 614             ac[(100 * 1024) - 1] = 'X';
 615             bc[(100 * 1024) - 1] = 'Z';
 616             String a2 = new String(ac);
 617             String b2 = new String(bc);
 618             assertEquals(-2, asmStringCompareTo(a2, b2),
 619                          "TestOther.asmStringCompareTo(very_long_strings_2)");
 620         }
 621 
 622         // very very long strings (2M)
 623         {
 624             char[] ac = new char[(2 * 1024 * 1024)];
 625             for (int i = 0; i < (2 * 1024 * 1024); i += 315)
 626                 ac[i] = (char) ((i % 12) + 'a');
 627             char[] bc = new char[(2 * 1024 * 1024)];
 628             for (int i = 0; i < (2 * 1024 * 1024); i += 315)
 629                 bc[i] = (char) ((i % 12) + 'a');
 630 
 631             ac[(2 * 1024 * 1024) - 1] = '3';
 632             bc[(2 * 1024 * 1024) - 1] = '3';
 633             String a1 = new String(ac);
 634             String b1 = new String(bc);
 635             assertEquals(0, asmStringCompareTo(a1, b1),
 636                          "TestOther.asmStringCompareTo(very_very_long_strings_1)");
 637 
 638             ac[(2 * 1024 * 1024) - 1] = 'W';
 639             bc[(2 * 1024 * 1024) - 1] = 'Z';
 640             String a2 = new String(ac);
 641             String b2 = new String(bc);
 642             assertEquals(-3, asmStringCompareTo(a2, b2),
 643                          "TestOther.asmStringCompareTo(very_very_long_strings_2)");
 644         }
 645     }
 646 
 647 
 648     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1, warmupArgs = { "abc", "abcd" })
 649     public static boolean asmStringEquals(String a, String b) {
 650         return a.equals(b);
 651     }
 652 
 653     static String a1 = "abcd";
 654     static String b1 = "abcd";
 655     static final String a2 = "1234";
 656     static final String b2 = "1234";
 657 
 658     @Test(role = Role.TEST_HELPER, compileAt = 4, warmup = 1)
 659     public static boolean asmStringEqualsConst() {
 660         boolean ret = a1.equals(b1);
 661         ret &= a2.equals(b2);
 662         ret &= !a2.equals(b1);
 663         ret &= "ABCD".equals("ABCD");
 664         return ret;
 665     }
 666 
 667 
 668     @Test(role = Role.TEST_ENTRY)
 669     public static void test_asmStringEquals() {
 670         // null
 671         {
 672             assertFalse(asmStringEquals("not null", null),
 673                         "TestOther.asmStringEquals(\"not null\", null)");
 674         }
 675 
 676         // true
 677         {
 678             // check constant optimization
 679             assertTrue(asmStringEqualsConst(),
 680                        "TestOther.asmStringEqualsConst(\"\", \"\")");
 681 
 682             // check length 0 optimization
 683             assertTrue(asmStringEquals("", ""),
 684                        "TestOther.asmStringEquals(\"\", \"\")");
 685 
 686             // check first character optimization
 687             assertTrue(asmStringEquals("A", "A"),
 688                        "TestOther.asmStringEquals(\"A\", \"A\")");
 689 
 690             // check real comparisons
 691             assertTrue(asmStringEquals(new String("eq") + new String("ual"), "equal"),
 692                        "TestOther.asmStringEquals(\"equal\", \"equal\")");
 693             assertTrue(asmStringEquals("textABC", "textABC"),
 694                        "TestOther.asmStringEquals(\"textABC\", \"textABC\")");
 695             assertTrue(asmStringEquals(new String("abcdefgh01234") +
 696                                        new String("56abcdefgh0123456abcdefgh0123456"),
 697                                        "abcdefgh0123456abcdefgh0123456abcdefgh0123456"),
 698                        "TestOther.asmStringEquals(\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\", " +
 699                        "\"abcdefgh0123456abcdefgh0123456abcdefgh0123456\")");
 700         }
 701     }
 702 
 703 }