@@ -416,33 +416,50 @@ static void generate_string_indexof_stubs(StubGenerator *stubgen, address *fnptr
416416 assert (arrayOopDesc::base_offset_in_bytes (T_BYTE) >= 8 ,
417417 " need at least 8 bytes preceding the haystack" );
418418 if (arrayOopDesc::base_offset_in_bytes (T_BYTE) < 16 ) {
419- Label L_moreThan8;
420- __ cmpq (haystack_len, 0x8 );
421- __ ja_b (L_moreThan8);
422- __ movq (index, COPIED_HAYSTACK_STACK_OFFSET + 0x8 );
423- __ movq (XMM_TMP1, Address (haystack, haystack_len, Address::times_1, -0x8 ));
424- __ movq (Address (rsp, COPIED_HAYSTACK_STACK_OFFSET), XMM_TMP1);
425- __ jmpb (L_adjustHaystack);
426- __ bind (L_moreThan8);
427- }
419+ Label L_loop;
420+ // haystack_adjust = 8 - (haystack_len % 8);
421+ __ movq (index, haystack_len);
422+ __ andq (index, BytesPerWord - 1 );
423+ __ negq (index);
424+ __ addq (index, BytesPerWord);
425+ __ movq (XMM_TMP2, index); // Save for adjusting result.
426+ __ subq (haystack, index);
427+
428+ // num_words (zero-based) = (haystack_len - 1) / 8;
429+ __ movq (index, haystack_len);
430+ __ subq (index, 1 );
431+ __ shrq (index, LogBytesPerWord);
432+
433+ // Copy 8 bytes at a time onto the stack.
434+ __ bind (L_loop);
435+ __ movq (XMM_TMP1, Address (haystack, index, Address::times_8));
436+ __ movq (Address (rsp, index, Address::times_8), XMM_TMP1);
437+ __ subq (index, 1 );
438+ __ jcc (Assembler::positive, L_loop);
439+
440+ // Adjust-back stack pointer
441+ __ movq (index, XMM_TMP2);
442+ __ lea (haystack, Address (rsp, index, Address::times_1));
443+ } else {
428444
429- __ cmpq (haystack_len, 0x10 );
430- __ ja_b (L_moreThan16);
445+ __ cmpq (haystack_len, 0x10 );
446+ __ ja_b (L_moreThan16);
431447
432- __ movq (index, COPIED_HAYSTACK_STACK_OFFSET + 0x10 );
433- __ movdqu (XMM_TMP1, Address (haystack, haystack_len, Address::times_1, -0x10 ));
434- __ movdqu (Address (rsp, COPIED_HAYSTACK_STACK_OFFSET), XMM_TMP1);
435- __ jmpb (L_adjustHaystack);
448+ __ movq (index, COPIED_HAYSTACK_STACK_OFFSET + 0x10 );
449+ __ movdqu (XMM_TMP1, Address (haystack, haystack_len, Address::times_1, -0x10 ));
450+ __ movdqu (Address (rsp, COPIED_HAYSTACK_STACK_OFFSET), XMM_TMP1);
451+ __ jmpb (L_adjustHaystack);
436452
437- __ bind (L_moreThan16);
438- __ movq (index, COPIED_HAYSTACK_STACK_OFFSET + 0x20 );
439- __ vmovdqu (XMM_TMP1, Address (haystack, haystack_len, Address::times_1, -0x20 ));
440- __ vmovdqu (Address (rsp, COPIED_HAYSTACK_STACK_OFFSET), XMM_TMP1);
453+ __ bind (L_moreThan16);
454+ __ movq (index, COPIED_HAYSTACK_STACK_OFFSET + 0x20 );
455+ __ vmovdqu (XMM_TMP1, Address (haystack, haystack_len, Address::times_1, -0x20 ));
456+ __ vmovdqu (Address (rsp, COPIED_HAYSTACK_STACK_OFFSET), XMM_TMP1);
441457
442- // Point the haystack at the correct location of the first byte of the "real" haystack on the stack
443- __ bind (L_adjustHaystack);
444- __ subq (index, haystack_len);
445- __ leaq (haystack, Address (rsp, index, Address::times_1));
458+ // Point the haystack at the correct location of the first byte of the "real" haystack on the stack
459+ __ bind (L_adjustHaystack);
460+ __ subq (index, haystack_len);
461+ __ leaq (haystack, Address (rsp, index, Address::times_1));
462+ }
446463 }
447464
448465 // Dispatch to handlers for small needle and small haystack
0 commit comments