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

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

Issue 3327001: ia32 StringAddStub: fast two character case. (Closed)
Patch Set: Better comment. Created 10 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
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 3810 matching lines...) Expand 10 before | Expand all | Expand 10 after
3821 __ j(overflow, &string_add_runtime); 3821 __ j(overflow, &string_add_runtime);
3822 // Use the runtime system when adding two one character strings, as it 3822 // Use the runtime system when adding two one character strings, as it
3823 // contains optimizations for this specific case using the symbol table. 3823 // contains optimizations for this specific case using the symbol table.
3824 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2))); 3824 __ cmp(Operand(ebx), Immediate(Smi::FromInt(2)));
3825 __ j(not_equal, &longer_than_two); 3825 __ j(not_equal, &longer_than_two);
3826 3826
3827 // Check that both strings are non-external ascii strings. 3827 // Check that both strings are non-external ascii strings.
3828 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx, 3828 __ JumpIfNotBothSequentialAsciiStrings(eax, edx, ebx, ecx,
3829 &string_add_runtime); 3829 &string_add_runtime);
3830 3830
3831 // Get the two characters forming the sub string. 3831 // Get the two characters forming the new string.
3832 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize)); 3832 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
3833 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize)); 3833 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
3834 3834
3835 // Try to lookup two character string in symbol table. If it is not found 3835 // Try to lookup two character string in symbol table. If it is not found
3836 // just allocate a new one. 3836 // just allocate a new one.
3837 Label make_two_character_string, make_flat_ascii_string; 3837 Label make_two_character_string, make_two_character_string_no_reload;
3838 StringHelper::GenerateTwoCharacterSymbolTableProbe( 3838 StringHelper::GenerateTwoCharacterSymbolTableProbe(
3839 masm, ebx, ecx, eax, edx, edi, &make_two_character_string); 3839 masm, ebx, ecx, eax, edx, edi,
3840 &make_two_character_string_no_reload, &make_two_character_string);
3840 __ IncrementCounter(&Counters::string_add_native, 1); 3841 __ IncrementCounter(&Counters::string_add_native, 1);
3841 __ ret(2 * kPointerSize); 3842 __ ret(2 * kPointerSize);
3842 3843
3844 // Allocate a two character string.
3843 __ bind(&make_two_character_string); 3845 __ bind(&make_two_character_string);
3844 __ Set(ebx, Immediate(Smi::FromInt(2))); 3846 // Reload the arguments.
3845 __ jmp(&make_flat_ascii_string); 3847 __ mov(eax, Operand(esp, 2 * kPointerSize)); // First argument.
3848 __ mov(edx, Operand(esp, 1 * kPointerSize)); // Second argument.
3849 // Get the two characters forming the new string.
3850 __ movzx_b(ebx, FieldOperand(eax, SeqAsciiString::kHeaderSize));
3851 __ movzx_b(ecx, FieldOperand(edx, SeqAsciiString::kHeaderSize));
3852 __ bind(&make_two_character_string_no_reload);
3853 __ IncrementCounter(&Counters::string_add_make_two_char, 1);
3854 __ AllocateAsciiString(eax, // Result.
3855 2, // Length.
3856 edi, // Scratch.
3857 &string_add_runtime);
3858 // Pack both characters in ebx.
3859 __ shl(ecx, kBitsPerByte);
3860 __ or_(ebx, Operand(ecx));
3861 // Set the characters in the new string.
3862 __ mov_w(FieldOperand(eax, SeqAsciiString::kHeaderSize), ebx);
3863 __ IncrementCounter(&Counters::string_add_native, 1);
3864 __ ret(2 * kPointerSize);
3846 3865
3847 __ bind(&longer_than_two); 3866 __ bind(&longer_than_two);
3848 // Check if resulting string will be flat. 3867 // Check if resulting string will be flat.
3849 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength))); 3868 __ cmp(Operand(ebx), Immediate(Smi::FromInt(String::kMinNonFlatLength)));
3850 __ j(below, &string_add_flat_result); 3869 __ j(below, &string_add_flat_result);
3851 3870
3852 // If result is not supposed to be flat allocate a cons string object. If both 3871 // If result is not supposed to be flat allocate a cons string object. If both
3853 // strings are ascii the result is an ascii cons string. 3872 // strings are ascii the result is an ascii cons string.
3854 Label non_ascii, allocated, ascii_data; 3873 Label non_ascii, allocated, ascii_data;
3855 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset)); 3874 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset));
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
3914 // edx: second string 3933 // edx: second string
3915 Label non_ascii_string_add_flat_result; 3934 Label non_ascii_string_add_flat_result;
3916 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); 3935 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag);
3917 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); 3936 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
3918 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 3937 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
3919 __ j(zero, &non_ascii_string_add_flat_result); 3938 __ j(zero, &non_ascii_string_add_flat_result);
3920 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); 3939 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset));
3921 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); 3940 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag);
3922 __ j(zero, &string_add_runtime); 3941 __ j(zero, &string_add_runtime);
3923 3942
3924 __ bind(&make_flat_ascii_string);
3925 // Both strings are ascii strings. As they are short they are both flat. 3943 // Both strings are ascii strings. As they are short they are both flat.
3926 // ebx: length of resulting flat string as a smi 3944 // ebx: length of resulting flat string as a smi
3927 __ SmiUntag(ebx); 3945 __ SmiUntag(ebx);
3928 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); 3946 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime);
3929 // eax: result string 3947 // eax: result string
3930 __ mov(ecx, eax); 3948 __ mov(ecx, eax);
3931 // Locate first character of result. 3949 // Locate first character of result.
3932 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); 3950 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag));
3933 // Load first argument and locate first character. 3951 // Load first argument and locate first character.
3934 __ mov(edx, Operand(esp, 2 * kPointerSize)); 3952 __ mov(edx, Operand(esp, 2 * kPointerSize));
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
4085 __ bind(&done); 4103 __ bind(&done);
4086 } 4104 }
4087 4105
4088 4106
4089 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm, 4107 void StringHelper::GenerateTwoCharacterSymbolTableProbe(MacroAssembler* masm,
4090 Register c1, 4108 Register c1,
4091 Register c2, 4109 Register c2,
4092 Register scratch1, 4110 Register scratch1,
4093 Register scratch2, 4111 Register scratch2,
4094 Register scratch3, 4112 Register scratch3,
4113 Label* not_probed,
4095 Label* not_found) { 4114 Label* not_found) {
4096 // Register scratch3 is the general scratch register in this function. 4115 // Register scratch3 is the general scratch register in this function.
4097 Register scratch = scratch3; 4116 Register scratch = scratch3;
4098 4117
4099 // Make sure that both characters are not digits as such strings has a 4118 // Make sure that both characters are not digits as such strings has a
4100 // different hash algorithm. Don't try to look for these in the symbol table. 4119 // different hash algorithm. Don't try to look for these in the symbol table.
4101 Label not_array_index; 4120 Label not_array_index;
4102 __ mov(scratch, c1); 4121 __ mov(scratch, c1);
4103 __ sub(Operand(scratch), Immediate(static_cast<int>('0'))); 4122 __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
4104 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0'))); 4123 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
4105 __ j(above, &not_array_index); 4124 __ j(above, &not_array_index);
4106 __ mov(scratch, c2); 4125 __ mov(scratch, c2);
4107 __ sub(Operand(scratch), Immediate(static_cast<int>('0'))); 4126 __ sub(Operand(scratch), Immediate(static_cast<int>('0')));
4108 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0'))); 4127 __ cmp(Operand(scratch), Immediate(static_cast<int>('9' - '0')));
4109 __ j(below_equal, not_found); 4128 __ j(below_equal, not_probed);
4110 4129
4111 __ bind(&not_array_index); 4130 __ bind(&not_array_index);
4112 // Calculate the two character string hash. 4131 // Calculate the two character string hash.
4113 Register hash = scratch1; 4132 Register hash = scratch1;
4114 GenerateHashInit(masm, hash, c1, scratch); 4133 GenerateHashInit(masm, hash, c1, scratch);
4115 GenerateHashAddCharacter(masm, hash, c2, scratch); 4134 GenerateHashAddCharacter(masm, hash, c2, scratch);
4116 GenerateHashGetHash(masm, hash, scratch); 4135 GenerateHashGetHash(masm, hash, scratch);
4117 4136
4118 // Collect the two characters in a register. 4137 // Collect the two characters in a register.
4119 Register chars = c1; 4138 Register chars = c1;
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
4313 4332
4314 // Get the two characters forming the sub string. 4333 // Get the two characters forming the sub string.
4315 __ SmiUntag(edx); // From index is no longer smi. 4334 __ SmiUntag(edx); // From index is no longer smi.
4316 __ movzx_b(ebx, FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize)); 4335 __ movzx_b(ebx, FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize));
4317 __ movzx_b(ecx, 4336 __ movzx_b(ecx,
4318 FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize + 1)); 4337 FieldOperand(eax, edx, times_1, SeqAsciiString::kHeaderSize + 1));
4319 4338
4320 // Try to lookup two character string in symbol table. 4339 // Try to lookup two character string in symbol table.
4321 Label make_two_character_string; 4340 Label make_two_character_string;
4322 StringHelper::GenerateTwoCharacterSymbolTableProbe( 4341 StringHelper::GenerateTwoCharacterSymbolTableProbe(
4323 masm, ebx, ecx, eax, edx, edi, &make_two_character_string); 4342 masm, ebx, ecx, eax, edx, edi,
4343 &make_two_character_string, &make_two_character_string);
4324 __ ret(3 * kPointerSize); 4344 __ ret(3 * kPointerSize);
4325 4345
4326 __ bind(&make_two_character_string); 4346 __ bind(&make_two_character_string);
4327 // Setup registers for allocating the two character string. 4347 // Setup registers for allocating the two character string.
4328 __ mov(eax, Operand(esp, 3 * kPointerSize)); 4348 __ mov(eax, Operand(esp, 3 * kPointerSize));
4329 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 4349 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
4330 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 4350 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
4331 __ Set(ecx, Immediate(2)); 4351 __ Set(ecx, Immediate(2));
4332 4352
4333 __ bind(&result_longer_than_two); 4353 __ bind(&result_longer_than_two);
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
4531 // tagged as a small integer. 4551 // tagged as a small integer.
4532 __ bind(&runtime); 4552 __ bind(&runtime);
4533 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 4553 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
4534 } 4554 }
4535 4555
4536 #undef __ 4556 #undef __
4537 4557
4538 } } // namespace v8::internal 4558 } } // namespace v8::internal
4539 4559
4540 #endif // V8_TARGET_ARCH_IA32 4560 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698