comparison src/cpu/x86/vm/assembler_x86.cpp @ 2320:41d4973cf100

6942326: x86 code in string_indexof() could read beyond reserved heap space Summary: copy small (<8) strings on stack if str+16 crosses a page boundary and load from stack into XMM. Back up pointer when loading string's tail. Reviewed-by: never
author kvn
date Sat, 26 Feb 2011 12:10:54 -0800
parents 6bbaedb03534
children 8033953d67ff
comparison
equal deleted inserted replaced
2319:8190d4b75e09 2320:41d4973cf100
1599 emit_byte(0x0F); 1599 emit_byte(0x0F);
1600 emit_byte(0x7E); 1600 emit_byte(0x7E);
1601 emit_byte(0xC0 | encode); 1601 emit_byte(0xC0 | encode);
1602 } 1602 }
1603 1603
1604 void Assembler::movdl(XMMRegister dst, Address src) {
1605 NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1606 InstructionMark im(this);
1607 emit_byte(0x66);
1608 prefix(src, dst);
1609 emit_byte(0x0F);
1610 emit_byte(0x6E);
1611 emit_operand(dst, src);
1612 }
1613
1614
1604 void Assembler::movdqa(XMMRegister dst, Address src) { 1615 void Assembler::movdqa(XMMRegister dst, Address src) {
1605 NOT_LP64(assert(VM_Version::supports_sse2(), "")); 1616 NOT_LP64(assert(VM_Version::supports_sse2(), ""));
1606 InstructionMark im(this); 1617 InstructionMark im(this);
1607 emit_byte(0x66); 1618 emit_byte(0x66);
1608 prefix(src, dst); 1619 prefix(src, dst);
2410 emit_operand(dst, src); 2421 emit_operand(dst, src);
2411 emit_byte(mode & 0xFF); 2422 emit_byte(mode & 0xFF);
2412 } 2423 }
2413 2424
2414 void Assembler::psrlq(XMMRegister dst, int shift) { 2425 void Assembler::psrlq(XMMRegister dst, int shift) {
2415 // HMM Table D-1 says sse2 or mmx 2426 // Shift 64 bit value logically right by specified number of bits.
2427 // HMM Table D-1 says sse2 or mmx.
2428 // Do not confuse it with psrldq SSE2 instruction which
2429 // shifts 128 bit value in xmm register by number of bytes.
2416 NOT_LP64(assert(VM_Version::supports_sse(), "")); 2430 NOT_LP64(assert(VM_Version::supports_sse(), ""));
2417 2431
2418 int encode = prefixq_and_encode(xmm2->encoding(), dst->encoding()); 2432 int encode = prefixq_and_encode(xmm2->encoding(), dst->encoding());
2433 emit_byte(0x66);
2434 emit_byte(0x0F);
2435 emit_byte(0x73);
2436 emit_byte(0xC0 | encode);
2437 emit_byte(shift);
2438 }
2439
2440 void Assembler::psrldq(XMMRegister dst, int shift) {
2441 // Shift 128 bit value in xmm register by number of bytes.
2442 NOT_LP64(assert(VM_Version::supports_sse2(), ""));
2443
2444 int encode = prefixq_and_encode(xmm3->encoding(), dst->encoding());
2419 emit_byte(0x66); 2445 emit_byte(0x66);
2420 emit_byte(0x0F); 2446 emit_byte(0x0F);
2421 emit_byte(0x73); 2447 emit_byte(0x73);
2422 emit_byte(0xC0 | encode); 2448 emit_byte(0xC0 | encode);
2423 emit_byte(shift); 2449 emit_byte(shift);
8565 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr())); 8591 movptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
8566 } 8592 }
8567 } 8593 }
8568 #endif // _LP64 8594 #endif // _LP64
8569 8595
8570 // IndexOf substring. 8596 // IndexOf for constant substrings with size >= 8 chars
8571 void MacroAssembler::string_indexof(Register str1, Register str2, 8597 // which don't need to be loaded through stack.
8572 Register cnt1, Register cnt2, Register result, 8598 void MacroAssembler::string_indexofC8(Register str1, Register str2,
8573 XMMRegister vec, Register tmp) { 8599 Register cnt1, Register cnt2,
8600 int int_cnt2, Register result,
8601 XMMRegister vec, Register tmp) {
8574 assert(UseSSE42Intrinsics, "SSE4.2 is required"); 8602 assert(UseSSE42Intrinsics, "SSE4.2 is required");
8575 8603
8576 Label RELOAD_SUBSTR, PREP_FOR_SCAN, SCAN_TO_SUBSTR, 8604 // This method uses pcmpestri inxtruction with bound registers
8577 SCAN_SUBSTR, RET_NOT_FOUND, CLEANUP;
8578
8579 push(str1); // string addr
8580 push(str2); // substr addr
8581 push(cnt2); // substr count
8582 jmpb(PREP_FOR_SCAN);
8583
8584 // Substr count saved at sp
8585 // Substr saved at sp+1*wordSize
8586 // String saved at sp+2*wordSize
8587
8588 // Reload substr for rescan
8589 bind(RELOAD_SUBSTR);
8590 movl(cnt2, Address(rsp, 0));
8591 movptr(str2, Address(rsp, wordSize));
8592 // We came here after the beginninig of the substring was
8593 // matched but the rest of it was not so we need to search
8594 // again. Start from the next element after the previous match.
8595 subptr(str1, result); // Restore counter
8596 shrl(str1, 1);
8597 addl(cnt1, str1);
8598 decrementl(cnt1);
8599 lea(str1, Address(result, 2)); // Reload string
8600
8601 // Load substr
8602 bind(PREP_FOR_SCAN);
8603 movdqu(vec, Address(str2, 0));
8604 addl(cnt1, 8); // prime the loop
8605 subptr(str1, 16);
8606
8607 // Scan string for substr in 16-byte vectors
8608 bind(SCAN_TO_SUBSTR);
8609 subl(cnt1, 8);
8610 addptr(str1, 16);
8611
8612 // pcmpestri
8613 // inputs: 8605 // inputs:
8614 // xmm - substring 8606 // xmm - substring
8615 // rax - substring length (elements count) 8607 // rax - substring length (elements count)
8616 // mem - scaned string 8608 // mem - scanned string
8617 // rdx - string length (elements count) 8609 // rdx - string length (elements count)
8618 // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts) 8610 // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
8619 // outputs: 8611 // outputs:
8620 // rcx - matched index in string 8612 // rcx - matched index in string
8621 assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri"); 8613 assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
8622 8614
8623 pcmpestri(vec, Address(str1, 0), 0x0d); 8615 Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR,
8624 jcc(Assembler::above, SCAN_TO_SUBSTR); // CF == 0 && ZF == 0 8616 RET_FOUND, RET_NOT_FOUND, EXIT, FOUND_SUBSTR,
8625 jccb(Assembler::aboveEqual, RET_NOT_FOUND); // CF == 0 8617 MATCH_SUBSTR_HEAD, RELOAD_STR, FOUND_CANDIDATE;
8626 8618
8627 // Fallthrough: found a potential substr 8619 // Note, inline_string_indexOf() generates checks:
8620 // if (substr.count > string.count) return -1;
8621 // if (substr.count == 0) return 0;
8622 assert(int_cnt2 >= 8, "this code isused only for cnt2 >= 8 chars");
8623
8624 // Load substring.
8625 movdqu(vec, Address(str2, 0));
8626 movl(cnt2, int_cnt2);
8627 movptr(result, str1); // string addr
8628
8629 if (int_cnt2 > 8) {
8630 jmpb(SCAN_TO_SUBSTR);
8631
8632 // Reload substr for rescan, this code
8633 // is executed only for large substrings (> 8 chars)
8634 bind(RELOAD_SUBSTR);
8635 movdqu(vec, Address(str2, 0));
8636 negptr(cnt2); // Jumped here with negative cnt2, convert to positive
8637
8638 bind(RELOAD_STR);
8639 // We came here after the beginning of the substring was
8640 // matched but the rest of it was not so we need to search
8641 // again. Start from the next element after the previous match.
8642
8643 // cnt2 is number of substring reminding elements and
8644 // cnt1 is number of string reminding elements when cmp failed.
8645 // Restored cnt1 = cnt1 - cnt2 + int_cnt2
8646 subl(cnt1, cnt2);
8647 addl(cnt1, int_cnt2);
8648 movl(cnt2, int_cnt2); // Now restore cnt2
8649
8650 decrementl(cnt1); // Shift to next element
8651 cmpl(cnt1, cnt2);
8652 jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
8653
8654 addptr(result, 2);
8655
8656 } // (int_cnt2 > 8)
8657
8658 // Scan string for start of substr in 16-byte vectors
8659 bind(SCAN_TO_SUBSTR);
8660 pcmpestri(vec, Address(result, 0), 0x0d);
8661 jccb(Assembler::below, FOUND_CANDIDATE); // CF == 1
8662 subl(cnt1, 8);
8663 jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
8664 cmpl(cnt1, cnt2);
8665 jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
8666 addptr(result, 16);
8667 jmpb(SCAN_TO_SUBSTR);
8668
8669 // Found a potential substr
8670 bind(FOUND_CANDIDATE);
8671 // Matched whole vector if first element matched (tmp(rcx) == 0).
8672 if (int_cnt2 == 8) {
8673 jccb(Assembler::overflow, RET_FOUND); // OF == 1
8674 } else { // int_cnt2 > 8
8675 jccb(Assembler::overflow, FOUND_SUBSTR);
8676 }
8677 // After pcmpestri tmp(rcx) contains matched element index
8678 // Compute start addr of substr
8679 lea(result, Address(result, tmp, Address::times_2));
8628 8680
8629 // Make sure string is still long enough 8681 // Make sure string is still long enough
8630 subl(cnt1, tmp); 8682 subl(cnt1, tmp);
8631 cmpl(cnt1, cnt2); 8683 cmpl(cnt1, cnt2);
8632 jccb(Assembler::negative, RET_NOT_FOUND); 8684 if (int_cnt2 == 8) {
8633 // Compute start addr of substr 8685 jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
8634 lea(str1, Address(str1, tmp, Address::times_2)); 8686 } else { // int_cnt2 > 8
8635 movptr(result, str1); // save 8687 jccb(Assembler::greaterEqual, MATCH_SUBSTR_HEAD);
8636 8688 }
8637 // Compare potential substr 8689 // Left less then substring.
8638 addl(cnt1, 8); // prime the loop
8639 addl(cnt2, 8);
8640 subptr(str1, 16);
8641 subptr(str2, 16);
8642
8643 // Scan 16-byte vectors of string and substr
8644 bind(SCAN_SUBSTR);
8645 subl(cnt1, 8);
8646 subl(cnt2, 8);
8647 addptr(str1, 16);
8648 addptr(str2, 16);
8649 movdqu(vec, Address(str2, 0));
8650 pcmpestri(vec, Address(str1, 0), 0x0d);
8651 jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
8652 jcc(Assembler::positive, SCAN_SUBSTR); // SF == 0
8653
8654 // Compute substr offset
8655 subptr(result, Address(rsp, 2*wordSize));
8656 shrl(result, 1); // index
8657 jmpb(CLEANUP);
8658 8690
8659 bind(RET_NOT_FOUND); 8691 bind(RET_NOT_FOUND);
8660 movl(result, -1); 8692 movl(result, -1);
8693 jmpb(EXIT);
8694
8695 if (int_cnt2 > 8) {
8696 // This code is optimized for the case when whole substring
8697 // is matched if its head is matched.
8698 bind(MATCH_SUBSTR_HEAD);
8699 pcmpestri(vec, Address(result, 0), 0x0d);
8700 // Reload only string if does not match
8701 jccb(Assembler::noOverflow, RELOAD_STR); // OF == 0
8702
8703 Label CONT_SCAN_SUBSTR;
8704 // Compare the rest of substring (> 8 chars).
8705 bind(FOUND_SUBSTR);
8706 // First 8 chars are already matched.
8707 negptr(cnt2);
8708 addptr(cnt2, 8);
8709
8710 bind(SCAN_SUBSTR);
8711 subl(cnt1, 8);
8712 cmpl(cnt2, -8); // Do not read beyond substring
8713 jccb(Assembler::lessEqual, CONT_SCAN_SUBSTR);
8714 // Back-up strings to avoid reading beyond substring:
8715 // cnt1 = cnt1 - cnt2 + 8
8716 addl(cnt1, cnt2); // cnt2 is negative
8717 addl(cnt1, 8);
8718 movl(cnt2, 8); negptr(cnt2);
8719 bind(CONT_SCAN_SUBSTR);
8720 if (int_cnt2 < (int)G) {
8721 movdqu(vec, Address(str2, cnt2, Address::times_2, int_cnt2*2));
8722 pcmpestri(vec, Address(result, cnt2, Address::times_2, int_cnt2*2), 0x0d);
8723 } else {
8724 // calculate index in register to avoid integer overflow (int_cnt2*2)
8725 movl(tmp, int_cnt2);
8726 addptr(tmp, cnt2);
8727 movdqu(vec, Address(str2, tmp, Address::times_2, 0));
8728 pcmpestri(vec, Address(result, tmp, Address::times_2, 0), 0x0d);
8729 }
8730 // Need to reload strings pointers if not matched whole vector
8731 jccb(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
8732 addptr(cnt2, 8);
8733 jccb(Assembler::negative, SCAN_SUBSTR);
8734 // Fall through if found full substring
8735
8736 } // (int_cnt2 > 8)
8737
8738 bind(RET_FOUND);
8739 // Found result if we matched full small substring.
8740 // Compute substr offset
8741 subptr(result, str1);
8742 shrl(result, 1); // index
8743 bind(EXIT);
8744
8745 } // string_indexofC8
8746
8747 // Small strings are loaded through stack if they cross page boundary.
8748 void MacroAssembler::string_indexof(Register str1, Register str2,
8749 Register cnt1, Register cnt2,
8750 int int_cnt2, Register result,
8751 XMMRegister vec, Register tmp) {
8752 assert(UseSSE42Intrinsics, "SSE4.2 is required");
8753 //
8754 // int_cnt2 is length of small (< 8 chars) constant substring
8755 // or (-1) for non constant substring in which case its length
8756 // is in cnt2 register.
8757 //
8758 // Note, inline_string_indexOf() generates checks:
8759 // if (substr.count > string.count) return -1;
8760 // if (substr.count == 0) return 0;
8761 //
8762 assert(int_cnt2 == -1 || (0 < int_cnt2 && int_cnt2 < 8), "should be != 0");
8763
8764 // This method uses pcmpestri inxtruction with bound registers
8765 // inputs:
8766 // xmm - substring
8767 // rax - substring length (elements count)
8768 // mem - scanned string
8769 // rdx - string length (elements count)
8770 // 0xd - mode: 1100 (substring search) + 01 (unsigned shorts)
8771 // outputs:
8772 // rcx - matched index in string
8773 assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
8774
8775 Label RELOAD_SUBSTR, SCAN_TO_SUBSTR, SCAN_SUBSTR, ADJUST_STR,
8776 RET_FOUND, RET_NOT_FOUND, CLEANUP, FOUND_SUBSTR,
8777 FOUND_CANDIDATE;
8778
8779 { //========================================================
8780 // We don't know where these strings are located
8781 // and we can't read beyond them. Load them through stack.
8782 Label BIG_STRINGS, CHECK_STR, COPY_SUBSTR, COPY_STR;
8783
8784 movptr(tmp, rsp); // save old SP
8785
8786 if (int_cnt2 > 0) { // small (< 8 chars) constant substring
8787 if (int_cnt2 == 1) { // One char
8788 load_unsigned_short(result, Address(str2, 0));
8789 movdl(vec, result); // move 32 bits
8790 } else if (int_cnt2 == 2) { // Two chars
8791 movdl(vec, Address(str2, 0)); // move 32 bits
8792 } else if (int_cnt2 == 4) { // Four chars
8793 movq(vec, Address(str2, 0)); // move 64 bits
8794 } else { // cnt2 = { 3, 5, 6, 7 }
8795 // Array header size is 12 bytes in 32-bit VM
8796 // + 6 bytes for 3 chars == 18 bytes,
8797 // enough space to load vec and shift.
8798 assert(HeapWordSize*typeArrayKlass::header_size() >= 12,"sanity");
8799 movdqu(vec, Address(str2, (int_cnt2*2)-16));
8800 psrldq(vec, 16-(int_cnt2*2));
8801 }
8802 } else { // not constant substring
8803 cmpl(cnt2, 8);
8804 jccb(Assembler::aboveEqual, BIG_STRINGS); // Both strings are big enough
8805
8806 // We can read beyond string if srt+16 does not cross page boundary
8807 // since heaps are aligned and mapped by pages.
8808 assert(os::vm_page_size() < (int)G, "default page should be small");
8809 movl(result, str2); // We need only low 32 bits
8810 andl(result, (os::vm_page_size()-1));
8811 cmpl(result, (os::vm_page_size()-16));
8812 jccb(Assembler::belowEqual, CHECK_STR);
8813
8814 // Move small strings to stack to allow load 16 bytes into vec.
8815 subptr(rsp, 16);
8816 int stk_offset = wordSize-2;
8817 push(cnt2);
8818
8819 bind(COPY_SUBSTR);
8820 load_unsigned_short(result, Address(str2, cnt2, Address::times_2, -2));
8821 movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
8822 decrement(cnt2);
8823 jccb(Assembler::notZero, COPY_SUBSTR);
8824
8825 pop(cnt2);
8826 movptr(str2, rsp); // New substring address
8827 } // non constant
8828
8829 bind(CHECK_STR);
8830 cmpl(cnt1, 8);
8831 jccb(Assembler::aboveEqual, BIG_STRINGS);
8832
8833 // Check cross page boundary.
8834 movl(result, str1); // We need only low 32 bits
8835 andl(result, (os::vm_page_size()-1));
8836 cmpl(result, (os::vm_page_size()-16));
8837 jccb(Assembler::belowEqual, BIG_STRINGS);
8838
8839 subptr(rsp, 16);
8840 int stk_offset = -2;
8841 if (int_cnt2 < 0) { // not constant
8842 push(cnt2);
8843 stk_offset += wordSize;
8844 }
8845 movl(cnt2, cnt1);
8846
8847 bind(COPY_STR);
8848 load_unsigned_short(result, Address(str1, cnt2, Address::times_2, -2));
8849 movw(Address(rsp, cnt2, Address::times_2, stk_offset), result);
8850 decrement(cnt2);
8851 jccb(Assembler::notZero, COPY_STR);
8852
8853 if (int_cnt2 < 0) { // not constant
8854 pop(cnt2);
8855 }
8856 movptr(str1, rsp); // New string address
8857
8858 bind(BIG_STRINGS);
8859 // Load substring.
8860 if (int_cnt2 < 0) { // -1
8861 movdqu(vec, Address(str2, 0));
8862 push(cnt2); // substr count
8863 push(str2); // substr addr
8864 push(str1); // string addr
8865 } else {
8866 // Small (< 8 chars) constant substrings are loaded already.
8867 movl(cnt2, int_cnt2);
8868 }
8869 push(tmp); // original SP
8870
8871 } // Finished loading
8872
8873 //========================================================
8874 // Start search
8875 //
8876
8877 movptr(result, str1); // string addr
8878
8879 if (int_cnt2 < 0) { // Only for non constant substring
8880 jmpb(SCAN_TO_SUBSTR);
8881
8882 // SP saved at sp+0
8883 // String saved at sp+1*wordSize
8884 // Substr saved at sp+2*wordSize
8885 // Substr count saved at sp+3*wordSize
8886
8887 // Reload substr for rescan, this code
8888 // is executed only for large substrings (> 8 chars)
8889 bind(RELOAD_SUBSTR);
8890 movptr(str2, Address(rsp, 2*wordSize));
8891 movl(cnt2, Address(rsp, 3*wordSize));
8892 movdqu(vec, Address(str2, 0));
8893 // We came here after the beginning of the substring was
8894 // matched but the rest of it was not so we need to search
8895 // again. Start from the next element after the previous match.
8896 subptr(str1, result); // Restore counter
8897 shrl(str1, 1);
8898 addl(cnt1, str1);
8899 decrementl(cnt1); // Shift to next element
8900 cmpl(cnt1, cnt2);
8901 jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
8902
8903 addptr(result, 2);
8904 } // non constant
8905
8906 // Scan string for start of substr in 16-byte vectors
8907 bind(SCAN_TO_SUBSTR);
8908 assert(cnt1 == rdx && cnt2 == rax && tmp == rcx, "pcmpestri");
8909 pcmpestri(vec, Address(result, 0), 0x0d);
8910 jccb(Assembler::below, FOUND_CANDIDATE); // CF == 1
8911 subl(cnt1, 8);
8912 jccb(Assembler::lessEqual, RET_NOT_FOUND); // Scanned full string
8913 cmpl(cnt1, cnt2);
8914 jccb(Assembler::negative, RET_NOT_FOUND); // Left less then substring
8915 addptr(result, 16);
8916
8917 bind(ADJUST_STR);
8918 cmpl(cnt1, 8); // Do not read beyond string
8919 jccb(Assembler::greaterEqual, SCAN_TO_SUBSTR);
8920 // Back-up string to avoid reading beyond string.
8921 lea(result, Address(result, cnt1, Address::times_2, -16));
8922 movl(cnt1, 8);
8923 jmpb(SCAN_TO_SUBSTR);
8924
8925 // Found a potential substr
8926 bind(FOUND_CANDIDATE);
8927 // After pcmpestri tmp(rcx) contains matched element index
8928
8929 // Make sure string is still long enough
8930 subl(cnt1, tmp);
8931 cmpl(cnt1, cnt2);
8932 jccb(Assembler::greaterEqual, FOUND_SUBSTR);
8933 // Left less then substring.
8934
8935 bind(RET_NOT_FOUND);
8936 movl(result, -1);
8937 jmpb(CLEANUP);
8938
8939 bind(FOUND_SUBSTR);
8940 // Compute start addr of substr
8941 lea(result, Address(result, tmp, Address::times_2));
8942
8943 if (int_cnt2 > 0) { // Constant substring
8944 // Repeat search for small substring (< 8 chars)
8945 // from new point without reloading substring.
8946 // Have to check that we don't read beyond string.
8947 cmpl(tmp, 8-int_cnt2);
8948 jccb(Assembler::greater, ADJUST_STR);
8949 // Fall through if matched whole substring.
8950 } else { // non constant
8951 assert(int_cnt2 == -1, "should be != 0");
8952
8953 addl(tmp, cnt2);
8954 // Found result if we matched whole substring.
8955 cmpl(tmp, 8);
8956 jccb(Assembler::lessEqual, RET_FOUND);
8957
8958 // Repeat search for small substring (<= 8 chars)
8959 // from new point 'str1' without reloading substring.
8960 cmpl(cnt2, 8);
8961 // Have to check that we don't read beyond string.
8962 jccb(Assembler::lessEqual, ADJUST_STR);
8963
8964 Label CHECK_NEXT, CONT_SCAN_SUBSTR, RET_FOUND_LONG;
8965 // Compare the rest of substring (> 8 chars).
8966 movptr(str1, result);
8967
8968 cmpl(tmp, cnt2);
8969 // First 8 chars are already matched.
8970 jccb(Assembler::equal, CHECK_NEXT);
8971
8972 bind(SCAN_SUBSTR);
8973 pcmpestri(vec, Address(str1, 0), 0x0d);
8974 // Need to reload strings pointers if not matched whole vector
8975 jcc(Assembler::noOverflow, RELOAD_SUBSTR); // OF == 0
8976
8977 bind(CHECK_NEXT);
8978 subl(cnt2, 8);
8979 jccb(Assembler::lessEqual, RET_FOUND_LONG); // Found full substring
8980 addptr(str1, 16);
8981 addptr(str2, 16);
8982 subl(cnt1, 8);
8983 cmpl(cnt2, 8); // Do not read beyond substring
8984 jccb(Assembler::greaterEqual, CONT_SCAN_SUBSTR);
8985 // Back-up strings to avoid reading beyond substring.
8986 lea(str2, Address(str2, cnt2, Address::times_2, -16));
8987 lea(str1, Address(str1, cnt2, Address::times_2, -16));
8988 subl(cnt1, cnt2);
8989 movl(cnt2, 8);
8990 addl(cnt1, 8);
8991 bind(CONT_SCAN_SUBSTR);
8992 movdqu(vec, Address(str2, 0));
8993 jmpb(SCAN_SUBSTR);
8994
8995 bind(RET_FOUND_LONG);
8996 movptr(str1, Address(rsp, wordSize));
8997 } // non constant
8998
8999 bind(RET_FOUND);
9000 // Compute substr offset
9001 subptr(result, str1);
9002 shrl(result, 1); // index
8661 9003
8662 bind(CLEANUP); 9004 bind(CLEANUP);
8663 addptr(rsp, 3*wordSize); 9005 pop(rsp); // restore SP
8664 } 9006
9007 } // string_indexof
8665 9008
8666 // Compare strings. 9009 // Compare strings.
8667 void MacroAssembler::string_compare(Register str1, Register str2, 9010 void MacroAssembler::string_compare(Register str1, Register str2,
8668 Register cnt1, Register cnt2, Register result, 9011 Register cnt1, Register cnt2, Register result,
8669 XMMRegister vec1) { 9012 XMMRegister vec1) {