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

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

Issue 7795018: Generated code for substring slices in x64 and arm. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 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
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 4621 matching lines...) Expand 10 before | Expand all | Expand 10 after
4632 // if (hash == 0) hash = 27; 4632 // if (hash == 0) hash = 27;
4633 Label hash_not_zero; 4633 Label hash_not_zero;
4634 __ j(not_zero, &hash_not_zero); 4634 __ j(not_zero, &hash_not_zero);
4635 __ Set(hash, 27); 4635 __ Set(hash, 27);
4636 __ bind(&hash_not_zero); 4636 __ bind(&hash_not_zero);
4637 } 4637 }
4638 4638
4639 void SubStringStub::Generate(MacroAssembler* masm) { 4639 void SubStringStub::Generate(MacroAssembler* masm) {
4640 Label runtime; 4640 Label runtime;
4641 4641
4642 if (FLAG_string_slices) {
4643 __ jmp(&runtime);
4644 }
4645 // Stack frame on entry. 4642 // Stack frame on entry.
4646 // rsp[0]: return address 4643 // rsp[0]: return address
4647 // rsp[8]: to 4644 // rsp[8]: to
4648 // rsp[16]: from 4645 // rsp[16]: from
4649 // rsp[24]: string 4646 // rsp[24]: string
4650 4647
4651 const int kToOffset = 1 * kPointerSize; 4648 const int kToOffset = 1 * kPointerSize;
4652 const int kFromOffset = kToOffset + kPointerSize; 4649 const int kFromOffset = kToOffset + kPointerSize;
4653 const int kStringOffset = kFromOffset + kPointerSize; 4650 const int kStringOffset = kFromOffset + kPointerSize;
4654 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset; 4651 const int kArgumentsSize = (kStringOffset + kPointerSize) - kToOffset;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
4700 masm, rbx, rcx, rax, rdx, rdi, r14, &make_two_character_string); 4697 masm, rbx, rcx, rax, rdx, rdi, r14, &make_two_character_string);
4701 __ ret(3 * kPointerSize); 4698 __ ret(3 * kPointerSize);
4702 4699
4703 __ bind(&make_two_character_string); 4700 __ bind(&make_two_character_string);
4704 // Setup registers for allocating the two character string. 4701 // Setup registers for allocating the two character string.
4705 __ movq(rax, Operand(rsp, kStringOffset)); 4702 __ movq(rax, Operand(rsp, kStringOffset));
4706 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset)); 4703 __ movq(rbx, FieldOperand(rax, HeapObject::kMapOffset));
4707 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 4704 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
4708 __ Set(rcx, 2); 4705 __ Set(rcx, 2);
4709 4706
4710 __ bind(&result_longer_than_two); 4707 if (FLAG_string_slices) {
4708 Label copy_routine;
4709 // If coming from the make_two_character_string path, the string
4710 // is too short to be sliced anyways.
4711 STATIC_ASSERT(2 < SlicedString::kMinLength);
4712 __ jmp(&copy_routine);
4713 __ bind(&result_longer_than_two);
4714
4715 // rax: string
4716 // rbx: instance type
4717 // rcx: sub string length
4718 // rdx: from index (smi)
4719 Label allocate_slice, sliced_string, seq_string;
4720 __ cmpq(rcx, Immediate(SlicedString::kMinLength));
4721 // Short slice. Copy instead of slicing.
4722 __ j(less, &copy_routine);
4723 STATIC_ASSERT(kSeqStringTag == 0);
4724 __ testb(rbx, Immediate(kStringRepresentationMask));
4725 __ j(zero, &seq_string, Label::kNear);
4726 STATIC_ASSERT(kIsIndirectStringMask == (kSlicedStringTag & kConsStringTag));
4727 STATIC_ASSERT(kIsIndirectStringMask != 0);
4728 __ testb(rbx, Immediate(kIsIndirectStringMask));
4729 // External string. Jump to runtime.
4730 __ j(zero, &runtime);
4731
4732 __ testb(rbx, Immediate(kSlicedNotConsMask));
4733 __ j(not_zero, &sliced_string, Label::kNear);
4734 // Cons string. Check whether it is flat, then fetch first part.
4735 __ CompareRoot(FieldOperand(rax, ConsString::kSecondOffset),
4736 Heap::kEmptyStringRootIndex);
4737 __ j(not_equal, &runtime);
4738 __ movq(rdi, FieldOperand(rax, ConsString::kFirstOffset));
4739 __ jmp(&allocate_slice, Label::kNear);
4740
4741 __ bind(&sliced_string);
4742 // Sliced string. Fetch parent and correct start index by offset.
4743 __ addq(rdx, FieldOperand(rax, SlicedString::kOffsetOffset));
4744 __ movq(rdi, FieldOperand(rax, SlicedString::kParentOffset));
4745 __ jmp(&allocate_slice, Label::kNear);
4746
4747 __ bind(&seq_string);
4748 // Sequential string. Just move string to the right register.
4749 __ movq(rdi, rax);
4750
4751 __ bind(&allocate_slice);
4752 // edi: underlying subject string
4753 // ebx: instance type of original subject string
4754 // edx: offset
4755 // ecx: length
4756 // Allocate new sliced string. At this point we do not reload the instance
4757 // type including the string encoding because we simply rely on the info
4758 // provided by the original string. It does not matter if the original
4759 // string's encoding is wrong because we always have to recheck encoding of
4760 // the newly created string's parent anyways due to externalized strings.
4761 Label two_byte_slice, set_slice_header;
4762 STATIC_ASSERT(kAsciiStringTag != 0);
4763 __ testb(rbx, Immediate(kAsciiStringTag));
4764 __ j(zero, &two_byte_slice, Label::kNear);
4765 __ AllocateAsciiSlicedString(rax, rbx, no_reg, &runtime);
4766 __ jmp(&set_slice_header, Label::kNear);
4767 __ bind(&two_byte_slice);
4768 __ AllocateSlicedString(rax, rbx, no_reg, &runtime);
4769 __ bind(&set_slice_header);
4770 __ movq(FieldOperand(rax, SlicedString::kOffsetOffset), rdx);
4771 __ Integer32ToSmi(rcx, rcx);
4772 __ movq(FieldOperand(rax, SlicedString::kLengthOffset), rcx);
4773 __ movq(FieldOperand(rax, SlicedString::kParentOffset), rdi);
4774 __ movq(FieldOperand(rax, SlicedString::kHashFieldOffset),
4775 Immediate(String::kEmptyHashField));
4776 __ jmp(&return_rax);
4777
4778 __ bind(&copy_routine);
4779 } else {
4780 __ bind(&result_longer_than_two);
4781 }
4711 4782
4712 // rax: string 4783 // rax: string
4713 // rbx: instance type 4784 // rbx: instance type
4714 // rcx: result string length 4785 // rcx: result string length
4715 // Check for flat ascii string 4786 // Check for flat ascii string
4716 Label non_ascii_flat; 4787 Label non_ascii_flat;
4717 __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &non_ascii_flat); 4788 __ JumpIfInstanceTypeIsNotSequentialAscii(rbx, rbx, &non_ascii_flat);
4718 4789
4719 // Allocate the result. 4790 // Allocate the result.
4720 __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime); 4791 __ AllocateAsciiString(rax, rcx, rbx, rdx, rdi, &runtime);
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after
5396 __ Drop(1); 5467 __ Drop(1);
5397 __ ret(2 * kPointerSize); 5468 __ ret(2 * kPointerSize);
5398 } 5469 }
5399 5470
5400 5471
5401 #undef __ 5472 #undef __
5402 5473
5403 } } // namespace v8::internal 5474 } } // namespace v8::internal
5404 5475
5405 #endif // V8_TARGET_ARCH_X64 5476 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698