| 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 |