OLD | NEW |
---|---|
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2842 frame_->Pop(ebx); | 2842 frame_->Pop(ebx); |
2843 | 2843 |
2844 // Check for negative or non-smi index. | 2844 // Check for negative or non-smi index. |
2845 ASSERT(kSmiTag == 0); | 2845 ASSERT(kSmiTag == 0); |
2846 __ test(ebx, Immediate(kSmiTagMask | 0x80000000)); | 2846 __ test(ebx, Immediate(kSmiTagMask | 0x80000000)); |
2847 __ j(not_zero, &slow_case, not_taken); | 2847 __ j(not_zero, &slow_case, not_taken); |
2848 // Get rid of the smi tag on the index. | 2848 // Get rid of the smi tag on the index. |
2849 __ sar(ebx, kSmiTagSize); | 2849 __ sar(ebx, kSmiTagSize); |
2850 | 2850 |
2851 __ bind(&try_again_with_new_string); | 2851 __ bind(&try_again_with_new_string); |
2852 // Get the type of the heap object into ecx. | 2852 // Get the type of the heap object into edi. |
2853 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); | 2853 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); |
2854 __ movzx_b(ecx, FieldOperand(edx, Map::kInstanceTypeOffset)); | 2854 __ movzx_b(edi, FieldOperand(edx, Map::kInstanceTypeOffset)); |
2855 // We don't handle non-strings. | 2855 // We don't handle non-strings. |
2856 __ test(ecx, Immediate(kIsNotStringMask)); | 2856 __ test(edi, Immediate(kIsNotStringMask)); |
2857 __ j(not_zero, &slow_case, not_taken); | 2857 __ j(not_zero, &slow_case, not_taken); |
2858 | 2858 |
2859 // The code assumes the tags are serendpitous. | |
Kasper Lund
2008/10/27 08:27:31
Please choose a better word than serendpitous. Pre
| |
2860 ASSERT(kLongStringTag == 0); | |
2861 ASSERT(kMediumStringTag + String::kLongLengthShift == String::kMediumLengthShi ft); | |
Kasper Lund
2008/10/27 08:27:31
Is this line too long?
| |
2862 ASSERT(kShortStringTag + String::kLongLengthShift == String::kShortLengthShift ); | |
Kasper Lund
2008/10/27 08:27:31
Ditto?
| |
2863 __ mov(ecx, Operand(edi)); | |
2864 __ and_(ecx, kStringSizeMask); | |
2865 __ add(Operand(ecx), Immediate(String::kLongLengthShift)); | |
2859 // Get the length field. | 2866 // Get the length field. |
2860 __ mov(edx, FieldOperand(eax, String::kLengthOffset)); | 2867 __ mov(edx, FieldOperand(eax, String::kLengthOffset)); |
2861 Label long_string; | 2868 __ shr(edx); // Ecx is implicit operand. |
Mads Ager (chromium)
2008/10/27 09:37:00
Since Ecx is a register name, I probably would not
| |
2862 Label medium_string; | |
2863 Label string_length_shifted; | |
2864 // The code assumes the tags are disjoint. | |
2865 ASSERT((kLongStringTag & kMediumStringTag) == 0); | |
2866 ASSERT(kShortStringTag == 0); | |
2867 __ test(ecx, Immediate(kLongStringTag)); | |
2868 __ j(not_zero, &long_string, not_taken); | |
2869 __ test(ecx, Immediate(kMediumStringTag)); | |
2870 __ j(not_zero, &medium_string, taken); | |
2871 // Short string. | |
2872 __ shr(edx, String::kShortLengthShift); | |
2873 __ jmp(&string_length_shifted); | |
2874 | |
2875 // Medium string. | |
2876 __ bind(&medium_string); | |
2877 __ shr(edx, String::kMediumLengthShift - String::kLongLengthShift); | |
2878 // Fall through to long string. | |
2879 __ bind(&long_string); | |
2880 __ shr(edx, String::kLongLengthShift); | |
2881 | |
2882 __ bind(&string_length_shifted); | |
2883 ASSERT(kSmiTag == 0); | |
2884 // edx is now the length of the string. | 2869 // edx is now the length of the string. |
2885 | 2870 |
2886 // Check for index out of range. | 2871 // Check for index out of range. |
2887 __ cmp(ebx, Operand(edx)); | 2872 __ cmp(ebx, Operand(edx)); |
2888 __ j(greater_equal, &slow_case, not_taken); | 2873 __ j(greater_equal, &slow_case, not_taken); |
2889 | 2874 |
2890 // We need special handling for non-flat strings. | 2875 // We need special handling for non-flat strings. |
2891 ASSERT(kSeqStringTag == 0); | 2876 ASSERT(kSeqStringTag == 0); |
2892 __ test(ecx, Immediate(kStringRepresentationMask)); | 2877 __ test(edi, Immediate(kStringRepresentationMask)); |
2893 __ j(not_zero, ¬_a_flat_string, not_taken); | 2878 __ j(not_zero, ¬_a_flat_string, not_taken); |
2894 | 2879 |
2895 // Check for 1-byte or 2-byte string. | 2880 // Check for 1-byte or 2-byte string. |
2896 __ test(ecx, Immediate(kStringEncodingMask)); | 2881 __ test(edi, Immediate(kStringEncodingMask)); |
2897 __ j(not_zero, &ascii_string, taken); | 2882 __ j(not_zero, &ascii_string, taken); |
2898 | 2883 |
2899 // 2-byte string. | 2884 // 2-byte string. |
2900 // Load the 2-byte character code. | 2885 // Load the 2-byte character code. |
2901 __ movzx_w(eax, | 2886 __ movzx_w(eax, |
2902 FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); | 2887 FieldOperand(eax, ebx, times_2, SeqTwoByteString::kHeaderSize)); |
2903 __ jmp(&got_char_code); | 2888 __ jmp(&got_char_code); |
2904 | 2889 |
2905 // ASCII string. | 2890 // ASCII string. |
2906 __ bind(&ascii_string); | 2891 __ bind(&ascii_string); |
2907 // Load the byte. | 2892 // Load the byte. |
2908 __ movzx_b(eax, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); | 2893 __ movzx_b(eax, FieldOperand(eax, ebx, times_1, SeqAsciiString::kHeaderSize)); |
2909 | 2894 |
2910 __ bind(&got_char_code); | 2895 __ bind(&got_char_code); |
2911 ASSERT(kSmiTag == 0); | 2896 ASSERT(kSmiTag == 0); |
2912 __ shl(eax, kSmiTagSize); | 2897 __ shl(eax, kSmiTagSize); |
2913 frame_->Push(eax); | 2898 frame_->Push(eax); |
2914 __ jmp(&end); | 2899 __ jmp(&end); |
2915 | 2900 |
2916 | |
2917 // Handle non-flat strings. | 2901 // Handle non-flat strings. |
2918 __ bind(¬_a_flat_string); | 2902 __ bind(¬_a_flat_string); |
2919 __ and_(ecx, kStringRepresentationMask); | 2903 __ and_(edi, kStringRepresentationMask); |
2920 __ cmp(ecx, kConsStringTag); | 2904 __ cmp(edi, kConsStringTag); |
2921 __ j(not_equal, ¬_a_cons_string_either, not_taken); | 2905 __ j(not_equal, ¬_a_cons_string_either, not_taken); |
2922 | 2906 |
2923 // ConsString. | 2907 // ConsString. |
2924 // Get the first of the two strings. | 2908 // Get the first of the two strings. |
2925 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); | 2909 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); |
2926 __ jmp(&try_again_with_new_string); | 2910 __ jmp(&try_again_with_new_string); |
2927 | 2911 |
2928 __ bind(¬_a_cons_string_either); | 2912 __ bind(¬_a_cons_string_either); |
2929 __ cmp(ecx, kSlicedStringTag); | 2913 __ cmp(edi, kSlicedStringTag); |
2930 __ j(not_equal, &slow_case, not_taken); | 2914 __ j(not_equal, &slow_case, not_taken); |
2931 | 2915 |
2932 // SlicedString. | 2916 // SlicedString. |
2933 // Add the offset to the index. | 2917 // Add the offset to the index. |
2934 __ add(ebx, FieldOperand(eax, SlicedString::kStartOffset)); | 2918 __ add(ebx, FieldOperand(eax, SlicedString::kStartOffset)); |
2935 __ j(overflow, &slow_case); | 2919 __ j(overflow, &slow_case); |
2936 // Get the underlying string. | 2920 // Get the underlying string. |
2937 __ mov(eax, FieldOperand(eax, SlicedString::kBufferOffset)); | 2921 __ mov(eax, FieldOperand(eax, SlicedString::kBufferOffset)); |
2938 __ jmp(&try_again_with_new_string); | 2922 __ jmp(&try_again_with_new_string); |
2939 | 2923 |
(...skipping 2173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5113 | 5097 |
5114 // Slow-case: Go through the JavaScript implementation. | 5098 // Slow-case: Go through the JavaScript implementation. |
5115 __ bind(&slow); | 5099 __ bind(&slow); |
5116 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); | 5100 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); |
5117 } | 5101 } |
5118 | 5102 |
5119 | 5103 |
5120 #undef __ | 5104 #undef __ |
5121 | 5105 |
5122 } } // namespace v8::internal | 5106 } } // namespace v8::internal |
OLD | NEW |