Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(332)

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 6927044: Extract common code in string compare loops. (Closed)
Patch Set: Created 9 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 4505 matching lines...) Expand 10 before | Expand all | Expand 10 after
4516 NearLabel compare_chars; 4516 NearLabel compare_chars;
4517 __ bind(&check_zero_length); 4517 __ bind(&check_zero_length);
4518 STATIC_ASSERT(kSmiTag == 0); 4518 STATIC_ASSERT(kSmiTag == 0);
4519 __ SmiTest(length); 4519 __ SmiTest(length);
4520 __ j(not_zero, &compare_chars); 4520 __ j(not_zero, &compare_chars);
4521 __ Move(rax, Smi::FromInt(EQUAL)); 4521 __ Move(rax, Smi::FromInt(EQUAL));
4522 __ ret(0); 4522 __ ret(0);
4523 4523
4524 // Compare characters. 4524 // Compare characters.
4525 __ bind(&compare_chars); 4525 __ bind(&compare_chars);
4526 4526 NearLabel strings_not_equal;
4527 // Change index to run from -length to -1 by adding length to string 4527 GenerateAsciiCharsCompareLoop(masm, left, right, length, scratch2,
4528 // start. This means that loop ends when index reaches zero, which 4528 &strings_not_equal);
4529 // doesn't need an additional compare.
4530 __ SmiToInteger32(length, length);
4531 __ lea(left,
4532 FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize));
4533 __ lea(right,
4534 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize));
4535 __ neg(length);
4536 Register index = length; // index = -length;
4537
4538 // Compare loop.
4539 NearLabel strings_not_equal, loop;
4540 __ bind(&loop);
4541 __ movb(scratch2, Operand(left, index, times_1, 0));
4542 __ cmpb(scratch2, Operand(right, index, times_1, 0));
4543 __ j(not_equal, &strings_not_equal);
4544 __ addq(index, Immediate(1));
4545 __ j(not_zero, &loop);
4546 4529
4547 // Characters are equal. 4530 // Characters are equal.
4548 __ Move(rax, Smi::FromInt(EQUAL)); 4531 __ Move(rax, Smi::FromInt(EQUAL));
4549 __ ret(0); 4532 __ ret(0);
4550 4533
4551 // Characters are not equal. 4534 // Characters are not equal.
4552 __ bind(&strings_not_equal); 4535 __ bind(&strings_not_equal);
4553 __ Move(rax, Smi::FromInt(NOT_EQUAL)); 4536 __ Move(rax, Smi::FromInt(NOT_EQUAL));
4554 __ ret(0); 4537 __ ret(0);
4555 } 4538 }
(...skipping 26 matching lines...) Expand all
4582 __ SmiSub(scratch1, scratch1, length_difference); 4565 __ SmiSub(scratch1, scratch1, length_difference);
4583 __ bind(&left_shorter); 4566 __ bind(&left_shorter);
4584 // Register scratch1 now holds Min(left.length, right.length). 4567 // Register scratch1 now holds Min(left.length, right.length).
4585 const Register min_length = scratch1; 4568 const Register min_length = scratch1;
4586 4569
4587 NearLabel compare_lengths; 4570 NearLabel compare_lengths;
4588 // If min-length is zero, go directly to comparing lengths. 4571 // If min-length is zero, go directly to comparing lengths.
4589 __ SmiTest(min_length); 4572 __ SmiTest(min_length);
4590 __ j(zero, &compare_lengths); 4573 __ j(zero, &compare_lengths);
4591 4574
4592 __ SmiToInteger32(min_length, min_length); 4575 // Compare loop.
4576 NearLabel result_not_equal;
4577 GenerateAsciiCharsCompareLoop(masm, left, right, min_length, scratch2,
4578 &result_not_equal);
4593 4579
4594 // Registers scratch2 and scratch3 are free.
4595 NearLabel result_not_equal;
4596 Label loop;
4597 {
4598 // Check characters 0 .. min_length - 1 in a loop.
4599 // Use scratch3 as loop index, min_length as limit and scratch2
4600 // for computation.
4601 const Register index = scratch3;
4602 __ Set(index, 0); // Index into strings.
4603 __ bind(&loop);
4604 // Compare characters.
4605 // TODO(lrn): Could we load more than one character at a time?
4606 __ movb(scratch2, FieldOperand(left,
4607 index,
4608 times_1,
4609 SeqAsciiString::kHeaderSize));
4610 // Increment index and use -1 modifier on next load to give
4611 // the previous load extra time to complete.
4612 __ addl(index, Immediate(1));
4613 __ cmpb(scratch2, FieldOperand(right,
4614 index,
4615 times_1,
4616 SeqAsciiString::kHeaderSize - 1));
4617 __ j(not_equal, &result_not_equal);
4618 __ cmpl(index, min_length);
4619 __ j(not_equal, &loop);
4620 }
4621 // Completed loop without finding different characters. 4580 // Completed loop without finding different characters.
4622 // Compare lengths (precomputed). 4581 // Compare lengths (precomputed).
4623 __ bind(&compare_lengths); 4582 __ bind(&compare_lengths);
4624 __ SmiTest(length_difference); 4583 __ SmiTest(length_difference);
4625 __ j(not_zero, &result_not_equal); 4584 __ j(not_zero, &result_not_equal);
4626 4585
4627 // Result is EQUAL. 4586 // Result is EQUAL.
4628 __ Move(rax, Smi::FromInt(EQUAL)); 4587 __ Move(rax, Smi::FromInt(EQUAL));
4629 __ ret(0); 4588 __ ret(0);
4630 4589
4631 NearLabel result_greater; 4590 NearLabel result_greater;
4632 __ bind(&result_not_equal); 4591 __ bind(&result_not_equal);
4633 // Unequal comparison of left to right, either character or length. 4592 // Unequal comparison of left to right, either character or length.
4634 __ j(greater, &result_greater); 4593 __ j(greater, &result_greater);
4635 4594
4636 // Result is LESS. 4595 // Result is LESS.
4637 __ Move(rax, Smi::FromInt(LESS)); 4596 __ Move(rax, Smi::FromInt(LESS));
4638 __ ret(0); 4597 __ ret(0);
4639 4598
4640 // Result is GREATER. 4599 // Result is GREATER.
4641 __ bind(&result_greater); 4600 __ bind(&result_greater);
4642 __ Move(rax, Smi::FromInt(GREATER)); 4601 __ Move(rax, Smi::FromInt(GREATER));
4643 __ ret(0); 4602 __ ret(0);
4644 } 4603 }
4645 4604
4646 4605
4606 void StringCompareStub::GenerateAsciiCharsCompareLoop(
4607 MacroAssembler* masm,
4608 Register left,
4609 Register right,
4610 Register length,
4611 Register scratch,
4612 NearLabel* chars_not_equal) {
4613 // Change index to run from -length to -1 by adding length to string
4614 // start. This means that loop ends when index reaches zero, which
4615 // doesn't need an additional compare.
4616 __ SmiToInteger32(length, length);
4617 __ lea(left,
4618 FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize));
4619 __ lea(right,
4620 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize));
4621 __ neg(length);
4622 Register index = length; // index = -length;
4623
4624 // Compare loop.
4625 NearLabel loop;
4626 __ bind(&loop);
4627 __ movb(scratch, Operand(left, index, times_1, 0));
4628 __ cmpb(scratch, Operand(right, index, times_1, 0));
4629 __ j(not_equal, chars_not_equal);
4630 __ addq(index, Immediate(1));
4631 __ j(not_zero, &loop);
4632 }
4633
4634
4647 void StringCompareStub::Generate(MacroAssembler* masm) { 4635 void StringCompareStub::Generate(MacroAssembler* masm) {
4648 Label runtime; 4636 Label runtime;
4649 4637
4650 // Stack frame on entry. 4638 // Stack frame on entry.
4651 // rsp[0]: return address 4639 // rsp[0]: return address
4652 // rsp[8]: right string 4640 // rsp[8]: right string
4653 // rsp[16]: left string 4641 // rsp[16]: left string
4654 4642
4655 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left 4643 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left
4656 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right 4644 __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
4874 // Do a tail call to the rewritten stub. 4862 // Do a tail call to the rewritten stub.
4875 __ jmp(rdi); 4863 __ jmp(rdi);
4876 } 4864 }
4877 4865
4878 4866
4879 #undef __ 4867 #undef __
4880 4868
4881 } } // namespace v8::internal 4869 } } // namespace v8::internal
4882 4870
4883 #endif // V8_TARGET_ARCH_X64 4871 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698