OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
814 | 814 |
815 | 815 |
816 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 816 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { |
817 if (kind_ == Code::KEYED_CALL_IC) { | 817 if (kind_ == Code::KEYED_CALL_IC) { |
818 __ Cmp(rcx, Handle<String>(name)); | 818 __ Cmp(rcx, Handle<String>(name)); |
819 __ j(not_equal, miss); | 819 __ j(not_equal, miss); |
820 } | 820 } |
821 } | 821 } |
822 | 822 |
823 | 823 |
824 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | |
825 JSObject* holder, | |
826 String* name, | |
827 Label* miss) { | |
828 // Get the number of arguments. | |
829 const int argc = arguments().immediate(); | |
830 | |
831 // Get the receiver from the stack. | |
832 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | |
833 | |
834 // If the object is the holder then we know that it's a global | |
835 // object which can only happen for contextual calls. In this case, | |
836 // the receiver cannot be a smi. | |
837 if (object != holder) { | |
838 __ JumpIfSmi(rdx, miss); | |
839 } | |
840 | |
841 // Check that the maps haven't changed. | |
842 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, miss); | |
843 } | |
844 | |
845 | |
846 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, | |
847 JSFunction* function, | |
848 Label* miss) { | |
849 // Get the value from the cell. | |
850 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); | |
851 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | |
852 | |
853 // Check that the cell contains the same function. | |
854 if (Heap::InNewSpace(function)) { | |
855 // We can't embed a pointer to a function in new space so we have | |
856 // to verify that the shared function info is unchanged. This has | |
857 // the nice side effect that multiple closures based on the same | |
858 // function can all use this call IC. Before we load through the | |
859 // function, we have to verify that it still is a function. | |
860 __ JumpIfSmi(rdi, miss); | |
861 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); | |
862 __ j(not_equal, miss); | |
863 | |
864 // Check the shared function info. Make sure it hasn't changed. | |
865 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | |
866 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | |
867 __ j(not_equal, miss); | |
868 } else { | |
869 __ Cmp(rdi, Handle<JSFunction>(function)); | |
870 __ j(not_equal, miss); | |
871 } | |
872 } | |
873 | |
874 | |
824 Object* CallStubCompiler::GenerateMissBranch() { | 875 Object* CallStubCompiler::GenerateMissBranch() { |
825 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); | 876 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); |
826 if (obj->IsFailure()) return obj; | 877 if (obj->IsFailure()) return obj; |
827 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 878 __ Jump(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
828 return obj; | 879 return obj; |
829 } | 880 } |
830 | 881 |
831 | 882 |
832 Object* CallStubCompiler::CompileCallConstant(Object* object, | 883 Object* CallStubCompiler::CompileCallConstant(Object* object, |
833 JSObject* holder, | 884 JSObject* holder, |
834 JSFunction* function, | 885 JSFunction* function, |
835 String* name, | 886 String* name, |
836 StubCompiler::CheckType check) { | 887 StubCompiler::CheckType check) { |
837 // ----------- S t a t e ------------- | 888 // ----------- S t a t e ------------- |
838 // rcx : function name | 889 // rcx : function name |
839 // rsp[0] : return address | 890 // rsp[0] : return address |
840 // rsp[8] : argument argc | 891 // rsp[8] : argument argc |
841 // rsp[16] : argument argc - 1 | 892 // rsp[16] : argument argc - 1 |
842 // ... | 893 // ... |
843 // rsp[argc * 8] : argument 1 | 894 // rsp[argc * 8] : argument 1 |
844 // rsp[(argc + 1) * 8] : argument 0 = receiver | 895 // rsp[(argc + 1) * 8] : argument 0 = receiver |
845 // ----------------------------------- | 896 // ----------------------------------- |
846 | 897 |
847 SharedFunctionInfo* function_info = function->shared(); | 898 SharedFunctionInfo* function_info = function->shared(); |
848 if (function_info->HasCustomCallGenerator()) { | 899 if (function_info->HasCustomCallGenerator()) { |
849 const int id = function_info->custom_call_generator_id(); | 900 const int id = function_info->custom_call_generator_id(); |
850 Object* result = | 901 Object* result = CompileCustomCall( |
851 CompileCustomCall(id, object, holder, function, name, check); | 902 id, object, holder, NULL, function, name); |
852 // undefined means bail out to regular compiler. | 903 // undefined means bail out to regular compiler. |
853 if (!result->IsUndefined()) { | 904 if (!result->IsUndefined()) return result; |
854 return result; | |
855 } | |
856 } | 905 } |
857 | 906 |
858 Label miss_in_smi_check; | 907 Label miss_in_smi_check; |
859 | 908 |
860 GenerateNameCheck(name, &miss_in_smi_check); | 909 GenerateNameCheck(name, &miss_in_smi_check); |
861 | 910 |
862 // Get the receiver from the stack. | 911 // Get the receiver from the stack. |
863 const int argc = arguments().immediate(); | 912 const int argc = arguments().immediate(); |
864 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 913 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
865 | 914 |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1036 Object* obj = GenerateMissBranch(); | 1085 Object* obj = GenerateMissBranch(); |
1037 if (obj->IsFailure()) return obj; | 1086 if (obj->IsFailure()) return obj; |
1038 | 1087 |
1039 // Return the generated code. | 1088 // Return the generated code. |
1040 return GetCode(FIELD, name); | 1089 return GetCode(FIELD, name); |
1041 } | 1090 } |
1042 | 1091 |
1043 | 1092 |
1044 Object* CallStubCompiler::CompileArrayPushCall(Object* object, | 1093 Object* CallStubCompiler::CompileArrayPushCall(Object* object, |
1045 JSObject* holder, | 1094 JSObject* holder, |
1095 JSGlobalPropertyCell* cell, | |
1046 JSFunction* function, | 1096 JSFunction* function, |
1047 String* name, | 1097 String* name) { |
1048 CheckType check) { | |
1049 // ----------- S t a t e ------------- | 1098 // ----------- S t a t e ------------- |
1050 // -- rcx : name | 1099 // -- rcx : name |
1051 // -- rsp[0] : return address | 1100 // -- rsp[0] : return address |
1052 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1101 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1053 // -- ... | 1102 // -- ... |
1054 // -- rsp[(argc + 1) * 8] : receiver | 1103 // -- rsp[(argc + 1) * 8] : receiver |
1055 // ----------------------------------- | 1104 // ----------------------------------- |
1056 ASSERT(check == RECEIVER_MAP_CHECK); | |
1057 | 1105 |
1058 // If object is not an array, bail out to regular call. | 1106 // If object is not an array, bail out to regular call. |
1059 if (!object->IsJSArray()) { | 1107 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
1060 return Heap::undefined_value(); | |
1061 } | |
1062 | 1108 |
1063 Label miss; | 1109 Label miss; |
1064 | 1110 |
1065 GenerateNameCheck(name, &miss); | 1111 GenerateNameCheck(name, &miss); |
1066 | 1112 |
1067 // Get the receiver from the stack. | 1113 // Get the receiver from the stack. |
1068 const int argc = arguments().immediate(); | 1114 const int argc = arguments().immediate(); |
1069 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1115 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1070 | 1116 |
1071 // Check that the receiver isn't a smi. | 1117 // Check that the receiver isn't a smi. |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1197 Object* obj = GenerateMissBranch(); | 1243 Object* obj = GenerateMissBranch(); |
1198 if (obj->IsFailure()) return obj; | 1244 if (obj->IsFailure()) return obj; |
1199 | 1245 |
1200 // Return the generated code. | 1246 // Return the generated code. |
1201 return GetCode(function); | 1247 return GetCode(function); |
1202 } | 1248 } |
1203 | 1249 |
1204 | 1250 |
1205 Object* CallStubCompiler::CompileArrayPopCall(Object* object, | 1251 Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
1206 JSObject* holder, | 1252 JSObject* holder, |
1253 JSGlobalPropertyCell* cell, | |
1207 JSFunction* function, | 1254 JSFunction* function, |
1208 String* name, | 1255 String* name) { |
1209 CheckType check) { | |
1210 // ----------- S t a t e ------------- | 1256 // ----------- S t a t e ------------- |
1211 // -- rcx : name | 1257 // -- rcx : name |
1212 // -- rsp[0] : return address | 1258 // -- rsp[0] : return address |
1213 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1259 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1214 // -- ... | 1260 // -- ... |
1215 // -- rsp[(argc + 1) * 8] : receiver | 1261 // -- rsp[(argc + 1) * 8] : receiver |
1216 // ----------------------------------- | 1262 // ----------------------------------- |
1217 ASSERT(check == RECEIVER_MAP_CHECK); | |
1218 | 1263 |
1219 // If object is not an array, bail out to regular call. | 1264 // If object is not an array, bail out to regular call. |
1220 if (!object->IsJSArray()) { | 1265 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
1221 return Heap::undefined_value(); | |
1222 } | |
1223 | 1266 |
1224 Label miss, return_undefined, call_builtin; | 1267 Label miss, return_undefined, call_builtin; |
1225 | 1268 |
1226 GenerateNameCheck(name, &miss); | 1269 GenerateNameCheck(name, &miss); |
1227 | 1270 |
1228 // Get the receiver from the stack. | 1271 // Get the receiver from the stack. |
1229 const int argc = arguments().immediate(); | 1272 const int argc = arguments().immediate(); |
1230 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | 1273 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); |
1231 | 1274 |
1232 // Check that the receiver isn't a smi. | 1275 // Check that the receiver isn't a smi. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1282 Object* obj = GenerateMissBranch(); | 1325 Object* obj = GenerateMissBranch(); |
1283 if (obj->IsFailure()) return obj; | 1326 if (obj->IsFailure()) return obj; |
1284 | 1327 |
1285 // Return the generated code. | 1328 // Return the generated code. |
1286 return GetCode(function); | 1329 return GetCode(function); |
1287 } | 1330 } |
1288 | 1331 |
1289 | 1332 |
1290 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, | 1333 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
1291 JSObject* holder, | 1334 JSObject* holder, |
1335 JSGlobalPropertyCell* cell, | |
1292 JSFunction* function, | 1336 JSFunction* function, |
1293 String* name, | 1337 String* name) { |
1294 CheckType check) { | |
1295 // ----------- S t a t e ------------- | 1338 // ----------- S t a t e ------------- |
1296 // -- rcx : function name | 1339 // -- rcx : function name |
1297 // -- rsp[0] : return address | 1340 // -- rsp[0] : return address |
1298 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1341 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1299 // -- ... | 1342 // -- ... |
1300 // -- rsp[(argc + 1) * 8] : receiver | 1343 // -- rsp[(argc + 1) * 8] : receiver |
1301 // ----------------------------------- | 1344 // ----------------------------------- |
1302 | 1345 |
1303 // If object is not a string, bail out to regular call. | 1346 // If object is not a string, bail out to regular call. |
1304 if (!object->IsString()) return Heap::undefined_value(); | 1347 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1305 | 1348 |
1306 const int argc = arguments().immediate(); | 1349 const int argc = arguments().immediate(); |
1307 | 1350 |
1308 Label miss; | 1351 Label miss; |
1309 Label index_out_of_range; | 1352 Label index_out_of_range; |
1310 | 1353 |
1311 GenerateNameCheck(name, &miss); | 1354 GenerateNameCheck(name, &miss); |
1312 | 1355 |
1313 // Check that the maps starting from the prototype haven't changed. | 1356 // Check that the maps starting from the prototype haven't changed. |
1314 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1357 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1351 | 1394 |
1352 __ bind(&miss); | 1395 __ bind(&miss); |
1353 Object* obj = GenerateMissBranch(); | 1396 Object* obj = GenerateMissBranch(); |
1354 if (obj->IsFailure()) return obj; | 1397 if (obj->IsFailure()) return obj; |
1355 | 1398 |
1356 // Return the generated code. | 1399 // Return the generated code. |
1357 return GetCode(function); | 1400 return GetCode(function); |
1358 } | 1401 } |
1359 | 1402 |
1360 | 1403 |
1361 Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, | 1404 Object* CallStubCompiler::CompileStringCharCodeAtCall( |
1362 JSObject* holder, | 1405 Object* object, |
1363 JSFunction* function, | 1406 JSObject* holder, |
1364 String* name, | 1407 JSGlobalPropertyCell* cell, |
1365 CheckType check) { | 1408 JSFunction* function, |
1409 String* name) { | |
1366 // ----------- S t a t e ------------- | 1410 // ----------- S t a t e ------------- |
1367 // -- rcx : function name | 1411 // -- rcx : function name |
1368 // -- rsp[0] : return address | 1412 // -- rsp[0] : return address |
1369 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | 1413 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) |
1370 // -- ... | 1414 // -- ... |
1371 // -- rsp[(argc + 1) * 8] : receiver | 1415 // -- rsp[(argc + 1) * 8] : receiver |
1372 // ----------------------------------- | 1416 // ----------------------------------- |
1373 | 1417 |
1374 // If object is not a string, bail out to regular call. | 1418 // If object is not a string, bail out to regular call. |
1375 if (!object->IsString()) return Heap::undefined_value(); | 1419 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1376 | 1420 |
1377 const int argc = arguments().immediate(); | 1421 const int argc = arguments().immediate(); |
1378 | 1422 |
1379 Label miss; | 1423 Label miss; |
1380 Label index_out_of_range; | 1424 Label index_out_of_range; |
1381 GenerateNameCheck(name, &miss); | 1425 GenerateNameCheck(name, &miss); |
1382 | 1426 |
1383 // Check that the maps starting from the prototype haven't changed. | 1427 // Check that the maps starting from the prototype haven't changed. |
1384 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1428 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1385 Context::STRING_FUNCTION_INDEX, | 1429 Context::STRING_FUNCTION_INDEX, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1419 | 1463 |
1420 __ bind(&miss); | 1464 __ bind(&miss); |
1421 Object* obj = GenerateMissBranch(); | 1465 Object* obj = GenerateMissBranch(); |
1422 if (obj->IsFailure()) return obj; | 1466 if (obj->IsFailure()) return obj; |
1423 | 1467 |
1424 // Return the generated code. | 1468 // Return the generated code. |
1425 return GetCode(function); | 1469 return GetCode(function); |
1426 } | 1470 } |
1427 | 1471 |
1428 | 1472 |
1473 Object* CallStubCompiler::CompileStringFromCharCodeCall( | |
1474 Object* object, | |
1475 JSObject* holder, | |
1476 JSGlobalPropertyCell* cell, | |
1477 JSFunction* function, | |
1478 String* name) { | |
1479 // ----------- S t a t e ------------- | |
1480 // -- rcx : function name | |
1481 // -- rsp[0] : return address | |
1482 // -- rsp[(argc - n) * 8] : arg[n] (zero-based) | |
1483 // -- ... | |
1484 // -- rsp[(argc + 1) * 8] : receiver | |
1485 // ----------------------------------- | |
1486 | |
1487 const int argc = arguments().immediate(); | |
1488 | |
1489 // If the object is not a JSObject or we got an unexpected number of | |
1490 // arguments, bail out to the regular call. | |
1491 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); | |
1492 | |
1493 Label miss; | |
1494 GenerateNameCheck(name, &miss); | |
1495 | |
1496 if (cell == NULL) { | |
1497 __ movq(rdx, Operand(rsp, 2 * kPointerSize)); | |
1498 | |
1499 __ JumpIfSmi(rdx, &miss); | |
1500 | |
1501 CheckPrototypes(JSObject::cast(object), rdx, holder, rbx, rax, rdi, name, | |
1502 &miss); | |
1503 } else { | |
1504 ASSERT(cell->value() == function); | |
1505 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); | |
1506 GenerateLoadFunctionFromCell(cell, function, &miss); | |
1507 } | |
1508 | |
1509 // Load the char code argument. | |
1510 Register code = rbx; | |
1511 __ movq(code, Operand(rsp, 1 * kPointerSize)); | |
1512 | |
1513 // Check the code is a smi. | |
1514 Label slow; | |
1515 __ JumpIfNotSmi(code, &slow); | |
1516 | |
1517 // Convert the smi code to uint16. | |
1518 __ SmiAndConstant(code, code, Smi::FromInt(0xffff)); | |
1519 | |
1520 StringCharFromCodeGenerator char_from_code_generator(code, rax); | |
1521 char_from_code_generator.GenerateFast(masm()); | |
1522 __ ret(2 * kPointerSize); | |
1523 | |
1524 ICRuntimeCallHelper call_helper; | |
1525 char_from_code_generator.GenerateSlow(masm(), call_helper); | |
1526 | |
1527 // Tail call the full function. | |
antonm
2010/09/08 15:26:05
do you want to unify this comment across platforms
| |
1528 __ bind(&slow); | |
1529 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | |
1530 | |
1531 __ bind(&miss); | |
1532 // rcx: function name. | |
1533 Object* obj = GenerateMissBranch(); | |
1534 if (obj->IsFailure()) return obj; | |
1535 | |
1536 // Return the generated code. | |
1537 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | |
1538 } | |
1539 | |
1540 | |
1429 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, | 1541 Object* CallStubCompiler::CompileCallInterceptor(JSObject* object, |
1430 JSObject* holder, | 1542 JSObject* holder, |
1431 String* name) { | 1543 String* name) { |
1432 // ----------- S t a t e ------------- | 1544 // ----------- S t a t e ------------- |
1433 // rcx : function name | 1545 // rcx : function name |
1434 // rsp[0] : return address | 1546 // rsp[0] : return address |
1435 // rsp[8] : argument argc | 1547 // rsp[8] : argument argc |
1436 // rsp[16] : argument argc - 1 | 1548 // rsp[16] : argument argc - 1 |
1437 // ... | 1549 // ... |
1438 // rsp[argc * 8] : argument 1 | 1550 // rsp[argc * 8] : argument 1 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1491 return GetCode(INTERCEPTOR, name); | 1603 return GetCode(INTERCEPTOR, name); |
1492 } | 1604 } |
1493 | 1605 |
1494 | 1606 |
1495 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, | 1607 Object* CallStubCompiler::CompileCallGlobal(JSObject* object, |
1496 GlobalObject* holder, | 1608 GlobalObject* holder, |
1497 JSGlobalPropertyCell* cell, | 1609 JSGlobalPropertyCell* cell, |
1498 JSFunction* function, | 1610 JSFunction* function, |
1499 String* name) { | 1611 String* name) { |
1500 // ----------- S t a t e ------------- | 1612 // ----------- S t a t e ------------- |
1501 // ----------------------------------- | |
1502 // rcx : function name | 1613 // rcx : function name |
1503 // rsp[0] : return address | 1614 // rsp[0] : return address |
1504 // rsp[8] : argument argc | 1615 // rsp[8] : argument argc |
1505 // rsp[16] : argument argc - 1 | 1616 // rsp[16] : argument argc - 1 |
1506 // ... | 1617 // ... |
1507 // rsp[argc * 8] : argument 1 | 1618 // rsp[argc * 8] : argument 1 |
1508 // rsp[(argc + 1) * 8] : argument 0 = receiver | 1619 // rsp[(argc + 1) * 8] : argument 0 = receiver |
1620 // ----------------------------------- | |
1621 | |
1622 SharedFunctionInfo* function_info = function->shared(); | |
1623 if (function_info->HasCustomCallGenerator()) { | |
1624 const int id = function_info->custom_call_generator_id(); | |
1625 Object* result = CompileCustomCall( | |
1626 id, object, holder, cell, function, name); | |
1627 // undefined means bail out to regular compiler. | |
1628 if (!result->IsUndefined()) return result; | |
1629 } | |
1630 | |
1509 Label miss; | 1631 Label miss; |
1510 | 1632 |
1511 GenerateNameCheck(name, &miss); | 1633 GenerateNameCheck(name, &miss); |
1512 | 1634 |
1513 // Get the number of arguments. | 1635 // Get the number of arguments. |
1514 const int argc = arguments().immediate(); | 1636 const int argc = arguments().immediate(); |
1515 | 1637 |
1516 // Get the receiver from the stack. | 1638 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
1517 __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); | |
1518 | 1639 |
1519 // If the object is the holder then we know that it's a global | 1640 GenerateLoadFunctionFromCell(cell, function, &miss); |
1520 // object which can only happen for contextual calls. In this case, | |
1521 // the receiver cannot be a smi. | |
1522 if (object != holder) { | |
1523 __ JumpIfSmi(rdx, &miss); | |
1524 } | |
1525 | |
1526 // Check that the maps haven't changed. | |
1527 CheckPrototypes(object, rdx, holder, rbx, rax, rdi, name, &miss); | |
1528 | |
1529 // Get the value from the cell. | |
1530 __ Move(rdi, Handle<JSGlobalPropertyCell>(cell)); | |
1531 __ movq(rdi, FieldOperand(rdi, JSGlobalPropertyCell::kValueOffset)); | |
1532 | |
1533 // Check that the cell contains the same function. | |
1534 if (Heap::InNewSpace(function)) { | |
1535 // We can't embed a pointer to a function in new space so we have | |
1536 // to verify that the shared function info is unchanged. This has | |
1537 // the nice side effect that multiple closures based on the same | |
1538 // function can all use this call IC. Before we load through the | |
1539 // function, we have to verify that it still is a function. | |
1540 __ JumpIfSmi(rdi, &miss); | |
1541 __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rax); | |
1542 __ j(not_equal, &miss); | |
1543 | |
1544 // Check the shared function info. Make sure it hasn't changed. | |
1545 __ Move(rax, Handle<SharedFunctionInfo>(function->shared())); | |
1546 __ cmpq(FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset), rax); | |
1547 __ j(not_equal, &miss); | |
1548 } else { | |
1549 __ Cmp(rdi, Handle<JSFunction>(function)); | |
1550 __ j(not_equal, &miss); | |
1551 } | |
1552 | 1641 |
1553 // Patch the receiver on the stack with the global proxy. | 1642 // Patch the receiver on the stack with the global proxy. |
1554 if (object->IsGlobalObject()) { | 1643 if (object->IsGlobalObject()) { |
1555 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); | 1644 __ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset)); |
1556 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); | 1645 __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx); |
1557 } | 1646 } |
1558 | 1647 |
1559 // Setup the context (function already in edi). | 1648 // Setup the context (function already in edi). |
1560 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); | 1649 __ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset)); |
1561 | 1650 |
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2713 // Return the generated code. | 2802 // Return the generated code. |
2714 return GetCode(); | 2803 return GetCode(); |
2715 } | 2804 } |
2716 | 2805 |
2717 | 2806 |
2718 #undef __ | 2807 #undef __ |
2719 | 2808 |
2720 } } // namespace v8::internal | 2809 } } // namespace v8::internal |
2721 | 2810 |
2722 #endif // V8_TARGET_ARCH_X64 | 2811 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |