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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 7191007: Cleanup: use JumpIf[Not]Smi() whenever we can (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: introduced new macro Created 9 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/x64/code-stubs-x64.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 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 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 ASSERT(!scratch.is(name)); 181 ASSERT(!scratch.is(name));
182 ASSERT(!extra.is(receiver)); 182 ASSERT(!extra.is(receiver));
183 ASSERT(!extra.is(name)); 183 ASSERT(!extra.is(name));
184 ASSERT(!extra.is(scratch)); 184 ASSERT(!extra.is(scratch));
185 185
186 // Check scratch and extra registers are valid, and extra2 is unused. 186 // Check scratch and extra registers are valid, and extra2 is unused.
187 ASSERT(!scratch.is(no_reg)); 187 ASSERT(!scratch.is(no_reg));
188 ASSERT(extra2.is(no_reg)); 188 ASSERT(extra2.is(no_reg));
189 189
190 // Check that the receiver isn't a smi. 190 // Check that the receiver isn't a smi.
191 __ test(receiver, Immediate(kSmiTagMask)); 191 __ JumpIfSmi(receiver, &miss);
192 __ j(zero, &miss);
193 192
194 // Get the map of the receiver and compute the hash. 193 // Get the map of the receiver and compute the hash.
195 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset)); 194 __ mov(scratch, FieldOperand(name, String::kHashFieldOffset));
196 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 195 __ add(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
197 __ xor_(scratch, flags); 196 __ xor_(scratch, flags);
198 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize); 197 __ and_(scratch, (kPrimaryTableSize - 1) << kHeapObjectTagSize);
199 198
200 // Probe the primary table. 199 // Probe the primary table.
201 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra); 200 ProbeTable(isolate, masm, flags, kPrimary, name, scratch, extra);
202 201
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 // Load the prototype from the initial map. 241 // Load the prototype from the initial map.
243 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 242 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
244 } 243 }
245 244
246 245
247 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 246 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
248 Register receiver, 247 Register receiver,
249 Register scratch, 248 Register scratch,
250 Label* miss_label) { 249 Label* miss_label) {
251 // Check that the receiver isn't a smi. 250 // Check that the receiver isn't a smi.
252 __ test(receiver, Immediate(kSmiTagMask)); 251 __ JumpIfSmi(receiver, miss_label);
253 __ j(zero, miss_label);
254 252
255 // Check that the object is a JS array. 253 // Check that the object is a JS array.
256 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch); 254 __ CmpObjectType(receiver, JS_ARRAY_TYPE, scratch);
257 __ j(not_equal, miss_label); 255 __ j(not_equal, miss_label);
258 256
259 // Load length directly from the JS array. 257 // Load length directly from the JS array.
260 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset)); 258 __ mov(eax, FieldOperand(receiver, JSArray::kLengthOffset));
261 __ ret(0); 259 __ ret(0);
262 } 260 }
263 261
264 262
265 // Generate code to check if an object is a string. If the object is 263 // Generate code to check if an object is a string. If the object is
266 // a string, the map's instance type is left in the scratch register. 264 // a string, the map's instance type is left in the scratch register.
267 static void GenerateStringCheck(MacroAssembler* masm, 265 static void GenerateStringCheck(MacroAssembler* masm,
268 Register receiver, 266 Register receiver,
269 Register scratch, 267 Register scratch,
270 Label* smi, 268 Label* smi,
271 Label* non_string_object) { 269 Label* non_string_object) {
272 // Check that the object isn't a smi. 270 // Check that the object isn't a smi.
273 __ test(receiver, Immediate(kSmiTagMask)); 271 __ JumpIfSmi(receiver, smi);
274 __ j(zero, smi);
275 272
276 // Check that the object is a string. 273 // Check that the object is a string.
277 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset)); 274 __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
278 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset)); 275 __ movzx_b(scratch, FieldOperand(scratch, Map::kInstanceTypeOffset));
279 ASSERT(kNotStringTag != 0); 276 ASSERT(kNotStringTag != 0);
280 __ test(scratch, Immediate(kNotStringTag)); 277 __ test(scratch, Immediate(kNotStringTag));
281 __ j(not_zero, non_string_object); 278 __ j(not_zero, non_string_object);
282 } 279 }
283 280
284 281
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
502 LookupResult* lookup, 499 LookupResult* lookup,
503 Register receiver, 500 Register receiver,
504 Register scratch1, 501 Register scratch1,
505 Register scratch2, 502 Register scratch2,
506 Register scratch3, 503 Register scratch3,
507 Label* miss) { 504 Label* miss) {
508 ASSERT(holder->HasNamedInterceptor()); 505 ASSERT(holder->HasNamedInterceptor());
509 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined()); 506 ASSERT(!holder->GetNamedInterceptor()->getter()->IsUndefined());
510 507
511 // Check that the receiver isn't a smi. 508 // Check that the receiver isn't a smi.
512 __ test(receiver, Immediate(kSmiTagMask)); 509 __ JumpIfSmi(receiver, miss);
513 __ j(zero, miss);
514 510
515 CallOptimization optimization(lookup); 511 CallOptimization optimization(lookup);
516 512
517 if (optimization.is_constant_call()) { 513 if (optimization.is_constant_call()) {
518 return CompileCacheable(masm, 514 return CompileCacheable(masm,
519 object, 515 object,
520 receiver, 516 receiver,
521 scratch1, 517 scratch1,
522 scratch2, 518 scratch2,
523 scratch3, 519 scratch3,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
731 // but may be destroyed if store is successful. 727 // but may be destroyed if store is successful.
732 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 728 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
733 JSObject* object, 729 JSObject* object,
734 int index, 730 int index,
735 Map* transition, 731 Map* transition,
736 Register receiver_reg, 732 Register receiver_reg,
737 Register name_reg, 733 Register name_reg,
738 Register scratch, 734 Register scratch,
739 Label* miss_label) { 735 Label* miss_label) {
740 // Check that the object isn't a smi. 736 // Check that the object isn't a smi.
741 __ test(receiver_reg, Immediate(kSmiTagMask)); 737 __ JumpIfSmi(receiver_reg, miss_label);
742 __ j(zero, miss_label);
743 738
744 // Check that the map of the object hasn't changed. 739 // Check that the map of the object hasn't changed.
745 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), 740 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset),
746 Immediate(Handle<Map>(object->map()))); 741 Immediate(Handle<Map>(object->map())));
747 __ j(not_equal, miss_label); 742 __ j(not_equal, miss_label);
748 743
749 // Perform global security token check if needed. 744 // Perform global security token check if needed.
750 if (object->IsJSGlobalProxy()) { 745 if (object->IsJSGlobalProxy()) {
751 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); 746 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label);
752 } 747 }
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1013 void StubCompiler::GenerateLoadField(JSObject* object, 1008 void StubCompiler::GenerateLoadField(JSObject* object,
1014 JSObject* holder, 1009 JSObject* holder,
1015 Register receiver, 1010 Register receiver,
1016 Register scratch1, 1011 Register scratch1,
1017 Register scratch2, 1012 Register scratch2,
1018 Register scratch3, 1013 Register scratch3,
1019 int index, 1014 int index,
1020 String* name, 1015 String* name,
1021 Label* miss) { 1016 Label* miss) {
1022 // Check that the receiver isn't a smi. 1017 // Check that the receiver isn't a smi.
1023 __ test(receiver, Immediate(kSmiTagMask)); 1018 __ JumpIfSmi(receiver, miss);
1024 __ j(zero, miss);
1025 1019
1026 // Check the prototype chain. 1020 // Check the prototype chain.
1027 Register reg = 1021 Register reg =
1028 CheckPrototypes(object, receiver, holder, 1022 CheckPrototypes(object, receiver, holder,
1029 scratch1, scratch2, scratch3, name, miss); 1023 scratch1, scratch2, scratch3, name, miss);
1030 1024
1031 // Get the value from the properties. 1025 // Get the value from the properties.
1032 GenerateFastPropertyLoad(masm(), eax, reg, holder, index); 1026 GenerateFastPropertyLoad(masm(), eax, reg, holder, index);
1033 __ ret(0); 1027 __ ret(0);
1034 } 1028 }
1035 1029
1036 1030
1037 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, 1031 MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object,
1038 JSObject* holder, 1032 JSObject* holder,
1039 Register receiver, 1033 Register receiver,
1040 Register name_reg, 1034 Register name_reg,
1041 Register scratch1, 1035 Register scratch1,
1042 Register scratch2, 1036 Register scratch2,
1043 Register scratch3, 1037 Register scratch3,
1044 AccessorInfo* callback, 1038 AccessorInfo* callback,
1045 String* name, 1039 String* name,
1046 Label* miss) { 1040 Label* miss) {
1047 // Check that the receiver isn't a smi. 1041 // Check that the receiver isn't a smi.
1048 __ test(receiver, Immediate(kSmiTagMask)); 1042 __ JumpIfSmi(receiver, miss);
1049 __ j(zero, miss);
1050 1043
1051 // Check that the maps haven't changed. 1044 // Check that the maps haven't changed.
1052 Register reg = 1045 Register reg =
1053 CheckPrototypes(object, receiver, holder, scratch1, 1046 CheckPrototypes(object, receiver, holder, scratch1,
1054 scratch2, scratch3, name, miss); 1047 scratch2, scratch3, name, miss);
1055 1048
1056 Handle<AccessorInfo> callback_handle(callback); 1049 Handle<AccessorInfo> callback_handle(callback);
1057 1050
1058 // Insert additional parameters into the stack frame above return address. 1051 // Insert additional parameters into the stack frame above return address.
1059 ASSERT(!scratch3.is(reg)); 1052 ASSERT(!scratch3.is(reg));
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1105 void StubCompiler::GenerateLoadConstant(JSObject* object, 1098 void StubCompiler::GenerateLoadConstant(JSObject* object,
1106 JSObject* holder, 1099 JSObject* holder,
1107 Register receiver, 1100 Register receiver,
1108 Register scratch1, 1101 Register scratch1,
1109 Register scratch2, 1102 Register scratch2,
1110 Register scratch3, 1103 Register scratch3,
1111 Object* value, 1104 Object* value,
1112 String* name, 1105 String* name,
1113 Label* miss) { 1106 Label* miss) {
1114 // Check that the receiver isn't a smi. 1107 // Check that the receiver isn't a smi.
1115 __ test(receiver, Immediate(kSmiTagMask)); 1108 __ JumpIfSmi(receiver, miss);
1116 __ j(zero, miss);
1117 1109
1118 // Check that the maps haven't changed. 1110 // Check that the maps haven't changed.
1119 CheckPrototypes(object, receiver, holder, 1111 CheckPrototypes(object, receiver, holder,
1120 scratch1, scratch2, scratch3, name, miss); 1112 scratch1, scratch2, scratch3, name, miss);
1121 1113
1122 // Return the constant value. 1114 // Return the constant value.
1123 __ mov(eax, Handle<Object>(value)); 1115 __ mov(eax, Handle<Object>(value));
1124 __ ret(0); 1116 __ ret(0);
1125 } 1117 }
1126 1118
1127 1119
1128 void StubCompiler::GenerateLoadInterceptor(JSObject* object, 1120 void StubCompiler::GenerateLoadInterceptor(JSObject* object,
1129 JSObject* interceptor_holder, 1121 JSObject* interceptor_holder,
1130 LookupResult* lookup, 1122 LookupResult* lookup,
1131 Register receiver, 1123 Register receiver,
1132 Register name_reg, 1124 Register name_reg,
1133 Register scratch1, 1125 Register scratch1,
1134 Register scratch2, 1126 Register scratch2,
1135 Register scratch3, 1127 Register scratch3,
1136 String* name, 1128 String* name,
1137 Label* miss) { 1129 Label* miss) {
1138 ASSERT(interceptor_holder->HasNamedInterceptor()); 1130 ASSERT(interceptor_holder->HasNamedInterceptor());
1139 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined()); 1131 ASSERT(!interceptor_holder->GetNamedInterceptor()->getter()->IsUndefined());
1140 1132
1141 // Check that the receiver isn't a smi. 1133 // Check that the receiver isn't a smi.
1142 __ test(receiver, Immediate(kSmiTagMask)); 1134 __ JumpIfSmi(receiver, miss);
1143 __ j(zero, miss);
1144 1135
1145 // So far the most popular follow ups for interceptor loads are FIELD 1136 // So far the most popular follow ups for interceptor loads are FIELD
1146 // and CALLBACKS, so inline only them, other cases may be added 1137 // and CALLBACKS, so inline only them, other cases may be added
1147 // later. 1138 // later.
1148 bool compile_followup_inline = false; 1139 bool compile_followup_inline = false;
1149 if (lookup->IsProperty() && lookup->IsCacheable()) { 1140 if (lookup->IsProperty() && lookup->IsCacheable()) {
1150 if (lookup->type() == FIELD) { 1141 if (lookup->type() == FIELD) {
1151 compile_followup_inline = true; 1142 compile_followup_inline = true;
1152 } else if (lookup->type() == CALLBACKS && 1143 } else if (lookup->type() == CALLBACKS &&
1153 lookup->GetCallbackObject()->IsAccessorInfo() && 1144 lookup->GetCallbackObject()->IsAccessorInfo() &&
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 // Get the number of arguments. 1274 // Get the number of arguments.
1284 const int argc = arguments().immediate(); 1275 const int argc = arguments().immediate();
1285 1276
1286 // Get the receiver from the stack. 1277 // Get the receiver from the stack.
1287 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1278 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1288 1279
1289 // If the object is the holder then we know that it's a global 1280 // If the object is the holder then we know that it's a global
1290 // object which can only happen for contextual calls. In this case, 1281 // object which can only happen for contextual calls. In this case,
1291 // the receiver cannot be a smi. 1282 // the receiver cannot be a smi.
1292 if (object != holder) { 1283 if (object != holder) {
1293 __ test(edx, Immediate(kSmiTagMask)); 1284 __ JumpIfSmi(edx, miss);
1294 __ j(zero, miss);
1295 } 1285 }
1296 1286
1297 // Check that the maps haven't changed. 1287 // Check that the maps haven't changed.
1298 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); 1288 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss);
1299 } 1289 }
1300 1290
1301 1291
1302 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, 1292 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell,
1303 JSFunction* function, 1293 JSFunction* function,
1304 Label* miss) { 1294 Label* miss) {
1305 // Get the value from the cell. 1295 // Get the value from the cell.
1306 if (Serializer::enabled()) { 1296 if (Serializer::enabled()) {
1307 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); 1297 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell)));
1308 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); 1298 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
1309 } else { 1299 } else {
1310 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 1300 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
1311 } 1301 }
1312 1302
1313 // Check that the cell contains the same function. 1303 // Check that the cell contains the same function.
1314 if (isolate()->heap()->InNewSpace(function)) { 1304 if (isolate()->heap()->InNewSpace(function)) {
1315 // We can't embed a pointer to a function in new space so we have 1305 // We can't embed a pointer to a function in new space so we have
1316 // to verify that the shared function info is unchanged. This has 1306 // to verify that the shared function info is unchanged. This has
1317 // the nice side effect that multiple closures based on the same 1307 // the nice side effect that multiple closures based on the same
1318 // function can all use this call IC. Before we load through the 1308 // function can all use this call IC. Before we load through the
1319 // function, we have to verify that it still is a function. 1309 // function, we have to verify that it still is a function.
1320 __ test(edi, Immediate(kSmiTagMask)); 1310 __ JumpIfSmi(edi, miss);
1321 __ j(zero, miss);
1322 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1311 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1323 __ j(not_equal, miss); 1312 __ j(not_equal, miss);
1324 1313
1325 // Check the shared function info. Make sure it hasn't changed. 1314 // Check the shared function info. Make sure it hasn't changed.
1326 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1315 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1327 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1316 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1328 __ j(not_equal, miss); 1317 __ j(not_equal, miss);
1329 } else { 1318 } else {
1330 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1319 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1331 __ j(not_equal, miss); 1320 __ j(not_equal, miss);
(...skipping 27 matching lines...) Expand all
1359 // ----------------------------------- 1348 // -----------------------------------
1360 Label miss; 1349 Label miss;
1361 1350
1362 GenerateNameCheck(name, &miss); 1351 GenerateNameCheck(name, &miss);
1363 1352
1364 // Get the receiver from the stack. 1353 // Get the receiver from the stack.
1365 const int argc = arguments().immediate(); 1354 const int argc = arguments().immediate();
1366 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1355 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1367 1356
1368 // Check that the receiver isn't a smi. 1357 // Check that the receiver isn't a smi.
1369 __ test(edx, Immediate(kSmiTagMask)); 1358 __ JumpIfSmi(edx, &miss);
1370 __ j(zero, &miss);
1371 1359
1372 // Do the right check and compute the holder register. 1360 // Do the right check and compute the holder register.
1373 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi, 1361 Register reg = CheckPrototypes(object, edx, holder, ebx, eax, edi,
1374 name, &miss); 1362 name, &miss);
1375 1363
1376 GenerateFastPropertyLoad(masm(), edi, reg, holder, index); 1364 GenerateFastPropertyLoad(masm(), edi, reg, holder, index);
1377 1365
1378 // Check that the function really is a function. 1366 // Check that the function really is a function.
1379 __ test(edi, Immediate(kSmiTagMask)); 1367 __ JumpIfSmi(edi, &miss);
1380 __ j(zero, &miss);
1381 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1368 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1382 __ j(not_equal, &miss); 1369 __ j(not_equal, &miss);
1383 1370
1384 // Patch the receiver on the stack with the global proxy if 1371 // Patch the receiver on the stack with the global proxy if
1385 // necessary. 1372 // necessary.
1386 if (object->IsGlobalObject()) { 1373 if (object->IsGlobalObject()) {
1387 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 1374 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
1388 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 1375 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
1389 } 1376 }
1390 1377
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1425 1412
1426 Label miss; 1413 Label miss;
1427 1414
1428 GenerateNameCheck(name, &miss); 1415 GenerateNameCheck(name, &miss);
1429 1416
1430 // Get the receiver from the stack. 1417 // Get the receiver from the stack.
1431 const int argc = arguments().immediate(); 1418 const int argc = arguments().immediate();
1432 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1419 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1433 1420
1434 // Check that the receiver isn't a smi. 1421 // Check that the receiver isn't a smi.
1435 __ test(edx, Immediate(kSmiTagMask)); 1422 __ JumpIfSmi(edx, &miss);
1436 __ j(zero, &miss);
1437 1423
1438 CheckPrototypes(JSObject::cast(object), edx, 1424 CheckPrototypes(JSObject::cast(object), edx,
1439 holder, ebx, 1425 holder, ebx,
1440 eax, edi, name, &miss); 1426 eax, edi, name, &miss);
1441 1427
1442 if (argc == 0) { 1428 if (argc == 0) {
1443 // Noop, return the length. 1429 // Noop, return the length.
1444 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset)); 1430 __ mov(eax, FieldOperand(edx, JSArray::kLengthOffset));
1445 __ ret((argc + 1) * kPointerSize); 1431 __ ret((argc + 1) * kPointerSize);
1446 } else { 1432 } else {
(...skipping 27 matching lines...) Expand all
1474 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1460 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1475 1461
1476 // Push the element. 1462 // Push the element.
1477 __ lea(edx, FieldOperand(ebx, 1463 __ lea(edx, FieldOperand(ebx,
1478 eax, times_half_pointer_size, 1464 eax, times_half_pointer_size,
1479 FixedArray::kHeaderSize - argc * kPointerSize)); 1465 FixedArray::kHeaderSize - argc * kPointerSize));
1480 __ mov(ecx, Operand(esp, argc * kPointerSize)); 1466 __ mov(ecx, Operand(esp, argc * kPointerSize));
1481 __ mov(Operand(edx, 0), ecx); 1467 __ mov(Operand(edx, 0), ecx);
1482 1468
1483 // Check if value is a smi. 1469 // Check if value is a smi.
1484 __ test(ecx, Immediate(kSmiTagMask)); 1470 __ JumpIfNotSmi(ecx, &with_write_barrier);
1485 __ j(not_zero, &with_write_barrier);
1486 1471
1487 __ bind(&exit); 1472 __ bind(&exit);
1488 __ ret((argc + 1) * kPointerSize); 1473 __ ret((argc + 1) * kPointerSize);
1489 1474
1490 __ bind(&with_write_barrier); 1475 __ bind(&with_write_barrier);
1491 1476
1492 __ InNewSpace(ebx, ecx, equal, &exit); 1477 __ InNewSpace(ebx, ecx, equal, &exit);
1493 1478
1494 __ RecordWriteHelper(ebx, edx, ecx); 1479 __ RecordWriteHelper(ebx, edx, ecx);
1495 __ ret((argc + 1) * kPointerSize); 1480 __ ret((argc + 1) * kPointerSize);
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 1563
1579 Label miss, return_undefined, call_builtin; 1564 Label miss, return_undefined, call_builtin;
1580 1565
1581 GenerateNameCheck(name, &miss); 1566 GenerateNameCheck(name, &miss);
1582 1567
1583 // Get the receiver from the stack. 1568 // Get the receiver from the stack.
1584 const int argc = arguments().immediate(); 1569 const int argc = arguments().immediate();
1585 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1570 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1586 1571
1587 // Check that the receiver isn't a smi. 1572 // Check that the receiver isn't a smi.
1588 __ test(edx, Immediate(kSmiTagMask)); 1573 __ JumpIfSmi(edx, &miss);
1589 __ j(zero, &miss);
1590 CheckPrototypes(JSObject::cast(object), edx, 1574 CheckPrototypes(JSObject::cast(object), edx,
1591 holder, ebx, 1575 holder, ebx,
1592 eax, edi, name, &miss); 1576 eax, edi, name, &miss);
1593 1577
1594 // Get the elements array of the object. 1578 // Get the elements array of the object.
1595 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset)); 1579 __ mov(ebx, FieldOperand(edx, JSArray::kElementsOffset));
1596 1580
1597 // Check that the elements are in fast mode and writable. 1581 // Check that the elements are in fast mode and writable.
1598 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset), 1582 __ cmp(FieldOperand(ebx, HeapObject::kMapOffset),
1599 Immediate(factory()->fixed_array_map())); 1583 Immediate(factory()->fixed_array_map()));
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 return isolate()->heap()->undefined_value(); 1822 return isolate()->heap()->undefined_value();
1839 } 1823 }
1840 1824
1841 Label miss; 1825 Label miss;
1842 GenerateNameCheck(name, &miss); 1826 GenerateNameCheck(name, &miss);
1843 1827
1844 if (cell == NULL) { 1828 if (cell == NULL) {
1845 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1829 __ mov(edx, Operand(esp, 2 * kPointerSize));
1846 1830
1847 STATIC_ASSERT(kSmiTag == 0); 1831 STATIC_ASSERT(kSmiTag == 0);
1848 __ test(edx, Immediate(kSmiTagMask)); 1832 __ JumpIfSmi(edx, &miss);
1849 __ j(zero, &miss);
1850 1833
1851 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 1834 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1852 &miss); 1835 &miss);
1853 } else { 1836 } else {
1854 ASSERT(cell->value() == function); 1837 ASSERT(cell->value() == function);
1855 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 1838 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
1856 GenerateLoadFunctionFromCell(cell, function, &miss); 1839 GenerateLoadFunctionFromCell(cell, function, &miss);
1857 } 1840 }
1858 1841
1859 // Load the char code argument. 1842 // Load the char code argument.
1860 Register code = ebx; 1843 Register code = ebx;
1861 __ mov(code, Operand(esp, 1 * kPointerSize)); 1844 __ mov(code, Operand(esp, 1 * kPointerSize));
1862 1845
1863 // Check the code is a smi. 1846 // Check the code is a smi.
1864 Label slow; 1847 Label slow;
1865 STATIC_ASSERT(kSmiTag == 0); 1848 STATIC_ASSERT(kSmiTag == 0);
1866 __ test(code, Immediate(kSmiTagMask)); 1849 __ JumpIfNotSmi(code, &slow);
1867 __ j(not_zero, &slow);
1868 1850
1869 // Convert the smi code to uint16. 1851 // Convert the smi code to uint16.
1870 __ and_(code, Immediate(Smi::FromInt(0xffff))); 1852 __ and_(code, Immediate(Smi::FromInt(0xffff)));
1871 1853
1872 StringCharFromCodeGenerator char_from_code_generator(code, eax); 1854 StringCharFromCodeGenerator char_from_code_generator(code, eax);
1873 char_from_code_generator.GenerateFast(masm()); 1855 char_from_code_generator.GenerateFast(masm());
1874 __ ret(2 * kPointerSize); 1856 __ ret(2 * kPointerSize);
1875 1857
1876 StubRuntimeCallHelper call_helper; 1858 StubRuntimeCallHelper call_helper;
1877 char_from_code_generator.GenerateSlow(masm(), call_helper); 1859 char_from_code_generator.GenerateSlow(masm(), call_helper);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1922 return isolate()->heap()->undefined_value(); 1904 return isolate()->heap()->undefined_value();
1923 } 1905 }
1924 1906
1925 Label miss; 1907 Label miss;
1926 GenerateNameCheck(name, &miss); 1908 GenerateNameCheck(name, &miss);
1927 1909
1928 if (cell == NULL) { 1910 if (cell == NULL) {
1929 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1911 __ mov(edx, Operand(esp, 2 * kPointerSize));
1930 1912
1931 STATIC_ASSERT(kSmiTag == 0); 1913 STATIC_ASSERT(kSmiTag == 0);
1932 __ test(edx, Immediate(kSmiTagMask)); 1914 __ JumpIfSmi(edx, &miss);
1933 __ j(zero, &miss);
1934 1915
1935 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 1916 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
1936 &miss); 1917 &miss);
1937 } else { 1918 } else {
1938 ASSERT(cell->value() == function); 1919 ASSERT(cell->value() == function);
1939 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 1920 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
1940 GenerateLoadFunctionFromCell(cell, function, &miss); 1921 GenerateLoadFunctionFromCell(cell, function, &miss);
1941 } 1922 }
1942 1923
1943 // Load the (only) argument into eax. 1924 // Load the (only) argument into eax.
1944 __ mov(eax, Operand(esp, 1 * kPointerSize)); 1925 __ mov(eax, Operand(esp, 1 * kPointerSize));
1945 1926
1946 // Check if the argument is a smi. 1927 // Check if the argument is a smi.
1947 Label smi; 1928 Label smi;
1948 STATIC_ASSERT(kSmiTag == 0); 1929 STATIC_ASSERT(kSmiTag == 0);
1949 __ test(eax, Immediate(kSmiTagMask)); 1930 __ JumpIfSmi(eax, &smi);
1950 __ j(zero, &smi);
1951 1931
1952 // Check if the argument is a heap number and load its value into xmm0. 1932 // Check if the argument is a heap number and load its value into xmm0.
1953 Label slow; 1933 Label slow;
1954 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK); 1934 __ CheckMap(eax, factory()->heap_number_map(), &slow, DONT_DO_SMI_CHECK);
1955 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 1935 __ movdbl(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
1956 1936
1957 // Check if the argument is strictly positive. Note this also 1937 // Check if the argument is strictly positive. Note this also
1958 // discards NaN. 1938 // discards NaN.
1959 __ xorpd(xmm1, xmm1); 1939 __ xorpd(xmm1, xmm1);
1960 __ ucomisd(xmm0, xmm1); 1940 __ ucomisd(xmm0, xmm1);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
2047 return isolate()->heap()->undefined_value(); 2027 return isolate()->heap()->undefined_value();
2048 } 2028 }
2049 2029
2050 Label miss; 2030 Label miss;
2051 GenerateNameCheck(name, &miss); 2031 GenerateNameCheck(name, &miss);
2052 2032
2053 if (cell == NULL) { 2033 if (cell == NULL) {
2054 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2034 __ mov(edx, Operand(esp, 2 * kPointerSize));
2055 2035
2056 STATIC_ASSERT(kSmiTag == 0); 2036 STATIC_ASSERT(kSmiTag == 0);
2057 __ test(edx, Immediate(kSmiTagMask)); 2037 __ JumpIfSmi(edx, &miss);
2058 __ j(zero, &miss);
2059 2038
2060 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, 2039 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name,
2061 &miss); 2040 &miss);
2062 } else { 2041 } else {
2063 ASSERT(cell->value() == function); 2042 ASSERT(cell->value() == function);
2064 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); 2043 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss);
2065 GenerateLoadFunctionFromCell(cell, function, &miss); 2044 GenerateLoadFunctionFromCell(cell, function, &miss);
2066 } 2045 }
2067 2046
2068 // Load the (only) argument into eax. 2047 // Load the (only) argument into eax.
2069 __ mov(eax, Operand(esp, 1 * kPointerSize)); 2048 __ mov(eax, Operand(esp, 1 * kPointerSize));
2070 2049
2071 // Check if the argument is a smi. 2050 // Check if the argument is a smi.
2072 Label not_smi; 2051 Label not_smi;
2073 STATIC_ASSERT(kSmiTag == 0); 2052 STATIC_ASSERT(kSmiTag == 0);
2074 __ test(eax, Immediate(kSmiTagMask)); 2053 __ JumpIfNotSmi(eax, &not_smi);
2075 __ j(not_zero, &not_smi);
2076 2054
2077 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0 2055 // Set ebx to 1...1 (== -1) if the argument is negative, or to 0...0
2078 // otherwise. 2056 // otherwise.
2079 __ mov(ebx, eax); 2057 __ mov(ebx, eax);
2080 __ sar(ebx, kBitsPerInt - 1); 2058 __ sar(ebx, kBitsPerInt - 1);
2081 2059
2082 // Do bitwise not or do nothing depending on ebx. 2060 // Do bitwise not or do nothing depending on ebx.
2083 __ xor_(eax, Operand(ebx)); 2061 __ xor_(eax, Operand(ebx));
2084 2062
2085 // Add 1 or do nothing depending on ebx. 2063 // Add 1 or do nothing depending on ebx.
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2151 2129
2152 Label miss, miss_before_stack_reserved; 2130 Label miss, miss_before_stack_reserved;
2153 2131
2154 GenerateNameCheck(name, &miss_before_stack_reserved); 2132 GenerateNameCheck(name, &miss_before_stack_reserved);
2155 2133
2156 // Get the receiver from the stack. 2134 // Get the receiver from the stack.
2157 const int argc = arguments().immediate(); 2135 const int argc = arguments().immediate();
2158 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2136 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2159 2137
2160 // Check that the receiver isn't a smi. 2138 // Check that the receiver isn't a smi.
2161 __ test(edx, Immediate(kSmiTagMask)); 2139 __ JumpIfSmi(edx, &miss_before_stack_reserved);
2162 __ j(zero, &miss_before_stack_reserved);
2163 2140
2164 Counters* counters = isolate()->counters(); 2141 Counters* counters = isolate()->counters();
2165 __ IncrementCounter(counters->call_const(), 1); 2142 __ IncrementCounter(counters->call_const(), 1);
2166 __ IncrementCounter(counters->call_const_fast_api(), 1); 2143 __ IncrementCounter(counters->call_const_fast_api(), 1);
2167 2144
2168 // Allocate space for v8::Arguments implicit values. Must be initialized 2145 // Allocate space for v8::Arguments implicit values. Must be initialized
2169 // before calling any runtime function. 2146 // before calling any runtime function.
2170 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2147 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2171 2148
2172 // Check that the maps haven't changed and find a Holder as a side effect. 2149 // Check that the maps haven't changed and find a Holder as a side effect.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2220 Label miss; 2197 Label miss;
2221 2198
2222 GenerateNameCheck(name, &miss); 2199 GenerateNameCheck(name, &miss);
2223 2200
2224 // Get the receiver from the stack. 2201 // Get the receiver from the stack.
2225 const int argc = arguments().immediate(); 2202 const int argc = arguments().immediate();
2226 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2203 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2227 2204
2228 // Check that the receiver isn't a smi. 2205 // Check that the receiver isn't a smi.
2229 if (check != NUMBER_CHECK) { 2206 if (check != NUMBER_CHECK) {
2230 __ test(edx, Immediate(kSmiTagMask)); 2207 __ JumpIfSmi(edx, &miss);
2231 __ j(zero, &miss);
2232 } 2208 }
2233 2209
2234 // Make sure that it's okay not to patch the on stack receiver 2210 // Make sure that it's okay not to patch the on stack receiver
2235 // unless we're doing a receiver map check. 2211 // unless we're doing a receiver map check.
2236 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2212 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2237 2213
2238 SharedFunctionInfo* function_info = function->shared(); 2214 SharedFunctionInfo* function_info = function->shared();
2239 switch (check) { 2215 switch (check) {
2240 case RECEIVER_MAP_CHECK: 2216 case RECEIVER_MAP_CHECK:
2241 __ IncrementCounter(isolate()->counters()->call_const(), 1); 2217 __ IncrementCounter(isolate()->counters()->call_const(), 1);
(...skipping 28 matching lines...) Expand all
2270 break; 2246 break;
2271 2247
2272 case NUMBER_CHECK: { 2248 case NUMBER_CHECK: {
2273 if (!function->IsBuiltin() && !function_info->strict_mode()) { 2249 if (!function->IsBuiltin() && !function_info->strict_mode()) {
2274 // Calling non-strict non-builtins with a value as the receiver 2250 // Calling non-strict non-builtins with a value as the receiver
2275 // requires boxing. 2251 // requires boxing.
2276 __ jmp(&miss); 2252 __ jmp(&miss);
2277 } else { 2253 } else {
2278 Label fast; 2254 Label fast;
2279 // Check that the object is a smi or a heap number. 2255 // Check that the object is a smi or a heap number.
2280 __ test(edx, Immediate(kSmiTagMask)); 2256 __ JumpIfSmi(edx, &fast);
2281 __ j(zero, &fast);
2282 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax); 2257 __ CmpObjectType(edx, HEAP_NUMBER_TYPE, eax);
2283 __ j(not_equal, &miss); 2258 __ j(not_equal, &miss);
2284 __ bind(&fast); 2259 __ bind(&fast);
2285 // Check that the maps starting from the prototype haven't changed. 2260 // Check that the maps starting from the prototype haven't changed.
2286 GenerateDirectLoadGlobalFunctionPrototype( 2261 GenerateDirectLoadGlobalFunctionPrototype(
2287 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss); 2262 masm(), Context::NUMBER_FUNCTION_INDEX, eax, &miss);
2288 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder, 2263 CheckPrototypes(JSObject::cast(object->GetPrototype()), eax, holder,
2289 ebx, edx, edi, name, &miss); 2264 ebx, edx, edi, name, &miss);
2290 } 2265 }
2291 break; 2266 break;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2366 ebx, 2341 ebx,
2367 edi, 2342 edi,
2368 eax, 2343 eax,
2369 &miss); 2344 &miss);
2370 if (result->IsFailure()) return result; 2345 if (result->IsFailure()) return result;
2371 2346
2372 // Restore receiver. 2347 // Restore receiver.
2373 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2348 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2374 2349
2375 // Check that the function really is a function. 2350 // Check that the function really is a function.
2376 __ test(eax, Immediate(kSmiTagMask)); 2351 __ JumpIfSmi(eax, &miss);
2377 __ j(zero, &miss);
2378 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx); 2352 __ CmpObjectType(eax, JS_FUNCTION_TYPE, ebx);
2379 __ j(not_equal, &miss); 2353 __ j(not_equal, &miss);
2380 2354
2381 // Patch the receiver on the stack with the global proxy if 2355 // Patch the receiver on the stack with the global proxy if
2382 // necessary. 2356 // necessary.
2383 if (object->IsGlobalObject()) { 2357 if (object->IsGlobalObject()) {
2384 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2358 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2385 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2359 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2386 } 2360 }
2387 2361
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2515 String* name) { 2489 String* name) {
2516 // ----------- S t a t e ------------- 2490 // ----------- S t a t e -------------
2517 // -- eax : value 2491 // -- eax : value
2518 // -- ecx : name 2492 // -- ecx : name
2519 // -- edx : receiver 2493 // -- edx : receiver
2520 // -- esp[0] : return address 2494 // -- esp[0] : return address
2521 // ----------------------------------- 2495 // -----------------------------------
2522 Label miss; 2496 Label miss;
2523 2497
2524 // Check that the object isn't a smi. 2498 // Check that the object isn't a smi.
2525 __ test(edx, Immediate(kSmiTagMask)); 2499 __ JumpIfSmi(edx, &miss);
2526 __ j(zero, &miss);
2527 2500
2528 // Check that the map of the object hasn't changed. 2501 // Check that the map of the object hasn't changed.
2529 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2502 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2530 Immediate(Handle<Map>(object->map()))); 2503 Immediate(Handle<Map>(object->map())));
2531 __ j(not_equal, &miss); 2504 __ j(not_equal, &miss);
2532 2505
2533 // Perform global security token check if needed. 2506 // Perform global security token check if needed.
2534 if (object->IsJSGlobalProxy()) { 2507 if (object->IsJSGlobalProxy()) {
2535 __ CheckAccessGlobalProxy(edx, ebx, &miss); 2508 __ CheckAccessGlobalProxy(edx, ebx, &miss);
2536 } 2509 }
(...skipping 28 matching lines...) Expand all
2565 String* name) { 2538 String* name) {
2566 // ----------- S t a t e ------------- 2539 // ----------- S t a t e -------------
2567 // -- eax : value 2540 // -- eax : value
2568 // -- ecx : name 2541 // -- ecx : name
2569 // -- edx : receiver 2542 // -- edx : receiver
2570 // -- esp[0] : return address 2543 // -- esp[0] : return address
2571 // ----------------------------------- 2544 // -----------------------------------
2572 Label miss; 2545 Label miss;
2573 2546
2574 // Check that the object isn't a smi. 2547 // Check that the object isn't a smi.
2575 __ test(edx, Immediate(kSmiTagMask)); 2548 __ JumpIfSmi(edx, &miss);
2576 __ j(zero, &miss);
2577 2549
2578 // Check that the map of the object hasn't changed. 2550 // Check that the map of the object hasn't changed.
2579 __ cmp(FieldOperand(edx, HeapObject::kMapOffset), 2551 __ cmp(FieldOperand(edx, HeapObject::kMapOffset),
2580 Immediate(Handle<Map>(receiver->map()))); 2552 Immediate(Handle<Map>(receiver->map())));
2581 __ j(not_equal, &miss); 2553 __ j(not_equal, &miss);
2582 2554
2583 // Perform global security token check if needed. 2555 // Perform global security token check if needed.
2584 if (receiver->IsJSGlobalProxy()) { 2556 if (receiver->IsJSGlobalProxy()) {
2585 __ CheckAccessGlobalProxy(edx, ebx, &miss); 2557 __ CheckAccessGlobalProxy(edx, ebx, &miss);
2586 } 2558 }
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
2755 JSObject* object, 2727 JSObject* object,
2756 JSObject* last) { 2728 JSObject* last) {
2757 // ----------- S t a t e ------------- 2729 // ----------- S t a t e -------------
2758 // -- eax : receiver 2730 // -- eax : receiver
2759 // -- ecx : name 2731 // -- ecx : name
2760 // -- esp[0] : return address 2732 // -- esp[0] : return address
2761 // ----------------------------------- 2733 // -----------------------------------
2762 Label miss; 2734 Label miss;
2763 2735
2764 // Check that the receiver isn't a smi. 2736 // Check that the receiver isn't a smi.
2765 __ test(eax, Immediate(kSmiTagMask)); 2737 __ JumpIfSmi(eax, &miss);
2766 __ j(zero, &miss);
2767 2738
2768 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); 2739 ASSERT(last->IsGlobalObject() || last->HasFastProperties());
2769 2740
2770 // Check the maps of the full prototype chain. Also check that 2741 // Check the maps of the full prototype chain. Also check that
2771 // global property cells up to (but not including) the last object 2742 // global property cells up to (but not including) the last object
2772 // in the prototype chain are empty. 2743 // in the prototype chain are empty.
2773 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); 2744 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss);
2774 2745
2775 // If the last object in the prototype chain is a global object, 2746 // If the last object in the prototype chain is a global object,
2776 // check that the global property cell is empty. 2747 // check that the global property cell is empty.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
2908 // -- eax : receiver 2879 // -- eax : receiver
2909 // -- ecx : name 2880 // -- ecx : name
2910 // -- esp[0] : return address 2881 // -- esp[0] : return address
2911 // ----------------------------------- 2882 // -----------------------------------
2912 Label miss; 2883 Label miss;
2913 2884
2914 // If the object is the holder then we know that it's a global 2885 // If the object is the holder then we know that it's a global
2915 // object which can only happen for contextual loads. In this case, 2886 // object which can only happen for contextual loads. In this case,
2916 // the receiver cannot be a smi. 2887 // the receiver cannot be a smi.
2917 if (object != holder) { 2888 if (object != holder) {
2918 __ test(eax, Immediate(kSmiTagMask)); 2889 __ JumpIfSmi(eax, &miss);
2919 __ j(zero, &miss);
2920 } 2890 }
2921 2891
2922 // Check that the maps haven't changed. 2892 // Check that the maps haven't changed.
2923 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); 2893 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss);
2924 2894
2925 // Get the value from the cell. 2895 // Get the value from the cell.
2926 if (Serializer::enabled()) { 2896 if (Serializer::enabled()) {
2927 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell))); 2897 __ mov(ebx, Immediate(Handle<JSGlobalPropertyCell>(cell)));
2928 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); 2898 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset));
2929 } else { 2899 } else {
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after
3225 // code for the function thereby hitting the break points. 3195 // code for the function thereby hitting the break points.
3226 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); 3196 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
3227 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset)); 3197 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kDebugInfoOffset));
3228 __ cmp(ebx, factory()->undefined_value()); 3198 __ cmp(ebx, factory()->undefined_value());
3229 __ j(not_equal, &generic_stub_call); 3199 __ j(not_equal, &generic_stub_call);
3230 #endif 3200 #endif
3231 3201
3232 // Load the initial map and verify that it is in fact a map. 3202 // Load the initial map and verify that it is in fact a map.
3233 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); 3203 __ mov(ebx, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
3234 // Will both indicate a NULL and a Smi. 3204 // Will both indicate a NULL and a Smi.
3235 __ test(ebx, Immediate(kSmiTagMask)); 3205 __ JumpIfSmi(ebx, &generic_stub_call);
3236 __ j(zero, &generic_stub_call);
3237 __ CmpObjectType(ebx, MAP_TYPE, ecx); 3206 __ CmpObjectType(ebx, MAP_TYPE, ecx);
3238 __ j(not_equal, &generic_stub_call); 3207 __ j(not_equal, &generic_stub_call);
3239 3208
3240 #ifdef DEBUG 3209 #ifdef DEBUG
3241 // Cannot construct functions this way. 3210 // Cannot construct functions this way.
3242 // edi: constructor 3211 // edi: constructor
3243 // ebx: initial map 3212 // ebx: initial map
3244 __ CmpInstanceType(ebx, JS_FUNCTION_TYPE); 3213 __ CmpInstanceType(ebx, JS_FUNCTION_TYPE);
3245 __ Assert(not_equal, "Function constructed by construct stub."); 3214 __ Assert(not_equal, "Function constructed by construct stub.");
3246 #endif 3215 #endif
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
3359 // -- eax : key 3328 // -- eax : key
3360 // -- edx : receiver 3329 // -- edx : receiver
3361 // -- esp[0] : return address 3330 // -- esp[0] : return address
3362 // ----------------------------------- 3331 // -----------------------------------
3363 Label miss_force_generic, failed_allocation, slow; 3332 Label miss_force_generic, failed_allocation, slow;
3364 3333
3365 // This stub is meant to be tail-jumped to, the receiver must already 3334 // This stub is meant to be tail-jumped to, the receiver must already
3366 // have been verified by the caller to not be a smi. 3335 // have been verified by the caller to not be a smi.
3367 3336
3368 // Check that the key is a smi. 3337 // Check that the key is a smi.
3369 __ test(eax, Immediate(kSmiTagMask)); 3338 __ JumpIfNotSmi(eax, &miss_force_generic);
3370 __ j(not_zero, &miss_force_generic);
3371 3339
3372 // Check that the index is in range. 3340 // Check that the index is in range.
3373 __ mov(ecx, eax); 3341 __ mov(ecx, eax);
3374 __ SmiUntag(ecx); // Untag the index. 3342 __ SmiUntag(ecx); // Untag the index.
3375 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3343 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3376 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3344 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset));
3377 // Unsigned comparison catches both negative and too-large values. 3345 // Unsigned comparison catches both negative and too-large values.
3378 __ j(above_equal, &miss_force_generic); 3346 __ j(above_equal, &miss_force_generic);
3379 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3347 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3380 // ebx: base pointer of external storage 3348 // ebx: base pointer of external storage
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
3515 // -- eax : key 3483 // -- eax : key
3516 // -- edx : receiver 3484 // -- edx : receiver
3517 // -- esp[0] : return address 3485 // -- esp[0] : return address
3518 // ----------------------------------- 3486 // -----------------------------------
3519 Label miss_force_generic, slow, check_heap_number; 3487 Label miss_force_generic, slow, check_heap_number;
3520 3488
3521 // This stub is meant to be tail-jumped to, the receiver must already 3489 // This stub is meant to be tail-jumped to, the receiver must already
3522 // have been verified by the caller to not be a smi. 3490 // have been verified by the caller to not be a smi.
3523 3491
3524 // Check that the key is a smi. 3492 // Check that the key is a smi.
3525 __ test(ecx, Immediate(kSmiTagMask)); 3493 __ JumpIfNotSmi(ecx, &miss_force_generic);
3526 __ j(not_zero, &miss_force_generic);
3527 3494
3528 // Check that the index is in range. 3495 // Check that the index is in range.
3529 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3496 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3530 __ mov(ebx, ecx); 3497 __ mov(ebx, ecx);
3531 __ SmiUntag(ebx); 3498 __ SmiUntag(ebx);
3532 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3499 __ cmp(ebx, FieldOperand(edi, ExternalArray::kLengthOffset));
3533 // Unsigned comparison catches both negative and too-large values. 3500 // Unsigned comparison catches both negative and too-large values.
3534 __ j(above_equal, &slow); 3501 __ j(above_equal, &slow);
3535 3502
3536 // Handle both smis and HeapNumbers in the fast path. Go to the 3503 // Handle both smis and HeapNumbers in the fast path. Go to the
3537 // runtime for all other kinds of values. 3504 // runtime for all other kinds of values.
3538 // eax: value 3505 // eax: value
3539 // edx: receiver 3506 // edx: receiver
3540 // ecx: key 3507 // ecx: key
3541 // edi: elements array 3508 // edi: elements array
3542 // ebx: untagged index 3509 // ebx: untagged index
3543 __ test(eax, Immediate(kSmiTagMask)); 3510 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) {
3544 if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) 3511 __ JumpIfNotSmi(eax, &slow);
3545 __ j(not_equal, &slow); 3512 } else {
3546 else 3513 __ JumpIfNotSmi(eax, &check_heap_number);
3547 __ j(not_equal, &check_heap_number); 3514 }
3548 3515
3549 // smi case 3516 // smi case
3550 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed. 3517 __ mov(ecx, eax); // Preserve the value in eax. Key is no longer needed.
3551 __ SmiUntag(ecx); 3518 __ SmiUntag(ecx);
3552 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); 3519 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3553 // ecx: base pointer of external storage 3520 // ecx: base pointer of external storage
3554 switch (elements_kind) { 3521 switch (elements_kind) {
3555 case JSObject::EXTERNAL_PIXEL_ELEMENTS: 3522 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3556 { // Clamp the value to [0..255]. 3523 { // Clamp the value to [0..255].
3557 Label done; 3524 Label done;
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
3729 // -- eax : key 3696 // -- eax : key
3730 // -- edx : receiver 3697 // -- edx : receiver
3731 // -- esp[0] : return address 3698 // -- esp[0] : return address
3732 // ----------------------------------- 3699 // -----------------------------------
3733 Label miss_force_generic; 3700 Label miss_force_generic;
3734 3701
3735 // This stub is meant to be tail-jumped to, the receiver must already 3702 // This stub is meant to be tail-jumped to, the receiver must already
3736 // have been verified by the caller to not be a smi. 3703 // have been verified by the caller to not be a smi.
3737 3704
3738 // Check that the key is a smi. 3705 // Check that the key is a smi.
3739 __ test(eax, Immediate(kSmiTagMask)); 3706 __ JumpIfNotSmi(eax, &miss_force_generic);
3740 __ j(not_zero, &miss_force_generic);
3741 3707
3742 // Get the elements array. 3708 // Get the elements array.
3743 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3709 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3744 __ AssertFastElements(ecx); 3710 __ AssertFastElements(ecx);
3745 3711
3746 // Check that the key is within bounds. 3712 // Check that the key is within bounds.
3747 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3713 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3748 __ j(above_equal, &miss_force_generic); 3714 __ j(above_equal, &miss_force_generic);
3749 3715
3750 // Load the result and make sure it's not the hole. 3716 // Load the result and make sure it's not the hole.
(...skipping 17 matching lines...) Expand all
3768 // -- eax : key 3734 // -- eax : key
3769 // -- edx : receiver 3735 // -- edx : receiver
3770 // -- esp[0] : return address 3736 // -- esp[0] : return address
3771 // ----------------------------------- 3737 // -----------------------------------
3772 Label miss_force_generic; 3738 Label miss_force_generic;
3773 3739
3774 // This stub is meant to be tail-jumped to, the receiver must already 3740 // This stub is meant to be tail-jumped to, the receiver must already
3775 // have been verified by the caller to not be a smi. 3741 // have been verified by the caller to not be a smi.
3776 3742
3777 // Check that the key is a smi. 3743 // Check that the key is a smi.
3778 __ test(ecx, Immediate(kSmiTagMask)); 3744 __ JumpIfNotSmi(ecx, &miss_force_generic);
3779 __ j(not_zero, &miss_force_generic);
3780 3745
3781 // Get the elements array and make sure it is a fast element array, not 'cow'. 3746 // Get the elements array and make sure it is a fast element array, not 'cow'.
3782 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3747 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3783 __ cmp(FieldOperand(edi, HeapObject::kMapOffset), 3748 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3784 Immediate(masm->isolate()->factory()->fixed_array_map())); 3749 Immediate(masm->isolate()->factory()->fixed_array_map()));
3785 __ j(not_equal, &miss_force_generic); 3750 __ j(not_equal, &miss_force_generic);
3786 3751
3787 if (is_js_array) { 3752 if (is_js_array) {
3788 // Check that the key is within bounds. 3753 // Check that the key is within bounds.
3789 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 3754 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
(...skipping 19 matching lines...) Expand all
3809 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3774 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3810 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3775 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3811 } 3776 }
3812 3777
3813 3778
3814 #undef __ 3779 #undef __
3815 3780
3816 } } // namespace v8::internal 3781 } } // namespace v8::internal
3817 3782
3818 #endif // V8_TARGET_ARCH_IA32 3783 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698