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

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

Issue 11411005: Rename SeqAsciiString (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 1 month 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/v8conversions.cc ('k') | src/x64/codegen-x64.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2996 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 // Load the length from the original sliced string if that is the case. 3007 // Load the length from the original sliced string if that is the case.
3008 __ addq(rbx, r14); 3008 __ addq(rbx, r14);
3009 __ SmiToInteger32(arg3, FieldOperand(r15, String::kLengthOffset)); 3009 __ SmiToInteger32(arg3, FieldOperand(r15, String::kLengthOffset));
3010 __ addq(r14, arg3); // Using arg3 as scratch. 3010 __ addq(r14, arg3); // Using arg3 as scratch.
3011 3011
3012 // rbx: start index of the input 3012 // rbx: start index of the input
3013 // r14: end index of the input 3013 // r14: end index of the input
3014 // r15: original subject string 3014 // r15: original subject string
3015 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string. 3015 __ testb(rcx, rcx); // Last use of rcx as encoding of subject string.
3016 __ j(zero, &setup_two_byte, Label::kNear); 3016 __ j(zero, &setup_two_byte, Label::kNear);
3017 __ lea(arg4, FieldOperand(rdi, r14, times_1, SeqAsciiString::kHeaderSize)); 3017 __ lea(arg4, FieldOperand(rdi, r14, times_1, SeqOneByteString::kHeaderSize));
3018 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqAsciiString::kHeaderSize)); 3018 __ lea(arg3, FieldOperand(rdi, rbx, times_1, SeqOneByteString::kHeaderSize));
3019 __ jmp(&setup_rest, Label::kNear); 3019 __ jmp(&setup_rest, Label::kNear);
3020 __ bind(&setup_two_byte); 3020 __ bind(&setup_two_byte);
3021 __ lea(arg4, FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize)); 3021 __ lea(arg4, FieldOperand(rdi, r14, times_2, SeqTwoByteString::kHeaderSize));
3022 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize)); 3022 __ lea(arg3, FieldOperand(rdi, rbx, times_2, SeqTwoByteString::kHeaderSize));
3023 __ bind(&setup_rest); 3023 __ bind(&setup_rest);
3024 3024
3025 // Argument 1: Original subject string. 3025 // Argument 1: Original subject string.
3026 // The original subject is in the previous stack frame. Therefore we have to 3026 // The original subject is in the previous stack frame. Therefore we have to
3027 // use rbp, which points exactly to one pointer size below the previous rsp. 3027 // use rbp, which points exactly to one pointer size below the previous rsp.
3028 // (Because creating a new stack frame pushes the previous rbp onto the stack 3028 // (Because creating a new stack frame pushes the previous rbp onto the stack
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3148 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset)); 3148 __ movq(rbx, FieldOperand(rdi, HeapObject::kMapOffset));
3149 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset)); 3149 __ movzxbl(rbx, FieldOperand(rbx, Map::kInstanceTypeOffset));
3150 if (FLAG_debug_code) { 3150 if (FLAG_debug_code) {
3151 // Assert that we do not have a cons or slice (indirect strings) here. 3151 // Assert that we do not have a cons or slice (indirect strings) here.
3152 // Sequential strings have already been ruled out. 3152 // Sequential strings have already been ruled out.
3153 __ testb(rbx, Immediate(kIsIndirectStringMask)); 3153 __ testb(rbx, Immediate(kIsIndirectStringMask));
3154 __ Assert(zero, "external string expected, but not found"); 3154 __ Assert(zero, "external string expected, but not found");
3155 } 3155 }
3156 __ movq(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset)); 3156 __ movq(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset));
3157 // Move the pointer so that offset-wise, it looks like a sequential string. 3157 // Move the pointer so that offset-wise, it looks like a sequential string.
3158 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); 3158 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
3159 __ subq(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 3159 __ subq(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
3160 STATIC_ASSERT(kTwoByteStringTag == 0); 3160 STATIC_ASSERT(kTwoByteStringTag == 0);
3161 __ testb(rbx, Immediate(kStringEncodingMask)); 3161 __ testb(rbx, Immediate(kStringEncodingMask));
3162 __ j(not_zero, &seq_ascii_string); 3162 __ j(not_zero, &seq_ascii_string);
3163 __ jmp(&seq_two_byte_string); 3163 __ jmp(&seq_two_byte_string);
3164 3164
3165 // Do the runtime call to execute the regexp. 3165 // Do the runtime call to execute the regexp.
3166 __ bind(&runtime); 3166 __ bind(&runtime);
3167 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); 3167 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1);
3168 #endif // V8_INTERPRETED_REGEXP 3168 #endif // V8_INTERPRETED_REGEXP
(...skipping 1480 matching lines...) Expand 10 before | Expand all | Expand 10 after
4649 // Use the symbol table when adding two one character strings, as it 4649 // Use the symbol table when adding two one character strings, as it
4650 // helps later optimizations to return a symbol here. 4650 // helps later optimizations to return a symbol here.
4651 __ SmiCompare(rbx, Smi::FromInt(2)); 4651 __ SmiCompare(rbx, Smi::FromInt(2));
4652 __ j(not_equal, &longer_than_two); 4652 __ j(not_equal, &longer_than_two);
4653 4653
4654 // Check that both strings are non-external ASCII strings. 4654 // Check that both strings are non-external ASCII strings.
4655 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx, 4655 __ JumpIfBothInstanceTypesAreNotSequentialAscii(r8, r9, rbx, rcx,
4656 &call_runtime); 4656 &call_runtime);
4657 4657
4658 // Get the two characters forming the sub string. 4658 // Get the two characters forming the sub string.
4659 __ movzxbq(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 4659 __ movzxbq(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
4660 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); 4660 __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
4661 4661
4662 // Try to lookup two character string in symbol table. If it is not found 4662 // Try to lookup two character string in symbol table. If it is not found
4663 // just allocate a new one. 4663 // just allocate a new one.
4664 Label make_two_character_string, make_flat_ascii_string; 4664 Label make_two_character_string, make_flat_ascii_string;
4665 StringHelper::GenerateTwoCharacterSymbolTableProbe( 4665 StringHelper::GenerateTwoCharacterSymbolTableProbe(
4666 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string); 4666 masm, rbx, rcx, r14, r11, rdi, r15, &make_two_character_string);
4667 __ IncrementCounter(counters->string_add_native(), 1); 4667 __ IncrementCounter(counters->string_add_native(), 1);
4668 __ ret(2 * kPointerSize); 4668 __ ret(2 * kPointerSize);
4669 4669
4670 __ bind(&make_two_character_string); 4670 __ bind(&make_two_character_string);
4671 __ Set(rdi, 2); 4671 __ Set(rdi, 2);
4672 __ AllocateAsciiString(rax, rdi, r8, r9, r11, &call_runtime); 4672 __ AllocateAsciiString(rax, rdi, r8, r9, r11, &call_runtime);
4673 // rbx - first byte: first character 4673 // rbx - first byte: first character
4674 // rbx - second byte: *maybe* second character 4674 // rbx - second byte: *maybe* second character
4675 // Make sure that the second byte of rbx contains the second character. 4675 // Make sure that the second byte of rbx contains the second character.
4676 __ movzxbq(rcx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); 4676 __ movzxbq(rcx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
4677 __ shll(rcx, Immediate(kBitsPerByte)); 4677 __ shll(rcx, Immediate(kBitsPerByte));
4678 __ orl(rbx, rcx); 4678 __ orl(rbx, rcx);
4679 // Write both characters to the new string. 4679 // Write both characters to the new string.
4680 __ movw(FieldOperand(rax, SeqAsciiString::kHeaderSize), rbx); 4680 __ movw(FieldOperand(rax, SeqOneByteString::kHeaderSize), rbx);
4681 __ IncrementCounter(counters->string_add_native(), 1); 4681 __ IncrementCounter(counters->string_add_native(), 1);
4682 __ ret(2 * kPointerSize); 4682 __ ret(2 * kPointerSize);
4683 4683
4684 __ bind(&longer_than_two); 4684 __ bind(&longer_than_two);
4685 // Check if resulting string will be flat. 4685 // Check if resulting string will be flat.
4686 __ SmiCompare(rbx, Smi::FromInt(ConsString::kMinLength)); 4686 __ SmiCompare(rbx, Smi::FromInt(ConsString::kMinLength));
4687 __ j(below, &string_add_flat_result); 4687 __ j(below, &string_add_flat_result);
4688 // Handle exceptionally long strings in the runtime system. 4688 // Handle exceptionally long strings in the runtime system.
4689 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0); 4689 STATIC_ASSERT((String::kMaxLength & 0x80000000) == 0);
4690 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength)); 4690 __ SmiCompare(rbx, Smi::FromInt(String::kMaxLength));
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
4747 STATIC_ASSERT(kSeqStringTag == 0); 4747 STATIC_ASSERT(kSeqStringTag == 0);
4748 __ testb(r8, Immediate(kStringRepresentationMask)); 4748 __ testb(r8, Immediate(kStringRepresentationMask));
4749 __ j(zero, &first_is_sequential, Label::kNear); 4749 __ j(zero, &first_is_sequential, Label::kNear);
4750 // Rule out short external string and load string resource. 4750 // Rule out short external string and load string resource.
4751 STATIC_ASSERT(kShortExternalStringTag != 0); 4751 STATIC_ASSERT(kShortExternalStringTag != 0);
4752 __ testb(r8, Immediate(kShortExternalStringMask)); 4752 __ testb(r8, Immediate(kShortExternalStringMask));
4753 __ j(not_zero, &call_runtime); 4753 __ j(not_zero, &call_runtime);
4754 __ movq(rcx, FieldOperand(rax, ExternalString::kResourceDataOffset)); 4754 __ movq(rcx, FieldOperand(rax, ExternalString::kResourceDataOffset));
4755 __ jmp(&first_prepared, Label::kNear); 4755 __ jmp(&first_prepared, Label::kNear);
4756 __ bind(&first_is_sequential); 4756 __ bind(&first_is_sequential);
4757 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); 4757 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
4758 __ lea(rcx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 4758 __ lea(rcx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
4759 __ bind(&first_prepared); 4759 __ bind(&first_prepared);
4760 4760
4761 // Check whether both strings have same encoding. 4761 // Check whether both strings have same encoding.
4762 __ xorl(r8, r9); 4762 __ xorl(r8, r9);
4763 __ testb(r8, Immediate(kStringEncodingMask)); 4763 __ testb(r8, Immediate(kStringEncodingMask));
4764 __ j(not_zero, &call_runtime); 4764 __ j(not_zero, &call_runtime);
4765 4765
4766 __ SmiToInteger32(r15, FieldOperand(rdx, SeqString::kLengthOffset)); 4766 __ SmiToInteger32(r15, FieldOperand(rdx, SeqString::kLengthOffset));
4767 // r15: length of second string 4767 // r15: length of second string
4768 STATIC_ASSERT(kSeqStringTag == 0); 4768 STATIC_ASSERT(kSeqStringTag == 0);
4769 __ testb(r9, Immediate(kStringRepresentationMask)); 4769 __ testb(r9, Immediate(kStringRepresentationMask));
4770 __ j(zero, &second_is_sequential, Label::kNear); 4770 __ j(zero, &second_is_sequential, Label::kNear);
4771 // Rule out short external string and load string resource. 4771 // Rule out short external string and load string resource.
4772 STATIC_ASSERT(kShortExternalStringTag != 0); 4772 STATIC_ASSERT(kShortExternalStringTag != 0);
4773 __ testb(r9, Immediate(kShortExternalStringMask)); 4773 __ testb(r9, Immediate(kShortExternalStringMask));
4774 __ j(not_zero, &call_runtime); 4774 __ j(not_zero, &call_runtime);
4775 __ movq(rdx, FieldOperand(rdx, ExternalString::kResourceDataOffset)); 4775 __ movq(rdx, FieldOperand(rdx, ExternalString::kResourceDataOffset));
4776 __ jmp(&second_prepared, Label::kNear); 4776 __ jmp(&second_prepared, Label::kNear);
4777 __ bind(&second_is_sequential); 4777 __ bind(&second_is_sequential);
4778 STATIC_ASSERT(SeqAsciiString::kHeaderSize == SeqTwoByteString::kHeaderSize); 4778 STATIC_ASSERT(SeqOneByteString::kHeaderSize == SeqTwoByteString::kHeaderSize);
4779 __ lea(rdx, FieldOperand(rdx, SeqAsciiString::kHeaderSize)); 4779 __ lea(rdx, FieldOperand(rdx, SeqOneByteString::kHeaderSize));
4780 __ bind(&second_prepared); 4780 __ bind(&second_prepared);
4781 4781
4782 Label non_ascii_string_add_flat_result; 4782 Label non_ascii_string_add_flat_result;
4783 // r9: instance type of second string 4783 // r9: instance type of second string
4784 // First string and second string have the same encoding. 4784 // First string and second string have the same encoding.
4785 STATIC_ASSERT(kTwoByteStringTag == 0); 4785 STATIC_ASSERT(kTwoByteStringTag == 0);
4786 __ SmiToInteger32(rbx, rbx); 4786 __ SmiToInteger32(rbx, rbx);
4787 __ testb(r9, Immediate(kStringEncodingMask)); 4787 __ testb(r9, Immediate(kStringEncodingMask));
4788 __ j(zero, &non_ascii_string_add_flat_result); 4788 __ j(zero, &non_ascii_string_add_flat_result);
4789 4789
4790 __ bind(&make_flat_ascii_string); 4790 __ bind(&make_flat_ascii_string);
4791 // Both strings are ASCII strings. As they are short they are both flat. 4791 // Both strings are ASCII strings. As they are short they are both flat.
4792 __ AllocateAsciiString(rax, rbx, rdi, r8, r9, &call_runtime); 4792 __ AllocateAsciiString(rax, rbx, rdi, r8, r9, &call_runtime);
4793 // rax: result string 4793 // rax: result string
4794 // Locate first character of result. 4794 // Locate first character of result.
4795 __ lea(rbx, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 4795 __ lea(rbx, FieldOperand(rax, SeqOneByteString::kHeaderSize));
4796 // rcx: first char of first string 4796 // rcx: first char of first string
4797 // rbx: first character of result 4797 // rbx: first character of result
4798 // r14: length of first string 4798 // r14: length of first string
4799 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, true); 4799 StringHelper::GenerateCopyCharacters(masm, rbx, rcx, r14, true);
4800 // rbx: next character of result 4800 // rbx: next character of result
4801 // rdx: first char of second string 4801 // rdx: first char of second string
4802 // r15: length of second string 4802 // r15: length of second string
4803 StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, true); 4803 StringHelper::GenerateCopyCharacters(masm, rbx, rdx, r15, true);
4804 __ IncrementCounter(counters->string_add_native(), 1); 4804 __ IncrementCounter(counters->string_add_native(), 1);
4805 __ ret(2 * kPointerSize); 4805 __ ret(2 * kPointerSize);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
5058 // We use kScratchRegister as a temporary register in assumption that 5058 // We use kScratchRegister as a temporary register in assumption that
5059 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly 5059 // JumpIfInstanceTypeIsNotSequentialAscii does not use it implicitly
5060 Register temp = kScratchRegister; 5060 Register temp = kScratchRegister;
5061 5061
5062 // Check that the candidate is a non-external ASCII string. 5062 // Check that the candidate is a non-external ASCII string.
5063 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset)); 5063 __ movzxbl(temp, FieldOperand(map, Map::kInstanceTypeOffset));
5064 __ JumpIfInstanceTypeIsNotSequentialAscii( 5064 __ JumpIfInstanceTypeIsNotSequentialAscii(
5065 temp, temp, &next_probe[i]); 5065 temp, temp, &next_probe[i]);
5066 5066
5067 // Check if the two characters match. 5067 // Check if the two characters match.
5068 __ movl(temp, FieldOperand(candidate, SeqAsciiString::kHeaderSize)); 5068 __ movl(temp, FieldOperand(candidate, SeqOneByteString::kHeaderSize));
5069 __ andl(temp, Immediate(0x0000ffff)); 5069 __ andl(temp, Immediate(0x0000ffff));
5070 __ cmpl(chars, temp); 5070 __ cmpl(chars, temp);
5071 __ j(equal, &found_in_symbol_table); 5071 __ j(equal, &found_in_symbol_table);
5072 __ bind(&next_probe[i]); 5072 __ bind(&next_probe[i]);
5073 } 5073 }
5074 5074
5075 // No matching 2 character string found by probing. 5075 // No matching 2 character string found by probing.
5076 __ jmp(not_found); 5076 __ jmp(not_found);
5077 5077
5078 // Scratch register contains result when we fall through to here. 5078 // Scratch register contains result when we fall through to here.
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
5276 __ testb(rbx, Immediate(kExternalStringTag)); 5276 __ testb(rbx, Immediate(kExternalStringTag));
5277 __ j(zero, &sequential_string); 5277 __ j(zero, &sequential_string);
5278 5278
5279 // Handle external string. 5279 // Handle external string.
5280 // Rule out short external strings. 5280 // Rule out short external strings.
5281 STATIC_CHECK(kShortExternalStringTag != 0); 5281 STATIC_CHECK(kShortExternalStringTag != 0);
5282 __ testb(rbx, Immediate(kShortExternalStringMask)); 5282 __ testb(rbx, Immediate(kShortExternalStringMask));
5283 __ j(not_zero, &runtime); 5283 __ j(not_zero, &runtime);
5284 __ movq(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset)); 5284 __ movq(rdi, FieldOperand(rdi, ExternalString::kResourceDataOffset));
5285 // Move the pointer so that offset-wise, it looks like a sequential string. 5285 // Move the pointer so that offset-wise, it looks like a sequential string.
5286 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqAsciiString::kHeaderSize); 5286 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
5287 __ subq(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 5287 __ subq(rdi, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
5288 5288
5289 __ bind(&sequential_string); 5289 __ bind(&sequential_string);
5290 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0); 5290 STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
5291 __ testb(rbx, Immediate(kStringEncodingMask)); 5291 __ testb(rbx, Immediate(kStringEncodingMask));
5292 __ j(zero, &two_byte_sequential); 5292 __ j(zero, &two_byte_sequential);
5293 5293
5294 // Allocate the result. 5294 // Allocate the result.
5295 __ AllocateAsciiString(rax, rcx, r11, r14, r15, &runtime); 5295 __ AllocateAsciiString(rax, rcx, r11, r14, r15, &runtime);
5296 5296
5297 // rax: result string 5297 // rax: result string
5298 // rcx: result string length 5298 // rcx: result string length
5299 __ movq(r14, rsi); // esi used by following code. 5299 __ movq(r14, rsi); // esi used by following code.
5300 { // Locate character of sub string start. 5300 { // Locate character of sub string start.
5301 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_1); 5301 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_1);
5302 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale, 5302 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
5303 SeqAsciiString::kHeaderSize - kHeapObjectTag)); 5303 SeqOneByteString::kHeaderSize - kHeapObjectTag));
5304 } 5304 }
5305 // Locate first character of result. 5305 // Locate first character of result.
5306 __ lea(rdi, FieldOperand(rax, SeqAsciiString::kHeaderSize)); 5306 __ lea(rdi, FieldOperand(rax, SeqOneByteString::kHeaderSize));
5307 5307
5308 // rax: result string 5308 // rax: result string
5309 // rcx: result length 5309 // rcx: result length
5310 // rdi: first character of result 5310 // rdi: first character of result
5311 // rsi: character of sub string start 5311 // rsi: character of sub string start
5312 // r14: original value of rsi 5312 // r14: original value of rsi
5313 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true); 5313 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, true);
5314 __ movq(rsi, r14); // Restore rsi. 5314 __ movq(rsi, r14); // Restore rsi.
5315 __ IncrementCounter(counters->sub_string_native(), 1); 5315 __ IncrementCounter(counters->sub_string_native(), 1);
5316 __ ret(kArgumentsSize); 5316 __ ret(kArgumentsSize);
5317 5317
5318 __ bind(&two_byte_sequential); 5318 __ bind(&two_byte_sequential);
5319 // Allocate the result. 5319 // Allocate the result.
5320 __ AllocateTwoByteString(rax, rcx, r11, r14, r15, &runtime); 5320 __ AllocateTwoByteString(rax, rcx, r11, r14, r15, &runtime);
5321 5321
5322 // rax: result string 5322 // rax: result string
5323 // rcx: result string length 5323 // rcx: result string length
5324 __ movq(r14, rsi); // esi used by following code. 5324 __ movq(r14, rsi); // esi used by following code.
5325 { // Locate character of sub string start. 5325 { // Locate character of sub string start.
5326 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_2); 5326 SmiIndex smi_as_index = masm->SmiToIndex(rdx, rdx, times_2);
5327 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale, 5327 __ lea(rsi, Operand(rdi, smi_as_index.reg, smi_as_index.scale,
5328 SeqAsciiString::kHeaderSize - kHeapObjectTag)); 5328 SeqOneByteString::kHeaderSize - kHeapObjectTag));
5329 } 5329 }
5330 // Locate first character of result. 5330 // Locate first character of result.
5331 __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize)); 5331 __ lea(rdi, FieldOperand(rax, SeqTwoByteString::kHeaderSize));
5332 5332
5333 // rax: result string 5333 // rax: result string
5334 // rcx: result length 5334 // rcx: result length
5335 // rdi: first character of result 5335 // rdi: first character of result
5336 // rsi: character of sub string start 5336 // rsi: character of sub string start
5337 // r14: original value of rsi 5337 // r14: original value of rsi
5338 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false); 5338 StringHelper::GenerateCopyCharactersREP(masm, rdi, rsi, rcx, false);
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
5458 Register right, 5458 Register right,
5459 Register length, 5459 Register length,
5460 Register scratch, 5460 Register scratch,
5461 Label* chars_not_equal, 5461 Label* chars_not_equal,
5462 Label::Distance near_jump) { 5462 Label::Distance near_jump) {
5463 // Change index to run from -length to -1 by adding length to string 5463 // Change index to run from -length to -1 by adding length to string
5464 // start. This means that loop ends when index reaches zero, which 5464 // start. This means that loop ends when index reaches zero, which
5465 // doesn't need an additional compare. 5465 // doesn't need an additional compare.
5466 __ SmiToInteger32(length, length); 5466 __ SmiToInteger32(length, length);
5467 __ lea(left, 5467 __ lea(left,
5468 FieldOperand(left, length, times_1, SeqAsciiString::kHeaderSize)); 5468 FieldOperand(left, length, times_1, SeqOneByteString::kHeaderSize));
5469 __ lea(right, 5469 __ lea(right,
5470 FieldOperand(right, length, times_1, SeqAsciiString::kHeaderSize)); 5470 FieldOperand(right, length, times_1, SeqOneByteString::kHeaderSize));
5471 __ neg(length); 5471 __ neg(length);
5472 Register index = length; // index = -length; 5472 Register index = length; // index = -length;
5473 5473
5474 // Compare loop. 5474 // Compare loop.
5475 Label loop; 5475 Label loop;
5476 __ bind(&loop); 5476 __ bind(&loop);
5477 __ movb(scratch, Operand(left, index, times_1, 0)); 5477 __ movb(scratch, Operand(left, index, times_1, 0));
5478 __ cmpb(scratch, Operand(right, index, times_1, 0)); 5478 __ cmpb(scratch, Operand(right, index, times_1, 0));
5479 __ j(not_equal, chars_not_equal, near_jump); 5479 __ j(not_equal, chars_not_equal, near_jump);
5480 __ incq(index); 5480 __ incq(index);
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
6474 #endif 6474 #endif
6475 6475
6476 __ Ret(); 6476 __ Ret();
6477 } 6477 }
6478 6478
6479 #undef __ 6479 #undef __
6480 6480
6481 } } // namespace v8::internal 6481 } } // namespace v8::internal
6482 6482
6483 #endif // V8_TARGET_ARCH_X64 6483 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/v8conversions.cc ('k') | src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698