44 * @summary Test intrinsification of StringLatin1.indexOf(char). Note that
55 * differing code paths are taken contingent upon the length of the input String.
66 * Hence we must test against differing string lengths in order to validate
7- * correct functionality
7+ * correct functionality. We also ensure the strings are long enough to trigger
8+ * the looping conditions of the individual code paths.
9+ *
10+ * Run with varing levels of AVX and SSE support, also without the intrinsic at all
811 *
912 * @library /compiler/patches /test/lib
10- * @run main/othervm -Xbatch -XX:CompileThreshold=100 -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_indexOfL_char compiler.intrinsics.string.TestStringLatin1IndexOfChar
11- * @run main/othervm -Xbatch -XX:CompileThreshold=100 compiler.intrinsics.string.TestStringLatin1IndexOfChar
13+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 compiler.intrinsics.string.TestStringLatin1IndexOfChar
14+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 -XX:+UnlockDiagnosticVMOptions -XX:DisableIntrinsic=_indexOfL_char compiler.intrinsics.string.TestStringLatin1IndexOfChar
15+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 -XX:UseSSE=0 compiler.intrinsics.string.TestStringLatin1IndexOfChar
16+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 -XX:UseAVX=1 compiler.intrinsics.string.TestStringLatin1IndexOfChar
17+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 -XX:UseAVX=2 compiler.intrinsics.string.TestStringLatin1IndexOfChar
18+ * @run main/othervm -Xbatch -XX:Tier4InvocationThreshold=200 -XX:CompileThreshold=100 -XX:UseAVX=3 compiler.intrinsics.string.TestStringLatin1IndexOfChar
1219 */
1320
1421package compiler .intrinsics .string ;
1522
1623import jdk .test .lib .Asserts ;
17- import java .util .HashMap ;
18- import java .util .Map ;
1924
2025public class TestStringLatin1IndexOfChar {
21- private final static int MAX_LENGTH = 513 ;//future proof for AVX-512 instructions
26+ private final static int MAX_LENGTH = 2048 ;//future proof for AVX-512 instructions
2227
2328 public static void main (String [] args ) throws Exception {
24- for (int i = 0 ; i < 100_0 ; ++i ) {//repeat such that we enter into C2 code...
29+ for (int i = 0 ; i < 1_000 ; ++i ) {//repeat such that we enter into C2 code...
2530 maintest ();
2631 testEmpty ();
2732 }
@@ -31,46 +36,62 @@ private static void testEmpty(){
3136 Asserts .assertEQ ("" .indexOf ('a' ), -1 );
3237 }
3338
34- private static final char [] alphabet = new char []{'a' , 'b' , 'c' };//Latin1 are made of these
39+ private final static char SEARCH_CHAR = 'z' ;
40+ private final static char INVERLEAVING_CHAR = 'a' ;
41+ private final static char MISSING_CHAR = 'd' ;
3542
3643 private static void maintest (){
3744 //progressivly move through string checking indexes and starting offset correctly processed
38- for (int strLength = alphabet .length ; strLength < MAX_LENGTH ; strLength ++){
39- String totest = makeCandidateStringLatin1 (strLength );
45+ //string is of form azaza, aazaazaa, aaazaaazaaa, etc
46+ //we find n s.t. maxlength = (n*3) + 2
47+ int maxaInstances = (MAX_LENGTH -2 )/3 ;
4048
41- //track starting offset here
42- Map <Character , Integer > lastIndexOf = new HashMap <Character , Integer >();
43- for (Character c : alphabet ){
44- lastIndexOf .put (c , 0 );
45- }
49+ for (int aInstances = 5 ; aInstances < MAX_LENGTH ; aInstances ++){
50+ String totest = makeCandidateStringLatin1 (aInstances );
51+
52+ int startoffset ;
53+ {
54+ int intri = totest .indexOf (SEARCH_CHAR );
55+ int nonintri = indexOfCharNonIntrinsic (totest , SEARCH_CHAR , 0 );
4656
47- for ( int alphaidx = 0 ; ; alphaidx ++){
48- char wanted = alphabet [ alphaidx % alphabet . length ] ;
49- int lastInst = lastIndexOf . get ( wanted );
57+ Asserts . assertEQ ( intri , nonintri );
58+ startoffset = intri + 1 ;
59+ }
5060
51- int intri = totest .indexOf (wanted , lastInst );
52- int nonintri = indexOfChar (totest , wanted , lastInst );
61+ {
62+ int intri = totest .indexOf (SEARCH_CHAR , startoffset );
63+ int nonintri = indexOfCharNonIntrinsic (totest , SEARCH_CHAR , startoffset );
5364
5465 Asserts .assertEQ (intri , nonintri );
55- if (intri == -1 || intri == strLength -1 ){
56- break ;
57- }
58- lastIndexOf .put (wanted , intri +1 );
66+ startoffset = intri +1 ;
5967 }
6068
61- Asserts .assertEQ (totest .indexOf ('d' ), -1 );
69+ Asserts .assertEQ (totest .indexOf (SEARCH_CHAR , startoffset ), -1 );//only two SEARCH_CHAR per string
70+ Asserts .assertEQ (totest .indexOf (MISSING_CHAR ), -1 );
6271 }
6372 }
6473
65- private static String makeCandidateStringLatin1 (int strLength ){
66- StringBuilder sb = new StringBuilder (strLength );
67- for (int n =0 ; n < strLength ; n ++){//only 1 byte elements...
68- sb .append (alphabet [n % alphabet .length ]);
74+ private static String makeCandidateStringLatin1 (int aInstances ){
75+ StringBuilder sb = new StringBuilder ((aInstances *3 ) + 2 );
76+ for (int n =0 ; n < aInstances ; n ++){
77+ sb .append (INVERLEAVING_CHAR );
78+ }
79+
80+ sb .append (SEARCH_CHAR );
81+
82+ for (int n =0 ; n < aInstances ; n ++){
83+ sb .append (INVERLEAVING_CHAR );
84+ }
85+
86+ sb .append (SEARCH_CHAR );
87+
88+ for (int n =0 ; n < aInstances ; n ++){
89+ sb .append (INVERLEAVING_CHAR );
6990 }
7091 return sb .toString ();
7192 }
7293
73- private static int indexOfChar (String value , int ch , int fromIndex ) {
94+ private static int indexOfCharNonIntrinsic (String value , int ch , int fromIndex ) {
7495 //non intrinsic version of indexOfChar
7596 byte c = (byte )ch ;
7697 for (int i = fromIndex ; i < value .length (); i ++) {
@@ -80,5 +101,4 @@ private static int indexOfChar(String value, int ch, int fromIndex) {
80101 }
81102 return -1 ;
82103 }
83-
84- }
104+ }
0 commit comments