@@ -293,6 +293,15 @@ bool LibraryCallKit::try_to_inline(int predicate) {
293293 case vmIntrinsics::_compareToLU: return inline_string_compareTo (StrIntrinsicNode::LU);
294294 case vmIntrinsics::_compareToUL: return inline_string_compareTo (StrIntrinsicNode::UL);
295295
296+ #if HOTSPOT_TARGET_CLASSLIB == 8
297+ case vmIntrinsics::_sgetChars: return inline_string_getCharsU ();
298+ // String.equals(), Arrays.equals() both are comparing char[], and have identical signature
299+ case vmIntrinsics::_sequals: return inline_array_equals (StrIntrinsicNode::UU);
300+ case vmIntrinsics::_scompareTo: return inline_string_compareTo (StrIntrinsicNode::UU);
301+ case vmIntrinsics::_sindexOf: return inline_string_indexOf (StrIntrinsicNode::UU);
302+ case vmIntrinsics::_sindexOfI: return inline_string_indexOfI (StrIntrinsicNode::UU);
303+ case vmIntrinsics::_sindexOfChar: return inline_string_indexOfChar (StrIntrinsicNode::U);
304+ #else
296305 case vmIntrinsics::_indexOfL: return inline_string_indexOf (StrIntrinsicNode::LL);
297306 case vmIntrinsics::_indexOfU: return inline_string_indexOf (StrIntrinsicNode::UU);
298307 case vmIntrinsics::_indexOfUL: return inline_string_indexOf (StrIntrinsicNode::UL);
@@ -301,6 +310,7 @@ bool LibraryCallKit::try_to_inline(int predicate) {
301310 case vmIntrinsics::_indexOfIUL: return inline_string_indexOfI (StrIntrinsicNode::UL);
302311 case vmIntrinsics::_indexOfU_char: return inline_string_indexOfChar (StrIntrinsicNode::U);
303312 case vmIntrinsics::_indexOfL_char: return inline_string_indexOfChar (StrIntrinsicNode::L);
313+ #endif
304314
305315 case vmIntrinsics::_equalsL: return inline_string_equals (StrIntrinsicNode::LL);
306316
@@ -949,10 +959,12 @@ void LibraryCallKit::generate_string_range_check(Node* array, Node* offset, Node
949959 }
950960 RegionNode* bailout = new RegionNode (1 );
951961 record_for_igvn (bailout);
962+ #if HOTSPOT_TARGET_CLASSLIB != 8
952963 if (char_count) {
953964 // Convert char count to byte count
954965 count = _gvn.transform (new LShiftINode (count, intcon (1 )));
955966 }
967+ #endif
956968
957969 // Offset and count must not be negative
958970 generate_negative_guard (offset, bailout);
@@ -1010,16 +1022,31 @@ Node* LibraryCallKit::generate_virtual_thread(Node* tls_output) {
10101022// characters (depending on 'is_byte'). cnt1 and cnt2 are pointing to Int nodes
10111023// containing the lengths of str1 and str2.
10121024Node* LibraryCallKit::make_string_method_node (int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2, StrIntrinsicNode::ArgEnc ae) {
1025+ #if HOTSPOT_TARGET_CLASSLIB == 8
1026+ assert (!CompactStrings && ae == StrIntrinsicNode::UU, " classlib8 requires CHARS" );
1027+ #endif
10131028 Node* result = nullptr ;
10141029 switch (opcode) {
10151030 case Op_StrIndexOf:
1031+ #if HOTSPOT_TARGET_CLASSLIB == 8
1032+ result = new StrIndexOfNode (control (), memory (TypeAryPtr::CHARS),
1033+ str1_start, cnt1, str2_start, cnt2, ae);
1034+ #else
10161035 result = new StrIndexOfNode (control (), memory (TypeAryPtr::BYTES),
10171036 str1_start, cnt1, str2_start, cnt2, ae);
1037+ #endif
10181038 break ;
10191039 case Op_StrComp:
1040+ #if HOTSPOT_TARGET_CLASSLIB == 8
1041+ result = new StrCompNode (control (), memory (TypeAryPtr::CHARS),
1042+ str1_start, cnt1, str2_start, cnt2, ae);
1043+ #else
10201044 result = new StrCompNode (control (), memory (TypeAryPtr::BYTES),
10211045 str1_start, cnt1, str2_start, cnt2, ae);
1046+ #endif
10221047 break ;
1048+ // This call is made from StringLatin1.java/StringUTF16.java, which does not exist in cvm8,
1049+ // so no change is needed in this branch
10231050 case Op_StrEquals:
10241051 // We already know that cnt1 == cnt2 here (checked in 'inline_string_equals').
10251052 // Use the constant length if there is one because optimized match rule may exist.
@@ -1046,13 +1073,23 @@ bool LibraryCallKit::inline_string_compareTo(StrIntrinsicNode::ArgEnc ae) {
10461073 arg1 = must_be_not_null (arg1, true );
10471074 arg2 = must_be_not_null (arg2, true );
10481075
1076+ #if HOTSPOT_TARGET_CLASSLIB == 8
1077+ // Get start addr and length of first argument
1078+ Node* arg1_start = array_element_address (arg1, intcon (0 ), T_CHAR);
1079+ Node* arg1_cnt = load_array_length (arg1);
1080+
1081+ // Get start addr and length of second argument
1082+ Node* arg2_start = array_element_address (arg2, intcon (0 ), T_CHAR);
1083+ Node* arg2_cnt = load_array_length (arg2);
1084+ #else
10491085 // Get start addr and length of first argument
10501086 Node* arg1_start = array_element_address (arg1, intcon (0 ), T_BYTE);
10511087 Node* arg1_cnt = load_array_length (arg1);
10521088
10531089 // Get start addr and length of second argument
10541090 Node* arg2_start = array_element_address (arg2, intcon (0 ), T_BYTE);
10551091 Node* arg2_cnt = load_array_length (arg2);
1092+ #endif
10561093
10571094 Node* result = make_string_method_node (Op_StrComp, arg1_start, arg1_cnt, arg2_start, arg2_cnt, ae);
10581095 set_result (result);
@@ -1225,17 +1262,28 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
12251262 src = must_be_not_null (src, true );
12261263 tgt = must_be_not_null (tgt, true );
12271264
1265+ #if HOTSPOT_TARGET_CLASSLIB == 8
1266+ // Get start addr and length of source string
1267+ Node* src_start = array_element_address (src, intcon (0 ), T_CHAR);
1268+ Node* src_count = load_array_length (src);
1269+
1270+ // Get start addr and length of substring
1271+ Node* tgt_start = array_element_address (tgt, intcon (0 ), T_CHAR);
1272+ Node* tgt_count = load_array_length (tgt);
1273+ #else
12281274 // Get start addr and length of source string
12291275 Node* src_start = array_element_address (src, intcon (0 ), T_BYTE);
12301276 Node* src_count = load_array_length (src);
12311277
12321278 // Get start addr and length of substring
12331279 Node* tgt_start = array_element_address (tgt, intcon (0 ), T_BYTE);
12341280 Node* tgt_count = load_array_length (tgt);
1281+ #endif
12351282
12361283 Node* result = nullptr ;
12371284 bool call_opt_stub = (StubRoutines::_string_indexof_array[ae] != nullptr );
12381285
1286+ #if HOTSPOT_TARGET_CLASSLIB != 8
12391287 if (ae == StrIntrinsicNode::UU || ae == StrIntrinsicNode::UL) {
12401288 // Divide src size by 2 if String is UTF16 encoded
12411289 src_count = _gvn.transform (new RShiftINode (src_count, intcon (1 )));
@@ -1244,6 +1292,7 @@ bool LibraryCallKit::inline_string_indexOf(StrIntrinsicNode::ArgEnc ae) {
12441292 // Divide substring size by 2 if String is UTF16 encoded
12451293 tgt_count = _gvn.transform (new RShiftINode (tgt_count, intcon (1 )));
12461294 }
1295+ #endif
12471296
12481297 if (call_opt_stub) {
12491298 Node* call = make_runtime_call (RC_LEAF, OptoRuntime::string_IndexOf_Type (),
@@ -1286,10 +1335,18 @@ bool LibraryCallKit::inline_string_indexOfI(StrIntrinsicNode::ArgEnc ae) {
12861335 tgt = must_be_not_null (tgt, true );
12871336
12881337 // Multiply byte array index by 2 if String is UTF16 encoded
1338+ #if HOTSPOT_TARGET_CLASSLIB == 8
1339+ assert (!CompactStrings && ae == StrIntrinsicNode::UU, " classlib-8 requires T_CHAR" );
1340+ Node* src_offset = from_index;
1341+ src_count = _gvn.transform (new SubINode (src_count, from_index));
1342+ Node* src_start = array_element_address (src, src_offset, T_CHAR);
1343+ Node* tgt_start = array_element_address (tgt, intcon (0 ), T_CHAR);
1344+ #else
12891345 Node* src_offset = (ae == StrIntrinsicNode::LL) ? from_index : _gvn.transform (new LShiftINode (from_index, intcon (1 )));
12901346 src_count = _gvn.transform (new SubINode (src_count, from_index));
12911347 Node* src_start = array_element_address (src, src_offset, T_BYTE);
12921348 Node* tgt_start = array_element_address (tgt, intcon (0 ), T_BYTE);
1349+ #endif
12931350
12941351 // Range checks
12951352 generate_string_range_check (src, src_offset, src_count, ae != StrIntrinsicNode::LL);
@@ -1384,8 +1441,14 @@ bool LibraryCallKit::inline_string_indexOfChar(StrIntrinsicNode::ArgEnc ae) {
13841441
13851442 src = must_be_not_null (src, true );
13861443
1444+ #if HOTSPOT_TARGET_CLASSLIB == 8
1445+ assert (!CompactStrings && ae == StrIntrinsicNode::U, " classlib8 requires CHARS" );
1446+ Node* src_offset = from_index;
1447+ Node* src_start = array_element_address (src, src_offset, T_CHAR);
1448+ #else
13871449 Node* src_offset = ae == StrIntrinsicNode::L ? from_index : _gvn.transform (new LShiftINode (from_index, intcon (1 )));
13881450 Node* src_start = array_element_address (src, src_offset, T_BYTE);
1451+ #endif
13891452 Node* src_count = _gvn.transform (new SubINode (max, from_index));
13901453
13911454 // Range checks
@@ -1406,7 +1469,11 @@ bool LibraryCallKit::inline_string_indexOfChar(StrIntrinsicNode::ArgEnc ae) {
14061469 RegionNode* region = new RegionNode (3 );
14071470 Node* phi = new PhiNode (region, TypeInt::INT);
14081471
1472+ #if HOTSPOT_TARGET_CLASSLIB == 8
1473+ Node* result = new StrIndexOfCharNode (control (), memory (TypeAryPtr::CHARS), src_start, src_count, int_ch, ae);
1474+ #else
14091475 Node* result = new StrIndexOfCharNode (control (), memory (TypeAryPtr::BYTES), src_start, src_count, int_ch, ae);
1476+ #endif
14101477 C->set_has_split_ifs (true ); // Has chance for split-if optimization
14111478 _gvn.transform (result);
14121479
@@ -1651,7 +1718,9 @@ bool LibraryCallKit::inline_string_getCharsU() {
16511718
16521719 // Get length and convert char[] offset to byte[] offset
16531720 Node* length = _gvn.transform (new SubINode (src_end, src_begin));
1721+ #if HOTSPOT_TARGET_CLASSLIB != 8
16541722 src_begin = _gvn.transform (new LShiftINode (src_begin, intcon (1 )));
1723+ #endif
16551724
16561725 // Range checks
16571726 generate_string_range_check (src, src_begin, length, true );
@@ -1662,13 +1731,21 @@ bool LibraryCallKit::inline_string_getCharsU() {
16621731
16631732 if (!stopped ()) {
16641733 // Calculate starting addresses.
1734+ #if HOTSPOT_TARGET_CLASSLIB == 8
1735+ Node* src_start = array_element_address (src, src_begin, T_CHAR);
1736+ #else
16651737 Node* src_start = array_element_address (src, src_begin, T_BYTE);
1738+ #endif
16661739 Node* dst_start = array_element_address (dst, dst_begin, T_CHAR);
16671740
16681741 // Check if array addresses are aligned to HeapWordSize
16691742 const TypeInt* tsrc = gvn ().type (src_begin)->is_int ();
16701743 const TypeInt* tdst = gvn ().type (dst_begin)->is_int ();
1744+ #if HOTSPOT_TARGET_CLASSLIB == 8
1745+ bool aligned = tsrc->is_con () && ((arrayOopDesc::base_offset_in_bytes (T_CHAR) + tsrc->get_con () * type2aelembytes (T_CHAR)) % HeapWordSize == 0 ) &&
1746+ #else
16711747 bool aligned = tsrc->is_con () && ((arrayOopDesc::base_offset_in_bytes (T_BYTE) + tsrc->get_con () * type2aelembytes (T_BYTE)) % HeapWordSize == 0 ) &&
1748+ #endif
16721749 tdst->is_con () && ((arrayOopDesc::base_offset_in_bytes (T_CHAR) + tdst->get_con () * type2aelembytes (T_CHAR)) % HeapWordSize == 0 );
16731750
16741751 // Figure out which arraycopy runtime method to call (disjoint, uninitialized).
0 commit comments