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