| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #if V8_TARGET_ARCH_X64 | 5 #if V8_TARGET_ARCH_X64 |
| 6 | 6 |
| 7 #include "src/full-codegen/full-codegen.h" | 7 #include "src/full-codegen/full-codegen.h" |
| 8 #include "src/ast/compile-time-value.h" | 8 #include "src/ast/compile-time-value.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 break; | 1363 break; |
| 1364 case NAMED_PROPERTY: | 1364 case NAMED_PROPERTY: |
| 1365 if (expr->is_compound()) { | 1365 if (expr->is_compound()) { |
| 1366 // We need the receiver both on the stack and in the register. | 1366 // We need the receiver both on the stack and in the register. |
| 1367 VisitForStackValue(property->obj()); | 1367 VisitForStackValue(property->obj()); |
| 1368 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1368 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1369 } else { | 1369 } else { |
| 1370 VisitForStackValue(property->obj()); | 1370 VisitForStackValue(property->obj()); |
| 1371 } | 1371 } |
| 1372 break; | 1372 break; |
| 1373 case NAMED_SUPER_PROPERTY: | |
| 1374 VisitForStackValue( | |
| 1375 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1376 VisitForAccumulatorValue( | |
| 1377 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1378 PushOperand(result_register()); | |
| 1379 if (expr->is_compound()) { | |
| 1380 PushOperand(MemOperand(rsp, kPointerSize)); | |
| 1381 PushOperand(result_register()); | |
| 1382 } | |
| 1383 break; | |
| 1384 case KEYED_SUPER_PROPERTY: | |
| 1385 VisitForStackValue( | |
| 1386 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1387 VisitForStackValue( | |
| 1388 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1389 VisitForAccumulatorValue(property->key()); | |
| 1390 PushOperand(result_register()); | |
| 1391 if (expr->is_compound()) { | |
| 1392 PushOperand(MemOperand(rsp, 2 * kPointerSize)); | |
| 1393 PushOperand(MemOperand(rsp, 2 * kPointerSize)); | |
| 1394 PushOperand(result_register()); | |
| 1395 } | |
| 1396 break; | |
| 1397 case KEYED_PROPERTY: { | 1373 case KEYED_PROPERTY: { |
| 1398 if (expr->is_compound()) { | 1374 if (expr->is_compound()) { |
| 1399 VisitForStackValue(property->obj()); | 1375 VisitForStackValue(property->obj()); |
| 1400 VisitForStackValue(property->key()); | 1376 VisitForStackValue(property->key()); |
| 1401 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); | 1377 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); |
| 1402 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); | 1378 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); |
| 1403 } else { | 1379 } else { |
| 1404 VisitForStackValue(property->obj()); | 1380 VisitForStackValue(property->obj()); |
| 1405 VisitForStackValue(property->key()); | 1381 VisitForStackValue(property->key()); |
| 1406 } | 1382 } |
| 1407 break; | 1383 break; |
| 1408 } | 1384 } |
| 1385 case NAMED_SUPER_PROPERTY: |
| 1386 case KEYED_SUPER_PROPERTY: |
| 1387 UNREACHABLE(); |
| 1388 break; |
| 1409 } | 1389 } |
| 1410 | 1390 |
| 1411 // For compound assignments we need another deoptimization point after the | 1391 // For compound assignments we need another deoptimization point after the |
| 1412 // variable/property load. | 1392 // variable/property load. |
| 1413 if (expr->is_compound()) { | 1393 if (expr->is_compound()) { |
| 1414 { AccumulatorValueContext context(this); | 1394 { AccumulatorValueContext context(this); |
| 1415 switch (assign_type) { | 1395 switch (assign_type) { |
| 1416 case VARIABLE: | 1396 case VARIABLE: |
| 1417 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1397 EmitVariableLoad(expr->target()->AsVariableProxy()); |
| 1418 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1398 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
| 1419 break; | 1399 break; |
| 1420 case NAMED_PROPERTY: | 1400 case NAMED_PROPERTY: |
| 1421 EmitNamedPropertyLoad(property); | 1401 EmitNamedPropertyLoad(property); |
| 1422 PrepareForBailoutForId(property->LoadId(), | 1402 PrepareForBailoutForId(property->LoadId(), |
| 1423 BailoutState::TOS_REGISTER); | 1403 BailoutState::TOS_REGISTER); |
| 1424 break; | 1404 break; |
| 1425 case NAMED_SUPER_PROPERTY: | |
| 1426 EmitNamedSuperPropertyLoad(property); | |
| 1427 PrepareForBailoutForId(property->LoadId(), | |
| 1428 BailoutState::TOS_REGISTER); | |
| 1429 break; | |
| 1430 case KEYED_SUPER_PROPERTY: | |
| 1431 EmitKeyedSuperPropertyLoad(property); | |
| 1432 PrepareForBailoutForId(property->LoadId(), | |
| 1433 BailoutState::TOS_REGISTER); | |
| 1434 break; | |
| 1435 case KEYED_PROPERTY: | 1405 case KEYED_PROPERTY: |
| 1436 EmitKeyedPropertyLoad(property); | 1406 EmitKeyedPropertyLoad(property); |
| 1437 PrepareForBailoutForId(property->LoadId(), | 1407 PrepareForBailoutForId(property->LoadId(), |
| 1438 BailoutState::TOS_REGISTER); | 1408 BailoutState::TOS_REGISTER); |
| 1439 break; | 1409 break; |
| 1410 case NAMED_SUPER_PROPERTY: |
| 1411 case KEYED_SUPER_PROPERTY: |
| 1412 UNREACHABLE(); |
| 1413 break; |
| 1440 } | 1414 } |
| 1441 } | 1415 } |
| 1442 | 1416 |
| 1443 Token::Value op = expr->binary_op(); | 1417 Token::Value op = expr->binary_op(); |
| 1444 PushOperand(rax); // Left operand goes on the stack. | 1418 PushOperand(rax); // Left operand goes on the stack. |
| 1445 VisitForAccumulatorValue(expr->value()); | 1419 VisitForAccumulatorValue(expr->value()); |
| 1446 | 1420 |
| 1447 AccumulatorValueContext context(this); | 1421 AccumulatorValueContext context(this); |
| 1448 if (ShouldInlineSmiCase(op)) { | 1422 if (ShouldInlineSmiCase(op)) { |
| 1449 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1423 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1467 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1441 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1468 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1442 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1469 proxy->hole_check_mode()); | 1443 proxy->hole_check_mode()); |
| 1470 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1444 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1471 context()->Plug(rax); | 1445 context()->Plug(rax); |
| 1472 break; | 1446 break; |
| 1473 } | 1447 } |
| 1474 case NAMED_PROPERTY: | 1448 case NAMED_PROPERTY: |
| 1475 EmitNamedPropertyAssignment(expr); | 1449 EmitNamedPropertyAssignment(expr); |
| 1476 break; | 1450 break; |
| 1477 case NAMED_SUPER_PROPERTY: | |
| 1478 EmitNamedSuperPropertyStore(property); | |
| 1479 context()->Plug(rax); | |
| 1480 break; | |
| 1481 case KEYED_SUPER_PROPERTY: | |
| 1482 EmitKeyedSuperPropertyStore(property); | |
| 1483 context()->Plug(rax); | |
| 1484 break; | |
| 1485 case KEYED_PROPERTY: | 1451 case KEYED_PROPERTY: |
| 1486 EmitKeyedPropertyAssignment(expr); | 1452 EmitKeyedPropertyAssignment(expr); |
| 1487 break; | 1453 break; |
| 1454 case NAMED_SUPER_PROPERTY: |
| 1455 case KEYED_SUPER_PROPERTY: |
| 1456 UNREACHABLE(); |
| 1457 break; |
| 1488 } | 1458 } |
| 1489 } | 1459 } |
| 1490 | 1460 |
| 1491 | 1461 |
| 1492 void FullCodeGenerator::VisitYield(Yield* expr) { | 1462 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 1493 // Resumable functions are not supported. | 1463 // Resumable functions are not supported. |
| 1494 UNREACHABLE(); | 1464 UNREACHABLE(); |
| 1495 } | 1465 } |
| 1496 | 1466 |
| 1497 void FullCodeGenerator::PushOperand(MemOperand operand) { | 1467 void FullCodeGenerator::PushOperand(MemOperand operand) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1621 break; | 1591 break; |
| 1622 } | 1592 } |
| 1623 case NAMED_PROPERTY: { | 1593 case NAMED_PROPERTY: { |
| 1624 PushOperand(rax); // Preserve value. | 1594 PushOperand(rax); // Preserve value. |
| 1625 VisitForAccumulatorValue(prop->obj()); | 1595 VisitForAccumulatorValue(prop->obj()); |
| 1626 __ Move(StoreDescriptor::ReceiverRegister(), rax); | 1596 __ Move(StoreDescriptor::ReceiverRegister(), rax); |
| 1627 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1597 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1628 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1598 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 1629 break; | 1599 break; |
| 1630 } | 1600 } |
| 1631 case NAMED_SUPER_PROPERTY: { | |
| 1632 PushOperand(rax); | |
| 1633 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1634 VisitForAccumulatorValue( | |
| 1635 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1636 // stack: value, this; rax: home_object | |
| 1637 Register scratch = rcx; | |
| 1638 Register scratch2 = rdx; | |
| 1639 __ Move(scratch, result_register()); // home_object | |
| 1640 __ movp(rax, MemOperand(rsp, kPointerSize)); // value | |
| 1641 __ movp(scratch2, MemOperand(rsp, 0)); // this | |
| 1642 __ movp(MemOperand(rsp, kPointerSize), scratch2); // this | |
| 1643 __ movp(MemOperand(rsp, 0), scratch); // home_object | |
| 1644 // stack: this, home_object; rax: value | |
| 1645 EmitNamedSuperPropertyStore(prop); | |
| 1646 break; | |
| 1647 } | |
| 1648 case KEYED_SUPER_PROPERTY: { | |
| 1649 PushOperand(rax); | |
| 1650 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1651 VisitForStackValue( | |
| 1652 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1653 VisitForAccumulatorValue(prop->key()); | |
| 1654 Register scratch = rcx; | |
| 1655 Register scratch2 = rdx; | |
| 1656 __ movp(scratch2, MemOperand(rsp, 2 * kPointerSize)); // value | |
| 1657 // stack: value, this, home_object; rax: key, rdx: value | |
| 1658 __ movp(scratch, MemOperand(rsp, kPointerSize)); // this | |
| 1659 __ movp(MemOperand(rsp, 2 * kPointerSize), scratch); | |
| 1660 __ movp(scratch, MemOperand(rsp, 0)); // home_object | |
| 1661 __ movp(MemOperand(rsp, kPointerSize), scratch); | |
| 1662 __ movp(MemOperand(rsp, 0), rax); | |
| 1663 __ Move(rax, scratch2); | |
| 1664 // stack: this, home_object, key; rax: value. | |
| 1665 EmitKeyedSuperPropertyStore(prop); | |
| 1666 break; | |
| 1667 } | |
| 1668 case KEYED_PROPERTY: { | 1601 case KEYED_PROPERTY: { |
| 1669 PushOperand(rax); // Preserve value. | 1602 PushOperand(rax); // Preserve value. |
| 1670 VisitForStackValue(prop->obj()); | 1603 VisitForStackValue(prop->obj()); |
| 1671 VisitForAccumulatorValue(prop->key()); | 1604 VisitForAccumulatorValue(prop->key()); |
| 1672 __ Move(StoreDescriptor::NameRegister(), rax); | 1605 __ Move(StoreDescriptor::NameRegister(), rax); |
| 1673 PopOperand(StoreDescriptor::ReceiverRegister()); | 1606 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1674 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1607 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1675 CallKeyedStoreIC(slot); | 1608 CallKeyedStoreIC(slot); |
| 1676 break; | 1609 break; |
| 1677 } | 1610 } |
| 1611 case NAMED_SUPER_PROPERTY: |
| 1612 case KEYED_SUPER_PROPERTY: |
| 1613 UNREACHABLE(); |
| 1614 break; |
| 1678 } | 1615 } |
| 1679 context()->Plug(rax); | 1616 context()->Plug(rax); |
| 1680 } | 1617 } |
| 1681 | 1618 |
| 1682 | 1619 |
| 1683 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1620 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 1684 Variable* var, MemOperand location) { | 1621 Variable* var, MemOperand location) { |
| 1685 __ movp(location, rax); | 1622 __ movp(location, rax); |
| 1686 if (var->IsContextSlot()) { | 1623 if (var->IsContextSlot()) { |
| 1687 __ movp(rdx, rax); | 1624 __ movp(rdx, rax); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1756 DCHECK(prop->key()->IsLiteral()); | 1693 DCHECK(prop->key()->IsLiteral()); |
| 1757 | 1694 |
| 1758 PopOperand(StoreDescriptor::ReceiverRegister()); | 1695 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1759 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1696 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
| 1760 | 1697 |
| 1761 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1698 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1762 context()->Plug(rax); | 1699 context()->Plug(rax); |
| 1763 } | 1700 } |
| 1764 | 1701 |
| 1765 | 1702 |
| 1766 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
| 1767 // Assignment to named property of super. | |
| 1768 // rax : value | |
| 1769 // stack : receiver ('this'), home_object | |
| 1770 DCHECK(prop != NULL); | |
| 1771 Literal* key = prop->key()->AsLiteral(); | |
| 1772 DCHECK(key != NULL); | |
| 1773 | |
| 1774 PushOperand(key->value()); | |
| 1775 PushOperand(rax); | |
| 1776 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1777 ? Runtime::kStoreToSuper_Strict | |
| 1778 : Runtime::kStoreToSuper_Sloppy); | |
| 1779 } | |
| 1780 | |
| 1781 | |
| 1782 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
| 1783 // Assignment to named property of super. | |
| 1784 // rax : value | |
| 1785 // stack : receiver ('this'), home_object, key | |
| 1786 DCHECK(prop != NULL); | |
| 1787 | |
| 1788 PushOperand(rax); | |
| 1789 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1790 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1791 : Runtime::kStoreKeyedToSuper_Sloppy); | |
| 1792 } | |
| 1793 | |
| 1794 | |
| 1795 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1703 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1796 // Assignment to a property, using a keyed store IC. | 1704 // Assignment to a property, using a keyed store IC. |
| 1797 PopOperand(StoreDescriptor::NameRegister()); // Key. | 1705 PopOperand(StoreDescriptor::NameRegister()); // Key. |
| 1798 PopOperand(StoreDescriptor::ReceiverRegister()); | 1706 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1799 DCHECK(StoreDescriptor::ValueRegister().is(rax)); | 1707 DCHECK(StoreDescriptor::ValueRegister().is(rax)); |
| 1800 CallKeyedStoreIC(expr->AssignmentSlot()); | 1708 CallKeyedStoreIC(expr->AssignmentSlot()); |
| 1801 | 1709 |
| 1802 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1710 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1803 context()->Plug(rax); | 1711 context()->Plug(rax); |
| 1804 } | 1712 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1829 // Push the target function under the receiver. | 1737 // Push the target function under the receiver. |
| 1830 PushOperand(Operand(rsp, 0)); | 1738 PushOperand(Operand(rsp, 0)); |
| 1831 __ movp(Operand(rsp, kPointerSize), rax); | 1739 __ movp(Operand(rsp, kPointerSize), rax); |
| 1832 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1740 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1833 } | 1741 } |
| 1834 | 1742 |
| 1835 EmitCall(expr, convert_mode); | 1743 EmitCall(expr, convert_mode); |
| 1836 } | 1744 } |
| 1837 | 1745 |
| 1838 | 1746 |
| 1839 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
| 1840 Expression* callee = expr->expression(); | |
| 1841 DCHECK(callee->IsProperty()); | |
| 1842 Property* prop = callee->AsProperty(); | |
| 1843 DCHECK(prop->IsSuperAccess()); | |
| 1844 SetExpressionPosition(prop); | |
| 1845 | |
| 1846 Literal* key = prop->key()->AsLiteral(); | |
| 1847 DCHECK(!key->value()->IsSmi()); | |
| 1848 // Load the function from the receiver. | |
| 1849 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1850 VisitForStackValue(super_ref->home_object()); | |
| 1851 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1852 PushOperand(rax); | |
| 1853 PushOperand(rax); | |
| 1854 PushOperand(Operand(rsp, kPointerSize * 2)); | |
| 1855 PushOperand(key->value()); | |
| 1856 | |
| 1857 // Stack here: | |
| 1858 // - home_object | |
| 1859 // - this (receiver) | |
| 1860 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
| 1861 // - home_object | |
| 1862 // - key | |
| 1863 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
| 1864 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1865 | |
| 1866 // Replace home_object with target function. | |
| 1867 __ movp(Operand(rsp, kPointerSize), rax); | |
| 1868 | |
| 1869 // Stack here: | |
| 1870 // - target function | |
| 1871 // - this (receiver) | |
| 1872 EmitCall(expr); | |
| 1873 } | |
| 1874 | |
| 1875 | |
| 1876 // Common code for calls using the IC. | 1747 // Common code for calls using the IC. |
| 1877 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1748 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 1878 Expression* key) { | 1749 Expression* key) { |
| 1879 // Load the key. | 1750 // Load the key. |
| 1880 VisitForAccumulatorValue(key); | 1751 VisitForAccumulatorValue(key); |
| 1881 | 1752 |
| 1882 Expression* callee = expr->expression(); | 1753 Expression* callee = expr->expression(); |
| 1883 | 1754 |
| 1884 // Load the function from the receiver. | 1755 // Load the function from the receiver. |
| 1885 DCHECK(callee->IsProperty()); | 1756 DCHECK(callee->IsProperty()); |
| 1886 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 1757 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 1887 __ Move(LoadDescriptor::NameRegister(), rax); | 1758 __ Move(LoadDescriptor::NameRegister(), rax); |
| 1888 EmitKeyedPropertyLoad(callee->AsProperty()); | 1759 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 1889 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1760 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
| 1890 BailoutState::TOS_REGISTER); | 1761 BailoutState::TOS_REGISTER); |
| 1891 | 1762 |
| 1892 // Push the target function under the receiver. | 1763 // Push the target function under the receiver. |
| 1893 PushOperand(Operand(rsp, 0)); | 1764 PushOperand(Operand(rsp, 0)); |
| 1894 __ movp(Operand(rsp, kPointerSize), rax); | 1765 __ movp(Operand(rsp, kPointerSize), rax); |
| 1895 | 1766 |
| 1896 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1767 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 1897 } | 1768 } |
| 1898 | 1769 |
| 1899 | 1770 |
| 1900 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
| 1901 Expression* callee = expr->expression(); | |
| 1902 DCHECK(callee->IsProperty()); | |
| 1903 Property* prop = callee->AsProperty(); | |
| 1904 DCHECK(prop->IsSuperAccess()); | |
| 1905 | |
| 1906 SetExpressionPosition(prop); | |
| 1907 // Load the function from the receiver. | |
| 1908 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1909 VisitForStackValue(super_ref->home_object()); | |
| 1910 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1911 PushOperand(rax); | |
| 1912 PushOperand(rax); | |
| 1913 PushOperand(Operand(rsp, kPointerSize * 2)); | |
| 1914 VisitForStackValue(prop->key()); | |
| 1915 | |
| 1916 // Stack here: | |
| 1917 // - home_object | |
| 1918 // - this (receiver) | |
| 1919 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
| 1920 // - home_object | |
| 1921 // - key | |
| 1922 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
| 1923 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1924 | |
| 1925 // Replace home_object with target function. | |
| 1926 __ movp(Operand(rsp, kPointerSize), rax); | |
| 1927 | |
| 1928 // Stack here: | |
| 1929 // - target function | |
| 1930 // - this (receiver) | |
| 1931 EmitCall(expr); | |
| 1932 } | |
| 1933 | |
| 1934 | |
| 1935 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1771 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
| 1936 // Load the arguments. | 1772 // Load the arguments. |
| 1937 ZoneList<Expression*>* args = expr->arguments(); | 1773 ZoneList<Expression*>* args = expr->arguments(); |
| 1938 int arg_count = args->length(); | 1774 int arg_count = args->length(); |
| 1939 for (int i = 0; i < arg_count; i++) { | 1775 for (int i = 0; i < arg_count; i++) { |
| 1940 VisitForStackValue(args->at(i)); | 1776 VisitForStackValue(args->at(i)); |
| 1941 } | 1777 } |
| 1942 | 1778 |
| 1943 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1779 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
| 1944 SetCallPosition(expr, expr->tail_call_mode()); | 1780 SetCallPosition(expr, expr->tail_call_mode()); |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2455 PushOperand(Smi::kZero); | 2291 PushOperand(Smi::kZero); |
| 2456 } | 2292 } |
| 2457 switch (assign_type) { | 2293 switch (assign_type) { |
| 2458 case NAMED_PROPERTY: { | 2294 case NAMED_PROPERTY: { |
| 2459 VisitForStackValue(prop->obj()); | 2295 VisitForStackValue(prop->obj()); |
| 2460 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); | 2296 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, 0)); |
| 2461 EmitNamedPropertyLoad(prop); | 2297 EmitNamedPropertyLoad(prop); |
| 2462 break; | 2298 break; |
| 2463 } | 2299 } |
| 2464 | 2300 |
| 2465 case NAMED_SUPER_PROPERTY: { | |
| 2466 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2467 VisitForAccumulatorValue( | |
| 2468 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2469 PushOperand(result_register()); | |
| 2470 PushOperand(MemOperand(rsp, kPointerSize)); | |
| 2471 PushOperand(result_register()); | |
| 2472 EmitNamedSuperPropertyLoad(prop); | |
| 2473 break; | |
| 2474 } | |
| 2475 | |
| 2476 case KEYED_SUPER_PROPERTY: { | |
| 2477 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2478 VisitForStackValue( | |
| 2479 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2480 VisitForAccumulatorValue(prop->key()); | |
| 2481 PushOperand(result_register()); | |
| 2482 PushOperand(MemOperand(rsp, 2 * kPointerSize)); | |
| 2483 PushOperand(MemOperand(rsp, 2 * kPointerSize)); | |
| 2484 PushOperand(result_register()); | |
| 2485 EmitKeyedSuperPropertyLoad(prop); | |
| 2486 break; | |
| 2487 } | |
| 2488 | |
| 2489 case KEYED_PROPERTY: { | 2301 case KEYED_PROPERTY: { |
| 2490 VisitForStackValue(prop->obj()); | 2302 VisitForStackValue(prop->obj()); |
| 2491 VisitForStackValue(prop->key()); | 2303 VisitForStackValue(prop->key()); |
| 2492 // Leave receiver on stack | 2304 // Leave receiver on stack |
| 2493 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); | 2305 __ movp(LoadDescriptor::ReceiverRegister(), Operand(rsp, kPointerSize)); |
| 2494 // Copy of key, needed for later store. | 2306 // Copy of key, needed for later store. |
| 2495 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); | 2307 __ movp(LoadDescriptor::NameRegister(), Operand(rsp, 0)); |
| 2496 EmitKeyedPropertyLoad(prop); | 2308 EmitKeyedPropertyLoad(prop); |
| 2497 break; | 2309 break; |
| 2498 } | 2310 } |
| 2499 | 2311 |
| 2312 case NAMED_SUPER_PROPERTY: |
| 2313 case KEYED_SUPER_PROPERTY: |
| 2500 case VARIABLE: | 2314 case VARIABLE: |
| 2501 UNREACHABLE(); | 2315 UNREACHABLE(); |
| 2502 } | 2316 } |
| 2503 } | 2317 } |
| 2504 | 2318 |
| 2505 // We need a second deoptimization point after loading the value | 2319 // We need a second deoptimization point after loading the value |
| 2506 // in case evaluating the property load my have a side effect. | 2320 // in case evaluating the property load my have a side effect. |
| 2507 if (assign_type == VARIABLE) { | 2321 if (assign_type == VARIABLE) { |
| 2508 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2322 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
| 2509 } else { | 2323 } else { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2523 // Save the result on the stack. If we have a named or keyed property | 2337 // Save the result on the stack. If we have a named or keyed property |
| 2524 // we store the result under the receiver that is currently on top | 2338 // we store the result under the receiver that is currently on top |
| 2525 // of the stack. | 2339 // of the stack. |
| 2526 switch (assign_type) { | 2340 switch (assign_type) { |
| 2527 case VARIABLE: | 2341 case VARIABLE: |
| 2528 __ Push(rax); | 2342 __ Push(rax); |
| 2529 break; | 2343 break; |
| 2530 case NAMED_PROPERTY: | 2344 case NAMED_PROPERTY: |
| 2531 __ movp(Operand(rsp, kPointerSize), rax); | 2345 __ movp(Operand(rsp, kPointerSize), rax); |
| 2532 break; | 2346 break; |
| 2533 case NAMED_SUPER_PROPERTY: | |
| 2534 __ movp(Operand(rsp, 2 * kPointerSize), rax); | |
| 2535 break; | |
| 2536 case KEYED_PROPERTY: | 2347 case KEYED_PROPERTY: |
| 2537 __ movp(Operand(rsp, 2 * kPointerSize), rax); | 2348 __ movp(Operand(rsp, 2 * kPointerSize), rax); |
| 2538 break; | 2349 break; |
| 2350 case NAMED_SUPER_PROPERTY: |
| 2539 case KEYED_SUPER_PROPERTY: | 2351 case KEYED_SUPER_PROPERTY: |
| 2540 __ movp(Operand(rsp, 3 * kPointerSize), rax); | 2352 UNREACHABLE(); |
| 2541 break; | 2353 break; |
| 2542 } | 2354 } |
| 2543 } | 2355 } |
| 2544 } | 2356 } |
| 2545 | 2357 |
| 2546 SmiOperationConstraints constraints = | 2358 SmiOperationConstraints constraints = |
| 2547 SmiOperationConstraint::kPreserveSourceRegister | | 2359 SmiOperationConstraint::kPreserveSourceRegister | |
| 2548 SmiOperationConstraint::kBailoutOnNoOverflow; | 2360 SmiOperationConstraint::kBailoutOnNoOverflow; |
| 2549 if (expr->op() == Token::INC) { | 2361 if (expr->op() == Token::INC) { |
| 2550 __ SmiAddConstant(rax, rax, Smi::FromInt(1), constraints, &done, | 2362 __ SmiAddConstant(rax, rax, Smi::FromInt(1), constraints, &done, |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2568 // Save the result on the stack. If we have a named or keyed property | 2380 // Save the result on the stack. If we have a named or keyed property |
| 2569 // we store the result under the receiver that is currently on top | 2381 // we store the result under the receiver that is currently on top |
| 2570 // of the stack. | 2382 // of the stack. |
| 2571 switch (assign_type) { | 2383 switch (assign_type) { |
| 2572 case VARIABLE: | 2384 case VARIABLE: |
| 2573 PushOperand(rax); | 2385 PushOperand(rax); |
| 2574 break; | 2386 break; |
| 2575 case NAMED_PROPERTY: | 2387 case NAMED_PROPERTY: |
| 2576 __ movp(Operand(rsp, kPointerSize), rax); | 2388 __ movp(Operand(rsp, kPointerSize), rax); |
| 2577 break; | 2389 break; |
| 2578 case NAMED_SUPER_PROPERTY: | |
| 2579 __ movp(Operand(rsp, 2 * kPointerSize), rax); | |
| 2580 break; | |
| 2581 case KEYED_PROPERTY: | 2390 case KEYED_PROPERTY: |
| 2582 __ movp(Operand(rsp, 2 * kPointerSize), rax); | 2391 __ movp(Operand(rsp, 2 * kPointerSize), rax); |
| 2583 break; | 2392 break; |
| 2393 case NAMED_SUPER_PROPERTY: |
| 2584 case KEYED_SUPER_PROPERTY: | 2394 case KEYED_SUPER_PROPERTY: |
| 2585 __ movp(Operand(rsp, 3 * kPointerSize), rax); | 2395 UNREACHABLE(); |
| 2586 break; | 2396 break; |
| 2587 } | 2397 } |
| 2588 } | 2398 } |
| 2589 } | 2399 } |
| 2590 | 2400 |
| 2591 SetExpressionPosition(expr); | 2401 SetExpressionPosition(expr); |
| 2592 | 2402 |
| 2593 // Call stub for +1/-1. | 2403 // Call stub for +1/-1. |
| 2594 __ bind(&stub_call); | 2404 __ bind(&stub_call); |
| 2595 __ movp(rdx, rax); | 2405 __ movp(rdx, rax); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2634 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2444 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2635 if (expr->is_postfix()) { | 2445 if (expr->is_postfix()) { |
| 2636 if (!context()->IsEffect()) { | 2446 if (!context()->IsEffect()) { |
| 2637 context()->PlugTOS(); | 2447 context()->PlugTOS(); |
| 2638 } | 2448 } |
| 2639 } else { | 2449 } else { |
| 2640 context()->Plug(rax); | 2450 context()->Plug(rax); |
| 2641 } | 2451 } |
| 2642 break; | 2452 break; |
| 2643 } | 2453 } |
| 2644 case NAMED_SUPER_PROPERTY: { | |
| 2645 EmitNamedSuperPropertyStore(prop); | |
| 2646 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2647 if (expr->is_postfix()) { | |
| 2648 if (!context()->IsEffect()) { | |
| 2649 context()->PlugTOS(); | |
| 2650 } | |
| 2651 } else { | |
| 2652 context()->Plug(rax); | |
| 2653 } | |
| 2654 break; | |
| 2655 } | |
| 2656 case KEYED_SUPER_PROPERTY: { | |
| 2657 EmitKeyedSuperPropertyStore(prop); | |
| 2658 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2659 if (expr->is_postfix()) { | |
| 2660 if (!context()->IsEffect()) { | |
| 2661 context()->PlugTOS(); | |
| 2662 } | |
| 2663 } else { | |
| 2664 context()->Plug(rax); | |
| 2665 } | |
| 2666 break; | |
| 2667 } | |
| 2668 case KEYED_PROPERTY: { | 2454 case KEYED_PROPERTY: { |
| 2669 PopOperand(StoreDescriptor::NameRegister()); | 2455 PopOperand(StoreDescriptor::NameRegister()); |
| 2670 PopOperand(StoreDescriptor::ReceiverRegister()); | 2456 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 2671 CallKeyedStoreIC(expr->CountSlot()); | 2457 CallKeyedStoreIC(expr->CountSlot()); |
| 2672 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2458 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2673 if (expr->is_postfix()) { | 2459 if (expr->is_postfix()) { |
| 2674 if (!context()->IsEffect()) { | 2460 if (!context()->IsEffect()) { |
| 2675 context()->PlugTOS(); | 2461 context()->PlugTOS(); |
| 2676 } | 2462 } |
| 2677 } else { | 2463 } else { |
| 2678 context()->Plug(rax); | 2464 context()->Plug(rax); |
| 2679 } | 2465 } |
| 2680 break; | 2466 break; |
| 2681 } | 2467 } |
| 2468 case NAMED_SUPER_PROPERTY: |
| 2469 case KEYED_SUPER_PROPERTY: |
| 2470 UNREACHABLE(); |
| 2471 break; |
| 2682 } | 2472 } |
| 2683 } | 2473 } |
| 2684 | 2474 |
| 2685 | 2475 |
| 2686 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2476 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 2687 Expression* sub_expr, | 2477 Expression* sub_expr, |
| 2688 Handle<String> check) { | 2478 Handle<String> check) { |
| 2689 Label materialize_true, materialize_false; | 2479 Label materialize_true, materialize_false; |
| 2690 Label* if_true = NULL; | 2480 Label* if_true = NULL; |
| 2691 Label* if_false = NULL; | 2481 Label* if_false = NULL; |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2980 DCHECK_EQ( | 2770 DCHECK_EQ( |
| 2981 isolate->builtins()->OnStackReplacement()->entry(), | 2771 isolate->builtins()->OnStackReplacement()->entry(), |
| 2982 Assembler::target_address_at(call_target_address, unoptimized_code)); | 2772 Assembler::target_address_at(call_target_address, unoptimized_code)); |
| 2983 return ON_STACK_REPLACEMENT; | 2773 return ON_STACK_REPLACEMENT; |
| 2984 } | 2774 } |
| 2985 | 2775 |
| 2986 } // namespace internal | 2776 } // namespace internal |
| 2987 } // namespace v8 | 2777 } // namespace v8 |
| 2988 | 2778 |
| 2989 #endif // V8_TARGET_ARCH_X64 | 2779 #endif // V8_TARGET_ARCH_X64 |
| OLD | NEW |