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

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 525115: Add generated code for ascii string comparison... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 5429 matching lines...) Expand 10 before | Expand all | Expand 10 after
5440 Load(args->at(0)); 5440 Load(args->at(0));
5441 Load(args->at(1)); 5441 Load(args->at(1));
5442 Load(args->at(2)); 5442 Load(args->at(2));
5443 5443
5444 SubStringStub stub; 5444 SubStringStub stub;
5445 Result answer = frame_->CallStub(&stub, 3); 5445 Result answer = frame_->CallStub(&stub, 3);
5446 frame_->Push(&answer); 5446 frame_->Push(&answer);
5447 } 5447 }
5448 5448
5449 5449
5450 void CodeGenerator::GenerateStringCompare(ZoneList<Expression*>* args) {
5451 ASSERT_EQ(2, args->length());
5452
5453 Load(args->at(0));
5454 Load(args->at(1));
5455
5456 StringCompareStub stub;
5457 Result answer = frame_->CallStub(&stub, 2);
5458 frame_->Push(&answer);
5459 }
5460
5461
5450 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) { 5462 void CodeGenerator::GenerateRegExpExec(ZoneList<Expression*>* args) {
5451 ASSERT_EQ(args->length(), 4); 5463 ASSERT_EQ(args->length(), 4);
5452 5464
5453 // Load the arguments on the stack and call the stub. 5465 // Load the arguments on the stack and call the stub.
5454 Load(args->at(0)); 5466 Load(args->at(0));
5455 Load(args->at(1)); 5467 Load(args->at(1));
5456 Load(args->at(2)); 5468 Load(args->at(2));
5457 Load(args->at(3)); 5469 Load(args->at(3));
5458 RegExpExecStub stub; 5470 RegExpExecStub stub;
5459 Result result = frame_->CallStub(&stub, 4); 5471 Result result = frame_->CallStub(&stub, 4);
(...skipping 3095 matching lines...) Expand 10 before | Expand all | Expand 10 after
8555 ASSERT(cc_ != not_equal); 8567 ASSERT(cc_ != not_equal);
8556 if (cc_ == less || cc_ == less_equal) { 8568 if (cc_ == less || cc_ == less_equal) {
8557 __ mov(eax, Immediate(Smi::FromInt(1))); 8569 __ mov(eax, Immediate(Smi::FromInt(1)));
8558 } else { 8570 } else {
8559 __ mov(eax, Immediate(Smi::FromInt(-1))); 8571 __ mov(eax, Immediate(Smi::FromInt(-1)));
8560 } 8572 }
8561 __ ret(2 * kPointerSize); // eax, edx were pushed 8573 __ ret(2 * kPointerSize); // eax, edx were pushed
8562 8574
8563 // Fast negative check for symbol-to-symbol equality. 8575 // Fast negative check for symbol-to-symbol equality.
8564 __ bind(&check_for_symbols); 8576 __ bind(&check_for_symbols);
8577 Label check_for_strings;
8565 if (cc_ == equal) { 8578 if (cc_ == equal) {
8566 BranchIfNonSymbol(masm, &call_builtin, eax, ecx); 8579 BranchIfNonSymbol(masm, &check_for_strings, eax, ecx);
8567 BranchIfNonSymbol(masm, &call_builtin, edx, ecx); 8580 BranchIfNonSymbol(masm, &check_for_strings, edx, ecx);
8568 8581
8569 // We've already checked for object identity, so if both operands 8582 // We've already checked for object identity, so if both operands
8570 // are symbols they aren't equal. Register eax already holds a 8583 // are symbols they aren't equal. Register eax already holds a
8571 // non-zero value, which indicates not equal, so just return. 8584 // non-zero value, which indicates not equal, so just return.
8572 __ ret(2 * kPointerSize); 8585 __ ret(2 * kPointerSize);
8573 } 8586 }
8574 8587
8588 __ bind(&check_for_strings);
8589
8590 // Check that both objects are not smis.
8591 ASSERT_EQ(0, kSmiTag);
8592 __ mov(ebx, Operand(edx));
8593 __ and_(ebx, Operand(eax));
8594 __ test(ebx, Immediate(kSmiTagMask));
8595 __ j(zero, &call_builtin);
8596
8597 // Load instance type for both objects.
8598 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
8599 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
8600 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
8601 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
8602
8603 // Check that both are flat ascii strings.
8604 Label non_ascii_flat;
8605 ASSERT(kNotStringTag != 0);
8606 const int kFlatAsciiString =
8607 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
8608 __ and_(ecx, kFlatAsciiString);
8609 __ cmp(ecx, kStringTag | kSeqStringTag | kAsciiStringTag);
8610 __ j(not_equal, &call_builtin);
8611 __ and_(ebx, kFlatAsciiString);
8612 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
8613 __ j(not_equal, &call_builtin);
8614
8615 // Inline comparison of ascii strings.
8616 StringCompareStub::GenerateCompareFlatAsciiStrings(masm,
8617 edx,
8618 eax,
8619 ecx,
8620 ebx,
8621 edi);
8622 #ifdef DEBUG
8623 __ Abort("Unexpected fall-through from string comparison");
8624 #endif
8625
8575 __ bind(&call_builtin); 8626 __ bind(&call_builtin);
8576 // must swap argument order 8627 // must swap argument order
8577 __ pop(ecx); 8628 __ pop(ecx);
8578 __ pop(edx); 8629 __ pop(edx);
8579 __ pop(eax); 8630 __ pop(eax);
8580 __ push(edx); 8631 __ push(edx);
8581 __ push(eax); 8632 __ push(eax);
8582 8633
8583 // Figure out which native to call and setup the arguments. 8634 // Figure out which native to call and setup the arguments.
8584 Builtins::JavaScript builtin; 8635 Builtins::JavaScript builtin;
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after
9572 GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false); 9623 GenerateCopyCharactersREP(masm, edi, esi, ecx, ebx, false);
9573 __ mov(esi, edx); // Restore esi. 9624 __ mov(esi, edx); // Restore esi.
9574 __ IncrementCounter(&Counters::sub_string_native, 1); 9625 __ IncrementCounter(&Counters::sub_string_native, 1);
9575 __ ret(3 * kPointerSize); 9626 __ ret(3 * kPointerSize);
9576 9627
9577 // Just jump to runtime to create the sub string. 9628 // Just jump to runtime to create the sub string.
9578 __ bind(&runtime); 9629 __ bind(&runtime);
9579 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1); 9630 __ TailCallRuntime(ExternalReference(Runtime::kSubString), 3, 1);
9580 } 9631 }
9581 9632
9633
9634 void StringCompareStub::GenerateCompareFlatAsciiStrings(MacroAssembler* masm,
9635 Register left,
9636 Register right,
9637 Register counter,
9638 Register scratch1,
9639 Register scratch2) {
9640 ASSERT(counter.is(ecx));
9641 Label compare_lengths, compare_lengths_1;
9642
9643 // Find minimum length. If either length is zero just compare lengths.
9644 __ mov(counter, FieldOperand(left, String::kLengthOffset));
9645 __ test(counter, Operand(counter));
9646 __ j(zero, &compare_lengths_1);
9647 __ mov(scratch1, FieldOperand(right, String::kLengthOffset));
9648 __ test(scratch1, Operand(scratch1));
9649 __ j(zero, &compare_lengths_1);
9650 __ cmp(counter, Operand(scratch1));
9651 if (CpuFeatures::IsSupported(CMOV)) {
9652 CpuFeatures::Scope use_cmov(CMOV);
9653 __ cmov(less, counter, Operand(scratch1));
9654 } else {
9655 Label l;
9656 __ j(less, &l);
9657 __ mov(counter, scratch1);
9658 __ bind(&l);
9659 }
9660
9661 Label result_greater, result_less;
9662 Label loop;
9663 // Compare next character.
9664 __ mov(scratch2, Immediate(-1)); // Index into strings.
9665 __ bind(&loop);
9666 // Compare characters.
9667 __ add(Operand(scratch2), Immediate(1));
9668 __ mov_b(scratch1, Operand(left,
9669 scratch2,
9670 times_1,
9671 SeqAsciiString::kHeaderSize - kHeapObjectTag));
9672 __ subb(scratch1, Operand(right,
9673 scratch2,
9674 times_1,
9675 SeqAsciiString::kHeaderSize - kHeapObjectTag));
9676 __ loope(&loop);
9677 // If min length characters match compare lengths otherwise last character
9678 // compare is the result.
9679 __ j(equal, &compare_lengths);
9680 __ j(less, &result_less);
9681 __ jmp(&result_greater);
9682
9683 // Compare lengths.
9684 Label result_not_equal;
9685 __ bind(&compare_lengths);
9686 __ mov(counter, FieldOperand(left, String::kLengthOffset));
9687 __ bind(&compare_lengths_1);
9688 __ sub(counter, FieldOperand(right, String::kLengthOffset));
9689 __ j(not_zero, &result_not_equal);
9690
9691 // Result is EQUAL.
9692 ASSERT_EQ(0, EQUAL);
9693 ASSERT_EQ(0, kSmiTag);
9694 __ xor_(eax, Operand(eax));
9695 __ IncrementCounter(&Counters::string_compare_native, 1);
9696 __ ret(2 * kPointerSize);
9697 __ bind(&result_not_equal);
9698 __ j(greater, &result_greater);
9699
9700 // Result is LESS.
9701 __ bind(&result_less);
9702 __ mov(eax, Immediate(Smi::FromInt(LESS)->value()));
9703 __ IncrementCounter(&Counters::string_compare_native, 1);
9704 __ ret(2 * kPointerSize);
9705
9706 // Result is GREATER.
9707 __ bind(&result_greater);
9708 __ mov(eax, Immediate(Smi::FromInt(GREATER)->value()));
9709 __ IncrementCounter(&Counters::string_compare_native, 1);
9710 __ ret(2 * kPointerSize);
9711 }
9712
9713
9714 void StringCompareStub::Generate(MacroAssembler* masm) {
9715 Label runtime;
9716
9717 // Stack frame on entry.
9718 // esp[0]: return address
9719 // esp[4]: right string
9720 // esp[8]: left string
9721
9722 __ mov(edx, Operand(esp, 2 * kPointerSize)); // left
9723 __ mov(eax, Operand(esp, 1 * kPointerSize)); // right
9724
9725 Label not_same;
9726 __ cmp(edx, Operand(eax));
9727 __ j(not_equal, &not_same);
9728 ASSERT_EQ(0, EQUAL);
9729 ASSERT_EQ(0, kSmiTag);
9730 __ xor_(eax, Operand(eax));
9731 __ IncrementCounter(&Counters::string_compare_native, 1);
9732 __ ret(2 * kPointerSize);
9733
9734 __ bind(&not_same);
9735
9736 // Check that both objects are not smis.
9737 ASSERT_EQ(0, kSmiTag);
9738 __ mov(ebx, Operand(edx));
9739 __ and_(ebx, Operand(eax));
9740 __ test(ebx, Immediate(kSmiTagMask));
9741 __ j(zero, &runtime);
9742
9743 // Load instance type for both strings.
9744 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
9745 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
9746 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
9747 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
9748
9749 // Check that both are flat ascii strings.
9750 Label non_ascii_flat;
9751 __ and_(ecx, kStringRepresentationMask | kStringEncodingMask);
9752 __ cmp(ecx, kSeqStringTag | kAsciiStringTag);
9753 __ j(not_equal, &non_ascii_flat);
9754 const int kFlatAsciiString =
9755 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
9756 __ and_(ebx, kFlatAsciiString);
9757 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
9758 __ j(not_equal, &non_ascii_flat);
9759
9760 // Compare flat ascii strings.
9761 GenerateCompareFlatAsciiStrings(masm, edx, eax, ecx, ebx, edi);
9762
9763 __ bind(&non_ascii_flat);
9764
9765 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
9766 // tagged as a small integer.
9767 __ bind(&runtime);
9768 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
9769 }
9770
9582 #undef __ 9771 #undef __
9583 9772
9584 } } // namespace v8::internal 9773 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698