OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 4889 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4900 __ bind(&assure_seq_string); | 4900 __ bind(&assure_seq_string); |
4901 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 4901 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
4902 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 4902 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
4903 STATIC_ASSERT(kSeqStringTag == 0); | 4903 STATIC_ASSERT(kSeqStringTag == 0); |
4904 __ test(result_, Immediate(kStringRepresentationMask)); | 4904 __ test(result_, Immediate(kStringRepresentationMask)); |
4905 __ j(not_zero, &call_runtime_); | 4905 __ j(not_zero, &call_runtime_); |
4906 __ jmp(&flat_string, Label::kNear); | 4906 __ jmp(&flat_string, Label::kNear); |
4907 | 4907 |
4908 // Check for 1-byte or 2-byte string. | 4908 // Check for 1-byte or 2-byte string. |
4909 __ bind(&flat_string); | 4909 __ bind(&flat_string); |
4910 STATIC_ASSERT(kAsciiStringTag != 0); | 4910 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
| 4911 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
4911 __ test(result_, Immediate(kStringEncodingMask)); | 4912 __ test(result_, Immediate(kStringEncodingMask)); |
4912 __ j(not_zero, &ascii_string, Label::kNear); | 4913 __ j(not_zero, &ascii_string, Label::kNear); |
4913 | 4914 |
4914 // 2-byte string. | 4915 // 2-byte string. |
4915 // Load the 2-byte character code into the result register. | 4916 // Load the 2-byte character code into the result register. |
4916 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 4917 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
4917 __ movzx_w(result_, FieldOperand(object_, | 4918 __ movzx_w(result_, FieldOperand(object_, |
4918 scratch_, times_1, // Scratch is smi-tagged. | 4919 scratch_, times_1, // Scratch is smi-tagged. |
4919 SeqTwoByteString::kHeaderSize)); | 4920 SeqTwoByteString::kHeaderSize)); |
4920 __ jmp(&got_char_code, Label::kNear); | 4921 __ jmp(&got_char_code, Label::kNear); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5171 __ j(below, &string_add_flat_result); | 5172 __ j(below, &string_add_flat_result); |
5172 | 5173 |
5173 // If result is not supposed to be flat allocate a cons string object. If both | 5174 // If result is not supposed to be flat allocate a cons string object. If both |
5174 // strings are ascii the result is an ascii cons string. | 5175 // strings are ascii the result is an ascii cons string. |
5175 Label non_ascii, allocated, ascii_data; | 5176 Label non_ascii, allocated, ascii_data; |
5176 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset)); | 5177 __ mov(edi, FieldOperand(eax, HeapObject::kMapOffset)); |
5177 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset)); | 5178 __ movzx_b(ecx, FieldOperand(edi, Map::kInstanceTypeOffset)); |
5178 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); | 5179 __ mov(edi, FieldOperand(edx, HeapObject::kMapOffset)); |
5179 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); | 5180 __ movzx_b(edi, FieldOperand(edi, Map::kInstanceTypeOffset)); |
5180 __ and_(ecx, Operand(edi)); | 5181 __ and_(ecx, Operand(edi)); |
5181 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); | 5182 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
5182 __ test(ecx, Immediate(kAsciiStringTag)); | 5183 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
| 5184 __ test(ecx, Immediate(kStringEncodingMask)); |
5183 __ j(zero, &non_ascii); | 5185 __ j(zero, &non_ascii); |
5184 __ bind(&ascii_data); | 5186 __ bind(&ascii_data); |
5185 // Allocate an acsii cons string. | 5187 // Allocate an acsii cons string. |
5186 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime); | 5188 __ AllocateAsciiConsString(ecx, edi, no_reg, &string_add_runtime); |
5187 __ bind(&allocated); | 5189 __ bind(&allocated); |
5188 // Fill the fields of the cons string. | 5190 // Fill the fields of the cons string. |
5189 if (FLAG_debug_code) __ AbortIfNotSmi(ebx); | 5191 if (FLAG_debug_code) __ AbortIfNotSmi(ebx); |
5190 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); | 5192 __ mov(FieldOperand(ecx, ConsString::kLengthOffset), ebx); |
5191 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), | 5193 __ mov(FieldOperand(ecx, ConsString::kHashFieldOffset), |
5192 Immediate(String::kEmptyHashField)); | 5194 Immediate(String::kEmptyHashField)); |
(...skipping 10 matching lines...) Expand all Loading... |
5203 __ test(ecx, Immediate(kAsciiDataHintMask)); | 5205 __ test(ecx, Immediate(kAsciiDataHintMask)); |
5204 __ j(not_zero, &ascii_data); | 5206 __ j(not_zero, &ascii_data); |
5205 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5207 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5206 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5208 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5207 __ xor_(edi, Operand(ecx)); | 5209 __ xor_(edi, Operand(ecx)); |
5208 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); | 5210 STATIC_ASSERT(kAsciiStringTag != 0 && kAsciiDataHintTag != 0); |
5209 __ and_(edi, kAsciiStringTag | kAsciiDataHintTag); | 5211 __ and_(edi, kAsciiStringTag | kAsciiDataHintTag); |
5210 __ cmp(edi, kAsciiStringTag | kAsciiDataHintTag); | 5212 __ cmp(edi, kAsciiStringTag | kAsciiDataHintTag); |
5211 __ j(equal, &ascii_data); | 5213 __ j(equal, &ascii_data); |
5212 // Allocate a two byte cons string. | 5214 // Allocate a two byte cons string. |
5213 __ AllocateConsString(ecx, edi, no_reg, &string_add_runtime); | 5215 __ AllocateTwoByteConsString(ecx, edi, no_reg, &string_add_runtime); |
5214 __ jmp(&allocated); | 5216 __ jmp(&allocated); |
5215 | 5217 |
5216 // Handle creating a flat result. First check that both strings are not | 5218 // Handle creating a flat result. First check that both strings are not |
5217 // external strings. | 5219 // external strings. |
5218 // eax: first string | 5220 // eax: first string |
5219 // ebx: length of resulting flat string as a smi | 5221 // ebx: length of resulting flat string as a smi |
5220 // edx: second string | 5222 // edx: second string |
5221 __ bind(&string_add_flat_result); | 5223 __ bind(&string_add_flat_result); |
5222 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5224 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5223 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5225 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5224 __ and_(ecx, kStringRepresentationMask); | 5226 __ and_(ecx, kStringRepresentationMask); |
5225 __ cmp(ecx, kExternalStringTag); | 5227 __ cmp(ecx, kExternalStringTag); |
5226 __ j(equal, &string_add_runtime); | 5228 __ j(equal, &string_add_runtime); |
5227 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5229 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
5228 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5230 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
5229 __ and_(ecx, kStringRepresentationMask); | 5231 __ and_(ecx, kStringRepresentationMask); |
5230 __ cmp(ecx, kExternalStringTag); | 5232 __ cmp(ecx, kExternalStringTag); |
5231 __ j(equal, &string_add_runtime); | 5233 __ j(equal, &string_add_runtime); |
5232 // We cannot encounter sliced strings here since: | 5234 // We cannot encounter sliced strings here since: |
5233 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); | 5235 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); |
5234 // Now check if both strings are ascii strings. | 5236 // Now check if both strings are ascii strings. |
5235 // eax: first string | 5237 // eax: first string |
5236 // ebx: length of resulting flat string as a smi | 5238 // ebx: length of resulting flat string as a smi |
5237 // edx: second string | 5239 // edx: second string |
5238 Label non_ascii_string_add_flat_result; | 5240 Label non_ascii_string_add_flat_result; |
5239 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); | 5241 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
| 5242 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
5240 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5243 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
5241 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5244 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask); |
5242 __ j(zero, &non_ascii_string_add_flat_result); | 5245 __ j(zero, &non_ascii_string_add_flat_result); |
5243 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5246 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
5244 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5247 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask); |
5245 __ j(zero, &string_add_runtime); | 5248 __ j(zero, &string_add_runtime); |
5246 | 5249 |
5247 // Both strings are ascii strings. As they are short they are both flat. | 5250 // Both strings are ascii strings. As they are short they are both flat. |
5248 // ebx: length of resulting flat string as a smi | 5251 // ebx: length of resulting flat string as a smi |
5249 __ SmiUntag(ebx); | 5252 __ SmiUntag(ebx); |
5250 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); | 5253 __ AllocateAsciiString(eax, ebx, ecx, edx, edi, &string_add_runtime); |
5251 // eax: result string | 5254 // eax: result string |
5252 __ mov(ecx, eax); | 5255 __ mov(ecx, eax); |
5253 // Locate first character of result. | 5256 // Locate first character of result. |
5254 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); | 5257 __ add(Operand(ecx), Immediate(SeqAsciiString::kHeaderSize - kHeapObjectTag)); |
(...skipping 19 matching lines...) Expand all Loading... |
5274 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); | 5277 StringHelper::GenerateCopyCharacters(masm, ecx, edx, edi, ebx, true); |
5275 __ IncrementCounter(counters->string_add_native(), 1); | 5278 __ IncrementCounter(counters->string_add_native(), 1); |
5276 __ ret(2 * kPointerSize); | 5279 __ ret(2 * kPointerSize); |
5277 | 5280 |
5278 // Handle creating a flat two byte result. | 5281 // Handle creating a flat two byte result. |
5279 // eax: first string - known to be two byte | 5282 // eax: first string - known to be two byte |
5280 // ebx: length of resulting flat string as a smi | 5283 // ebx: length of resulting flat string as a smi |
5281 // edx: second string | 5284 // edx: second string |
5282 __ bind(&non_ascii_string_add_flat_result); | 5285 __ bind(&non_ascii_string_add_flat_result); |
5283 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5286 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
5284 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5287 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kStringEncodingMask); |
5285 __ j(not_zero, &string_add_runtime); | 5288 __ j(not_zero, &string_add_runtime); |
5286 // Both strings are two byte strings. As they are short they are both | 5289 // Both strings are two byte strings. As they are short they are both |
5287 // flat. | 5290 // flat. |
5288 __ SmiUntag(ebx); | 5291 __ SmiUntag(ebx); |
5289 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime); | 5292 __ AllocateTwoByteString(eax, ebx, ecx, edx, edi, &string_add_runtime); |
5290 // eax: result string | 5293 // eax: result string |
5291 __ mov(ecx, eax); | 5294 __ mov(ecx, eax); |
5292 // Locate first character of result. | 5295 // Locate first character of result. |
5293 __ add(Operand(ecx), | 5296 __ add(Operand(ecx), |
5294 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 5297 Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
(...skipping 457 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5752 // edi: underlying subject string | 5755 // edi: underlying subject string |
5753 // ebx: instance type of original subject string | 5756 // ebx: instance type of original subject string |
5754 // edx: offset | 5757 // edx: offset |
5755 // ecx: length | 5758 // ecx: length |
5756 // Allocate new sliced string. At this point we do not reload the instance | 5759 // Allocate new sliced string. At this point we do not reload the instance |
5757 // type including the string encoding because we simply rely on the info | 5760 // type including the string encoding because we simply rely on the info |
5758 // provided by the original string. It does not matter if the original | 5761 // provided by the original string. It does not matter if the original |
5759 // string's encoding is wrong because we always have to recheck encoding of | 5762 // string's encoding is wrong because we always have to recheck encoding of |
5760 // the newly created string's parent anyways due to externalized strings. | 5763 // the newly created string's parent anyways due to externalized strings. |
5761 Label two_byte_slice, set_slice_header; | 5764 Label two_byte_slice, set_slice_header; |
5762 STATIC_ASSERT(kAsciiStringTag != 0); | 5765 STATIC_ASSERT((kStringEncodingMask & kAsciiStringTag) != 0); |
5763 __ test(ebx, Immediate(kAsciiStringTag)); | 5766 STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0); |
| 5767 __ test(ebx, Immediate(kStringEncodingMask)); |
5764 __ j(zero, &two_byte_slice, Label::kNear); | 5768 __ j(zero, &two_byte_slice, Label::kNear); |
5765 __ AllocateAsciiSlicedString(eax, ebx, no_reg, &runtime); | 5769 __ AllocateAsciiSlicedString(eax, ebx, no_reg, &runtime); |
5766 __ jmp(&set_slice_header, Label::kNear); | 5770 __ jmp(&set_slice_header, Label::kNear); |
5767 __ bind(&two_byte_slice); | 5771 __ bind(&two_byte_slice); |
5768 __ AllocateSlicedString(eax, ebx, no_reg, &runtime); | 5772 __ AllocateTwoByteSlicedString(eax, ebx, no_reg, &runtime); |
5769 __ bind(&set_slice_header); | 5773 __ bind(&set_slice_header); |
5770 __ mov(FieldOperand(eax, SlicedString::kOffsetOffset), edx); | 5774 __ mov(FieldOperand(eax, SlicedString::kOffsetOffset), edx); |
5771 __ SmiTag(ecx); | 5775 __ SmiTag(ecx); |
5772 __ mov(FieldOperand(eax, SlicedString::kLengthOffset), ecx); | 5776 __ mov(FieldOperand(eax, SlicedString::kLengthOffset), ecx); |
5773 __ mov(FieldOperand(eax, SlicedString::kParentOffset), edi); | 5777 __ mov(FieldOperand(eax, SlicedString::kParentOffset), edi); |
5774 __ mov(FieldOperand(eax, SlicedString::kHashFieldOffset), | 5778 __ mov(FieldOperand(eax, SlicedString::kHashFieldOffset), |
5775 Immediate(String::kEmptyHashField)); | 5779 Immediate(String::kEmptyHashField)); |
5776 __ jmp(&return_eax); | 5780 __ jmp(&return_eax); |
5777 | 5781 |
5778 __ bind(©_routine); | 5782 __ bind(©_routine); |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6487 __ Drop(1); | 6491 __ Drop(1); |
6488 __ ret(2 * kPointerSize); | 6492 __ ret(2 * kPointerSize); |
6489 } | 6493 } |
6490 | 6494 |
6491 | 6495 |
6492 #undef __ | 6496 #undef __ |
6493 | 6497 |
6494 } } // namespace v8::internal | 6498 } } // namespace v8::internal |
6495 | 6499 |
6496 #endif // V8_TARGET_ARCH_IA32 | 6500 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |