Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(595)

Side by Side Diff: src/codegen-ia32.cc

Issue 8187: Serendipitously arrange the tags so that String.length() becomes a branch-fre... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 12 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/builtins.cc ('k') | src/ic.h » ('j') | src/objects.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, &not_a_flat_string, not_taken); 2878 __ j(not_zero, &not_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(&not_a_flat_string); 2902 __ bind(&not_a_flat_string);
2919 __ and_(ecx, kStringRepresentationMask); 2903 __ and_(edi, kStringRepresentationMask);
2920 __ cmp(ecx, kConsStringTag); 2904 __ cmp(edi, kConsStringTag);
2921 __ j(not_equal, &not_a_cons_string_either, not_taken); 2905 __ j(not_equal, &not_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(&not_a_cons_string_either); 2912 __ bind(&not_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
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
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | src/ic.h » ('j') | src/objects.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698