Chromium Code Reviews| 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 3381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3392 Label seq_ascii_string, seq_two_byte_string, check_code; | 3392 Label seq_ascii_string, seq_two_byte_string, check_code; |
| 3393 __ mov(eax, Operand(esp, kSubjectOffset)); | 3393 __ mov(eax, Operand(esp, kSubjectOffset)); |
| 3394 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 3394 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 3395 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); | 3395 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 3396 // First check for flat two byte string. | 3396 // First check for flat two byte string. |
| 3397 __ and_(ebx, | 3397 __ and_(ebx, |
| 3398 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); | 3398 kIsNotStringMask | kStringRepresentationMask | kStringEncodingMask); |
| 3399 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); | 3399 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); |
| 3400 __ j(zero, &seq_two_byte_string); | 3400 __ j(zero, &seq_two_byte_string); |
| 3401 // Any other flat string must be a flat ascii string. | 3401 // Any other flat string must be a flat ascii string. |
| 3402 __ test(Operand(ebx), | 3402 __ and_(Operand(ebx), |
| 3403 Immediate(kIsNotStringMask | kStringRepresentationMask)); | 3403 Immediate(kIsNotStringMask | kStringRepresentationMask)); |
| 3404 __ j(zero, &seq_ascii_string); | 3404 __ j(zero, &seq_ascii_string); |
| 3405 | 3405 |
| 3406 // Check for flat cons string. | 3406 // Check for flat cons string or truncated sliced string. |
| 3407 // A flat cons string is a cons string where the second part is the empty | 3407 // A flat cons string is a cons string where the second part is the empty |
| 3408 // string. In that case the subject string is just the first part of the cons | 3408 // string. In that case the subject string is just the first part of the cons |
| 3409 // string. Also in this case the first part of the cons string is known to be | 3409 // string. Also in this case the first part of the cons string is known to be |
| 3410 // a sequential string or an external string. | 3410 // a sequential string or an external string. |
| 3411 STATIC_ASSERT(kExternalStringTag != 0); | 3411 // A truncated sliced string has the offset 0 and the same length as the |
| 3412 STATIC_ASSERT((kConsStringTag & kExternalStringTag) == 0); | 3412 // parent string. |
| 3413 __ test(Operand(ebx), | 3413 Label cons_string, encoding; |
|
Vitaly Repeshko
2011/08/05 12:14:14
encoding -> check_encoding
| |
| 3414 Immediate(kIsNotStringMask | kExternalStringTag)); | 3414 __ cmp(Operand(ebx), Immediate(kConsStringTag)); |
| 3415 __ j(not_zero, &runtime); | 3415 __ j(equal, &cons_string); |
| 3416 // String is a cons string. | 3416 __ cmp(Operand(ebx), Immediate(kSlicedStringTag)); |
| 3417 __ mov(edx, FieldOperand(eax, ConsString::kSecondOffset)); | 3417 // If subject is not a sliced string, it can only be a non-string or an |
| 3418 __ cmp(Operand(edx), factory->empty_string()); | 3418 // external string. |
| 3419 __ j(not_equal, &runtime); | |
| 3420 // String is sliced, check whether it is truncated. | |
| 3421 __ mov(ebx, FieldOperand(eax, SlicedString::kLengthOffset)); | |
| 3422 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); | |
| 3423 // ebx: length of sliced string. | |
| 3424 // eax: parent string. | |
| 3425 __ cmp(ebx, FieldOperand(eax, String::kLengthOffset)); | |
| 3426 __ j(not_equal, &runtime); | |
| 3427 __ jmp(&encoding); | |
| 3428 // String is a cons string, check whether it is flat. | |
| 3429 __ bind(&cons_string); | |
| 3430 __ mov(ebx, FieldOperand(eax, ConsString::kSecondOffset)); | |
| 3431 __ cmp(Operand(ebx), factory->empty_string()); | |
| 3419 __ j(not_equal, &runtime); | 3432 __ j(not_equal, &runtime); |
| 3420 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); | 3433 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
| 3434 // eax: first part of cons string or parent of sliced string. | |
| 3435 // edx: map of first part of cons string or map of parent of sliced string. | |
| 3436 // Is first part of cons or parent of slice a flat two byte string? | |
| 3437 __ bind(&encoding); | |
| 3421 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); | 3438 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 3422 // String is a cons string with empty second part. | |
| 3423 // eax: first part of cons string. | |
| 3424 // ebx: map of first part of cons string. | |
| 3425 // Is first part a flat two byte string? | |
| 3426 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), | 3439 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), |
| 3427 kStringRepresentationMask | kStringEncodingMask); | 3440 kStringRepresentationMask | kStringEncodingMask); |
| 3428 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); | 3441 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0); |
| 3429 __ j(zero, &seq_two_byte_string); | 3442 __ j(zero, &seq_two_byte_string); |
| 3430 // Any other flat string must be ascii. | 3443 // Any other flat string must be ascii. |
| 3431 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), | 3444 __ test_b(FieldOperand(ebx, Map::kInstanceTypeOffset), |
| 3432 kStringRepresentationMask); | 3445 kStringRepresentationMask); |
| 3433 __ j(not_zero, &runtime); | 3446 __ j(not_zero, &runtime); |
| 3434 | 3447 |
| 3435 __ bind(&seq_ascii_string); | 3448 __ bind(&seq_ascii_string); |
| (...skipping 1384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4820 } | 4833 } |
| 4821 | 4834 |
| 4822 | 4835 |
| 4823 // ------------------------------------------------------------------------- | 4836 // ------------------------------------------------------------------------- |
| 4824 // StringCharCodeAtGenerator | 4837 // StringCharCodeAtGenerator |
| 4825 | 4838 |
| 4826 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 4839 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
| 4827 Label flat_string; | 4840 Label flat_string; |
| 4828 Label ascii_string; | 4841 Label ascii_string; |
| 4829 Label got_char_code; | 4842 Label got_char_code; |
| 4843 Label sliced_string; | |
| 4830 | 4844 |
| 4831 // If the receiver is a smi trigger the non-string case. | 4845 // If the receiver is a smi trigger the non-string case. |
| 4832 STATIC_ASSERT(kSmiTag == 0); | 4846 STATIC_ASSERT(kSmiTag == 0); |
| 4833 __ JumpIfSmi(object_, receiver_not_string_); | 4847 __ JumpIfSmi(object_, receiver_not_string_); |
| 4834 | 4848 |
| 4835 // Fetch the instance type of the receiver into result register. | 4849 // Fetch the instance type of the receiver into result register. |
| 4836 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 4850 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 4837 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 4851 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 4838 // If the receiver is not a string trigger the non-string case. | 4852 // If the receiver is not a string trigger the non-string case. |
| 4839 __ test(result_, Immediate(kIsNotStringMask)); | 4853 __ test(result_, Immediate(kIsNotStringMask)); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 4850 // Check for index out of range. | 4864 // Check for index out of range. |
| 4851 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); | 4865 __ cmp(scratch_, FieldOperand(object_, String::kLengthOffset)); |
| 4852 __ j(above_equal, index_out_of_range_); | 4866 __ j(above_equal, index_out_of_range_); |
| 4853 | 4867 |
| 4854 // We need special handling for non-flat strings. | 4868 // We need special handling for non-flat strings. |
| 4855 STATIC_ASSERT(kSeqStringTag == 0); | 4869 STATIC_ASSERT(kSeqStringTag == 0); |
| 4856 __ test(result_, Immediate(kStringRepresentationMask)); | 4870 __ test(result_, Immediate(kStringRepresentationMask)); |
| 4857 __ j(zero, &flat_string); | 4871 __ j(zero, &flat_string); |
| 4858 | 4872 |
| 4859 // Handle non-flat strings. | 4873 // Handle non-flat strings. |
| 4860 __ test(result_, Immediate(kIsConsStringMask)); | 4874 __ and_(result_, kStringRepresentationMask); |
| 4861 __ j(zero, &call_runtime_); | 4875 __ cmp(result_, kSlicedStringTag); |
| 4876 __ j(equal, &sliced_string); | |
| 4877 __ cmp(result_, kExternalStringTag); | |
| 4878 __ j(equal, &call_runtime_); | |
| 4862 | 4879 |
| 4863 // ConsString. | 4880 // ConsString. |
| 4864 // Check whether the right hand side is the empty string (i.e. if | 4881 // Check whether the right hand side is the empty string (i.e. if |
| 4865 // this is really a flat string in a cons string). If that is not | 4882 // this is really a flat string in a cons string). If that is not |
| 4866 // the case we would rather go to the runtime system now to flatten | 4883 // the case we would rather go to the runtime system now to flatten |
| 4867 // the string. | 4884 // the string. |
| 4868 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), | 4885 __ cmp(FieldOperand(object_, ConsString::kSecondOffset), |
| 4869 Immediate(masm->isolate()->factory()->empty_string())); | 4886 Immediate(masm->isolate()->factory()->empty_string())); |
| 4870 __ j(not_equal, &call_runtime_); | 4887 __ j(not_equal, &call_runtime_); |
| 4871 // Get the first of the two strings and load its instance type. | 4888 // Get the first of the two strings and load its instance type. |
| 4872 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); | 4889 __ mov(object_, FieldOperand(object_, ConsString::kFirstOffset)); |
| 4873 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | 4890 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); |
| 4874 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | 4891 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); |
| 4875 // If the first cons component is also non-flat, then go to runtime. | 4892 // If the first cons component is also non-flat, then go to runtime. |
| 4876 STATIC_ASSERT(kSeqStringTag == 0); | 4893 STATIC_ASSERT(kSeqStringTag == 0); |
| 4877 __ test(result_, Immediate(kStringRepresentationMask)); | 4894 __ test(result_, Immediate(kStringRepresentationMask)); |
| 4878 __ j(not_zero, &call_runtime_); | 4895 __ j(not_zero, &call_runtime_); |
| 4896 __ jmp(&flat_string); | |
| 4897 | |
| 4898 // SlicedString, unpack and add offset. | |
| 4899 __ bind(&sliced_string); | |
| 4900 __ add(scratch_, FieldOperand(object_, SlicedString::kOffsetOffset)); | |
| 4901 __ mov(object_, FieldOperand(object_, SlicedString::kParentOffset)); | |
| 4902 __ mov(result_, FieldOperand(object_, HeapObject::kMapOffset)); | |
| 4903 __ movzx_b(result_, FieldOperand(result_, Map::kInstanceTypeOffset)); | |
| 4879 | 4904 |
| 4880 // Check for 1-byte or 2-byte string. | 4905 // Check for 1-byte or 2-byte string. |
| 4881 __ bind(&flat_string); | 4906 __ bind(&flat_string); |
| 4882 STATIC_ASSERT(kAsciiStringTag != 0); | 4907 STATIC_ASSERT(kAsciiStringTag != 0); |
| 4883 __ test(result_, Immediate(kStringEncodingMask)); | 4908 __ test(result_, Immediate(kStringEncodingMask)); |
| 4884 __ j(not_zero, &ascii_string); | 4909 __ j(not_zero, &ascii_string); |
| 4885 | 4910 |
| 4886 // 2-byte string. | 4911 // 2-byte string. |
| 4887 // Load the 2-byte character code into the result register. | 4912 // Load the 2-byte character code into the result register. |
| 4888 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); | 4913 STATIC_ASSERT(kSmiTag == 0 && kSmiTagSize == 1); |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5194 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5219 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 5195 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5220 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 5196 __ and_(ecx, kStringRepresentationMask); | 5221 __ and_(ecx, kStringRepresentationMask); |
| 5197 __ cmp(ecx, kExternalStringTag); | 5222 __ cmp(ecx, kExternalStringTag); |
| 5198 __ j(equal, &string_add_runtime); | 5223 __ j(equal, &string_add_runtime); |
| 5199 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5224 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| 5200 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); | 5225 __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset)); |
| 5201 __ and_(ecx, kStringRepresentationMask); | 5226 __ and_(ecx, kStringRepresentationMask); |
| 5202 __ cmp(ecx, kExternalStringTag); | 5227 __ cmp(ecx, kExternalStringTag); |
| 5203 __ j(equal, &string_add_runtime); | 5228 __ j(equal, &string_add_runtime); |
| 5229 // We cannot encounter sliced strings here since: | |
| 5230 STATIC_ASSERT(SlicedString::kMinLength >= String::kMinNonFlatLength); | |
| 5204 // Now check if both strings are ascii strings. | 5231 // Now check if both strings are ascii strings. |
| 5205 // eax: first string | 5232 // eax: first string |
| 5206 // ebx: length of resulting flat string as a smi | 5233 // ebx: length of resulting flat string as a smi |
| 5207 // edx: second string | 5234 // edx: second string |
| 5208 Label non_ascii_string_add_flat_result; | 5235 Label non_ascii_string_add_flat_result; |
| 5209 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); | 5236 STATIC_ASSERT(kStringEncodingMask == kAsciiStringTag); |
| 5210 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); | 5237 __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset)); |
| 5211 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); | 5238 __ test_b(FieldOperand(ecx, Map::kInstanceTypeOffset), kAsciiStringTag); |
| 5212 __ j(zero, &non_ascii_string_add_flat_result); | 5239 __ j(zero, &non_ascii_string_add_flat_result); |
| 5213 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); | 5240 __ mov(ecx, FieldOperand(edx, HeapObject::kMapOffset)); |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5605 __ test(hash, Operand(hash)); | 5632 __ test(hash, Operand(hash)); |
| 5606 __ j(not_zero, &hash_not_zero, Label::kNear); | 5633 __ j(not_zero, &hash_not_zero, Label::kNear); |
| 5607 __ mov(hash, Immediate(27)); | 5634 __ mov(hash, Immediate(27)); |
| 5608 __ bind(&hash_not_zero); | 5635 __ bind(&hash_not_zero); |
| 5609 } | 5636 } |
| 5610 | 5637 |
| 5611 | 5638 |
| 5612 void SubStringStub::Generate(MacroAssembler* masm) { | 5639 void SubStringStub::Generate(MacroAssembler* masm) { |
| 5613 Label runtime; | 5640 Label runtime; |
| 5614 | 5641 |
| 5642 if (FLAG_string_slices) { | |
| 5643 __ jmp(&runtime); | |
| 5644 } | |
| 5615 // Stack frame on entry. | 5645 // Stack frame on entry. |
| 5616 // esp[0]: return address | 5646 // esp[0]: return address |
| 5617 // esp[4]: to | 5647 // esp[4]: to |
| 5618 // esp[8]: from | 5648 // esp[8]: from |
| 5619 // esp[12]: string | 5649 // esp[12]: string |
| 5620 | 5650 |
| 5621 // Make sure first argument is a string. | 5651 // Make sure first argument is a string. |
| 5622 __ mov(eax, Operand(esp, 3 * kPointerSize)); | 5652 __ mov(eax, Operand(esp, 3 * kPointerSize)); |
| 5623 STATIC_ASSERT(kSmiTag == 0); | 5653 STATIC_ASSERT(kSmiTag == 0); |
| 5624 __ JumpIfSmi(eax, &runtime); | 5654 __ JumpIfSmi(eax, &runtime); |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6381 __ Drop(1); | 6411 __ Drop(1); |
| 6382 __ ret(2 * kPointerSize); | 6412 __ ret(2 * kPointerSize); |
| 6383 } | 6413 } |
| 6384 | 6414 |
| 6385 | 6415 |
| 6386 #undef __ | 6416 #undef __ |
| 6387 | 6417 |
| 6388 } } // namespace v8::internal | 6418 } } // namespace v8::internal |
| 6389 | 6419 |
| 6390 #endif // V8_TARGET_ARCH_IA32 | 6420 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |