Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/mips/full-codegen-mips.cc

Issue 7216004: MIPS: port Merge arguments branch to bleeding edge (second try). (Closed)
Patch Set: Simplify one conditional. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 int offset = scope()->num_parameters() * kPointerSize; 231 int offset = scope()->num_parameters() * kPointerSize;
232 __ Addu(a2, fp, 232 __ Addu(a2, fp,
233 Operand(StandardFrameConstants::kCallerSPOffset + offset)); 233 Operand(StandardFrameConstants::kCallerSPOffset + offset));
234 __ li(a1, Operand(Smi::FromInt(scope()->num_parameters()))); 234 __ li(a1, Operand(Smi::FromInt(scope()->num_parameters())));
235 __ Push(a3, a2, a1); 235 __ Push(a3, a2, a1);
236 236
237 // Arguments to ArgumentsAccessStub: 237 // Arguments to ArgumentsAccessStub:
238 // function, receiver address, parameter count. 238 // function, receiver address, parameter count.
239 // The stub will rewrite receiever and parameter count if the previous 239 // The stub will rewrite receiever and parameter count if the previous
240 // stack frame was an arguments adapter frame. 240 // stack frame was an arguments adapter frame.
241 ArgumentsAccessStub stub( 241 ArgumentsAccessStub::Type type;
242 is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT 242 if (is_strict_mode()) {
243 : ArgumentsAccessStub::NEW_NON_STRICT); 243 type = ArgumentsAccessStub::NEW_STRICT;
244 } else if (function()->has_duplicate_parameters()) {
245 type = ArgumentsAccessStub::NEW_NON_STRICT_SLOW;
246 } else {
247 type = ArgumentsAccessStub::NEW_NON_STRICT_FAST;
248 }
249 ArgumentsAccessStub stub(type);
244 __ CallStub(&stub); 250 __ CallStub(&stub);
245 251
246 Variable* arguments_shadow = scope()->arguments_shadow();
247 if (arguments_shadow != NULL) {
248 // Duplicate the value; move-to-slot operation might clobber registers.
249 __ mov(a3, v0);
250 Move(arguments_shadow->AsSlot(), a3, a1, a2);
251 }
252 Move(arguments->AsSlot(), v0, a1, a2); 252 Move(arguments->AsSlot(), v0, a1, a2);
253 } 253 }
254 254
255 if (FLAG_trace) { 255 if (FLAG_trace) {
256 __ CallRuntime(Runtime::kTraceEnter, 0); 256 __ CallRuntime(Runtime::kTraceEnter, 0);
257 } 257 }
258 258
259 // Visit the declarations and body unless there is an illegal 259 // Visit the declarations and body unless there is an illegal
260 // redeclaration. 260 // redeclaration.
261 if (scope()->HasIllegalRedeclaration()) { 261 if (scope()->HasIllegalRedeclaration()) {
(...skipping 985 matching lines...) Expand 10 before | Expand all | Expand 10 after
1247 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1247 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1248 __ Branch(done); 1248 __ Branch(done);
1249 } 1249 }
1250 } 1250 }
1251 } 1251 }
1252 } 1252 }
1253 } 1253 }
1254 1254
1255 1255
1256 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1256 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1257 // Four cases: non-this global variables, lookup slots, all other 1257 // Three cases: non-this global variables, lookup slots, and all other
1258 // types of slots, and parameters that rewrite to explicit property 1258 // types of slots.
1259 // accesses on the arguments object.
1260 Slot* slot = var->AsSlot(); 1259 Slot* slot = var->AsSlot();
1261 Property* property = var->AsProperty(); 1260 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1262 1261
1263 if (var->is_global() && !var->is_this()) { 1262 if (slot == NULL) {
1264 Comment cmnt(masm_, "Global variable"); 1263 Comment cmnt(masm_, "Global variable");
1265 // Use inline caching. Variable name is passed in a2 and the global 1264 // Use inline caching. Variable name is passed in a2 and the global
1266 // object (receiver) in a0. 1265 // object (receiver) in a0.
1267 __ lw(a0, GlobalObjectOperand()); 1266 __ lw(a0, GlobalObjectOperand());
1268 __ li(a2, Operand(var->name())); 1267 __ li(a2, Operand(var->name()));
1269 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1268 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1270 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1269 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1271 context()->Plug(v0); 1270 context()->Plug(v0);
1272 1271
1273 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1272 } else if (slot->type() == Slot::LOOKUP) {
1274 Label done, slow; 1273 Label done, slow;
1275 1274
1276 // Generate code for loading from variables potentially shadowed 1275 // Generate code for loading from variables potentially shadowed
1277 // by eval-introduced variables. 1276 // by eval-introduced variables.
1278 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1277 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1279 1278
1280 __ bind(&slow); 1279 __ bind(&slow);
1281 Comment cmnt(masm_, "Lookup slot"); 1280 Comment cmnt(masm_, "Lookup slot");
1282 __ li(a1, Operand(var->name())); 1281 __ li(a1, Operand(var->name()));
1283 __ Push(cp, a1); // Context and name. 1282 __ Push(cp, a1); // Context and name.
1284 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1283 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1285 __ bind(&done); 1284 __ bind(&done);
1286 1285
1287 context()->Plug(v0); 1286 context()->Plug(v0);
1288 1287
1289 } else if (slot != NULL) { 1288 } else {
1290 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1289 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1291 ? "Context slot" 1290 ? "Context slot"
1292 : "Stack slot"); 1291 : "Stack slot");
1293 if (var->mode() == Variable::CONST) { 1292 if (var->mode() == Variable::CONST) {
1294 // Constants may be the hole value if they have not been initialized. 1293 // Constants may be the hole value if they have not been initialized.
1295 // Unhole them. 1294 // Unhole them.
1296 MemOperand slot_operand = EmitSlotSearch(slot, a0); 1295 MemOperand slot_operand = EmitSlotSearch(slot, a0);
1297 __ lw(v0, slot_operand); 1296 __ lw(v0, slot_operand);
1298 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); 1297 __ LoadRoot(at, Heap::kTheHoleValueRootIndex);
1299 __ subu(at, v0, at); // Sub as compare: at == 0 on eq. 1298 __ subu(at, v0, at); // Sub as compare: at == 0 on eq.
1300 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex); 1299 __ LoadRoot(a0, Heap::kUndefinedValueRootIndex);
1301 __ movz(v0, a0, at); // Conditional move. 1300 __ movz(v0, a0, at); // Conditional move.
1302 context()->Plug(v0); 1301 context()->Plug(v0);
1303 } else { 1302 } else {
1304 context()->Plug(slot); 1303 context()->Plug(slot);
1305 } 1304 }
1306 } else {
1307 Comment cmnt(masm_, "Rewritten parameter");
1308 ASSERT_NOT_NULL(property);
1309 // Rewritten parameter accesses are of the form "slot[literal]".
1310 // Assert that the object is in a slot.
1311 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1312 ASSERT_NOT_NULL(object_var);
1313 Slot* object_slot = object_var->AsSlot();
1314 ASSERT_NOT_NULL(object_slot);
1315
1316 // Load the object.
1317 Move(a1, object_slot);
1318
1319 // Assert that the key is a smi.
1320 Literal* key_literal = property->key()->AsLiteral();
1321 ASSERT_NOT_NULL(key_literal);
1322 ASSERT(key_literal->handle()->IsSmi());
1323
1324 // Load the key.
1325 __ li(a0, Operand(key_literal->handle()));
1326
1327 // Call keyed load IC. It has arguments key and receiver in a0 and a1.
1328 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1329 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1330 context()->Plug(v0);
1331 } 1305 }
1332 } 1306 }
1333 1307
1334 1308
1335 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1309 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1336 Comment cmnt(masm_, "[ RegExpLiteral"); 1310 Comment cmnt(masm_, "[ RegExpLiteral");
1337 Label materialized; 1311 Label materialized;
1338 // Registers will be used as follows: 1312 // Registers will be used as follows:
1339 // t1 = materialized value (RegExp literal) 1313 // t1 = materialized value (RegExp literal)
1340 // t0 = JS function, literals array 1314 // t0 = JS function, literals array
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1538 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1565 Comment cmnt(masm_, "[ Assignment"); 1539 Comment cmnt(masm_, "[ Assignment");
1566 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1540 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1567 // on the left-hand side. 1541 // on the left-hand side.
1568 if (!expr->target()->IsValidLeftHandSide()) { 1542 if (!expr->target()->IsValidLeftHandSide()) {
1569 VisitForEffect(expr->target()); 1543 VisitForEffect(expr->target());
1570 return; 1544 return;
1571 } 1545 }
1572 1546
1573 // Left-hand side can only be a property, a global or a (parameter or local) 1547 // Left-hand side can only be a property, a global or a (parameter or local)
1574 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1548 // slot.
1575 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1549 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1576 LhsKind assign_type = VARIABLE; 1550 LhsKind assign_type = VARIABLE;
1577 Property* property = expr->target()->AsProperty(); 1551 Property* property = expr->target()->AsProperty();
1578 if (property != NULL) { 1552 if (property != NULL) {
1579 assign_type = (property->key()->IsPropertyName()) 1553 assign_type = (property->key()->IsPropertyName())
1580 ? NAMED_PROPERTY 1554 ? NAMED_PROPERTY
1581 : KEYED_PROPERTY; 1555 : KEYED_PROPERTY;
1582 } 1556 }
1583 1557
1584 // Evaluate LHS expression. 1558 // Evaluate LHS expression.
1585 switch (assign_type) { 1559 switch (assign_type) {
1586 case VARIABLE: 1560 case VARIABLE:
1587 // Nothing to do here. 1561 // Nothing to do here.
1588 break; 1562 break;
1589 case NAMED_PROPERTY: 1563 case NAMED_PROPERTY:
1590 if (expr->is_compound()) { 1564 if (expr->is_compound()) {
1591 // We need the receiver both on the stack and in the accumulator. 1565 // We need the receiver both on the stack and in the accumulator.
1592 VisitForAccumulatorValue(property->obj()); 1566 VisitForAccumulatorValue(property->obj());
1593 __ push(result_register()); 1567 __ push(result_register());
1594 } else { 1568 } else {
1595 VisitForStackValue(property->obj()); 1569 VisitForStackValue(property->obj());
1596 } 1570 }
1597 break; 1571 break;
1598 case KEYED_PROPERTY: 1572 case KEYED_PROPERTY:
1599 // We need the key and receiver on both the stack and in v0 and a1. 1573 // We need the key and receiver on both the stack and in v0 and a1.
1600 if (expr->is_compound()) { 1574 if (expr->is_compound()) {
1601 if (property->is_arguments_access()) { 1575 VisitForStackValue(property->obj());
1602 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1576 VisitForAccumulatorValue(property->key());
1603 __ lw(v0, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
1604 __ push(v0);
1605 __ li(v0, Operand(property->key()->AsLiteral()->handle()));
1606 } else {
1607 VisitForStackValue(property->obj());
1608 VisitForAccumulatorValue(property->key());
1609 }
1610 __ lw(a1, MemOperand(sp, 0)); 1577 __ lw(a1, MemOperand(sp, 0));
1611 __ push(v0); 1578 __ push(v0);
1612 } else { 1579 } else {
1613 if (property->is_arguments_access()) { 1580 VisitForStackValue(property->obj());
1614 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1581 VisitForStackValue(property->key());
1615 __ lw(a1, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
1616 __ li(v0, Operand(property->key()->AsLiteral()->handle()));
1617 __ Push(a1, v0);
1618 } else {
1619 VisitForStackValue(property->obj());
1620 VisitForStackValue(property->key());
1621 }
1622 } 1582 }
1623 break; 1583 break;
1624 } 1584 }
1625 1585
1626 // For compound assignments we need another deoptimization point after the 1586 // For compound assignments we need another deoptimization point after the
1627 // variable/property load. 1587 // variable/property load.
1628 if (expr->is_compound()) { 1588 if (expr->is_compound()) {
1629 { AccumulatorValueContext context(this); 1589 { AccumulatorValueContext context(this);
1630 switch (assign_type) { 1590 switch (assign_type) {
1631 case VARIABLE: 1591 case VARIABLE:
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1821 1781
1822 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1782 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1823 // Invalid left-hand sides are rewritten to have a 'throw 1783 // Invalid left-hand sides are rewritten to have a 'throw
1824 // ReferenceError' on the left-hand side. 1784 // ReferenceError' on the left-hand side.
1825 if (!expr->IsValidLeftHandSide()) { 1785 if (!expr->IsValidLeftHandSide()) {
1826 VisitForEffect(expr); 1786 VisitForEffect(expr);
1827 return; 1787 return;
1828 } 1788 }
1829 1789
1830 // Left-hand side can only be a property, a global or a (parameter or local) 1790 // Left-hand side can only be a property, a global or a (parameter or local)
1831 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1791 // slot.
1832 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1792 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1833 LhsKind assign_type = VARIABLE; 1793 LhsKind assign_type = VARIABLE;
1834 Property* prop = expr->AsProperty(); 1794 Property* prop = expr->AsProperty();
1835 if (prop != NULL) { 1795 if (prop != NULL) {
1836 assign_type = (prop->key()->IsPropertyName()) 1796 assign_type = (prop->key()->IsPropertyName())
1837 ? NAMED_PROPERTY 1797 ? NAMED_PROPERTY
1838 : KEYED_PROPERTY; 1798 : KEYED_PROPERTY;
1839 } 1799 }
1840 1800
1841 switch (assign_type) { 1801 switch (assign_type) {
(...skipping 10 matching lines...) Expand all
1852 __ pop(a0); // Restore value. 1812 __ pop(a0); // Restore value.
1853 __ li(a2, Operand(prop->key()->AsLiteral()->handle())); 1813 __ li(a2, Operand(prop->key()->AsLiteral()->handle()));
1854 Handle<Code> ic = is_strict_mode() 1814 Handle<Code> ic = is_strict_mode()
1855 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1815 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1856 : isolate()->builtins()->StoreIC_Initialize(); 1816 : isolate()->builtins()->StoreIC_Initialize();
1857 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1817 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1858 break; 1818 break;
1859 } 1819 }
1860 case KEYED_PROPERTY: { 1820 case KEYED_PROPERTY: {
1861 __ push(result_register()); // Preserve value. 1821 __ push(result_register()); // Preserve value.
1862 if (prop->is_synthetic()) { 1822 VisitForStackValue(prop->obj());
1863 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1823 VisitForAccumulatorValue(prop->key());
1864 ASSERT(prop->key()->AsLiteral() != NULL); 1824 __ mov(a1, result_register());
1865 { AccumulatorValueContext for_object(this); 1825 __ pop(a2);
1866 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1867 }
1868 __ mov(a2, result_register());
1869 __ li(a1, Operand(prop->key()->AsLiteral()->handle()));
1870 } else {
1871 VisitForStackValue(prop->obj());
1872 VisitForAccumulatorValue(prop->key());
1873 __ mov(a1, result_register());
1874 __ pop(a2);
1875 }
1876 __ pop(a0); // Restore value. 1826 __ pop(a0); // Restore value.
1877 Handle<Code> ic = is_strict_mode() 1827 Handle<Code> ic = is_strict_mode()
1878 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1828 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1879 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1829 : isolate()->builtins()->KeyedStoreIC_Initialize();
1880 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1830 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1881 break; 1831 break;
1882 } 1832 }
1883 } 1833 }
1884 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1834 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1885 context()->Plug(v0); 1835 context()->Plug(v0);
1886 } 1836 }
1887 1837
1888 1838
1889 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1839 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1890 Token::Value op) { 1840 Token::Value op) {
1891 // Left-hand sides that rewrite to explicit property accesses do not reach
1892 // here.
1893 ASSERT(var != NULL); 1841 ASSERT(var != NULL);
1894 ASSERT(var->is_global() || var->AsSlot() != NULL); 1842 ASSERT(var->is_global() || var->AsSlot() != NULL);
1895 1843
1896 if (var->is_global()) { 1844 if (var->is_global()) {
1897 ASSERT(!var->is_this()); 1845 ASSERT(!var->is_this());
1898 // Assignment to a global variable. Use inline caching for the 1846 // Assignment to a global variable. Use inline caching for the
1899 // assignment. Right-hand-side value is passed in a0, variable name in 1847 // assignment. Right-hand-side value is passed in a0, variable name in
1900 // a2, and the global object in a1. 1848 // a2, and the global object in a1.
1901 __ mov(a0, result_register()); 1849 __ mov(a0, result_register());
1902 __ li(a2, Operand(var->name())); 1850 __ li(a2, Operand(var->name()));
(...skipping 1930 matching lines...) Expand 10 before | Expand all | Expand 10 after
3833 SetSourcePosition(expr->position()); 3781 SetSourcePosition(expr->position());
3834 3782
3835 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 3783 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
3836 // as the left-hand side. 3784 // as the left-hand side.
3837 if (!expr->expression()->IsValidLeftHandSide()) { 3785 if (!expr->expression()->IsValidLeftHandSide()) {
3838 VisitForEffect(expr->expression()); 3786 VisitForEffect(expr->expression());
3839 return; 3787 return;
3840 } 3788 }
3841 3789
3842 // Expression can only be a property, a global or a (parameter or local) 3790 // Expression can only be a property, a global or a (parameter or local)
3843 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 3791 // slot.
3844 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3792 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3845 LhsKind assign_type = VARIABLE; 3793 LhsKind assign_type = VARIABLE;
3846 Property* prop = expr->expression()->AsProperty(); 3794 Property* prop = expr->expression()->AsProperty();
3847 // In case of a property we use the uninitialized expression context 3795 // In case of a property we use the uninitialized expression context
3848 // of the key to detect a named property. 3796 // of the key to detect a named property.
3849 if (prop != NULL) { 3797 if (prop != NULL) {
3850 assign_type = 3798 assign_type =
3851 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3799 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3852 } 3800 }
3853 3801
3854 // Evaluate expression and get value. 3802 // Evaluate expression and get value.
3855 if (assign_type == VARIABLE) { 3803 if (assign_type == VARIABLE) {
3856 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3804 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3857 AccumulatorValueContext context(this); 3805 AccumulatorValueContext context(this);
3858 EmitVariableLoad(expr->expression()->AsVariableProxy()->var()); 3806 EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
3859 } else { 3807 } else {
3860 // Reserve space for result of postfix operation. 3808 // Reserve space for result of postfix operation.
3861 if (expr->is_postfix() && !context()->IsEffect()) { 3809 if (expr->is_postfix() && !context()->IsEffect()) {
3862 __ li(at, Operand(Smi::FromInt(0))); 3810 __ li(at, Operand(Smi::FromInt(0)));
3863 __ push(at); 3811 __ push(at);
3864 } 3812 }
3865 if (assign_type == NAMED_PROPERTY) { 3813 if (assign_type == NAMED_PROPERTY) {
3866 // Put the object both on the stack and in the accumulator. 3814 // Put the object both on the stack and in the accumulator.
3867 VisitForAccumulatorValue(prop->obj()); 3815 VisitForAccumulatorValue(prop->obj());
3868 __ push(v0); 3816 __ push(v0);
3869 EmitNamedPropertyLoad(prop); 3817 EmitNamedPropertyLoad(prop);
3870 } else { 3818 } else {
3871 if (prop->is_arguments_access()) { 3819 VisitForStackValue(prop->obj());
3872 VariableProxy* obj_proxy = prop->obj()->AsVariableProxy(); 3820 VisitForAccumulatorValue(prop->key());
3873 __ lw(v0, EmitSlotSearch(obj_proxy->var()->AsSlot(), v0));
3874 __ push(v0);
3875 __ li(v0, Operand(prop->key()->AsLiteral()->handle()));
3876 } else {
3877 VisitForStackValue(prop->obj());
3878 VisitForAccumulatorValue(prop->key());
3879 }
3880 __ lw(a1, MemOperand(sp, 0)); 3821 __ lw(a1, MemOperand(sp, 0));
3881 __ push(v0); 3822 __ push(v0);
3882 EmitKeyedPropertyLoad(prop); 3823 EmitKeyedPropertyLoad(prop);
3883 } 3824 }
3884 } 3825 }
3885 3826
3886 // We need a second deoptimization point after loading the value 3827 // We need a second deoptimization point after loading the value
3887 // in case evaluating the property load my have a side effect. 3828 // in case evaluating the property load my have a side effect.
3888 if (assign_type == VARIABLE) { 3829 if (assign_type == VARIABLE) {
3889 PrepareForBailout(expr->expression(), TOS_REG); 3830 PrepareForBailout(expr->expression(), TOS_REG);
(...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after
4378 __ Addu(at, a1, Operand(masm_->CodeObject())); 4319 __ Addu(at, a1, Operand(masm_->CodeObject()));
4379 __ Jump(at); 4320 __ Jump(at);
4380 } 4321 }
4381 4322
4382 4323
4383 #undef __ 4324 #undef __
4384 4325
4385 } } // namespace v8::internal 4326 } } // namespace v8::internal
4386 4327
4387 #endif // V8_TARGET_ARCH_MIPS 4328 #endif // V8_TARGET_ARCH_MIPS
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698