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

Side by Side Diff: src/stub-cache-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
« src/objects.h ('K') | « src/stub-cache.cc ('k') | no next file » | no next file with comments »
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 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 152 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
153 __ cmp(scratch, JS_ARRAY_TYPE); 153 __ cmp(scratch, JS_ARRAY_TYPE);
154 __ j(not_equal, miss_label, not_taken); 154 __ j(not_equal, miss_label, not_taken);
155 155
156 // Load length directly from the JS array. 156 // Load length directly from the JS array.
157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); 157 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset));
158 __ ret(0); 158 __ ret(0);
159 } 159 }
160 160
161 161
162 void StubCompiler::GenerateLoadShortStringLength(MacroAssembler* masm, 162 void StubCompiler::GenerateLoadStringLength(MacroAssembler* masm,
163 Register receiver, 163 Register receiver,
164 Register scratch, 164 Register scratch,
165 Label* miss_label) { 165 Label* miss_label) {
166 // Check that the receiver isn't a smi. 166 // Check that the receiver isn't a smi.
167 __ test(receiver, Immediate(kSmiTagMask)); 167 __ test(receiver, Immediate(kSmiTagMask));
168 __ j(zero, miss_label, not_taken); 168 __ j(zero, miss_label, not_taken);
169 169
170 // Check that the object is a short string. 170 // Check that the object is a string.
171 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 171 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
172 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 172 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
173 __ and_(scratch, kIsNotStringMask | kStringSizeMask); 173 ASSERT(kNotStringTag != 0);
174 __ cmp(scratch, kStringTag | kShortStringTag); 174 __ test(scratch, Immediate(kNotStringTag));
175 __ j(not_equal, miss_label, not_taken); 175 __ j(not_zero, miss_label, not_taken);
176
177 __ and_(scratch, kStringSizeMask);
176 178
177 // Load length directly from the string. 179 // Load length directly from the string.
178 __ mov(eax, FieldOperand(receiver, String::kLengthOffset)); 180 __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
179 __ shr(eax, String::kShortLengthShift); 181
182 // Ecx is also the receiver.
Mads Ager (chromium) 2008/10/27 09:37:00 Ecx -> ecx since it is a register name?
183 __ lea(ecx, Operand(scratch, String::kLongLengthShift));
184 __ shr(eax); // Ecx is implicit shift register.
Mads Ager (chromium) 2008/10/27 09:37:00 Ditto?
180 __ shl(eax, kSmiTagSize); 185 __ shl(eax, kSmiTagSize);
181 __ ret(0); 186 __ ret(0);
182 } 187 }
183
184 void StubCompiler::GenerateLoadMediumStringLength(MacroAssembler* masm,
185 Register receiver,
186 Register scratch,
187 Label* miss_label) {
188 // Check that the receiver isn't a smi.
189 __ test(receiver, Immediate(kSmiTagMask));
190 __ j(zero, miss_label, not_taken);
191
192 // Check that the object is a short string.
193 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
194 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
195 __ and_(scratch, kIsNotStringMask | kStringSizeMask);
196 __ cmp(scratch, kStringTag | kMediumStringTag);
197 __ j(not_equal, miss_label, not_taken);
198
199 // Load length directly from the string.
200 __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
201 __ shr(eax, String::kMediumLengthShift);
202 __ shl(eax, kSmiTagSize);
203 __ ret(0);
204 }
205
206
207 void StubCompiler::GenerateLoadLongStringLength(MacroAssembler* masm,
208 Register receiver,
209 Register scratch,
210 Label* miss_label) {
211 // Check that the receiver isn't a smi.
212 __ test(receiver, Immediate(kSmiTagMask));
213 __ j(zero, miss_label, not_taken);
214
215 // Check that the object is a short string.
216 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
217 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
218 __ and_(scratch, kIsNotStringMask | kStringSizeMask);
219 __ cmp(scratch, kStringTag | kLongStringTag);
220 __ j(not_equal, miss_label, not_taken);
221
222 // Load length directly from the string.
223 __ mov(eax, FieldOperand(receiver, String::kLengthOffset));
224 __ shr(eax, String::kLongLengthShift);
225 __ shl(eax, kSmiTagSize);
226 __ ret(0);
227 }
228 188
229 189
230 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm, 190 void StubCompiler::GenerateLoadFunctionPrototype(MacroAssembler* masm,
231 Register receiver, 191 Register receiver,
232 Register scratch1, 192 Register scratch1,
233 Register scratch2, 193 Register scratch2,
234 Label* miss_label) { 194 Label* miss_label) {
235 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 195 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
236 __ mov(eax, Operand(scratch1)); 196 __ mov(eax, Operand(scratch1));
237 __ ret(0); 197 __ ret(0);
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
1146 GenerateLoadArrayLength(masm(), ecx, edx, &miss); 1106 GenerateLoadArrayLength(masm(), ecx, edx, &miss);
1147 __ bind(&miss); 1107 __ bind(&miss);
1148 __ DecrementCounter(&Counters::keyed_load_array_length, 1); 1108 __ DecrementCounter(&Counters::keyed_load_array_length, 1);
1149 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1109 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1150 1110
1151 // Return the generated code. 1111 // Return the generated code.
1152 return GetCode(CALLBACKS); 1112 return GetCode(CALLBACKS);
1153 } 1113 }
1154 1114
1155 1115
1156 Object* KeyedLoadStubCompiler::CompileLoadShortStringLength(String* name) { 1116 Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
1157 // ----------- S t a t e ------------- 1117 // ----------- S t a t e -------------
1158 // -- esp[0] : return address 1118 // -- esp[0] : return address
1159 // -- esp[4] : name 1119 // -- esp[4] : name
1160 // -- esp[8] : receiver 1120 // -- esp[8] : receiver
1161 // ----------------------------------- 1121 // -----------------------------------
1162 HandleScope scope; 1122 HandleScope scope;
1163 Label miss; 1123 Label miss;
1164 1124
1165 __ mov(eax, (Operand(esp, kPointerSize))); 1125 __ mov(eax, (Operand(esp, kPointerSize)));
1166 __ mov(ecx, (Operand(esp, 2 * kPointerSize))); 1126 __ mov(ecx, (Operand(esp, 2 * kPointerSize)));
1167 __ IncrementCounter(&Counters::keyed_load_string_length, 1); 1127 __ IncrementCounter(&Counters::keyed_load_string_length, 1);
1168 1128
1169 // Check that the name has not changed. 1129 // Check that the name has not changed.
1170 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 1130 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
1171 __ j(not_equal, &miss, not_taken); 1131 __ j(not_equal, &miss, not_taken);
1172 1132
1173 GenerateLoadShortStringLength(masm(), ecx, edx, &miss); 1133 GenerateLoadStringLength(masm(), ecx, edx, &miss);
1174 __ bind(&miss); 1134 __ bind(&miss);
1175 __ DecrementCounter(&Counters::keyed_load_string_length, 1); 1135 __ DecrementCounter(&Counters::keyed_load_string_length, 1);
1176 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1136 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1177 1137
1178 // Return the generated code. 1138 // Return the generated code.
1179 return GetCode(CALLBACKS); 1139 return GetCode(CALLBACKS);
1180 } 1140 }
1181 1141
1182 1142
1183 Object* KeyedLoadStubCompiler::CompileLoadMediumStringLength(String* name) {
1184 // ----------- S t a t e -------------
1185 // -- esp[0] : return address
1186 // -- esp[4] : name
1187 // -- esp[8] : receiver
1188 // -----------------------------------
1189 HandleScope scope;
1190 Label miss;
1191
1192 __ mov(eax, (Operand(esp, kPointerSize)));
1193 __ mov(ecx, (Operand(esp, 2 * kPointerSize)));
1194 __ IncrementCounter(&Counters::keyed_load_string_length, 1);
1195
1196 // Check that the name has not changed.
1197 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
1198 __ j(not_equal, &miss, not_taken);
1199
1200 GenerateLoadMediumStringLength(masm(), ecx, edx, &miss);
1201 __ bind(&miss);
1202 __ DecrementCounter(&Counters::keyed_load_string_length, 1);
1203 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1204
1205 // Return the generated code.
1206 return GetCode(CALLBACKS);
1207 }
1208
1209
1210 Object* KeyedLoadStubCompiler::CompileLoadLongStringLength(String* name) {
1211 // ----------- S t a t e -------------
1212 // -- esp[0] : return address
1213 // -- esp[4] : name
1214 // -- esp[8] : receiver
1215 // -----------------------------------
1216 HandleScope scope;
1217 Label miss;
1218
1219 __ mov(eax, (Operand(esp, kPointerSize)));
1220 __ mov(ecx, (Operand(esp, 2 * kPointerSize)));
1221 __ IncrementCounter(&Counters::keyed_load_string_length, 1);
1222
1223 // Check that the name has not changed.
1224 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
1225 __ j(not_equal, &miss, not_taken);
1226
1227 GenerateLoadLongStringLength(masm(), ecx, edx, &miss);
1228 __ bind(&miss);
1229 __ DecrementCounter(&Counters::keyed_load_string_length, 1);
1230 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1231
1232 // Return the generated code.
1233 return GetCode(CALLBACKS);
1234 }
1235
1236
1237 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 1143 Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
1238 // ----------- S t a t e ------------- 1144 // ----------- S t a t e -------------
1239 // -- esp[0] : return address 1145 // -- esp[0] : return address
1240 // -- esp[4] : name 1146 // -- esp[4] : name
1241 // -- esp[8] : receiver 1147 // -- esp[8] : receiver
1242 // ----------------------------------- 1148 // -----------------------------------
1243 HandleScope scope; 1149 HandleScope scope;
1244 Label miss; 1150 Label miss;
1245 1151
1246 __ mov(eax, (Operand(esp, kPointerSize))); 1152 __ mov(eax, (Operand(esp, kPointerSize)));
(...skipping 10 matching lines...) Expand all
1257 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 1163 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
1258 1164
1259 // Return the generated code. 1165 // Return the generated code.
1260 return GetCode(CALLBACKS); 1166 return GetCode(CALLBACKS);
1261 } 1167 }
1262 1168
1263 1169
1264 #undef __ 1170 #undef __
1265 1171
1266 } } // namespace v8::internal 1172 } } // namespace v8::internal
OLDNEW
« src/objects.h ('K') | « src/stub-cache.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698