OLD | NEW |
---|---|
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 1237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1248 | 1248 |
1249 | 1249 |
1250 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { | 1250 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { |
1251 if (kind_ == Code::KEYED_CALL_IC) { | 1251 if (kind_ == Code::KEYED_CALL_IC) { |
1252 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 1252 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
1253 __ j(not_equal, miss, not_taken); | 1253 __ j(not_equal, miss, not_taken); |
1254 } | 1254 } |
1255 } | 1255 } |
1256 | 1256 |
1257 | 1257 |
1258 void CallStubCompiler::GenerateGlobalReceiverCheck(JSObject* object, | |
1259 JSObject* holder, | |
1260 String* name, | |
1261 Label* miss) { | |
1262 // Get the number of arguments. | |
1263 const int argc = arguments().immediate(); | |
1264 | |
1265 // Get the receiver from the stack. | |
1266 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | |
1267 | |
1268 // If the object is the holder then we know that it's a global | |
1269 // object which can only happen for contextual calls. In this case, | |
1270 // the receiver cannot be a smi. | |
1271 if (object != holder) { | |
1272 __ test(edx, Immediate(kSmiTagMask)); | |
1273 __ j(zero, miss, not_taken); | |
1274 } | |
1275 | |
1276 // Check that the maps haven't changed. | |
1277 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, miss); | |
1278 } | |
1279 | |
1280 | |
1281 void CallStubCompiler::GenerateLoadFunctionFromCell(JSGlobalPropertyCell* cell, | |
1282 JSFunction* function, | |
1283 Label* miss) { | |
1284 // Get the value from the cell. | |
1285 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | |
1286 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | |
1287 | |
1288 // Check that the cell contains the same function. | |
1289 if (Heap::InNewSpace(function)) { | |
1290 // We can't embed a pointer to a function in new space so we have | |
1291 // to verify that the shared function info is unchanged. This has | |
1292 // the nice side effect that multiple closures based on the same | |
1293 // function can all use this call IC. Before we load through the | |
1294 // function, we have to verify that it still is a function. | |
1295 __ test(edi, Immediate(kSmiTagMask)); | |
1296 __ j(zero, miss, not_taken); | |
1297 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | |
1298 __ j(not_equal, miss, not_taken); | |
1299 | |
1300 // Check the shared function info. Make sure it hasn't changed. | |
1301 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | |
1302 Immediate(Handle<SharedFunctionInfo>(function->shared()))); | |
1303 __ j(not_equal, miss, not_taken); | |
1304 } else { | |
1305 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | |
1306 __ j(not_equal, miss, not_taken); | |
1307 } | |
1308 } | |
1309 | |
1310 | |
1258 Object* CallStubCompiler::GenerateMissBranch() { | 1311 Object* CallStubCompiler::GenerateMissBranch() { |
1259 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); | 1312 Object* obj = StubCache::ComputeCallMiss(arguments().immediate(), kind_); |
1260 if (obj->IsFailure()) return obj; | 1313 if (obj->IsFailure()) return obj; |
1261 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); | 1314 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); |
1262 return obj; | 1315 return obj; |
1263 } | 1316 } |
1264 | 1317 |
1265 | 1318 |
1266 Object* CallStubCompiler::CompileCallField(JSObject* object, | 1319 Object* CallStubCompiler::CompileCallField(JSObject* object, |
1267 JSObject* holder, | 1320 JSObject* holder, |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1313 Object* obj = GenerateMissBranch(); | 1366 Object* obj = GenerateMissBranch(); |
1314 if (obj->IsFailure()) return obj; | 1367 if (obj->IsFailure()) return obj; |
1315 | 1368 |
1316 // Return the generated code. | 1369 // Return the generated code. |
1317 return GetCode(FIELD, name); | 1370 return GetCode(FIELD, name); |
1318 } | 1371 } |
1319 | 1372 |
1320 | 1373 |
1321 Object* CallStubCompiler::CompileArrayPushCall(Object* object, | 1374 Object* CallStubCompiler::CompileArrayPushCall(Object* object, |
1322 JSObject* holder, | 1375 JSObject* holder, |
1376 JSGlobalPropertyCell* cell, | |
1323 JSFunction* function, | 1377 JSFunction* function, |
1324 String* name, | 1378 String* name) { |
1325 CheckType check) { | |
1326 // ----------- S t a t e ------------- | 1379 // ----------- S t a t e ------------- |
1327 // -- ecx : name | 1380 // -- ecx : name |
1328 // -- esp[0] : return address | 1381 // -- esp[0] : return address |
1329 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1382 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1330 // -- ... | 1383 // -- ... |
1331 // -- esp[(argc + 1) * 4] : receiver | 1384 // -- esp[(argc + 1) * 4] : receiver |
1332 // ----------------------------------- | 1385 // ----------------------------------- |
1333 ASSERT(check == RECEIVER_MAP_CHECK); | |
1334 | 1386 |
1335 // If object is not an array, bail out to regular call. | 1387 // If object is not an array, bail out to regular call. |
1336 if (!object->IsJSArray()) { | 1388 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
1337 return Heap::undefined_value(); | |
1338 } | |
1339 | 1389 |
1340 Label miss; | 1390 Label miss; |
1341 | 1391 |
1342 GenerateNameCheck(name, &miss); | 1392 GenerateNameCheck(name, &miss); |
1343 | 1393 |
1344 // Get the receiver from the stack. | 1394 // Get the receiver from the stack. |
1345 const int argc = arguments().immediate(); | 1395 const int argc = arguments().immediate(); |
1346 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1396 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1347 | 1397 |
1348 // Check that the receiver isn't a smi. | 1398 // Check that the receiver isn't a smi. |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1462 Object* obj = GenerateMissBranch(); | 1512 Object* obj = GenerateMissBranch(); |
1463 if (obj->IsFailure()) return obj; | 1513 if (obj->IsFailure()) return obj; |
1464 | 1514 |
1465 // Return the generated code. | 1515 // Return the generated code. |
1466 return GetCode(function); | 1516 return GetCode(function); |
1467 } | 1517 } |
1468 | 1518 |
1469 | 1519 |
1470 Object* CallStubCompiler::CompileArrayPopCall(Object* object, | 1520 Object* CallStubCompiler::CompileArrayPopCall(Object* object, |
1471 JSObject* holder, | 1521 JSObject* holder, |
1522 JSGlobalPropertyCell* cell, | |
1472 JSFunction* function, | 1523 JSFunction* function, |
1473 String* name, | 1524 String* name) { |
1474 CheckType check) { | |
1475 // ----------- S t a t e ------------- | 1525 // ----------- S t a t e ------------- |
1476 // -- ecx : name | 1526 // -- ecx : name |
1477 // -- esp[0] : return address | 1527 // -- esp[0] : return address |
1478 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1528 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1479 // -- ... | 1529 // -- ... |
1480 // -- esp[(argc + 1) * 4] : receiver | 1530 // -- esp[(argc + 1) * 4] : receiver |
1481 // ----------------------------------- | 1531 // ----------------------------------- |
1482 ASSERT(check == RECEIVER_MAP_CHECK); | |
1483 | 1532 |
1484 // If object is not an array, bail out to regular call. | 1533 // If object is not an array, bail out to regular call. |
1485 if (!object->IsJSArray()) { | 1534 if (!object->IsJSArray() || cell != NULL) return Heap::undefined_value(); |
1486 return Heap::undefined_value(); | |
1487 } | |
1488 | 1535 |
1489 Label miss, return_undefined, call_builtin; | 1536 Label miss, return_undefined, call_builtin; |
1490 | 1537 |
1491 GenerateNameCheck(name, &miss); | 1538 GenerateNameCheck(name, &miss); |
1492 | 1539 |
1493 // Get the receiver from the stack. | 1540 // Get the receiver from the stack. |
1494 const int argc = arguments().immediate(); | 1541 const int argc = arguments().immediate(); |
1495 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1542 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1496 | 1543 |
1497 // Check that the receiver isn't a smi. | 1544 // Check that the receiver isn't a smi. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1544 | 1591 |
1545 __ bind(&miss); | 1592 __ bind(&miss); |
1546 Object* obj = GenerateMissBranch(); | 1593 Object* obj = GenerateMissBranch(); |
1547 if (obj->IsFailure()) return obj; | 1594 if (obj->IsFailure()) return obj; |
1548 | 1595 |
1549 // Return the generated code. | 1596 // Return the generated code. |
1550 return GetCode(function); | 1597 return GetCode(function); |
1551 } | 1598 } |
1552 | 1599 |
1553 | 1600 |
1554 Object* CallStubCompiler::CompileStringCharCodeAtCall(Object* object, | 1601 Object* CallStubCompiler::CompileStringCharCodeAtCall( |
1555 JSObject* holder, | 1602 Object* object, |
1556 JSFunction* function, | 1603 JSObject* holder, |
1557 String* name, | 1604 JSGlobalPropertyCell* cell, |
1558 CheckType check) { | 1605 JSFunction* function, |
1606 String* name) { | |
1559 // ----------- S t a t e ------------- | 1607 // ----------- S t a t e ------------- |
1560 // -- ecx : function name | 1608 // -- ecx : function name |
1561 // -- esp[0] : return address | 1609 // -- esp[0] : return address |
1562 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1610 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1563 // -- ... | 1611 // -- ... |
1564 // -- esp[(argc + 1) * 4] : receiver | 1612 // -- esp[(argc + 1) * 4] : receiver |
1565 // ----------------------------------- | 1613 // ----------------------------------- |
1566 | 1614 |
1567 // If object is not a string, bail out to regular call. | 1615 // If object is not a string, bail out to regular call. |
1568 if (!object->IsString()) return Heap::undefined_value(); | 1616 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1569 | 1617 |
1570 const int argc = arguments().immediate(); | 1618 const int argc = arguments().immediate(); |
1571 | 1619 |
1572 Label miss; | 1620 Label miss; |
1573 Label index_out_of_range; | 1621 Label index_out_of_range; |
1574 GenerateNameCheck(name, &miss); | 1622 GenerateNameCheck(name, &miss); |
1575 | 1623 |
1576 // Check that the maps starting from the prototype haven't changed. | 1624 // Check that the maps starting from the prototype haven't changed. |
1577 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1625 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
1578 Context::STRING_FUNCTION_INDEX, | 1626 Context::STRING_FUNCTION_INDEX, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1614 Object* obj = GenerateMissBranch(); | 1662 Object* obj = GenerateMissBranch(); |
1615 if (obj->IsFailure()) return obj; | 1663 if (obj->IsFailure()) return obj; |
1616 | 1664 |
1617 // Return the generated code. | 1665 // Return the generated code. |
1618 return GetCode(function); | 1666 return GetCode(function); |
1619 } | 1667 } |
1620 | 1668 |
1621 | 1669 |
1622 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, | 1670 Object* CallStubCompiler::CompileStringCharAtCall(Object* object, |
1623 JSObject* holder, | 1671 JSObject* holder, |
1672 JSGlobalPropertyCell* cell, | |
1624 JSFunction* function, | 1673 JSFunction* function, |
1625 String* name, | 1674 String* name) { |
1626 CheckType check) { | |
1627 // ----------- S t a t e ------------- | 1675 // ----------- S t a t e ------------- |
1628 // -- ecx : function name | 1676 // -- ecx : function name |
1629 // -- esp[0] : return address | 1677 // -- esp[0] : return address |
1630 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1678 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1631 // -- ... | 1679 // -- ... |
1632 // -- esp[(argc + 1) * 4] : receiver | 1680 // -- esp[(argc + 1) * 4] : receiver |
1633 // ----------------------------------- | 1681 // ----------------------------------- |
1634 | 1682 |
1635 // If object is not a string, bail out to regular call. | 1683 // If object is not a string, bail out to regular call. |
1636 if (!object->IsString()) return Heap::undefined_value(); | 1684 if (!object->IsString() || cell != NULL) return Heap::undefined_value(); |
1637 | 1685 |
1638 const int argc = arguments().immediate(); | 1686 const int argc = arguments().immediate(); |
1639 | 1687 |
1640 Label miss; | 1688 Label miss; |
1641 Label index_out_of_range; | 1689 Label index_out_of_range; |
1642 | 1690 |
1643 GenerateNameCheck(name, &miss); | 1691 GenerateNameCheck(name, &miss); |
1644 | 1692 |
1645 // Check that the maps starting from the prototype haven't changed. | 1693 // Check that the maps starting from the prototype haven't changed. |
1646 GenerateDirectLoadGlobalFunctionPrototype(masm(), | 1694 GenerateDirectLoadGlobalFunctionPrototype(masm(), |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1683 | 1731 |
1684 __ bind(&miss); | 1732 __ bind(&miss); |
1685 Object* obj = GenerateMissBranch(); | 1733 Object* obj = GenerateMissBranch(); |
1686 if (obj->IsFailure()) return obj; | 1734 if (obj->IsFailure()) return obj; |
1687 | 1735 |
1688 // Return the generated code. | 1736 // Return the generated code. |
1689 return GetCode(function); | 1737 return GetCode(function); |
1690 } | 1738 } |
1691 | 1739 |
1692 | 1740 |
1741 Object* CallStubCompiler::CompileStringFromCharCodeCall( | |
1742 Object* object, | |
1743 JSObject* holder, | |
1744 JSGlobalPropertyCell* cell, | |
1745 JSFunction* function, | |
1746 String* name) { | |
1747 // ----------- S t a t e ------------- | |
1748 // -- ecx : function name | |
1749 // -- esp[0] : return address | |
1750 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | |
1751 // -- ... | |
1752 // -- esp[(argc + 1) * 4] : receiver | |
1753 // ----------------------------------- | |
1754 | |
1755 const int argc = arguments().immediate(); | |
1756 | |
1757 // If the object is not a JSObject or we got an unexpected number of | |
1758 // arguments, bail out to the regular call. | |
1759 if (!object->IsJSObject() || argc != 1) return Heap::undefined_value(); | |
1760 | |
1761 Label miss; | |
1762 GenerateNameCheck(name, &miss); | |
1763 | |
1764 if (cell == NULL) { | |
1765 __ mov(edx, Operand(esp, 2 * kPointerSize)); | |
1766 | |
1767 STATIC_ASSERT(kSmiTag == 0); | |
1768 __ test(edx, Immediate(kSmiTagMask)); | |
1769 __ j(zero, &miss); | |
1770 | |
1771 CheckPrototypes(JSObject::cast(object), edx, holder, ebx, eax, edi, name, | |
1772 &miss); | |
1773 } else { | |
1774 ASSERT(cell->value() == function); | |
1775 GenerateGlobalReceiverCheck(JSObject::cast(object), holder, name, &miss); | |
1776 GenerateLoadFunctionFromCell(cell, function, &miss); | |
1777 } | |
1778 | |
1779 // Load the char code argument. | |
1780 Register code = ebx; | |
1781 __ mov(code, Operand(esp, 1 * kPointerSize)); | |
1782 | |
1783 // Check the code is a smi. | |
1784 Label slow; | |
1785 STATIC_ASSERT(kSmiTag == 0); | |
1786 __ test(code, Immediate(kSmiTagMask)); | |
1787 __ j(not_zero, &slow); | |
1788 | |
1789 // Convert the smi code to uint16. | |
1790 __ and_(code, (0xffff << kSmiTagSize) | kSmiTag); | |
antonm
2010/09/08 15:26:05
could it be rewritten as __ and_(Operand(code), Im
| |
1791 | |
1792 StringCharFromCodeGenerator char_from_code_generator(code, eax); | |
1793 char_from_code_generator.GenerateFast(masm()); | |
1794 __ ret(2 * kPointerSize); | |
1795 | |
1796 ICRuntimeCallHelper call_helper; | |
1797 char_from_code_generator.GenerateSlow(masm(), call_helper); | |
1798 | |
1799 // Tail call the full function. We do not have to patch the receiver | |
1800 // because the function makes no use of it. | |
1801 __ bind(&slow); | |
1802 __ InvokeFunction(function, arguments(), JUMP_FUNCTION); | |
1803 | |
1804 __ bind(&miss); | |
1805 // ecx: function name. | |
1806 Object* obj = GenerateMissBranch(); | |
1807 if (obj->IsFailure()) return obj; | |
1808 | |
1809 // Return the generated code. | |
1810 return (cell == NULL) ? GetCode(function) : GetCode(NORMAL, name); | |
1811 } | |
1812 | |
1813 | |
1693 Object* CallStubCompiler::CompileCallConstant(Object* object, | 1814 Object* CallStubCompiler::CompileCallConstant(Object* object, |
1694 JSObject* holder, | 1815 JSObject* holder, |
1695 JSFunction* function, | 1816 JSFunction* function, |
1696 String* name, | 1817 String* name, |
1697 CheckType check) { | 1818 CheckType check) { |
1698 // ----------- S t a t e ------------- | 1819 // ----------- S t a t e ------------- |
1699 // -- ecx : name | 1820 // -- ecx : name |
1700 // -- esp[0] : return address | 1821 // -- esp[0] : return address |
1701 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 1822 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1702 // -- ... | 1823 // -- ... |
1703 // -- esp[(argc + 1) * 4] : receiver | 1824 // -- esp[(argc + 1) * 4] : receiver |
1704 // ----------------------------------- | 1825 // ----------------------------------- |
1705 | 1826 |
1706 SharedFunctionInfo* function_info = function->shared(); | 1827 SharedFunctionInfo* function_info = function->shared(); |
1707 if (function_info->HasCustomCallGenerator()) { | 1828 if (function_info->HasCustomCallGenerator()) { |
1708 const int id = function_info->custom_call_generator_id(); | 1829 const int id = function_info->custom_call_generator_id(); |
1709 Object* result = | 1830 Object* result = CompileCustomCall( |
1710 CompileCustomCall(id, object, holder, function, name, check); | 1831 id, object, holder, NULL, function, name); |
1711 // undefined means bail out to regular compiler. | 1832 // undefined means bail out to regular compiler. |
1712 if (!result->IsUndefined()) { | 1833 if (!result->IsUndefined()) return result; |
1713 return result; | |
1714 } | |
1715 } | 1834 } |
1716 | 1835 |
1717 Label miss_in_smi_check; | 1836 Label miss_in_smi_check; |
1718 | 1837 |
1719 GenerateNameCheck(name, &miss_in_smi_check); | 1838 GenerateNameCheck(name, &miss_in_smi_check); |
1720 | 1839 |
1721 // Get the receiver from the stack. | 1840 // Get the receiver from the stack. |
1722 const int argc = arguments().immediate(); | 1841 const int argc = arguments().immediate(); |
1723 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | 1842 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); |
1724 | 1843 |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1915 JSGlobalPropertyCell* cell, | 2034 JSGlobalPropertyCell* cell, |
1916 JSFunction* function, | 2035 JSFunction* function, |
1917 String* name) { | 2036 String* name) { |
1918 // ----------- S t a t e ------------- | 2037 // ----------- S t a t e ------------- |
1919 // -- ecx : name | 2038 // -- ecx : name |
1920 // -- esp[0] : return address | 2039 // -- esp[0] : return address |
1921 // -- esp[(argc - n) * 4] : arg[n] (zero-based) | 2040 // -- esp[(argc - n) * 4] : arg[n] (zero-based) |
1922 // -- ... | 2041 // -- ... |
1923 // -- esp[(argc + 1) * 4] : receiver | 2042 // -- esp[(argc + 1) * 4] : receiver |
1924 // ----------------------------------- | 2043 // ----------------------------------- |
2044 | |
2045 SharedFunctionInfo* function_info = function->shared(); | |
2046 if (function_info->HasCustomCallGenerator()) { | |
2047 const int id = function_info->custom_call_generator_id(); | |
2048 Object* result = CompileCustomCall( | |
2049 id, object, holder, cell, function, name); | |
2050 // undefined means bail out to regular compiler. | |
2051 if (!result->IsUndefined()) return result; | |
2052 } | |
2053 | |
1925 Label miss; | 2054 Label miss; |
1926 | 2055 |
1927 GenerateNameCheck(name, &miss); | 2056 GenerateNameCheck(name, &miss); |
1928 | 2057 |
1929 // Get the number of arguments. | 2058 // Get the number of arguments. |
1930 const int argc = arguments().immediate(); | 2059 const int argc = arguments().immediate(); |
1931 | 2060 |
1932 // Get the receiver from the stack. | 2061 GenerateGlobalReceiverCheck(object, holder, name, &miss); |
1933 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); | |
1934 | 2062 |
1935 // If the object is the holder then we know that it's a global | 2063 GenerateLoadFunctionFromCell(cell, function, &miss); |
1936 // object which can only happen for contextual calls. In this case, | |
1937 // the receiver cannot be a smi. | |
1938 if (object != holder) { | |
1939 __ test(edx, Immediate(kSmiTagMask)); | |
1940 __ j(zero, &miss, not_taken); | |
1941 } | |
1942 | |
1943 // Check that the maps haven't changed. | |
1944 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, &miss); | |
1945 | |
1946 // Get the value from the cell. | |
1947 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); | |
1948 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); | |
1949 | |
1950 // Check that the cell contains the same function. | |
1951 if (Heap::InNewSpace(function)) { | |
1952 // We can't embed a pointer to a function in new space so we have | |
1953 // to verify that the shared function info is unchanged. This has | |
1954 // the nice side effect that multiple closures based on the same | |
1955 // function can all use this call IC. Before we load through the | |
1956 // function, we have to verify that it still is a function. | |
1957 __ test(edi, Immediate(kSmiTagMask)); | |
1958 __ j(zero, &miss, not_taken); | |
1959 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); | |
1960 __ j(not_equal, &miss, not_taken); | |
1961 | |
1962 // Check the shared function info. Make sure it hasn't changed. | |
1963 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), | |
1964 Immediate(Handle<SharedFunctionInfo>(function->shared()))); | |
1965 __ j(not_equal, &miss, not_taken); | |
1966 } else { | |
1967 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); | |
1968 __ j(not_equal, &miss, not_taken); | |
1969 } | |
1970 | 2064 |
1971 // Patch the receiver on the stack with the global proxy. | 2065 // Patch the receiver on the stack with the global proxy. |
1972 if (object->IsGlobalObject()) { | 2066 if (object->IsGlobalObject()) { |
1973 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); | 2067 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); |
1974 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); | 2068 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); |
1975 } | 2069 } |
1976 | 2070 |
1977 // Setup the context (function already in edi). | 2071 // Setup the context (function already in edi). |
1978 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 2072 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
1979 | 2073 |
(...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2724 // Return the generated code. | 2818 // Return the generated code. |
2725 return GetCode(); | 2819 return GetCode(); |
2726 } | 2820 } |
2727 | 2821 |
2728 | 2822 |
2729 #undef __ | 2823 #undef __ |
2730 | 2824 |
2731 } } // namespace v8::internal | 2825 } } // namespace v8::internal |
2732 | 2826 |
2733 #endif // V8_TARGET_ARCH_IA32 | 2827 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |