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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 1927003003: Version 5.0.71.40 (cherry-pick) (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@5.0
Patch Set: Created 4 years, 7 months 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
« no previous file with comments | « src/arm64/code-stubs-arm64.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/code-stubs.h" 9 #include "src/code-stubs.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 780 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1); 791 STATIC_ASSERT(kSmiTagSize + kSmiShiftSize == 1);
792 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2); 792 STATIC_ASSERT(Isolate::kJSRegexpStaticOffsetsVectorSize >= 2);
793 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2); 793 __ cmp(edx, Isolate::kJSRegexpStaticOffsetsVectorSize - 2);
794 __ j(above, &runtime); 794 __ j(above, &runtime);
795 795
796 // Reset offset for possibly sliced string. 796 // Reset offset for possibly sliced string.
797 __ Move(edi, Immediate(0)); 797 __ Move(edi, Immediate(0));
798 __ mov(eax, Operand(esp, kSubjectOffset)); 798 __ mov(eax, Operand(esp, kSubjectOffset));
799 __ JumpIfSmi(eax, &runtime); 799 __ JumpIfSmi(eax, &runtime);
800 __ mov(edx, eax); // Make a copy of the original subject string. 800 __ mov(edx, eax); // Make a copy of the original subject string.
801 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
802 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
803 801
804 // eax: subject string 802 // eax: subject string
805 // edx: subject string 803 // edx: subject string
806 // ebx: subject string instance type
807 // ecx: RegExp data (FixedArray) 804 // ecx: RegExp data (FixedArray)
808 // Handle subject string according to its encoding and representation: 805 // Handle subject string according to its encoding and representation:
809 // (1) Sequential two byte? If yes, go to (9). 806 // (1) Sequential two byte? If yes, go to (9).
810 // (2) Sequential one byte? If yes, go to (6). 807 // (2) Sequential one byte? If yes, go to (5).
811 // (3) Anything but sequential or cons? If yes, go to (7). 808 // (3) Sequential or cons? If not, go to (6).
812 // (4) Cons string. If the string is flat, replace subject with first string. 809 // (4) Cons string. If the string is flat, replace subject with first string
813 // Otherwise bailout. 810 // and go to (1). Otherwise bail out to runtime.
814 // (5a) Is subject sequential two byte? If yes, go to (9). 811 // (5) One byte sequential. Load regexp code for one byte.
815 // (5b) Is subject external? If yes, go to (8).
816 // (6) One byte sequential. Load regexp code for one byte.
817 // (E) Carry on. 812 // (E) Carry on.
818 /// [...] 813 /// [...]
819 814
820 // Deferred code at the end of the stub: 815 // Deferred code at the end of the stub:
821 // (7) Not a long external string? If yes, go to (10). 816 // (6) Long external string? If not, go to (10).
822 // (8) External string. Make it, offset-wise, look like a sequential string. 817 // (7) External string. Make it, offset-wise, look like a sequential string.
823 // (8a) Is the external string one byte? If yes, go to (6). 818 // (8) Is the external string one byte? If yes, go to (5).
824 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 819 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
825 // (10) Short external string or not a string? If yes, bail out to runtime. 820 // (10) Short external string or not a string? If yes, bail out to runtime.
826 // (11) Sliced string. Replace subject with parent. Go to (5a). 821 // (11) Sliced string. Replace subject with parent. Go to (1).
827 822
828 Label seq_one_byte_string /* 6 */, seq_two_byte_string /* 9 */, 823 Label seq_one_byte_string /* 5 */, seq_two_byte_string /* 9 */,
829 external_string /* 8 */, check_underlying /* 5a */, 824 external_string /* 7 */, check_underlying /* 1 */,
830 not_seq_nor_cons /* 7 */, check_code /* E */, 825 not_seq_nor_cons /* 6 */, check_code /* E */, not_long_external /* 10 */;
831 not_long_external /* 10 */;
832 826
827 __ bind(&check_underlying);
833 // (1) Sequential two byte? If yes, go to (9). 828 // (1) Sequential two byte? If yes, go to (9).
829 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
830 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
831
834 __ and_(ebx, kIsNotStringMask | 832 __ and_(ebx, kIsNotStringMask |
835 kStringRepresentationMask | 833 kStringRepresentationMask |
836 kStringEncodingMask | 834 kStringEncodingMask |
837 kShortExternalStringMask); 835 kShortExternalStringMask);
838 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0); 836 STATIC_ASSERT((kStringTag | kSeqStringTag | kTwoByteStringTag) == 0);
839 __ j(zero, &seq_two_byte_string); // Go to (9). 837 __ j(zero, &seq_two_byte_string); // Go to (9).
840 838
841 // (2) Sequential one byte? If yes, go to (6). 839 // (2) Sequential one byte? If yes, go to (5).
842 // Any other sequential string must be one byte. 840 // Any other sequential string must be one byte.
843 __ and_(ebx, Immediate(kIsNotStringMask | 841 __ and_(ebx, Immediate(kIsNotStringMask |
844 kStringRepresentationMask | 842 kStringRepresentationMask |
845 kShortExternalStringMask)); 843 kShortExternalStringMask));
846 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (6). 844 __ j(zero, &seq_one_byte_string, Label::kNear); // Go to (5).
847 845
848 // (3) Anything but sequential or cons? If yes, go to (7). 846 // (3) Sequential or cons? If not, go to (6).
849 // We check whether the subject string is a cons, since sequential strings 847 // We check whether the subject string is a cons, since sequential strings
850 // have already been covered. 848 // have already been covered.
851 STATIC_ASSERT(kConsStringTag < kExternalStringTag); 849 STATIC_ASSERT(kConsStringTag < kExternalStringTag);
852 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); 850 STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
853 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); 851 STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
854 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); 852 STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
855 __ cmp(ebx, Immediate(kExternalStringTag)); 853 __ cmp(ebx, Immediate(kExternalStringTag));
856 __ j(greater_equal, &not_seq_nor_cons); // Go to (7). 854 __ j(greater_equal, &not_seq_nor_cons); // Go to (6).
857 855
858 // (4) Cons string. Check that it's flat. 856 // (4) Cons string. Check that it's flat.
859 // Replace subject with first string and reload instance type. 857 // Replace subject with first string and reload instance type.
860 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string()); 858 __ cmp(FieldOperand(eax, ConsString::kSecondOffset), factory->empty_string());
861 __ j(not_equal, &runtime); 859 __ j(not_equal, &runtime);
862 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset)); 860 __ mov(eax, FieldOperand(eax, ConsString::kFirstOffset));
863 __ bind(&check_underlying); 861 __ jmp(&check_underlying);
864 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
865 __ mov(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
866
867 // (5a) Is subject sequential two byte? If yes, go to (9).
868 __ test_b(ebx, kStringRepresentationMask | kStringEncodingMask);
869 STATIC_ASSERT((kSeqStringTag | kTwoByteStringTag) == 0);
870 __ j(zero, &seq_two_byte_string); // Go to (9).
871 // (5b) Is subject external? If yes, go to (8).
872 __ test_b(ebx, kStringRepresentationMask);
873 // The underlying external string is never a short external string.
874 STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
875 STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
876 __ j(not_zero, &external_string); // Go to (8).
877 862
878 // eax: sequential subject string (or look-alike, external string) 863 // eax: sequential subject string (or look-alike, external string)
879 // edx: original subject string 864 // edx: original subject string
880 // ecx: RegExp data (FixedArray) 865 // ecx: RegExp data (FixedArray)
881 // (6) One byte sequential. Load regexp code for one byte. 866 // (5) One byte sequential. Load regexp code for one byte.
882 __ bind(&seq_one_byte_string); 867 __ bind(&seq_one_byte_string);
883 // Load previous index and check range before edx is overwritten. We have 868 // Load previous index and check range before edx is overwritten. We have
884 // to use edx instead of eax here because it might have been only made to 869 // to use edx instead of eax here because it might have been only made to
885 // look like a sequential string when it actually is an external string. 870 // look like a sequential string when it actually is an external string.
886 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 871 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
887 __ JumpIfNotSmi(ebx, &runtime); 872 __ JumpIfNotSmi(ebx, &runtime);
888 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 873 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
889 __ j(above_equal, &runtime); 874 __ j(above_equal, &runtime);
890 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataOneByteCodeOffset)); 875 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataOneByteCodeOffset));
891 __ Move(ecx, Immediate(1)); // Type is one byte. 876 __ Move(ecx, Immediate(1)); // Type is one byte.
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 1083
1099 // Return last match info. 1084 // Return last match info.
1100 __ mov(eax, Operand(esp, kLastMatchInfoOffset)); 1085 __ mov(eax, Operand(esp, kLastMatchInfoOffset));
1101 __ ret(4 * kPointerSize); 1086 __ ret(4 * kPointerSize);
1102 1087
1103 // Do the runtime call to execute the regexp. 1088 // Do the runtime call to execute the regexp.
1104 __ bind(&runtime); 1089 __ bind(&runtime);
1105 __ TailCallRuntime(Runtime::kRegExpExec); 1090 __ TailCallRuntime(Runtime::kRegExpExec);
1106 1091
1107 // Deferred code for string handling. 1092 // Deferred code for string handling.
1108 // (7) Not a long external string? If yes, go to (10). 1093 // (6) Long external string? If not, go to (10).
1109 __ bind(&not_seq_nor_cons); 1094 __ bind(&not_seq_nor_cons);
1110 // Compare flags are still set from (3). 1095 // Compare flags are still set from (3).
1111 __ j(greater, &not_long_external, Label::kNear); // Go to (10). 1096 __ j(greater, &not_long_external, Label::kNear); // Go to (10).
1112 1097
1113 // (8) External string. Short external strings have been ruled out. 1098 // (7) External string. Short external strings have been ruled out.
1114 __ bind(&external_string); 1099 __ bind(&external_string);
1115 // Reload instance type. 1100 // Reload instance type.
1116 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset)); 1101 __ mov(ebx, FieldOperand(eax, HeapObject::kMapOffset));
1117 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); 1102 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
1118 if (FLAG_debug_code) { 1103 if (FLAG_debug_code) {
1119 // Assert that we do not have a cons or slice (indirect strings) here. 1104 // Assert that we do not have a cons or slice (indirect strings) here.
1120 // Sequential strings have already been ruled out. 1105 // Sequential strings have already been ruled out.
1121 __ test_b(ebx, kIsIndirectStringMask); 1106 __ test_b(ebx, kIsIndirectStringMask);
1122 __ Assert(zero, kExternalStringExpectedButNotFound); 1107 __ Assert(zero, kExternalStringExpectedButNotFound);
1123 } 1108 }
1124 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset)); 1109 __ mov(eax, FieldOperand(eax, ExternalString::kResourceDataOffset));
1125 // Move the pointer so that offset-wise, it looks like a sequential string. 1110 // Move the pointer so that offset-wise, it looks like a sequential string.
1126 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); 1111 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
1127 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); 1112 __ sub(eax, Immediate(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
1128 STATIC_ASSERT(kTwoByteStringTag == 0); 1113 STATIC_ASSERT(kTwoByteStringTag == 0);
1129 // (8a) Is the external string one byte? If yes, go to (6). 1114 // (8) Is the external string one byte? If yes, go to (5).
1130 __ test_b(ebx, kStringEncodingMask); 1115 __ test_b(ebx, kStringEncodingMask);
1131 __ j(not_zero, &seq_one_byte_string); // Goto (6). 1116 __ j(not_zero, &seq_one_byte_string); // Go to (5).
1132 1117
1133 // eax: sequential subject string (or look-alike, external string) 1118 // eax: sequential subject string (or look-alike, external string)
1134 // edx: original subject string 1119 // edx: original subject string
1135 // ecx: RegExp data (FixedArray) 1120 // ecx: RegExp data (FixedArray)
1136 // (9) Two byte sequential. Load regexp code for one byte. Go to (E). 1121 // (9) Two byte sequential. Load regexp code for two byte. Go to (E).
1137 __ bind(&seq_two_byte_string); 1122 __ bind(&seq_two_byte_string);
1138 // Load previous index and check range before edx is overwritten. We have 1123 // Load previous index and check range before edx is overwritten. We have
1139 // to use edx instead of eax here because it might have been only made to 1124 // to use edx instead of eax here because it might have been only made to
1140 // look like a sequential string when it actually is an external string. 1125 // look like a sequential string when it actually is an external string.
1141 __ mov(ebx, Operand(esp, kPreviousIndexOffset)); 1126 __ mov(ebx, Operand(esp, kPreviousIndexOffset));
1142 __ JumpIfNotSmi(ebx, &runtime); 1127 __ JumpIfNotSmi(ebx, &runtime);
1143 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset)); 1128 __ cmp(ebx, FieldOperand(edx, String::kLengthOffset));
1144 __ j(above_equal, &runtime); 1129 __ j(above_equal, &runtime);
1145 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset)); 1130 __ mov(edx, FieldOperand(ecx, JSRegExp::kDataUC16CodeOffset));
1146 __ Move(ecx, Immediate(0)); // Type is two byte. 1131 __ Move(ecx, Immediate(0)); // Type is two byte.
1147 __ jmp(&check_code); // Go to (E). 1132 __ jmp(&check_code); // Go to (E).
1148 1133
1149 // (10) Not a string or a short external string? If yes, bail out to runtime. 1134 // (10) Not a string or a short external string? If yes, bail out to runtime.
1150 __ bind(&not_long_external); 1135 __ bind(&not_long_external);
1151 // Catch non-string subject or short external string. 1136 // Catch non-string subject or short external string.
1152 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); 1137 STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0);
1153 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag)); 1138 __ test(ebx, Immediate(kIsNotStringMask | kShortExternalStringTag));
1154 __ j(not_zero, &runtime); 1139 __ j(not_zero, &runtime);
1155 1140
1156 // (11) Sliced string. Replace subject with parent. Go to (5a). 1141 // (11) Sliced string. Replace subject with parent. Go to (1).
1157 // Load offset into edi and replace subject string with parent. 1142 // Load offset into edi and replace subject string with parent.
1158 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset)); 1143 __ mov(edi, FieldOperand(eax, SlicedString::kOffsetOffset));
1159 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset)); 1144 __ mov(eax, FieldOperand(eax, SlicedString::kParentOffset));
1160 __ jmp(&check_underlying); // Go to (5a). 1145 __ jmp(&check_underlying); // Go to (1).
1161 #endif // V8_INTERPRETED_REGEXP 1146 #endif // V8_INTERPRETED_REGEXP
1162 } 1147 }
1163 1148
1164 1149
1165 static int NegativeComparisonResult(Condition cc) { 1150 static int NegativeComparisonResult(Condition cc) {
1166 DCHECK(cc != equal); 1151 DCHECK(cc != equal);
1167 DCHECK((cc == less) || (cc == less_equal) 1152 DCHECK((cc == less) || (cc == less_equal)
1168 || (cc == greater) || (cc == greater_equal)); 1153 || (cc == greater) || (cc == greater_equal));
1169 return (cc == greater || cc == greater_equal) ? LESS : GREATER; 1154 return (cc == greater || cc == greater_equal) ? LESS : GREATER;
1170 } 1155 }
(...skipping 4751 matching lines...) Expand 10 before | Expand all | Expand 10 after
5922 return_value_operand, NULL); 5907 return_value_operand, NULL);
5923 } 5908 }
5924 5909
5925 5910
5926 #undef __ 5911 #undef __
5927 5912
5928 } // namespace internal 5913 } // namespace internal
5929 } // namespace v8 5914 } // namespace v8
5930 5915
5931 #endif // V8_TARGET_ARCH_IA32 5916 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm64/code-stubs-arm64.cc ('k') | src/mips/code-stubs-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698