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