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

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

Issue 2706001: Revert change 4812 due to performance problems. This was a change in string ... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 6 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 | « no previous file | 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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 11298 matching lines...) Expand 10 before | Expand all | Expand 10 after
11309 // Check that the last match info has space for the capture registers and the 11309 // Check that the last match info has space for the capture registers and the
11310 // additional information. 11310 // additional information.
11311 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset)); 11311 __ mov(eax, FieldOperand(ebx, FixedArray::kLengthOffset));
11312 __ SmiUntag(eax); 11312 __ SmiUntag(eax);
11313 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead)); 11313 __ add(Operand(edx), Immediate(RegExpImpl::kLastMatchOverhead));
11314 __ cmp(edx, Operand(eax)); 11314 __ cmp(edx, Operand(eax));
11315 __ j(greater, &runtime); 11315 __ j(greater, &runtime);
11316 11316
11317 // ecx: RegExp data (FixedArray) 11317 // ecx: RegExp data (FixedArray)
11318 // Check the representation and encoding of the subject string. 11318 // Check the representation and encoding of the subject string.
11319 Label seq_ascii_string, seq_two_byte_string, check_code; 11319 Label seq_string, seq_two_byte_string, check_code;
11320 const int kStringRepresentationEncodingMask =
11321 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask;
11320 __ mov(eax, Operand(esp, kSubjectOffset)); 11322 __ mov(eax, Operand(esp, kSubjectOffset));
11321 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 11323 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
11322 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 11324 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
11323 // First check for flat two-byte string. 11325 __ and_(ebx, kStringRepresentationEncodingMask);
11324 __ test_b(Operand(ebx), 11326 // First check for sequential string.
11325 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); 11327 ASSERT_EQ(0, kStringTag);
11326 ASSERT_EQ(0, kStringTag | kSeqStringTag | kTwoByteStringTag); 11328 ASSERT_EQ(0, kSeqStringTag);
11327 __ j(zero, &seq_two_byte_string); 11329 __ test(Operand(ebx),
11328 // Any other flat string must be a flat ascii string. 11330 Immediate(kIsNotStringMask | kStringRepresentationMask));
11329 __ test_b(Operand(ebx), kIsNotStringMask | kStringRepresentationMask); 11331 __ j(zero, &seq_string);
11330 __ j(zero, &seq_ascii_string);
11331 11332
11332 // Check for flat cons string. 11333 // Check for flat cons string.
11333 // If this is a string, and not an external string, it is a cons string.
11334 // A flat cons string is a cons string where the second part is the empty 11334 // A flat cons string is a cons string where the second part is the empty
11335 // string. In that case the subject string is just the first part of the cons 11335 // string. In that case the subject string is just the first part of the cons
11336 // string. Also in this case the first part of the cons string is known to be 11336 // string. Also in this case the first part of the cons string is known to be
11337 // a sequential string or an external string. 11337 // a sequential string or an external string.
11338 ASSERT(kExternalStringTag !=0); 11338 __ and_(ebx, kStringRepresentationMask);
11339 ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 11339 __ cmp(ebx, kConsStringTag);
11340 __ test_b(Operand(ebx), kIsNotStringMask | kExternalStringTag); 11340 __ j(not_equal, &runtime);
11341 __ j(not_zero, &runtime); 11341 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset));
11342 // String is a cons string. 11342 __ cmp(Operand(edx), Factory::empty_string());
11343 __ cmp(FieldOperand(eax, ConsString::kSecondOffset),
11344 Factory::empty_string());
11345 __ j(not_equal, &runtime); 11343 __ j(not_equal, &runtime);
11346 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 11344 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
11347 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 11345 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
11348 // String is a cons string with empty second part. 11346 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
11349 // eax: first part of cons string. 11347 ASSERT_EQ(0, kSeqStringTag);
11350 // ebx: map of first part of cons string. 11348 __ test(ebx, Immediate(kStringRepresentationMask));
11351 // Is first part a flat two byte string?
11352 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
11353 kStringRepresentationMask | kStringEncodingMask);
11354 ASSERT_EQ(0, kSeqStringTag | kTwoByteStringTag);
11355 __ j(zero, &seq_two_byte_string);
11356 // Any other flat string must be ascii.
11357 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset),
11358 kStringRepresentationMask);
11359 __ j(not_zero, &runtime); 11349 __ j(not_zero, &runtime);
11350 __ and_(ebx, kStringRepresentationEncodingMask);
11360 11351
11361 __ bind(&seq_ascii_string); 11352 __ bind(&seq_string);
11362 // eax: subject string (flat ascii) 11353 // eax: subject string (sequential either ascii to two byte)
11354 // ebx: suject string type & kStringRepresentationEncodingMask
11363 // ecx: RegExp data (FixedArray) 11355 // ecx: RegExp data (FixedArray)
11356 // Check that the irregexp code has been generated for an ascii string. If
11357 // it has, the field contains a code object otherwise it contains the hole.
11358 const int kSeqTwoByteString = kStringTag | kSeqStringTag | kTwoByteStringTag;
11359 __ cmp(ebx, kSeqTwoByteString);
11360 __ j(equal, &seq_two_byte_string);
11361 if (FLAG_debug_code) {
11362 __ cmp(ebx, kStringTag | kSeqStringTag | kAsciiStringTag);
11363 __ Check(equal, "Expected sequential ascii string");
11364 }
11364 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset)); 11365 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataAsciiCodeOffset));
11365 __ Set(edi, Immediate(1)); // Type is ascii. 11366 __ Set(edi, Immediate(1)); // Type is ascii.
11366 __ jmp(&check_code); 11367 __ jmp(&check_code);
11367 11368
11368 __ bind(&seq_two_byte_string); 11369 __ bind(&seq_two_byte_string);
11369 // eax: subject string (flat two byte) 11370 // eax: subject string
11370 // ecx: RegExp data (FixedArray) 11371 // ecx: RegExp data (FixedArray)
11371 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 11372 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
11372 __ Set(edi, Immediate(0)); // Type is two byte. 11373 __ Set(edi, Immediate(0)); // Type is two byte.
11373 11374
11374 __ bind(&check_code); 11375 __ bind(&check_code);
11375 // Check that the irregexp code has been generated for the actual string 11376 // Check that the irregexp code has been generated for the actual string
11376 // encoding. If it has, the field contains a code object otherwise it contains 11377 // encoding. If it has, the field contains a code object otherwise it contains
11377 // the hole. 11378 // the hole.
11378 __ CmpObjectType(edx, CODE_TYPE, ebx); 11379 __ CmpObjectType(edx, CODE_TYPE, ebx);
11379 __ j(not_equal, &runtime); 11380 __ j(not_equal, &runtime);
(...skipping 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
12765 12766
12766 void StringAddStub::Generate(MacroAssembler* masm) { 12767 void StringAddStub::Generate(MacroAssembler* masm) {
12767 Label string_add_runtime; 12768 Label string_add_runtime;
12768 12769
12769 // Load the two arguments. 12770 // Load the two arguments.
12770 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument. 12771 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
12771 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument. 12772 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
12772 12773
12773 // Make sure that both arguments are strings if not known in advance. 12774 // Make sure that both arguments are strings if not known in advance.
12774 if (string_check_) { 12775 if (string_check_) {
12775 __ mov(ecx, eax); 12776 __ test(eax, Immediate(kSmiTagMask));
12776 __ and_(Operand(ecx), edx);
12777 __ test(ecx, Immediate(kSmiTagMask));
12778 __ j(zero, &string_add_runtime); 12777 __ j(zero, &string_add_runtime);
12779 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 12778 __ CmpObjectType(eax, FIRST_NONSTRING_TYPE, ebx);
12780 __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 12779 __ j(above_equal, &string_add_runtime);
12781 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); 12780
12782 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 12781 // First argument is a a string, test second.
12783 __ or_(Operand(ecx), ebx); 12782 __ test(edx, Immediate(kSmiTagMask));
12784 __ test_b(Operand(ecx), kIsNotStringMask); 12783 __ j(zero, &string_add_runtime);
12785 __ j(not_zero, &string_add_runtime); 12784 __ CmpObjectType(edx, FIRST_NONSTRING_TYPE, ebx);
12785 __ j(above_equal, &string_add_runtime);
12786 } 12786 }
12787 12787
12788 // Both arguments are strings. 12788 // Both arguments are strings.
12789 // eax: first string 12789 // eax: first string
12790 // edx: second string 12790 // edx: second string
12791 // Check if either of the strings are empty. In that case return the other. 12791 // Check if either of the strings are empty. In that case return the other.
12792 Label second_not_zero_length, both_not_zero_length; 12792 Label second_not_zero_length, both_not_zero_length;
12793 __ mov(ecx, FieldOperand(edx, String::kLengthOffset)); 12793 __ mov(ecx, FieldOperand(edx, String::kLengthOffset));
12794 ASSERT(kSmiTag == 0); 12794 ASSERT(kSmiTag == 0);
12795 __ test(ecx, Operand(ecx)); 12795 __ test(ecx, Operand(ecx));
(...skipping 10 matching lines...) Expand all
12806 __ mov(eax, edx); 12806 __ mov(eax, edx);
12807 __ IncrementCounter(&Counters::string_add_native, 1); 12807 __ IncrementCounter(&Counters::string_add_native, 1);
12808 __ ret(2 * kPointerSize); 12808 __ ret(2 * kPointerSize);
12809 12809
12810 // Both strings are non-empty. 12810 // Both strings are non-empty.
12811 // eax: first string 12811 // eax: first string
12812 // ebx: length of first string as a smi 12812 // ebx: length of first string as a smi
12813 // ecx: length of second string as a smi 12813 // ecx: length of second string as a smi
12814 // edx: second string 12814 // edx: second string
12815 // Look at the length of the result of adding the two strings. 12815 // Look at the length of the result of adding the two strings.
12816 Label make_two_character_string, longer_than_two, 12816 Label string_add_flat_result, longer_than_two;
12817 make_flat_string, make_flat_ascii_string, make_flat_non_ascii_string;
12818 __ bind(&both_not_zero_length); 12817 __ bind(&both_not_zero_length);
12819 __ add(ebx, Operand(ecx)); 12818 __ add(ebx, Operand(ecx));
12820 ASSERT(Smi::kMaxValue == String::kMaxLength); 12819 ASSERT(Smi::kMaxValue == String::kMaxLength);
12821 // Handle exceptionally long strings in the runtime system. 12820 // Handle exceptionally long strings in the runtime system.
12822 __ j(overflow, &string_add_runtime); 12821 __ j(overflow, &string_add_runtime);
12823 // Use the runtime system when adding two one character strings, as it 12822 // Use the runtime system when adding two one character strings, as it
12824 // contains optimizations for this specific case using the symbol table. 12823 // contains optimizations for this specific case using the symbol table.
12825 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2))); 12824 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2)));
12826 __ j(not_equal, &longer_than_two); 12825 __ j(not_equal, &longer_than_two);
12827 12826
12828 // Check that both strings are non-external ascii strings. 12827 // Check that both strings are non-external ascii strings.
12829 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, 12828 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
12830 &string_add_runtime); 12829 &string_add_runtime);
12831 12830
12832 // Get the two characters forming the sub string. 12831 // Get the two characters forming the sub string.
12833 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); 12832 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
12834 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); 12833 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
12835 12834
12836 // Try to lookup two character string in symbol table. If it is not found 12835 // Try to lookup two character string in symbol table. If it is not found
12837 // just allocate a new one. 12836 // just allocate a new one.
12837 Label make_two_character_string, make_flat_ascii_string;
12838 StringHelper::GenerateTwoCharacterSymbolTableProbe( 12838 StringHelper::GenerateTwoCharacterSymbolTableProbe(
12839 masm, ebx, ecx, eax, edx, edi, &make_two_character_string); 12839 masm, ebx, ecx, eax, edx, edi, &make_two_character_string);
12840 __ IncrementCounter(&Counters::string_add_native, 1); 12840 __ IncrementCounter(&Counters::string_add_native, 1);
12841 __ ret(2 * kPointerSize); 12841 __ ret(2 * kPointerSize);
12842 12842
12843 __ bind(&make_two_character_string); 12843 __ bind(&make_two_character_string);
12844 __ Set(ebx, Immediate(Smi::FromInt(2))); 12844 __ Set(ebx, Immediate(Smi::FromInt(2)));
12845 __ jmp(&make_flat_ascii_string); 12845 __ jmp(&make_flat_ascii_string);
12846 12846
12847 __ bind(&longer_than_two); 12847 __ bind(&longer_than_two);
12848 // Check if resulting string will be flat. 12848 // Check if resulting string will be flat.
12849 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength))); 12849 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength)));
12850 __ j(below, &make_flat_string); 12850 __ j(below, &string_add_flat_result);
12851 12851
12852 // If result is not supposed to be flat allocate a cons string object. If both 12852 // If result is not supposed to be flat allocate a cons string object. If both
12853 // strings are ascii the result is an ascii cons string. 12853 // strings are ascii the result is an ascii cons string.
12854 Label non_ascii, allocated; 12854 Label non_ascii, allocated;
12855 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset)); 12855 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset));
12856 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset)); 12856 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset));
12857 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); 12857 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset));
12858 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); 12858 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset));
12859 __ and_(ecx, Operand(edi)); 12859 __ and_(ecx, Operand(edi));
12860 ASSERT(kStringEncodingMask == kAsciiStringTag); 12860 ASSERT(kStringEncodingMask == kAsciiStringTag);
(...skipping 10 matching lines...) Expand all
12871 __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax); 12871 __ mov(FieldOperand(ecx, ConsString::kFirstOffset), eax);
12872 __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx); 12872 __ mov(FieldOperand(ecx, ConsString::kSecondOffset), edx);
12873 __ mov(eax, ecx); 12873 __ mov(eax, ecx);
12874 __ IncrementCounter(&Counters::string_add_native, 1); 12874 __ IncrementCounter(&Counters::string_add_native, 1);
12875 __ ret(2 * kPointerSize); 12875 __ ret(2 * kPointerSize);
12876 __ bind(&non_ascii); 12876 __ bind(&non_ascii);
12877 // Allocate a two byte cons string. 12877 // Allocate a two byte cons string.
12878 __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime); 12878 __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime);
12879 __ jmp(&allocated); 12879 __ jmp(&allocated);
12880 12880
12881 // Handle creating a flat result. Branch to runtime if either string 12881 // Handle creating a flat result. First check that both strings are not
12882 // is external or if they are not both ascii or both two-byte. 12882 // external strings.
12883 // Otherwise branch to ascii case or two-byte case.
12884 // eax: first string 12883 // eax: first string
12885 // ebx: length of resulting flat string as a smi 12884 // ebx: length of resulting flat string as a smi
12886 // edx: second string 12885 // edx: second string
12887 __ bind(&make_flat_string); 12886 __ bind(&string_add_flat_result);
12888 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 12887 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
12889 __ movzx_b(edi, FieldOperand(ecx, Map::kInstanceTypeOffset)); 12888 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
12889 __ and_(ecx, kStringRepresentationMask);
12890 __ cmp(ecx, kExternalStringTag);
12891 __ j(equal, &string_add_runtime);
12890 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 12892 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
12891 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); 12893 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
12892 __ or_(ecx, Operand(edi)); 12894 __ and_(ecx, kStringRepresentationMask);
12893 ASSERT(kExternalStringTag !=0); 12895 __ cmp(ecx, kExternalStringTag);
12894 ASSERT_EQ(0, kConsStringTag & kExternalStringTag); 12896 __ j(equal, &string_add_runtime);
12895 ASSERT_EQ(0, kSeqStringTag & kExternalStringTag); 12897 // Now check if both strings are ascii strings.
12896 ASSERT_EQ(0, kTwoByteStringTag); 12898 // eax: first string
12897 __ test_b(Operand(ecx), kExternalStringTag | kStringEncodingMask); 12899 // ebx: length of resulting flat string as a smi
12898 __ j(zero, &make_flat_non_ascii_string); // Neither is ascii or external. 12900 // edx: second string
12899 __ test_b(Operand(ecx), kExternalStringTag); 12901 Label non_ascii_string_add_flat_result;
12900 __ j(not_zero, &string_add_runtime); // One or both is external. 12902 ASSERT(kStringEncodingMask == kAsciiStringTag);
12901 12903 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
12902 // At this point, neither is external, and at least one is ascii. 12904 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
12903 // Check that both are ascii, by computing mask & first type & second type. 12905 __ j(zero, &non_ascii_string_add_flat_result);
12904 __ and_(edi, kStringEncodingMask);
12905 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 12906 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
12906 __ test_b(edi, FieldOperand(ecx, Map::kInstanceTypeOffset)); 12907 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
12907 ASSERT(kAsciiStringTag != 0);
12908 __ j(zero, &string_add_runtime); 12908 __ j(zero, &string_add_runtime);
12909 12909
12910 __ bind(&make_flat_ascii_string); 12910 __ bind(&make_flat_ascii_string);
12911 // Both strings are ascii strings. As they are short they are both flat. 12911 // Both strings are ascii strings. As they are short they are both flat.
12912 // Create a flat ascii result.
12913 // ebx: length of resulting flat string as a smi 12912 // ebx: length of resulting flat string as a smi
12914 __ SmiUntag(ebx); 12913 __ SmiUntag(ebx);
12915 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); 12914 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
12916 // eax: result string 12915 // eax: result string
12917 __ mov(ecx, eax); 12916 __ mov(ecx, eax);
12918 // Locate first character of result. 12917 // Locate first character of result.
12919 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 12918 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
12920 // Load first argument and locate first character. 12919 // Load first argument and locate first character.
12921 __ mov(edx, Operand(esp, 2 * kPointerSize)); 12920 __ mov(edx, Operand(esp, 2 * kPointerSize));
12922 __ mov(edi, FieldOperand(edx, String::kLengthOffset)); 12921 __ mov(edi, FieldOperand(edx, String::kLengthOffset));
(...skipping 10 matching lines...) Expand all
12933 __ SmiUntag(edi); 12932 __ SmiUntag(edi);
12934 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 12933 __ add(Operand(edx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
12935 // eax: result string 12934 // eax: result string
12936 // ecx: next character of result 12935 // ecx: next character of result
12937 // edx: first char of second argument 12936 // edx: first char of second argument
12938 // edi: length of second argument 12937 // edi: length of second argument
12939 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); 12938 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true);
12940 __ IncrementCounter(&Counters::string_add_native, 1); 12939 __ IncrementCounter(&Counters::string_add_native, 1);
12941 __ ret(2 * kPointerSize); 12940 __ ret(2 * kPointerSize);
12942 12941
12943 // Both strings are two-byte strings. As they are short they are both flat. 12942 // Handle creating a flat two byte result.
12944 // Create a flat two byte result. 12943 // eax: first string - known to be two byte
12945 // ebx: length of resulting flat string as a smi 12944 // ebx: length of resulting flat string as a smi
12946 __ bind(&make_flat_non_ascii_string); 12945 // edx: second string
12946 __ bind(&non_ascii_string_add_flat_result);
12947 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
12948 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
12949 __ j(not_zero, &string_add_runtime);
12947 // Both strings are two byte strings. As they are short they are both 12950 // Both strings are two byte strings. As they are short they are both
12948 // flat. 12951 // flat.
12949 __ SmiUntag(ebx); 12952 __ SmiUntag(ebx);
12950 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime); 12953 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime);
12951 // eax: result string 12954 // eax: result string
12952 __ mov(ecx, eax); 12955 __ mov(ecx, eax);
12953 // Locate first character of result. 12956 // Locate first character of result.
12954 __ add(Operand(ecx), 12957 __ add(Operand(ecx),
12955 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 12958 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
12956 // Load first argument and locate first character. 12959 // Load first argument and locate first character.
(...skipping 752 matching lines...) Expand 10 before | Expand all | Expand 10 after
13709 masm.GetCode(&desc); 13712 masm.GetCode(&desc);
13710 // Call the function from C++. 13713 // Call the function from C++.
13711 return FUNCTION_CAST<MemCopyFunction>(buffer); 13714 return FUNCTION_CAST<MemCopyFunction>(buffer);
13712 } 13715 }
13713 13716
13714 #undef __ 13717 #undef __
13715 13718
13716 } } // namespace v8::internal 13719 } } // namespace v8::internal
13717 13720
13718 #endif // V8_TARGET_ARCH_IA32 13721 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698