OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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, ¬_array_index); | 4124 __ j(above, ¬_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(¬_array_index); | 4130 __ bind(¬_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 Loading... |
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 Loading... |
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 |
OLD | NEW |