OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
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 1383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1394 break; | 1394 break; |
1395 case NAMED_PROPERTY: | 1395 case NAMED_PROPERTY: |
1396 if (expr->is_compound()) { | 1396 if (expr->is_compound()) { |
1397 // We need the receiver both on the stack and in the register. | 1397 // We need the receiver both on the stack and in the register. |
1398 VisitForStackValue(property->obj()); | 1398 VisitForStackValue(property->obj()); |
1399 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 1399 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
1400 } else { | 1400 } else { |
1401 VisitForStackValue(property->obj()); | 1401 VisitForStackValue(property->obj()); |
1402 } | 1402 } |
1403 break; | 1403 break; |
1404 case NAMED_SUPER_PROPERTY: | |
1405 VisitForStackValue( | |
1406 property->obj()->AsSuperPropertyReference()->this_var()); | |
1407 VisitForAccumulatorValue( | |
1408 property->obj()->AsSuperPropertyReference()->home_object()); | |
1409 PushOperand(result_register()); | |
1410 if (expr->is_compound()) { | |
1411 const Register scratch = x10; | |
1412 __ Peek(scratch, kPointerSize); | |
1413 PushOperands(scratch, result_register()); | |
1414 } | |
1415 break; | |
1416 case KEYED_SUPER_PROPERTY: | |
1417 VisitForStackValue( | |
1418 property->obj()->AsSuperPropertyReference()->this_var()); | |
1419 VisitForStackValue( | |
1420 property->obj()->AsSuperPropertyReference()->home_object()); | |
1421 VisitForAccumulatorValue(property->key()); | |
1422 PushOperand(result_register()); | |
1423 if (expr->is_compound()) { | |
1424 const Register scratch1 = x10; | |
1425 const Register scratch2 = x11; | |
1426 __ Peek(scratch1, 2 * kPointerSize); | |
1427 __ Peek(scratch2, kPointerSize); | |
1428 PushOperands(scratch1, scratch2, result_register()); | |
1429 } | |
1430 break; | |
1431 case KEYED_PROPERTY: | 1404 case KEYED_PROPERTY: |
1432 if (expr->is_compound()) { | 1405 if (expr->is_compound()) { |
1433 VisitForStackValue(property->obj()); | 1406 VisitForStackValue(property->obj()); |
1434 VisitForStackValue(property->key()); | 1407 VisitForStackValue(property->key()); |
1435 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 1408 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
1436 __ Peek(LoadDescriptor::NameRegister(), 0); | 1409 __ Peek(LoadDescriptor::NameRegister(), 0); |
1437 } else { | 1410 } else { |
1438 VisitForStackValue(property->obj()); | 1411 VisitForStackValue(property->obj()); |
1439 VisitForStackValue(property->key()); | 1412 VisitForStackValue(property->key()); |
1440 } | 1413 } |
1441 break; | 1414 break; |
| 1415 case NAMED_SUPER_PROPERTY: |
| 1416 case KEYED_SUPER_PROPERTY: |
| 1417 UNREACHABLE(); |
| 1418 break; |
1442 } | 1419 } |
1443 | 1420 |
1444 // For compound assignments we need another deoptimization point after the | 1421 // For compound assignments we need another deoptimization point after the |
1445 // variable/property load. | 1422 // variable/property load. |
1446 if (expr->is_compound()) { | 1423 if (expr->is_compound()) { |
1447 { AccumulatorValueContext context(this); | 1424 { AccumulatorValueContext context(this); |
1448 switch (assign_type) { | 1425 switch (assign_type) { |
1449 case VARIABLE: | 1426 case VARIABLE: |
1450 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1427 EmitVariableLoad(expr->target()->AsVariableProxy()); |
1451 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1428 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
1452 break; | 1429 break; |
1453 case NAMED_PROPERTY: | 1430 case NAMED_PROPERTY: |
1454 EmitNamedPropertyLoad(property); | 1431 EmitNamedPropertyLoad(property); |
1455 PrepareForBailoutForId(property->LoadId(), | 1432 PrepareForBailoutForId(property->LoadId(), |
1456 BailoutState::TOS_REGISTER); | 1433 BailoutState::TOS_REGISTER); |
1457 break; | 1434 break; |
1458 case NAMED_SUPER_PROPERTY: | |
1459 EmitNamedSuperPropertyLoad(property); | |
1460 PrepareForBailoutForId(property->LoadId(), | |
1461 BailoutState::TOS_REGISTER); | |
1462 break; | |
1463 case KEYED_SUPER_PROPERTY: | |
1464 EmitKeyedSuperPropertyLoad(property); | |
1465 PrepareForBailoutForId(property->LoadId(), | |
1466 BailoutState::TOS_REGISTER); | |
1467 break; | |
1468 case KEYED_PROPERTY: | 1435 case KEYED_PROPERTY: |
1469 EmitKeyedPropertyLoad(property); | 1436 EmitKeyedPropertyLoad(property); |
1470 PrepareForBailoutForId(property->LoadId(), | 1437 PrepareForBailoutForId(property->LoadId(), |
1471 BailoutState::TOS_REGISTER); | 1438 BailoutState::TOS_REGISTER); |
1472 break; | 1439 break; |
| 1440 case NAMED_SUPER_PROPERTY: |
| 1441 case KEYED_SUPER_PROPERTY: |
| 1442 UNREACHABLE(); |
| 1443 break; |
1473 } | 1444 } |
1474 } | 1445 } |
1475 | 1446 |
1476 Token::Value op = expr->binary_op(); | 1447 Token::Value op = expr->binary_op(); |
1477 PushOperand(x0); // Left operand goes on the stack. | 1448 PushOperand(x0); // Left operand goes on the stack. |
1478 VisitForAccumulatorValue(expr->value()); | 1449 VisitForAccumulatorValue(expr->value()); |
1479 | 1450 |
1480 AccumulatorValueContext context(this); | 1451 AccumulatorValueContext context(this); |
1481 if (ShouldInlineSmiCase(op)) { | 1452 if (ShouldInlineSmiCase(op)) { |
1482 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1453 EmitInlineSmiBinaryOp(expr->binary_operation(), |
(...skipping 18 matching lines...) Expand all Loading... |
1501 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1472 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
1502 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1473 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
1503 proxy->hole_check_mode()); | 1474 proxy->hole_check_mode()); |
1504 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1475 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
1505 context()->Plug(x0); | 1476 context()->Plug(x0); |
1506 break; | 1477 break; |
1507 } | 1478 } |
1508 case NAMED_PROPERTY: | 1479 case NAMED_PROPERTY: |
1509 EmitNamedPropertyAssignment(expr); | 1480 EmitNamedPropertyAssignment(expr); |
1510 break; | 1481 break; |
1511 case NAMED_SUPER_PROPERTY: | |
1512 EmitNamedSuperPropertyStore(property); | |
1513 context()->Plug(x0); | |
1514 break; | |
1515 case KEYED_SUPER_PROPERTY: | |
1516 EmitKeyedSuperPropertyStore(property); | |
1517 context()->Plug(x0); | |
1518 break; | |
1519 case KEYED_PROPERTY: | 1482 case KEYED_PROPERTY: |
1520 EmitKeyedPropertyAssignment(expr); | 1483 EmitKeyedPropertyAssignment(expr); |
1521 break; | 1484 break; |
| 1485 case NAMED_SUPER_PROPERTY: |
| 1486 case KEYED_SUPER_PROPERTY: |
| 1487 UNREACHABLE(); |
| 1488 break; |
1522 } | 1489 } |
1523 } | 1490 } |
1524 | 1491 |
1525 | 1492 |
1526 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, | 1493 void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr, |
1527 Token::Value op, | 1494 Token::Value op, |
1528 Expression* left_expr, | 1495 Expression* left_expr, |
1529 Expression* right_expr) { | 1496 Expression* right_expr) { |
1530 Label done, both_smis, stub_call; | 1497 Label done, both_smis, stub_call; |
1531 | 1498 |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 case NAMED_PROPERTY: { | 1619 case NAMED_PROPERTY: { |
1653 PushOperand(x0); // Preserve value. | 1620 PushOperand(x0); // Preserve value. |
1654 VisitForAccumulatorValue(prop->obj()); | 1621 VisitForAccumulatorValue(prop->obj()); |
1655 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid | 1622 // TODO(all): We could introduce a VisitForRegValue(reg, expr) to avoid |
1656 // this copy. | 1623 // this copy. |
1657 __ Mov(StoreDescriptor::ReceiverRegister(), x0); | 1624 __ Mov(StoreDescriptor::ReceiverRegister(), x0); |
1658 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1625 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
1659 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1626 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
1660 break; | 1627 break; |
1661 } | 1628 } |
1662 case NAMED_SUPER_PROPERTY: { | |
1663 PushOperand(x0); | |
1664 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
1665 VisitForAccumulatorValue( | |
1666 prop->obj()->AsSuperPropertyReference()->home_object()); | |
1667 // stack: value, this; x0: home_object | |
1668 Register scratch = x10; | |
1669 Register scratch2 = x11; | |
1670 __ mov(scratch, result_register()); // home_object | |
1671 __ Peek(x0, kPointerSize); // value | |
1672 __ Peek(scratch2, 0); // this | |
1673 __ Poke(scratch2, kPointerSize); // this | |
1674 __ Poke(scratch, 0); // home_object | |
1675 // stack: this, home_object; x0: value | |
1676 EmitNamedSuperPropertyStore(prop); | |
1677 break; | |
1678 } | |
1679 case KEYED_SUPER_PROPERTY: { | |
1680 PushOperand(x0); | |
1681 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
1682 VisitForStackValue( | |
1683 prop->obj()->AsSuperPropertyReference()->home_object()); | |
1684 VisitForAccumulatorValue(prop->key()); | |
1685 Register scratch = x10; | |
1686 Register scratch2 = x11; | |
1687 __ Peek(scratch2, 2 * kPointerSize); // value | |
1688 // stack: value, this, home_object; x0: key, x11: value | |
1689 __ Peek(scratch, kPointerSize); // this | |
1690 __ Poke(scratch, 2 * kPointerSize); | |
1691 __ Peek(scratch, 0); // home_object | |
1692 __ Poke(scratch, kPointerSize); | |
1693 __ Poke(x0, 0); | |
1694 __ Move(x0, scratch2); | |
1695 // stack: this, home_object, key; x0: value. | |
1696 EmitKeyedSuperPropertyStore(prop); | |
1697 break; | |
1698 } | |
1699 case KEYED_PROPERTY: { | 1629 case KEYED_PROPERTY: { |
1700 PushOperand(x0); // Preserve value. | 1630 PushOperand(x0); // Preserve value. |
1701 VisitForStackValue(prop->obj()); | 1631 VisitForStackValue(prop->obj()); |
1702 VisitForAccumulatorValue(prop->key()); | 1632 VisitForAccumulatorValue(prop->key()); |
1703 __ Mov(StoreDescriptor::NameRegister(), x0); | 1633 __ Mov(StoreDescriptor::NameRegister(), x0); |
1704 PopOperands(StoreDescriptor::ReceiverRegister(), | 1634 PopOperands(StoreDescriptor::ReceiverRegister(), |
1705 StoreDescriptor::ValueRegister()); | 1635 StoreDescriptor::ValueRegister()); |
1706 CallKeyedStoreIC(slot); | 1636 CallKeyedStoreIC(slot); |
1707 break; | 1637 break; |
1708 } | 1638 } |
| 1639 case NAMED_SUPER_PROPERTY: |
| 1640 case KEYED_SUPER_PROPERTY: |
| 1641 UNREACHABLE(); |
| 1642 break; |
1709 } | 1643 } |
1710 context()->Plug(x0); | 1644 context()->Plug(x0); |
1711 } | 1645 } |
1712 | 1646 |
1713 | 1647 |
1714 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1648 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
1715 Variable* var, MemOperand location) { | 1649 Variable* var, MemOperand location) { |
1716 __ Str(result_register(), location); | 1650 __ Str(result_register(), location); |
1717 if (var->IsContextSlot()) { | 1651 if (var->IsContextSlot()) { |
1718 // RecordWrite may destroy all its register arguments. | 1652 // RecordWrite may destroy all its register arguments. |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1789 DCHECK(prop->key()->IsLiteral()); | 1723 DCHECK(prop->key()->IsLiteral()); |
1790 | 1724 |
1791 PopOperand(StoreDescriptor::ReceiverRegister()); | 1725 PopOperand(StoreDescriptor::ReceiverRegister()); |
1792 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1726 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
1793 | 1727 |
1794 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1728 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
1795 context()->Plug(x0); | 1729 context()->Plug(x0); |
1796 } | 1730 } |
1797 | 1731 |
1798 | 1732 |
1799 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
1800 // Assignment to named property of super. | |
1801 // x0 : value | |
1802 // stack : receiver ('this'), home_object | |
1803 DCHECK(prop != NULL); | |
1804 Literal* key = prop->key()->AsLiteral(); | |
1805 DCHECK(key != NULL); | |
1806 | |
1807 PushOperand(key->value()); | |
1808 PushOperand(x0); | |
1809 CallRuntimeWithOperands(is_strict(language_mode()) | |
1810 ? Runtime::kStoreToSuper_Strict | |
1811 : Runtime::kStoreToSuper_Sloppy); | |
1812 } | |
1813 | |
1814 | |
1815 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
1816 // Assignment to named property of super. | |
1817 // x0 : value | |
1818 // stack : receiver ('this'), home_object, key | |
1819 DCHECK(prop != NULL); | |
1820 | |
1821 PushOperand(x0); | |
1822 CallRuntimeWithOperands(is_strict(language_mode()) | |
1823 ? Runtime::kStoreKeyedToSuper_Strict | |
1824 : Runtime::kStoreKeyedToSuper_Sloppy); | |
1825 } | |
1826 | |
1827 | |
1828 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1733 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
1829 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); | 1734 ASM_LOCATION("FullCodeGenerator::EmitKeyedPropertyAssignment"); |
1830 // Assignment to a property, using a keyed store IC. | 1735 // Assignment to a property, using a keyed store IC. |
1831 | 1736 |
1832 // TODO(all): Could we pass this in registers rather than on the stack? | 1737 // TODO(all): Could we pass this in registers rather than on the stack? |
1833 PopOperands(StoreDescriptor::NameRegister(), | 1738 PopOperands(StoreDescriptor::NameRegister(), |
1834 StoreDescriptor::ReceiverRegister()); | 1739 StoreDescriptor::ReceiverRegister()); |
1835 DCHECK(StoreDescriptor::ValueRegister().is(x0)); | 1740 DCHECK(StoreDescriptor::ValueRegister().is(x0)); |
1836 | 1741 |
1837 CallKeyedStoreIC(expr->AssignmentSlot()); | 1742 CallKeyedStoreIC(expr->AssignmentSlot()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1872 // Push the target function under the receiver. | 1777 // Push the target function under the receiver. |
1873 PopOperand(x10); | 1778 PopOperand(x10); |
1874 PushOperands(x0, x10); | 1779 PushOperands(x0, x10); |
1875 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1780 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
1876 } | 1781 } |
1877 | 1782 |
1878 EmitCall(expr, convert_mode); | 1783 EmitCall(expr, convert_mode); |
1879 } | 1784 } |
1880 | 1785 |
1881 | 1786 |
1882 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
1883 ASM_LOCATION("FullCodeGenerator::EmitSuperCallWithLoadIC"); | |
1884 Expression* callee = expr->expression(); | |
1885 DCHECK(callee->IsProperty()); | |
1886 Property* prop = callee->AsProperty(); | |
1887 DCHECK(prop->IsSuperAccess()); | |
1888 SetExpressionPosition(prop); | |
1889 | |
1890 Literal* key = prop->key()->AsLiteral(); | |
1891 DCHECK(!key->value()->IsSmi()); | |
1892 | |
1893 // Load the function from the receiver. | |
1894 const Register scratch = x10; | |
1895 SuperPropertyReference* super_ref = | |
1896 callee->AsProperty()->obj()->AsSuperPropertyReference(); | |
1897 VisitForStackValue(super_ref->home_object()); | |
1898 VisitForAccumulatorValue(super_ref->this_var()); | |
1899 PushOperand(x0); | |
1900 __ Peek(scratch, kPointerSize); | |
1901 PushOperands(x0, scratch); | |
1902 PushOperand(key->value()); | |
1903 | |
1904 // Stack here: | |
1905 // - home_object | |
1906 // - this (receiver) | |
1907 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
1908 // - home_object | |
1909 // - key | |
1910 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
1911 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
1912 | |
1913 // Replace home_object with target function. | |
1914 __ Poke(x0, kPointerSize); | |
1915 | |
1916 // Stack here: | |
1917 // - target function | |
1918 // - this (receiver) | |
1919 EmitCall(expr); | |
1920 } | |
1921 | |
1922 | |
1923 // Code common for calls using the IC. | 1787 // Code common for calls using the IC. |
1924 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1788 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
1925 Expression* key) { | 1789 Expression* key) { |
1926 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); | 1790 ASM_LOCATION("FullCodeGenerator::EmitKeyedCallWithLoadIC"); |
1927 // Load the key. | 1791 // Load the key. |
1928 VisitForAccumulatorValue(key); | 1792 VisitForAccumulatorValue(key); |
1929 | 1793 |
1930 Expression* callee = expr->expression(); | 1794 Expression* callee = expr->expression(); |
1931 | 1795 |
1932 // Load the function from the receiver. | 1796 // Load the function from the receiver. |
1933 DCHECK(callee->IsProperty()); | 1797 DCHECK(callee->IsProperty()); |
1934 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 1798 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
1935 __ Move(LoadDescriptor::NameRegister(), x0); | 1799 __ Move(LoadDescriptor::NameRegister(), x0); |
1936 EmitKeyedPropertyLoad(callee->AsProperty()); | 1800 EmitKeyedPropertyLoad(callee->AsProperty()); |
1937 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1801 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
1938 BailoutState::TOS_REGISTER); | 1802 BailoutState::TOS_REGISTER); |
1939 | 1803 |
1940 // Push the target function under the receiver. | 1804 // Push the target function under the receiver. |
1941 PopOperand(x10); | 1805 PopOperand(x10); |
1942 PushOperands(x0, x10); | 1806 PushOperands(x0, x10); |
1943 | 1807 |
1944 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1808 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
1945 } | 1809 } |
1946 | 1810 |
1947 | 1811 |
1948 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
1949 ASM_LOCATION("FullCodeGenerator::EmitKeyedSuperCallWithLoadIC"); | |
1950 Expression* callee = expr->expression(); | |
1951 DCHECK(callee->IsProperty()); | |
1952 Property* prop = callee->AsProperty(); | |
1953 DCHECK(prop->IsSuperAccess()); | |
1954 SetExpressionPosition(prop); | |
1955 | |
1956 // Load the function from the receiver. | |
1957 const Register scratch = x10; | |
1958 SuperPropertyReference* super_ref = | |
1959 callee->AsProperty()->obj()->AsSuperPropertyReference(); | |
1960 VisitForStackValue(super_ref->home_object()); | |
1961 VisitForAccumulatorValue(super_ref->this_var()); | |
1962 PushOperand(x0); | |
1963 __ Peek(scratch, kPointerSize); | |
1964 PushOperands(x0, scratch); | |
1965 VisitForStackValue(prop->key()); | |
1966 | |
1967 // Stack here: | |
1968 // - home_object | |
1969 // - this (receiver) | |
1970 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
1971 // - home_object | |
1972 // - key | |
1973 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
1974 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
1975 | |
1976 // Replace home_object with target function. | |
1977 __ Poke(x0, kPointerSize); | |
1978 | |
1979 // Stack here: | |
1980 // - target function | |
1981 // - this (receiver) | |
1982 EmitCall(expr); | |
1983 } | |
1984 | |
1985 | |
1986 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1812 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
1987 ASM_LOCATION("FullCodeGenerator::EmitCall"); | 1813 ASM_LOCATION("FullCodeGenerator::EmitCall"); |
1988 // Load the arguments. | 1814 // Load the arguments. |
1989 ZoneList<Expression*>* args = expr->arguments(); | 1815 ZoneList<Expression*>* args = expr->arguments(); |
1990 int arg_count = args->length(); | 1816 int arg_count = args->length(); |
1991 for (int i = 0; i < arg_count; i++) { | 1817 for (int i = 0; i < arg_count; i++) { |
1992 VisitForStackValue(args->at(i)); | 1818 VisitForStackValue(args->at(i)); |
1993 } | 1819 } |
1994 | 1820 |
1995 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1821 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
(...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2517 } | 2343 } |
2518 switch (assign_type) { | 2344 switch (assign_type) { |
2519 case NAMED_PROPERTY: { | 2345 case NAMED_PROPERTY: { |
2520 // Put the object both on the stack and in the register. | 2346 // Put the object both on the stack and in the register. |
2521 VisitForStackValue(prop->obj()); | 2347 VisitForStackValue(prop->obj()); |
2522 __ Peek(LoadDescriptor::ReceiverRegister(), 0); | 2348 __ Peek(LoadDescriptor::ReceiverRegister(), 0); |
2523 EmitNamedPropertyLoad(prop); | 2349 EmitNamedPropertyLoad(prop); |
2524 break; | 2350 break; |
2525 } | 2351 } |
2526 | 2352 |
2527 case NAMED_SUPER_PROPERTY: { | |
2528 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
2529 VisitForAccumulatorValue( | |
2530 prop->obj()->AsSuperPropertyReference()->home_object()); | |
2531 PushOperand(result_register()); | |
2532 const Register scratch = x10; | |
2533 __ Peek(scratch, kPointerSize); | |
2534 PushOperands(scratch, result_register()); | |
2535 EmitNamedSuperPropertyLoad(prop); | |
2536 break; | |
2537 } | |
2538 | |
2539 case KEYED_SUPER_PROPERTY: { | |
2540 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
2541 VisitForStackValue( | |
2542 prop->obj()->AsSuperPropertyReference()->home_object()); | |
2543 VisitForAccumulatorValue(prop->key()); | |
2544 PushOperand(result_register()); | |
2545 const Register scratch1 = x10; | |
2546 const Register scratch2 = x11; | |
2547 __ Peek(scratch1, 2 * kPointerSize); | |
2548 __ Peek(scratch2, kPointerSize); | |
2549 PushOperands(scratch1, scratch2, result_register()); | |
2550 EmitKeyedSuperPropertyLoad(prop); | |
2551 break; | |
2552 } | |
2553 | |
2554 case KEYED_PROPERTY: { | 2353 case KEYED_PROPERTY: { |
2555 VisitForStackValue(prop->obj()); | 2354 VisitForStackValue(prop->obj()); |
2556 VisitForStackValue(prop->key()); | 2355 VisitForStackValue(prop->key()); |
2557 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); | 2356 __ Peek(LoadDescriptor::ReceiverRegister(), 1 * kPointerSize); |
2558 __ Peek(LoadDescriptor::NameRegister(), 0); | 2357 __ Peek(LoadDescriptor::NameRegister(), 0); |
2559 EmitKeyedPropertyLoad(prop); | 2358 EmitKeyedPropertyLoad(prop); |
2560 break; | 2359 break; |
2561 } | 2360 } |
2562 | 2361 |
| 2362 case NAMED_SUPER_PROPERTY: |
| 2363 case KEYED_SUPER_PROPERTY: |
2563 case VARIABLE: | 2364 case VARIABLE: |
2564 UNREACHABLE(); | 2365 UNREACHABLE(); |
2565 } | 2366 } |
2566 } | 2367 } |
2567 | 2368 |
2568 // We need a second deoptimization point after loading the value | 2369 // We need a second deoptimization point after loading the value |
2569 // in case evaluating the property load my have a side effect. | 2370 // in case evaluating the property load my have a side effect. |
2570 if (assign_type == VARIABLE) { | 2371 if (assign_type == VARIABLE) { |
2571 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2372 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
2572 } else { | 2373 } else { |
(...skipping 15 matching lines...) Expand all Loading... |
2588 // Save the result on the stack. If we have a named or keyed property we | 2389 // Save the result on the stack. If we have a named or keyed property we |
2589 // store the result under the receiver that is currently on top of the | 2390 // store the result under the receiver that is currently on top of the |
2590 // stack. | 2391 // stack. |
2591 switch (assign_type) { | 2392 switch (assign_type) { |
2592 case VARIABLE: | 2393 case VARIABLE: |
2593 __ Push(x0); | 2394 __ Push(x0); |
2594 break; | 2395 break; |
2595 case NAMED_PROPERTY: | 2396 case NAMED_PROPERTY: |
2596 __ Poke(x0, kPointerSize); | 2397 __ Poke(x0, kPointerSize); |
2597 break; | 2398 break; |
2598 case NAMED_SUPER_PROPERTY: | |
2599 __ Poke(x0, kPointerSize * 2); | |
2600 break; | |
2601 case KEYED_PROPERTY: | 2399 case KEYED_PROPERTY: |
2602 __ Poke(x0, kPointerSize * 2); | 2400 __ Poke(x0, kPointerSize * 2); |
2603 break; | 2401 break; |
| 2402 case NAMED_SUPER_PROPERTY: |
2604 case KEYED_SUPER_PROPERTY: | 2403 case KEYED_SUPER_PROPERTY: |
2605 __ Poke(x0, kPointerSize * 3); | 2404 UNREACHABLE(); |
2606 break; | 2405 break; |
2607 } | 2406 } |
2608 } | 2407 } |
2609 } | 2408 } |
2610 | 2409 |
2611 __ Adds(x0, x0, Smi::FromInt(count_value)); | 2410 __ Adds(x0, x0, Smi::FromInt(count_value)); |
2612 __ B(vc, &done); | 2411 __ B(vc, &done); |
2613 // Call stub. Undo operation first. | 2412 // Call stub. Undo operation first. |
2614 __ Sub(x0, x0, Smi::FromInt(count_value)); | 2413 __ Sub(x0, x0, Smi::FromInt(count_value)); |
2615 __ B(&stub_call); | 2414 __ B(&stub_call); |
(...skipping 11 matching lines...) Expand all Loading... |
2627 // Save the result on the stack. If we have a named or keyed property | 2426 // Save the result on the stack. If we have a named or keyed property |
2628 // we store the result under the receiver that is currently on top | 2427 // we store the result under the receiver that is currently on top |
2629 // of the stack. | 2428 // of the stack. |
2630 switch (assign_type) { | 2429 switch (assign_type) { |
2631 case VARIABLE: | 2430 case VARIABLE: |
2632 PushOperand(x0); | 2431 PushOperand(x0); |
2633 break; | 2432 break; |
2634 case NAMED_PROPERTY: | 2433 case NAMED_PROPERTY: |
2635 __ Poke(x0, kXRegSize); | 2434 __ Poke(x0, kXRegSize); |
2636 break; | 2435 break; |
2637 case NAMED_SUPER_PROPERTY: | |
2638 __ Poke(x0, 2 * kXRegSize); | |
2639 break; | |
2640 case KEYED_PROPERTY: | 2436 case KEYED_PROPERTY: |
2641 __ Poke(x0, 2 * kXRegSize); | 2437 __ Poke(x0, 2 * kXRegSize); |
2642 break; | 2438 break; |
| 2439 case NAMED_SUPER_PROPERTY: |
2643 case KEYED_SUPER_PROPERTY: | 2440 case KEYED_SUPER_PROPERTY: |
2644 __ Poke(x0, 3 * kXRegSize); | 2441 UNREACHABLE(); |
2645 break; | 2442 break; |
2646 } | 2443 } |
2647 } | 2444 } |
2648 } | 2445 } |
2649 | 2446 |
2650 __ Bind(&stub_call); | 2447 __ Bind(&stub_call); |
2651 __ Mov(x1, x0); | 2448 __ Mov(x1, x0); |
2652 __ Mov(x0, Smi::FromInt(count_value)); | 2449 __ Mov(x0, Smi::FromInt(count_value)); |
2653 | 2450 |
2654 SetExpressionPosition(expr); | 2451 SetExpressionPosition(expr); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2693 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2490 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2694 if (expr->is_postfix()) { | 2491 if (expr->is_postfix()) { |
2695 if (!context()->IsEffect()) { | 2492 if (!context()->IsEffect()) { |
2696 context()->PlugTOS(); | 2493 context()->PlugTOS(); |
2697 } | 2494 } |
2698 } else { | 2495 } else { |
2699 context()->Plug(x0); | 2496 context()->Plug(x0); |
2700 } | 2497 } |
2701 break; | 2498 break; |
2702 } | 2499 } |
2703 case NAMED_SUPER_PROPERTY: { | |
2704 EmitNamedSuperPropertyStore(prop); | |
2705 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
2706 if (expr->is_postfix()) { | |
2707 if (!context()->IsEffect()) { | |
2708 context()->PlugTOS(); | |
2709 } | |
2710 } else { | |
2711 context()->Plug(x0); | |
2712 } | |
2713 break; | |
2714 } | |
2715 case KEYED_SUPER_PROPERTY: { | |
2716 EmitKeyedSuperPropertyStore(prop); | |
2717 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
2718 if (expr->is_postfix()) { | |
2719 if (!context()->IsEffect()) { | |
2720 context()->PlugTOS(); | |
2721 } | |
2722 } else { | |
2723 context()->Plug(x0); | |
2724 } | |
2725 break; | |
2726 } | |
2727 case KEYED_PROPERTY: { | 2500 case KEYED_PROPERTY: { |
2728 PopOperand(StoreDescriptor::NameRegister()); | 2501 PopOperand(StoreDescriptor::NameRegister()); |
2729 PopOperand(StoreDescriptor::ReceiverRegister()); | 2502 PopOperand(StoreDescriptor::ReceiverRegister()); |
2730 CallKeyedStoreIC(expr->CountSlot()); | 2503 CallKeyedStoreIC(expr->CountSlot()); |
2731 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2504 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
2732 if (expr->is_postfix()) { | 2505 if (expr->is_postfix()) { |
2733 if (!context()->IsEffect()) { | 2506 if (!context()->IsEffect()) { |
2734 context()->PlugTOS(); | 2507 context()->PlugTOS(); |
2735 } | 2508 } |
2736 } else { | 2509 } else { |
2737 context()->Plug(x0); | 2510 context()->Plug(x0); |
2738 } | 2511 } |
2739 break; | 2512 break; |
2740 } | 2513 } |
| 2514 case NAMED_SUPER_PROPERTY: |
| 2515 case KEYED_SUPER_PROPERTY: |
| 2516 UNREACHABLE(); |
| 2517 break; |
2741 } | 2518 } |
2742 } | 2519 } |
2743 | 2520 |
2744 | 2521 |
2745 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2522 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
2746 Expression* sub_expr, | 2523 Expression* sub_expr, |
2747 Handle<String> check) { | 2524 Handle<String> check) { |
2748 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof"); | 2525 ASM_LOCATION("FullCodeGenerator::EmitLiteralCompareTypeof"); |
2749 Comment cmnt(masm_, "[ EmitLiteralCompareTypeof"); | 2526 Comment cmnt(masm_, "[ EmitLiteralCompareTypeof"); |
2750 Label materialize_true, materialize_false; | 2527 Label materialize_true, materialize_false; |
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3141 } | 2918 } |
3142 | 2919 |
3143 return INTERRUPT; | 2920 return INTERRUPT; |
3144 } | 2921 } |
3145 | 2922 |
3146 | 2923 |
3147 } // namespace internal | 2924 } // namespace internal |
3148 } // namespace v8 | 2925 } // namespace v8 |
3149 | 2926 |
3150 #endif // V8_TARGET_ARCH_ARM64 | 2927 #endif // V8_TARGET_ARCH_ARM64 |
OLD | NEW |