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