| 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_MIPS64 | 5 #if V8_TARGET_ARCH_MIPS64 |
| 6 | 6 |
| 7 // Note on Mips implementation: | 7 // Note on Mips implementation: |
| 8 // | 8 // |
| 9 // The result_register() for mips is the 'v0' register, which is defined | 9 // The result_register() for mips is the 'v0' register, which is defined |
| 10 // by the ABI to contain function return values. However, the first | 10 // by the ABI to contain function return values. However, the first |
| (...skipping 1402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1413 break; | 1413 break; |
| 1414 case NAMED_PROPERTY: | 1414 case NAMED_PROPERTY: |
| 1415 if (expr->is_compound()) { | 1415 if (expr->is_compound()) { |
| 1416 // We need the receiver both on the stack and in the register. | 1416 // We need the receiver both on the stack and in the register. |
| 1417 VisitForStackValue(property->obj()); | 1417 VisitForStackValue(property->obj()); |
| 1418 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1418 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 1419 } else { | 1419 } else { |
| 1420 VisitForStackValue(property->obj()); | 1420 VisitForStackValue(property->obj()); |
| 1421 } | 1421 } |
| 1422 break; | 1422 break; |
| 1423 case NAMED_SUPER_PROPERTY: | |
| 1424 VisitForStackValue( | |
| 1425 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1426 VisitForAccumulatorValue( | |
| 1427 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1428 PushOperand(result_register()); | |
| 1429 if (expr->is_compound()) { | |
| 1430 const Register scratch = a1; | |
| 1431 __ ld(scratch, MemOperand(sp, kPointerSize)); | |
| 1432 PushOperands(scratch, result_register()); | |
| 1433 } | |
| 1434 break; | |
| 1435 case KEYED_SUPER_PROPERTY: { | |
| 1436 VisitForStackValue( | |
| 1437 property->obj()->AsSuperPropertyReference()->this_var()); | |
| 1438 VisitForStackValue( | |
| 1439 property->obj()->AsSuperPropertyReference()->home_object()); | |
| 1440 VisitForAccumulatorValue(property->key()); | |
| 1441 PushOperand(result_register()); | |
| 1442 if (expr->is_compound()) { | |
| 1443 const Register scratch1 = a4; | |
| 1444 const Register scratch2 = a1; | |
| 1445 __ ld(scratch1, MemOperand(sp, 2 * kPointerSize)); | |
| 1446 __ ld(scratch2, MemOperand(sp, 1 * kPointerSize)); | |
| 1447 PushOperands(scratch1, scratch2, result_register()); | |
| 1448 } | |
| 1449 break; | |
| 1450 } | |
| 1451 case KEYED_PROPERTY: | 1423 case KEYED_PROPERTY: |
| 1452 // We need the key and receiver on both the stack and in v0 and a1. | 1424 // We need the key and receiver on both the stack and in v0 and a1. |
| 1453 if (expr->is_compound()) { | 1425 if (expr->is_compound()) { |
| 1454 VisitForStackValue(property->obj()); | 1426 VisitForStackValue(property->obj()); |
| 1455 VisitForStackValue(property->key()); | 1427 VisitForStackValue(property->key()); |
| 1456 __ ld(LoadDescriptor::ReceiverRegister(), | 1428 __ ld(LoadDescriptor::ReceiverRegister(), |
| 1457 MemOperand(sp, 1 * kPointerSize)); | 1429 MemOperand(sp, 1 * kPointerSize)); |
| 1458 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 1430 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 1459 } else { | 1431 } else { |
| 1460 VisitForStackValue(property->obj()); | 1432 VisitForStackValue(property->obj()); |
| 1461 VisitForStackValue(property->key()); | 1433 VisitForStackValue(property->key()); |
| 1462 } | 1434 } |
| 1463 break; | 1435 break; |
| 1436 case NAMED_SUPER_PROPERTY: |
| 1437 case KEYED_SUPER_PROPERTY: |
| 1438 UNREACHABLE(); |
| 1439 break; |
| 1464 } | 1440 } |
| 1465 | 1441 |
| 1466 // For compound assignments we need another deoptimization point after the | 1442 // For compound assignments we need another deoptimization point after the |
| 1467 // variable/property load. | 1443 // variable/property load. |
| 1468 if (expr->is_compound()) { | 1444 if (expr->is_compound()) { |
| 1469 { AccumulatorValueContext context(this); | 1445 { AccumulatorValueContext context(this); |
| 1470 switch (assign_type) { | 1446 switch (assign_type) { |
| 1471 case VARIABLE: | 1447 case VARIABLE: |
| 1472 EmitVariableLoad(expr->target()->AsVariableProxy()); | 1448 EmitVariableLoad(expr->target()->AsVariableProxy()); |
| 1473 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); | 1449 PrepareForBailout(expr->target(), BailoutState::TOS_REGISTER); |
| 1474 break; | 1450 break; |
| 1475 case NAMED_PROPERTY: | 1451 case NAMED_PROPERTY: |
| 1476 EmitNamedPropertyLoad(property); | 1452 EmitNamedPropertyLoad(property); |
| 1477 PrepareForBailoutForId(property->LoadId(), | 1453 PrepareForBailoutForId(property->LoadId(), |
| 1478 BailoutState::TOS_REGISTER); | 1454 BailoutState::TOS_REGISTER); |
| 1479 break; | 1455 break; |
| 1480 case NAMED_SUPER_PROPERTY: | |
| 1481 EmitNamedSuperPropertyLoad(property); | |
| 1482 PrepareForBailoutForId(property->LoadId(), | |
| 1483 BailoutState::TOS_REGISTER); | |
| 1484 break; | |
| 1485 case KEYED_SUPER_PROPERTY: | |
| 1486 EmitKeyedSuperPropertyLoad(property); | |
| 1487 PrepareForBailoutForId(property->LoadId(), | |
| 1488 BailoutState::TOS_REGISTER); | |
| 1489 break; | |
| 1490 case KEYED_PROPERTY: | 1456 case KEYED_PROPERTY: |
| 1491 EmitKeyedPropertyLoad(property); | 1457 EmitKeyedPropertyLoad(property); |
| 1492 PrepareForBailoutForId(property->LoadId(), | 1458 PrepareForBailoutForId(property->LoadId(), |
| 1493 BailoutState::TOS_REGISTER); | 1459 BailoutState::TOS_REGISTER); |
| 1494 break; | 1460 break; |
| 1461 case NAMED_SUPER_PROPERTY: |
| 1462 case KEYED_SUPER_PROPERTY: |
| 1463 UNREACHABLE(); |
| 1464 break; |
| 1495 } | 1465 } |
| 1496 } | 1466 } |
| 1497 | 1467 |
| 1498 Token::Value op = expr->binary_op(); | 1468 Token::Value op = expr->binary_op(); |
| 1499 PushOperand(v0); // Left operand goes on the stack. | 1469 PushOperand(v0); // Left operand goes on the stack. |
| 1500 VisitForAccumulatorValue(expr->value()); | 1470 VisitForAccumulatorValue(expr->value()); |
| 1501 | 1471 |
| 1502 AccumulatorValueContext context(this); | 1472 AccumulatorValueContext context(this); |
| 1503 if (ShouldInlineSmiCase(op)) { | 1473 if (ShouldInlineSmiCase(op)) { |
| 1504 EmitInlineSmiBinaryOp(expr->binary_operation(), | 1474 EmitInlineSmiBinaryOp(expr->binary_operation(), |
| (...skipping 18 matching lines...) Expand all Loading... |
| 1523 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1493 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1524 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), | 1494 EmitVariableAssignment(proxy->var(), expr->op(), expr->AssignmentSlot(), |
| 1525 proxy->hole_check_mode()); | 1495 proxy->hole_check_mode()); |
| 1526 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1496 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1527 context()->Plug(v0); | 1497 context()->Plug(v0); |
| 1528 break; | 1498 break; |
| 1529 } | 1499 } |
| 1530 case NAMED_PROPERTY: | 1500 case NAMED_PROPERTY: |
| 1531 EmitNamedPropertyAssignment(expr); | 1501 EmitNamedPropertyAssignment(expr); |
| 1532 break; | 1502 break; |
| 1533 case NAMED_SUPER_PROPERTY: | |
| 1534 EmitNamedSuperPropertyStore(property); | |
| 1535 context()->Plug(v0); | |
| 1536 break; | |
| 1537 case KEYED_SUPER_PROPERTY: | |
| 1538 EmitKeyedSuperPropertyStore(property); | |
| 1539 context()->Plug(v0); | |
| 1540 break; | |
| 1541 case KEYED_PROPERTY: | 1503 case KEYED_PROPERTY: |
| 1542 EmitKeyedPropertyAssignment(expr); | 1504 EmitKeyedPropertyAssignment(expr); |
| 1543 break; | 1505 break; |
| 1506 case NAMED_SUPER_PROPERTY: |
| 1507 case KEYED_SUPER_PROPERTY: |
| 1508 UNREACHABLE(); |
| 1509 break; |
| 1544 } | 1510 } |
| 1545 } | 1511 } |
| 1546 | 1512 |
| 1547 | 1513 |
| 1548 void FullCodeGenerator::VisitYield(Yield* expr) { | 1514 void FullCodeGenerator::VisitYield(Yield* expr) { |
| 1549 // Resumable functions are not supported. | 1515 // Resumable functions are not supported. |
| 1550 UNREACHABLE(); | 1516 UNREACHABLE(); |
| 1551 } | 1517 } |
| 1552 | 1518 |
| 1553 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { | 1519 void FullCodeGenerator::PushOperands(Register reg1, Register reg2) { |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1722 break; | 1688 break; |
| 1723 } | 1689 } |
| 1724 case NAMED_PROPERTY: { | 1690 case NAMED_PROPERTY: { |
| 1725 PushOperand(result_register()); // Preserve value. | 1691 PushOperand(result_register()); // Preserve value. |
| 1726 VisitForAccumulatorValue(prop->obj()); | 1692 VisitForAccumulatorValue(prop->obj()); |
| 1727 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); | 1693 __ mov(StoreDescriptor::ReceiverRegister(), result_register()); |
| 1728 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. | 1694 PopOperand(StoreDescriptor::ValueRegister()); // Restore value. |
| 1729 CallStoreIC(slot, prop->key()->AsLiteral()->value()); | 1695 CallStoreIC(slot, prop->key()->AsLiteral()->value()); |
| 1730 break; | 1696 break; |
| 1731 } | 1697 } |
| 1732 case NAMED_SUPER_PROPERTY: { | |
| 1733 PushOperand(v0); | |
| 1734 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1735 VisitForAccumulatorValue( | |
| 1736 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1737 // stack: value, this; v0: home_object | |
| 1738 Register scratch = a2; | |
| 1739 Register scratch2 = a3; | |
| 1740 __ mov(scratch, result_register()); // home_object | |
| 1741 __ ld(v0, MemOperand(sp, kPointerSize)); // value | |
| 1742 __ ld(scratch2, MemOperand(sp, 0)); // this | |
| 1743 __ sd(scratch2, MemOperand(sp, kPointerSize)); // this | |
| 1744 __ sd(scratch, MemOperand(sp, 0)); // home_object | |
| 1745 // stack: this, home_object; v0: value | |
| 1746 EmitNamedSuperPropertyStore(prop); | |
| 1747 break; | |
| 1748 } | |
| 1749 case KEYED_SUPER_PROPERTY: { | |
| 1750 PushOperand(v0); | |
| 1751 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 1752 VisitForStackValue( | |
| 1753 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 1754 VisitForAccumulatorValue(prop->key()); | |
| 1755 Register scratch = a2; | |
| 1756 Register scratch2 = a3; | |
| 1757 __ ld(scratch2, MemOperand(sp, 2 * kPointerSize)); // value | |
| 1758 // stack: value, this, home_object; v0: key, a3: value | |
| 1759 __ ld(scratch, MemOperand(sp, kPointerSize)); // this | |
| 1760 __ sd(scratch, MemOperand(sp, 2 * kPointerSize)); | |
| 1761 __ ld(scratch, MemOperand(sp, 0)); // home_object | |
| 1762 __ sd(scratch, MemOperand(sp, kPointerSize)); | |
| 1763 __ sd(v0, MemOperand(sp, 0)); | |
| 1764 __ Move(v0, scratch2); | |
| 1765 // stack: this, home_object, key; v0: value. | |
| 1766 EmitKeyedSuperPropertyStore(prop); | |
| 1767 break; | |
| 1768 } | |
| 1769 case KEYED_PROPERTY: { | 1698 case KEYED_PROPERTY: { |
| 1770 PushOperand(result_register()); // Preserve value. | 1699 PushOperand(result_register()); // Preserve value. |
| 1771 VisitForStackValue(prop->obj()); | 1700 VisitForStackValue(prop->obj()); |
| 1772 VisitForAccumulatorValue(prop->key()); | 1701 VisitForAccumulatorValue(prop->key()); |
| 1773 __ Move(StoreDescriptor::NameRegister(), result_register()); | 1702 __ Move(StoreDescriptor::NameRegister(), result_register()); |
| 1774 PopOperands(StoreDescriptor::ValueRegister(), | 1703 PopOperands(StoreDescriptor::ValueRegister(), |
| 1775 StoreDescriptor::ReceiverRegister()); | 1704 StoreDescriptor::ReceiverRegister()); |
| 1776 CallKeyedStoreIC(slot); | 1705 CallKeyedStoreIC(slot); |
| 1777 break; | 1706 break; |
| 1778 } | 1707 } |
| 1708 case NAMED_SUPER_PROPERTY: |
| 1709 case KEYED_SUPER_PROPERTY: |
| 1710 UNREACHABLE(); |
| 1711 break; |
| 1779 } | 1712 } |
| 1780 context()->Plug(v0); | 1713 context()->Plug(v0); |
| 1781 } | 1714 } |
| 1782 | 1715 |
| 1783 | 1716 |
| 1784 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( | 1717 void FullCodeGenerator::EmitStoreToStackLocalOrContextSlot( |
| 1785 Variable* var, MemOperand location) { | 1718 Variable* var, MemOperand location) { |
| 1786 __ sd(result_register(), location); | 1719 __ sd(result_register(), location); |
| 1787 if (var->IsContextSlot()) { | 1720 if (var->IsContextSlot()) { |
| 1788 // RecordWrite may destroy all its register arguments. | 1721 // RecordWrite may destroy all its register arguments. |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1862 | 1795 |
| 1863 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1796 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 1864 PopOperand(StoreDescriptor::ReceiverRegister()); | 1797 PopOperand(StoreDescriptor::ReceiverRegister()); |
| 1865 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); | 1798 CallStoreIC(expr->AssignmentSlot(), prop->key()->AsLiteral()->value()); |
| 1866 | 1799 |
| 1867 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 1800 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 1868 context()->Plug(v0); | 1801 context()->Plug(v0); |
| 1869 } | 1802 } |
| 1870 | 1803 |
| 1871 | 1804 |
| 1872 void FullCodeGenerator::EmitNamedSuperPropertyStore(Property* prop) { | |
| 1873 // Assignment to named property of super. | |
| 1874 // v0 : value | |
| 1875 // stack : receiver ('this'), home_object | |
| 1876 DCHECK(prop != NULL); | |
| 1877 Literal* key = prop->key()->AsLiteral(); | |
| 1878 DCHECK(key != NULL); | |
| 1879 | |
| 1880 PushOperand(key->value()); | |
| 1881 PushOperand(v0); | |
| 1882 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1883 ? Runtime::kStoreToSuper_Strict | |
| 1884 : Runtime::kStoreToSuper_Sloppy); | |
| 1885 } | |
| 1886 | |
| 1887 | |
| 1888 void FullCodeGenerator::EmitKeyedSuperPropertyStore(Property* prop) { | |
| 1889 // Assignment to named property of super. | |
| 1890 // v0 : value | |
| 1891 // stack : receiver ('this'), home_object, key | |
| 1892 DCHECK(prop != NULL); | |
| 1893 | |
| 1894 PushOperand(v0); | |
| 1895 CallRuntimeWithOperands(is_strict(language_mode()) | |
| 1896 ? Runtime::kStoreKeyedToSuper_Strict | |
| 1897 : Runtime::kStoreKeyedToSuper_Sloppy); | |
| 1898 } | |
| 1899 | |
| 1900 | |
| 1901 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { | 1805 void FullCodeGenerator::EmitKeyedPropertyAssignment(Assignment* expr) { |
| 1902 // Assignment to a property, using a keyed store IC. | 1806 // Assignment to a property, using a keyed store IC. |
| 1903 // Call keyed store IC. | 1807 // Call keyed store IC. |
| 1904 // The arguments are: | 1808 // The arguments are: |
| 1905 // - a0 is the value, | 1809 // - a0 is the value, |
| 1906 // - a1 is the key, | 1810 // - a1 is the key, |
| 1907 // - a2 is the receiver. | 1811 // - a2 is the receiver. |
| 1908 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 1812 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 1909 PopOperands(StoreDescriptor::ReceiverRegister(), | 1813 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 1910 StoreDescriptor::NameRegister()); | 1814 StoreDescriptor::NameRegister()); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1944 __ ld(at, MemOperand(sp, 0)); | 1848 __ ld(at, MemOperand(sp, 0)); |
| 1945 PushOperand(at); | 1849 PushOperand(at); |
| 1946 __ sd(v0, MemOperand(sp, kPointerSize)); | 1850 __ sd(v0, MemOperand(sp, kPointerSize)); |
| 1947 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; | 1851 convert_mode = ConvertReceiverMode::kNotNullOrUndefined; |
| 1948 } | 1852 } |
| 1949 | 1853 |
| 1950 EmitCall(expr, convert_mode); | 1854 EmitCall(expr, convert_mode); |
| 1951 } | 1855 } |
| 1952 | 1856 |
| 1953 | 1857 |
| 1954 void FullCodeGenerator::EmitSuperCallWithLoadIC(Call* expr) { | |
| 1955 SetExpressionPosition(expr); | |
| 1956 Expression* callee = expr->expression(); | |
| 1957 DCHECK(callee->IsProperty()); | |
| 1958 Property* prop = callee->AsProperty(); | |
| 1959 DCHECK(prop->IsSuperAccess()); | |
| 1960 | |
| 1961 Literal* key = prop->key()->AsLiteral(); | |
| 1962 DCHECK(!key->value()->IsSmi()); | |
| 1963 // Load the function from the receiver. | |
| 1964 const Register scratch = a1; | |
| 1965 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 1966 VisitForAccumulatorValue(super_ref->home_object()); | |
| 1967 __ mov(scratch, v0); | |
| 1968 VisitForAccumulatorValue(super_ref->this_var()); | |
| 1969 PushOperands(scratch, v0, v0, scratch); | |
| 1970 PushOperand(key->value()); | |
| 1971 | |
| 1972 // Stack here: | |
| 1973 // - home_object | |
| 1974 // - this (receiver) | |
| 1975 // - this (receiver) <-- LoadFromSuper will pop here and below. | |
| 1976 // - home_object | |
| 1977 // - key | |
| 1978 CallRuntimeWithOperands(Runtime::kLoadFromSuper); | |
| 1979 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 1980 | |
| 1981 // Replace home_object with target function. | |
| 1982 __ sd(v0, MemOperand(sp, kPointerSize)); | |
| 1983 | |
| 1984 // Stack here: | |
| 1985 // - target function | |
| 1986 // - this (receiver) | |
| 1987 EmitCall(expr); | |
| 1988 } | |
| 1989 | |
| 1990 | |
| 1991 // Code common for calls using the IC. | 1858 // Code common for calls using the IC. |
| 1992 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, | 1859 void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr, |
| 1993 Expression* key) { | 1860 Expression* key) { |
| 1994 // Load the key. | 1861 // Load the key. |
| 1995 VisitForAccumulatorValue(key); | 1862 VisitForAccumulatorValue(key); |
| 1996 | 1863 |
| 1997 Expression* callee = expr->expression(); | 1864 Expression* callee = expr->expression(); |
| 1998 | 1865 |
| 1999 // Load the function from the receiver. | 1866 // Load the function from the receiver. |
| 2000 DCHECK(callee->IsProperty()); | 1867 DCHECK(callee->IsProperty()); |
| 2001 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 1868 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2002 __ Move(LoadDescriptor::NameRegister(), v0); | 1869 __ Move(LoadDescriptor::NameRegister(), v0); |
| 2003 EmitKeyedPropertyLoad(callee->AsProperty()); | 1870 EmitKeyedPropertyLoad(callee->AsProperty()); |
| 2004 PrepareForBailoutForId(callee->AsProperty()->LoadId(), | 1871 PrepareForBailoutForId(callee->AsProperty()->LoadId(), |
| 2005 BailoutState::TOS_REGISTER); | 1872 BailoutState::TOS_REGISTER); |
| 2006 | 1873 |
| 2007 // Push the target function under the receiver. | 1874 // Push the target function under the receiver. |
| 2008 __ ld(at, MemOperand(sp, 0)); | 1875 __ ld(at, MemOperand(sp, 0)); |
| 2009 PushOperand(at); | 1876 PushOperand(at); |
| 2010 __ sd(v0, MemOperand(sp, kPointerSize)); | 1877 __ sd(v0, MemOperand(sp, kPointerSize)); |
| 2011 | 1878 |
| 2012 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); | 1879 EmitCall(expr, ConvertReceiverMode::kNotNullOrUndefined); |
| 2013 } | 1880 } |
| 2014 | 1881 |
| 2015 | 1882 |
| 2016 void FullCodeGenerator::EmitKeyedSuperCallWithLoadIC(Call* expr) { | |
| 2017 Expression* callee = expr->expression(); | |
| 2018 DCHECK(callee->IsProperty()); | |
| 2019 Property* prop = callee->AsProperty(); | |
| 2020 DCHECK(prop->IsSuperAccess()); | |
| 2021 | |
| 2022 SetExpressionPosition(prop); | |
| 2023 // Load the function from the receiver. | |
| 2024 const Register scratch = a1; | |
| 2025 SuperPropertyReference* super_ref = prop->obj()->AsSuperPropertyReference(); | |
| 2026 VisitForAccumulatorValue(super_ref->home_object()); | |
| 2027 __ Move(scratch, v0); | |
| 2028 VisitForAccumulatorValue(super_ref->this_var()); | |
| 2029 PushOperands(scratch, v0, v0, scratch); | |
| 2030 VisitForStackValue(prop->key()); | |
| 2031 | |
| 2032 // Stack here: | |
| 2033 // - home_object | |
| 2034 // - this (receiver) | |
| 2035 // - this (receiver) <-- LoadKeyedFromSuper will pop here and below. | |
| 2036 // - home_object | |
| 2037 // - key | |
| 2038 CallRuntimeWithOperands(Runtime::kLoadKeyedFromSuper); | |
| 2039 PrepareForBailoutForId(prop->LoadId(), BailoutState::TOS_REGISTER); | |
| 2040 | |
| 2041 // Replace home_object with target function. | |
| 2042 __ sd(v0, MemOperand(sp, kPointerSize)); | |
| 2043 | |
| 2044 // Stack here: | |
| 2045 // - target function | |
| 2046 // - this (receiver) | |
| 2047 EmitCall(expr); | |
| 2048 } | |
| 2049 | |
| 2050 | |
| 2051 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { | 1883 void FullCodeGenerator::EmitCall(Call* expr, ConvertReceiverMode mode) { |
| 2052 // Load the arguments. | 1884 // Load the arguments. |
| 2053 ZoneList<Expression*>* args = expr->arguments(); | 1885 ZoneList<Expression*>* args = expr->arguments(); |
| 2054 int arg_count = args->length(); | 1886 int arg_count = args->length(); |
| 2055 for (int i = 0; i < arg_count; i++) { | 1887 for (int i = 0; i < arg_count; i++) { |
| 2056 VisitForStackValue(args->at(i)); | 1888 VisitForStackValue(args->at(i)); |
| 2057 } | 1889 } |
| 2058 | 1890 |
| 2059 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); | 1891 PrepareForBailoutForId(expr->CallId(), BailoutState::NO_REGISTERS); |
| 2060 // Record source position of the IC call. | 1892 // Record source position of the IC call. |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2570 } | 2402 } |
| 2571 switch (assign_type) { | 2403 switch (assign_type) { |
| 2572 case NAMED_PROPERTY: { | 2404 case NAMED_PROPERTY: { |
| 2573 // Put the object both on the stack and in the register. | 2405 // Put the object both on the stack and in the register. |
| 2574 VisitForStackValue(prop->obj()); | 2406 VisitForStackValue(prop->obj()); |
| 2575 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); | 2407 __ ld(LoadDescriptor::ReceiverRegister(), MemOperand(sp, 0)); |
| 2576 EmitNamedPropertyLoad(prop); | 2408 EmitNamedPropertyLoad(prop); |
| 2577 break; | 2409 break; |
| 2578 } | 2410 } |
| 2579 | 2411 |
| 2580 case NAMED_SUPER_PROPERTY: { | |
| 2581 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2582 VisitForAccumulatorValue( | |
| 2583 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2584 const Register scratch = a1; | |
| 2585 __ ld(scratch, MemOperand(sp, 0)); // this | |
| 2586 PushOperands(result_register(), scratch, result_register()); | |
| 2587 EmitNamedSuperPropertyLoad(prop); | |
| 2588 break; | |
| 2589 } | |
| 2590 | |
| 2591 case KEYED_SUPER_PROPERTY: { | |
| 2592 VisitForStackValue(prop->obj()->AsSuperPropertyReference()->this_var()); | |
| 2593 VisitForStackValue( | |
| 2594 prop->obj()->AsSuperPropertyReference()->home_object()); | |
| 2595 VisitForAccumulatorValue(prop->key()); | |
| 2596 const Register scratch1 = a1; | |
| 2597 const Register scratch2 = a4; | |
| 2598 __ ld(scratch1, MemOperand(sp, 1 * kPointerSize)); // this | |
| 2599 __ ld(scratch2, MemOperand(sp, 0 * kPointerSize)); // home object | |
| 2600 PushOperands(result_register(), scratch1, scratch2, result_register()); | |
| 2601 EmitKeyedSuperPropertyLoad(prop); | |
| 2602 break; | |
| 2603 } | |
| 2604 | |
| 2605 case KEYED_PROPERTY: { | 2412 case KEYED_PROPERTY: { |
| 2606 VisitForStackValue(prop->obj()); | 2413 VisitForStackValue(prop->obj()); |
| 2607 VisitForStackValue(prop->key()); | 2414 VisitForStackValue(prop->key()); |
| 2608 __ ld(LoadDescriptor::ReceiverRegister(), | 2415 __ ld(LoadDescriptor::ReceiverRegister(), |
| 2609 MemOperand(sp, 1 * kPointerSize)); | 2416 MemOperand(sp, 1 * kPointerSize)); |
| 2610 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); | 2417 __ ld(LoadDescriptor::NameRegister(), MemOperand(sp, 0)); |
| 2611 EmitKeyedPropertyLoad(prop); | 2418 EmitKeyedPropertyLoad(prop); |
| 2612 break; | 2419 break; |
| 2613 } | 2420 } |
| 2614 | 2421 |
| 2422 case NAMED_SUPER_PROPERTY: |
| 2423 case KEYED_SUPER_PROPERTY: |
| 2615 case VARIABLE: | 2424 case VARIABLE: |
| 2616 UNREACHABLE(); | 2425 UNREACHABLE(); |
| 2617 } | 2426 } |
| 2618 } | 2427 } |
| 2619 | 2428 |
| 2620 // We need a second deoptimization point after loading the value | 2429 // We need a second deoptimization point after loading the value |
| 2621 // in case evaluating the property load my have a side effect. | 2430 // in case evaluating the property load my have a side effect. |
| 2622 if (assign_type == VARIABLE) { | 2431 if (assign_type == VARIABLE) { |
| 2623 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); | 2432 PrepareForBailout(expr->expression(), BailoutState::TOS_REGISTER); |
| 2624 } else { | 2433 } else { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2641 // Save the result on the stack. If we have a named or keyed property | 2450 // Save the result on the stack. If we have a named or keyed property |
| 2642 // we store the result under the receiver that is currently on top | 2451 // we store the result under the receiver that is currently on top |
| 2643 // of the stack. | 2452 // of the stack. |
| 2644 switch (assign_type) { | 2453 switch (assign_type) { |
| 2645 case VARIABLE: | 2454 case VARIABLE: |
| 2646 __ push(v0); | 2455 __ push(v0); |
| 2647 break; | 2456 break; |
| 2648 case NAMED_PROPERTY: | 2457 case NAMED_PROPERTY: |
| 2649 __ sd(v0, MemOperand(sp, kPointerSize)); | 2458 __ sd(v0, MemOperand(sp, kPointerSize)); |
| 2650 break; | 2459 break; |
| 2651 case NAMED_SUPER_PROPERTY: | |
| 2652 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); | |
| 2653 break; | |
| 2654 case KEYED_PROPERTY: | 2460 case KEYED_PROPERTY: |
| 2655 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); | 2461 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); |
| 2656 break; | 2462 break; |
| 2463 case NAMED_SUPER_PROPERTY: |
| 2657 case KEYED_SUPER_PROPERTY: | 2464 case KEYED_SUPER_PROPERTY: |
| 2658 __ sd(v0, MemOperand(sp, 3 * kPointerSize)); | 2465 UNREACHABLE(); |
| 2659 break; | 2466 break; |
| 2660 } | 2467 } |
| 2661 } | 2468 } |
| 2662 } | 2469 } |
| 2663 | 2470 |
| 2664 Register scratch1 = a1; | 2471 Register scratch1 = a1; |
| 2665 __ li(scratch1, Operand(Smi::FromInt(count_value))); | 2472 __ li(scratch1, Operand(Smi::FromInt(count_value))); |
| 2666 __ DaddBranchNoOvf(v0, v0, Operand(scratch1), &done); | 2473 __ DaddBranchNoOvf(v0, v0, Operand(scratch1), &done); |
| 2667 // Call stub. Undo operation first. | 2474 // Call stub. Undo operation first. |
| 2668 __ Move(v0, a0); | 2475 __ Move(v0, a0); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2681 // Save the result on the stack. If we have a named or keyed property | 2488 // Save the result on the stack. If we have a named or keyed property |
| 2682 // we store the result under the receiver that is currently on top | 2489 // we store the result under the receiver that is currently on top |
| 2683 // of the stack. | 2490 // of the stack. |
| 2684 switch (assign_type) { | 2491 switch (assign_type) { |
| 2685 case VARIABLE: | 2492 case VARIABLE: |
| 2686 PushOperand(v0); | 2493 PushOperand(v0); |
| 2687 break; | 2494 break; |
| 2688 case NAMED_PROPERTY: | 2495 case NAMED_PROPERTY: |
| 2689 __ sd(v0, MemOperand(sp, kPointerSize)); | 2496 __ sd(v0, MemOperand(sp, kPointerSize)); |
| 2690 break; | 2497 break; |
| 2691 case NAMED_SUPER_PROPERTY: | |
| 2692 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); | |
| 2693 break; | |
| 2694 case KEYED_PROPERTY: | 2498 case KEYED_PROPERTY: |
| 2695 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); | 2499 __ sd(v0, MemOperand(sp, 2 * kPointerSize)); |
| 2696 break; | 2500 break; |
| 2501 case NAMED_SUPER_PROPERTY: |
| 2697 case KEYED_SUPER_PROPERTY: | 2502 case KEYED_SUPER_PROPERTY: |
| 2698 __ sd(v0, MemOperand(sp, 3 * kPointerSize)); | 2503 UNREACHABLE(); |
| 2699 break; | 2504 break; |
| 2700 } | 2505 } |
| 2701 } | 2506 } |
| 2702 } | 2507 } |
| 2703 | 2508 |
| 2704 __ bind(&stub_call); | 2509 __ bind(&stub_call); |
| 2705 __ mov(a1, v0); | 2510 __ mov(a1, v0); |
| 2706 __ li(a0, Operand(Smi::FromInt(count_value))); | 2511 __ li(a0, Operand(Smi::FromInt(count_value))); |
| 2707 | 2512 |
| 2708 SetExpressionPosition(expr); | 2513 SetExpressionPosition(expr); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2745 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2550 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2746 if (expr->is_postfix()) { | 2551 if (expr->is_postfix()) { |
| 2747 if (!context()->IsEffect()) { | 2552 if (!context()->IsEffect()) { |
| 2748 context()->PlugTOS(); | 2553 context()->PlugTOS(); |
| 2749 } | 2554 } |
| 2750 } else { | 2555 } else { |
| 2751 context()->Plug(v0); | 2556 context()->Plug(v0); |
| 2752 } | 2557 } |
| 2753 break; | 2558 break; |
| 2754 } | 2559 } |
| 2755 case NAMED_SUPER_PROPERTY: { | |
| 2756 EmitNamedSuperPropertyStore(prop); | |
| 2757 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2758 if (expr->is_postfix()) { | |
| 2759 if (!context()->IsEffect()) { | |
| 2760 context()->PlugTOS(); | |
| 2761 } | |
| 2762 } else { | |
| 2763 context()->Plug(v0); | |
| 2764 } | |
| 2765 break; | |
| 2766 } | |
| 2767 case KEYED_SUPER_PROPERTY: { | |
| 2768 EmitKeyedSuperPropertyStore(prop); | |
| 2769 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | |
| 2770 if (expr->is_postfix()) { | |
| 2771 if (!context()->IsEffect()) { | |
| 2772 context()->PlugTOS(); | |
| 2773 } | |
| 2774 } else { | |
| 2775 context()->Plug(v0); | |
| 2776 } | |
| 2777 break; | |
| 2778 } | |
| 2779 case KEYED_PROPERTY: { | 2560 case KEYED_PROPERTY: { |
| 2780 __ mov(StoreDescriptor::ValueRegister(), result_register()); | 2561 __ mov(StoreDescriptor::ValueRegister(), result_register()); |
| 2781 PopOperands(StoreDescriptor::ReceiverRegister(), | 2562 PopOperands(StoreDescriptor::ReceiverRegister(), |
| 2782 StoreDescriptor::NameRegister()); | 2563 StoreDescriptor::NameRegister()); |
| 2783 CallKeyedStoreIC(expr->CountSlot()); | 2564 CallKeyedStoreIC(expr->CountSlot()); |
| 2784 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); | 2565 PrepareForBailoutForId(expr->AssignmentId(), BailoutState::TOS_REGISTER); |
| 2785 if (expr->is_postfix()) { | 2566 if (expr->is_postfix()) { |
| 2786 if (!context()->IsEffect()) { | 2567 if (!context()->IsEffect()) { |
| 2787 context()->PlugTOS(); | 2568 context()->PlugTOS(); |
| 2788 } | 2569 } |
| 2789 } else { | 2570 } else { |
| 2790 context()->Plug(v0); | 2571 context()->Plug(v0); |
| 2791 } | 2572 } |
| 2792 break; | 2573 break; |
| 2793 } | 2574 } |
| 2575 case NAMED_SUPER_PROPERTY: |
| 2576 case KEYED_SUPER_PROPERTY: |
| 2577 UNREACHABLE(); |
| 2578 break; |
| 2794 } | 2579 } |
| 2795 } | 2580 } |
| 2796 | 2581 |
| 2797 | 2582 |
| 2798 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, | 2583 void FullCodeGenerator::EmitLiteralCompareTypeof(Expression* expr, |
| 2799 Expression* sub_expr, | 2584 Expression* sub_expr, |
| 2800 Handle<String> check) { | 2585 Handle<String> check) { |
| 2801 Label materialize_true, materialize_false; | 2586 Label materialize_true, materialize_false; |
| 2802 Label* if_true = NULL; | 2587 Label* if_true = NULL; |
| 2803 Label* if_false = NULL; | 2588 Label* if_false = NULL; |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3101 reinterpret_cast<uint64_t>( | 2886 reinterpret_cast<uint64_t>( |
| 3102 isolate->builtins()->OnStackReplacement()->entry())); | 2887 isolate->builtins()->OnStackReplacement()->entry())); |
| 3103 return ON_STACK_REPLACEMENT; | 2888 return ON_STACK_REPLACEMENT; |
| 3104 } | 2889 } |
| 3105 | 2890 |
| 3106 | 2891 |
| 3107 } // namespace internal | 2892 } // namespace internal |
| 3108 } // namespace v8 | 2893 } // namespace v8 |
| 3109 | 2894 |
| 3110 #endif // V8_TARGET_ARCH_MIPS64 | 2895 #endif // V8_TARGET_ARCH_MIPS64 |
| OLD | NEW |