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

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

Issue 7187007: Merge arguments branch to bleeding edge (second try). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Undelete external-array test. 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 __ lea(rdx, 219 __ lea(rdx,
220 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset)); 220 Operand(rbp, StandardFrameConstants::kCallerSPOffset + offset));
221 __ push(rdx); 221 __ push(rdx);
222 __ Push(Smi::FromInt(scope()->num_parameters())); 222 __ Push(Smi::FromInt(scope()->num_parameters()));
223 // Arguments to ArgumentsAccessStub: 223 // Arguments to ArgumentsAccessStub:
224 // function, receiver address, parameter count. 224 // function, receiver address, parameter count.
225 // The stub will rewrite receiver and parameter count if the previous 225 // The stub will rewrite receiver and parameter count if the previous
226 // stack frame was an arguments adapter frame. 226 // stack frame was an arguments adapter frame.
227 ArgumentsAccessStub stub( 227 ArgumentsAccessStub stub(
228 is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT 228 is_strict_mode() ? ArgumentsAccessStub::NEW_STRICT
229 : ArgumentsAccessStub::NEW_NON_STRICT); 229 : ArgumentsAccessStub::NEW_NON_STRICT_SLOW);
230 __ CallStub(&stub); 230 __ CallStub(&stub);
231 231
232 Variable* arguments_shadow = scope()->arguments_shadow();
233 if (arguments_shadow != NULL) {
234 // Store new arguments object in both "arguments" and ".arguments" slots.
235 __ movq(rcx, rax);
236 Move(arguments_shadow->AsSlot(), rcx, rbx, rdx);
237 }
238 Move(arguments->AsSlot(), rax, rbx, rdx); 232 Move(arguments->AsSlot(), rax, rbx, rdx);
239 } 233 }
240 234
241 if (FLAG_trace) { 235 if (FLAG_trace) {
242 __ CallRuntime(Runtime::kTraceEnter, 0); 236 __ CallRuntime(Runtime::kTraceEnter, 0);
243 } 237 }
244 238
245 // Visit the declarations and body unless there is an illegal 239 // Visit the declarations and body unless there is an illegal
246 // redeclaration. 240 // redeclaration.
247 if (scope()->HasIllegalRedeclaration()) { 241 if (scope()->HasIllegalRedeclaration()) {
(...skipping 966 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property)); 1208 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1215 __ jmp(done); 1209 __ jmp(done);
1216 } 1210 }
1217 } 1211 }
1218 } 1212 }
1219 } 1213 }
1220 } 1214 }
1221 1215
1222 1216
1223 void FullCodeGenerator::EmitVariableLoad(Variable* var) { 1217 void FullCodeGenerator::EmitVariableLoad(Variable* var) {
1224 // Four cases: non-this global variables, lookup slots, all other 1218 // Three cases: non-this global variables, lookup slots, and all other
1225 // types of slots, and parameters that rewrite to explicit property 1219 // types of slots.
1226 // accesses on the arguments object.
1227 Slot* slot = var->AsSlot(); 1220 Slot* slot = var->AsSlot();
1228 Property* property = var->AsProperty(); 1221 ASSERT((var->is_global() && !var->is_this()) == (slot == NULL));
1229 1222
1230 if (var->is_global() && !var->is_this()) { 1223 if (slot == NULL) {
1231 Comment cmnt(masm_, "Global variable"); 1224 Comment cmnt(masm_, "Global variable");
1232 // Use inline caching. Variable name is passed in rcx and the global 1225 // Use inline caching. Variable name is passed in rcx and the global
1233 // object on the stack. 1226 // object on the stack.
1234 __ Move(rcx, var->name()); 1227 __ Move(rcx, var->name());
1235 __ movq(rax, GlobalObjectOperand()); 1228 __ movq(rax, GlobalObjectOperand());
1236 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); 1229 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize();
1237 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber); 1230 EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT, AstNode::kNoNumber);
1238 context()->Plug(rax); 1231 context()->Plug(rax);
1239 1232
1240 } else if (slot != NULL && slot->type() == Slot::LOOKUP) { 1233 } else if (slot != NULL && slot->type() == Slot::LOOKUP) {
1241 Label done, slow; 1234 Label done, slow;
1242 1235
1243 // Generate code for loading from variables potentially shadowed 1236 // Generate code for loading from variables potentially shadowed
1244 // by eval-introduced variables. 1237 // by eval-introduced variables.
1245 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done); 1238 EmitDynamicLoadFromSlotFastCase(slot, NOT_INSIDE_TYPEOF, &slow, &done);
1246 1239
1247 __ bind(&slow); 1240 __ bind(&slow);
1248 Comment cmnt(masm_, "Lookup slot"); 1241 Comment cmnt(masm_, "Lookup slot");
1249 __ push(rsi); // Context. 1242 __ push(rsi); // Context.
1250 __ Push(var->name()); 1243 __ Push(var->name());
1251 __ CallRuntime(Runtime::kLoadContextSlot, 2); 1244 __ CallRuntime(Runtime::kLoadContextSlot, 2);
1252 __ bind(&done); 1245 __ bind(&done);
1253 1246
1254 context()->Plug(rax); 1247 context()->Plug(rax);
1255 1248
1256 } else if (slot != NULL) { 1249 } else {
1257 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT) 1250 Comment cmnt(masm_, (slot->type() == Slot::CONTEXT)
1258 ? "Context slot" 1251 ? "Context slot"
1259 : "Stack slot"); 1252 : "Stack slot");
1260 if (var->mode() == Variable::CONST) { 1253 if (var->mode() == Variable::CONST) {
1261 // Constants may be the hole value if they have not been initialized. 1254 // Constants may be the hole value if they have not been initialized.
1262 // Unhole them. 1255 // Unhole them.
1263 Label done; 1256 Label done;
1264 MemOperand slot_operand = EmitSlotSearch(slot, rax); 1257 MemOperand slot_operand = EmitSlotSearch(slot, rax);
1265 __ movq(rax, slot_operand); 1258 __ movq(rax, slot_operand);
1266 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex); 1259 __ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
1267 __ j(not_equal, &done, Label::kNear); 1260 __ j(not_equal, &done, Label::kNear);
1268 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); 1261 __ LoadRoot(rax, Heap::kUndefinedValueRootIndex);
1269 __ bind(&done); 1262 __ bind(&done);
1270 context()->Plug(rax); 1263 context()->Plug(rax);
1271 } else { 1264 } else {
1272 context()->Plug(slot); 1265 context()->Plug(slot);
1273 } 1266 }
1274
1275 } else {
1276 Comment cmnt(masm_, "Rewritten parameter");
1277 ASSERT_NOT_NULL(property);
1278 // Rewritten parameter accesses are of the form "slot[literal]".
1279
1280 // Assert that the object is in a slot.
1281 Variable* object_var = property->obj()->AsVariableProxy()->AsVariable();
1282 ASSERT_NOT_NULL(object_var);
1283 Slot* object_slot = object_var->AsSlot();
1284 ASSERT_NOT_NULL(object_slot);
1285
1286 // Load the object.
1287 MemOperand object_loc = EmitSlotSearch(object_slot, rax);
1288 __ movq(rdx, object_loc);
1289
1290 // Assert that the key is a smi.
1291 Literal* key_literal = property->key()->AsLiteral();
1292 ASSERT_NOT_NULL(key_literal);
1293 ASSERT(key_literal->handle()->IsSmi());
1294
1295 // Load the key.
1296 __ Move(rax, key_literal->handle());
1297
1298 // Do a keyed property load.
1299 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
1300 EmitCallIC(ic, RelocInfo::CODE_TARGET, GetPropertyId(property));
1301 context()->Plug(rax);
1302 } 1267 }
1303 } 1268 }
1304 1269
1305 1270
1306 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { 1271 void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
1307 Comment cmnt(masm_, "[ RegExpLiteral"); 1272 Comment cmnt(masm_, "[ RegExpLiteral");
1308 Label materialized; 1273 Label materialized;
1309 // Registers will be used as follows: 1274 // Registers will be used as follows:
1310 // rdi = JS function. 1275 // rdi = JS function.
1311 // rcx = literals array. 1276 // rcx = literals array.
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
1524 void FullCodeGenerator::VisitAssignment(Assignment* expr) { 1489 void FullCodeGenerator::VisitAssignment(Assignment* expr) {
1525 Comment cmnt(masm_, "[ Assignment"); 1490 Comment cmnt(masm_, "[ Assignment");
1526 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError' 1491 // Invalid left-hand sides are rewritten to have a 'throw ReferenceError'
1527 // on the left-hand side. 1492 // on the left-hand side.
1528 if (!expr->target()->IsValidLeftHandSide()) { 1493 if (!expr->target()->IsValidLeftHandSide()) {
1529 VisitForEffect(expr->target()); 1494 VisitForEffect(expr->target());
1530 return; 1495 return;
1531 } 1496 }
1532 1497
1533 // Left-hand side can only be a property, a global or a (parameter or local) 1498 // Left-hand side can only be a property, a global or a (parameter or local)
1534 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1499 // slot.
1535 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1500 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1536 LhsKind assign_type = VARIABLE; 1501 LhsKind assign_type = VARIABLE;
1537 Property* property = expr->target()->AsProperty(); 1502 Property* property = expr->target()->AsProperty();
1538 if (property != NULL) { 1503 if (property != NULL) {
1539 assign_type = (property->key()->IsPropertyName()) 1504 assign_type = (property->key()->IsPropertyName())
1540 ? NAMED_PROPERTY 1505 ? NAMED_PROPERTY
1541 : KEYED_PROPERTY; 1506 : KEYED_PROPERTY;
1542 } 1507 }
1543 1508
1544 // Evaluate LHS expression. 1509 // Evaluate LHS expression.
1545 switch (assign_type) { 1510 switch (assign_type) {
1546 case VARIABLE: 1511 case VARIABLE:
1547 // Nothing to do here. 1512 // Nothing to do here.
1548 break; 1513 break;
1549 case NAMED_PROPERTY: 1514 case NAMED_PROPERTY:
1550 if (expr->is_compound()) { 1515 if (expr->is_compound()) {
1551 // We need the receiver both on the stack and in the accumulator. 1516 // We need the receiver both on the stack and in the accumulator.
1552 VisitForAccumulatorValue(property->obj()); 1517 VisitForAccumulatorValue(property->obj());
1553 __ push(result_register()); 1518 __ push(result_register());
1554 } else { 1519 } else {
1555 VisitForStackValue(property->obj()); 1520 VisitForStackValue(property->obj());
1556 } 1521 }
1557 break; 1522 break;
1558 case KEYED_PROPERTY: { 1523 case KEYED_PROPERTY: {
1559 if (expr->is_compound()) { 1524 if (expr->is_compound()) {
1560 if (property->is_arguments_access()) { 1525 VisitForStackValue(property->obj());
1561 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1526 VisitForAccumulatorValue(property->key());
1562 MemOperand slot_operand =
1563 EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
1564 __ push(slot_operand);
1565 __ Move(rax, property->key()->AsLiteral()->handle());
1566 } else {
1567 VisitForStackValue(property->obj());
1568 VisitForAccumulatorValue(property->key());
1569 }
1570 __ movq(rdx, Operand(rsp, 0)); 1527 __ movq(rdx, Operand(rsp, 0));
1571 __ push(rax); 1528 __ push(rax);
1572 } else { 1529 } else {
1573 if (property->is_arguments_access()) { 1530 VisitForStackValue(property->obj());
1574 VariableProxy* obj_proxy = property->obj()->AsVariableProxy(); 1531 VisitForStackValue(property->key());
1575 MemOperand slot_operand =
1576 EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
1577 __ push(slot_operand);
1578 __ Push(property->key()->AsLiteral()->handle());
1579 } else {
1580 VisitForStackValue(property->obj());
1581 VisitForStackValue(property->key());
1582 }
1583 } 1532 }
1584 break; 1533 break;
1585 } 1534 }
1586 } 1535 }
1587 1536
1588 // For compound assignments we need another deoptimization point after the 1537 // For compound assignments we need another deoptimization point after the
1589 // variable/property load. 1538 // variable/property load.
1590 if (expr->is_compound()) { 1539 if (expr->is_compound()) {
1591 { AccumulatorValueContext context(this); 1540 { AccumulatorValueContext context(this);
1592 switch (assign_type) { 1541 switch (assign_type) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1688
1740 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) { 1689 void FullCodeGenerator::EmitAssignment(Expression* expr, int bailout_ast_id) {
1741 // Invalid left-hand sides are rewritten to have a 'throw 1690 // Invalid left-hand sides are rewritten to have a 'throw
1742 // ReferenceError' on the left-hand side. 1691 // ReferenceError' on the left-hand side.
1743 if (!expr->IsValidLeftHandSide()) { 1692 if (!expr->IsValidLeftHandSide()) {
1744 VisitForEffect(expr); 1693 VisitForEffect(expr);
1745 return; 1694 return;
1746 } 1695 }
1747 1696
1748 // Left-hand side can only be a property, a global or a (parameter or local) 1697 // Left-hand side can only be a property, a global or a (parameter or local)
1749 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 1698 // slot.
1750 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 1699 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
1751 LhsKind assign_type = VARIABLE; 1700 LhsKind assign_type = VARIABLE;
1752 Property* prop = expr->AsProperty(); 1701 Property* prop = expr->AsProperty();
1753 if (prop != NULL) { 1702 if (prop != NULL) {
1754 assign_type = (prop->key()->IsPropertyName()) 1703 assign_type = (prop->key()->IsPropertyName())
1755 ? NAMED_PROPERTY 1704 ? NAMED_PROPERTY
1756 : KEYED_PROPERTY; 1705 : KEYED_PROPERTY;
1757 } 1706 }
1758 1707
1759 switch (assign_type) { 1708 switch (assign_type) {
(...skipping 10 matching lines...) Expand all
1770 __ pop(rax); // Restore value. 1719 __ pop(rax); // Restore value.
1771 __ Move(rcx, prop->key()->AsLiteral()->handle()); 1720 __ Move(rcx, prop->key()->AsLiteral()->handle());
1772 Handle<Code> ic = is_strict_mode() 1721 Handle<Code> ic = is_strict_mode()
1773 ? isolate()->builtins()->StoreIC_Initialize_Strict() 1722 ? isolate()->builtins()->StoreIC_Initialize_Strict()
1774 : isolate()->builtins()->StoreIC_Initialize(); 1723 : isolate()->builtins()->StoreIC_Initialize();
1775 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1724 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1776 break; 1725 break;
1777 } 1726 }
1778 case KEYED_PROPERTY: { 1727 case KEYED_PROPERTY: {
1779 __ push(rax); // Preserve value. 1728 __ push(rax); // Preserve value.
1780 if (prop->is_synthetic()) { 1729 VisitForStackValue(prop->obj());
1781 ASSERT(prop->obj()->AsVariableProxy() != NULL); 1730 VisitForAccumulatorValue(prop->key());
1782 ASSERT(prop->key()->AsLiteral() != NULL); 1731 __ movq(rcx, rax);
1783 { AccumulatorValueContext for_object(this); 1732 __ pop(rdx);
1784 EmitVariableLoad(prop->obj()->AsVariableProxy()->var());
1785 }
1786 __ movq(rdx, rax);
1787 __ Move(rcx, prop->key()->AsLiteral()->handle());
1788 } else {
1789 VisitForStackValue(prop->obj());
1790 VisitForAccumulatorValue(prop->key());
1791 __ movq(rcx, rax);
1792 __ pop(rdx);
1793 }
1794 __ pop(rax); // Restore value. 1733 __ pop(rax); // Restore value.
1795 Handle<Code> ic = is_strict_mode() 1734 Handle<Code> ic = is_strict_mode()
1796 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 1735 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
1797 : isolate()->builtins()->KeyedStoreIC_Initialize(); 1736 : isolate()->builtins()->KeyedStoreIC_Initialize();
1798 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber); 1737 EmitCallIC(ic, RelocInfo::CODE_TARGET, AstNode::kNoNumber);
1799 break; 1738 break;
1800 } 1739 }
1801 } 1740 }
1802 PrepareForBailoutForId(bailout_ast_id, TOS_REG); 1741 PrepareForBailoutForId(bailout_ast_id, TOS_REG);
1803 context()->Plug(rax); 1742 context()->Plug(rax);
1804 } 1743 }
1805 1744
1806 1745
1807 void FullCodeGenerator::EmitVariableAssignment(Variable* var, 1746 void FullCodeGenerator::EmitVariableAssignment(Variable* var,
1808 Token::Value op) { 1747 Token::Value op) {
1809 // Left-hand sides that rewrite to explicit property accesses do not reach
1810 // here.
1811 ASSERT(var != NULL); 1748 ASSERT(var != NULL);
1812 ASSERT(var->is_global() || var->AsSlot() != NULL); 1749 ASSERT(var->is_global() || var->AsSlot() != NULL);
1813 1750
1814 if (var->is_global()) { 1751 if (var->is_global()) {
1815 ASSERT(!var->is_this()); 1752 ASSERT(!var->is_this());
1816 // Assignment to a global variable. Use inline caching for the 1753 // Assignment to a global variable. Use inline caching for the
1817 // assignment. Right-hand-side value is passed in rax, variable name in 1754 // assignment. Right-hand-side value is passed in rax, variable name in
1818 // rcx, and the global object on the stack. 1755 // rcx, and the global object on the stack.
1819 __ Move(rcx, var->name()); 1756 __ Move(rcx, var->name());
1820 __ movq(rdx, GlobalObjectOperand()); 1757 __ movq(rdx, GlobalObjectOperand());
(...skipping 1934 matching lines...) Expand 10 before | Expand all | Expand 10 after
3755 SetSourcePosition(expr->position()); 3692 SetSourcePosition(expr->position());
3756 3693
3757 // Invalid left-hand-sides are rewritten to have a 'throw 3694 // Invalid left-hand-sides are rewritten to have a 'throw
3758 // ReferenceError' as the left-hand side. 3695 // ReferenceError' as the left-hand side.
3759 if (!expr->expression()->IsValidLeftHandSide()) { 3696 if (!expr->expression()->IsValidLeftHandSide()) {
3760 VisitForEffect(expr->expression()); 3697 VisitForEffect(expr->expression());
3761 return; 3698 return;
3762 } 3699 }
3763 3700
3764 // Expression can only be a property, a global or a (parameter or local) 3701 // Expression can only be a property, a global or a (parameter or local)
3765 // slot. Variables with rewrite to .arguments are treated as KEYED_PROPERTY. 3702 // slot.
3766 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; 3703 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY };
3767 LhsKind assign_type = VARIABLE; 3704 LhsKind assign_type = VARIABLE;
3768 Property* prop = expr->expression()->AsProperty(); 3705 Property* prop = expr->expression()->AsProperty();
3769 // In case of a property we use the uninitialized expression context 3706 // In case of a property we use the uninitialized expression context
3770 // of the key to detect a named property. 3707 // of the key to detect a named property.
3771 if (prop != NULL) { 3708 if (prop != NULL) {
3772 assign_type = 3709 assign_type =
3773 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY; 3710 (prop->key()->IsPropertyName()) ? NAMED_PROPERTY : KEYED_PROPERTY;
3774 } 3711 }
3775 3712
3776 // Evaluate expression and get value. 3713 // Evaluate expression and get value.
3777 if (assign_type == VARIABLE) { 3714 if (assign_type == VARIABLE) {
3778 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL); 3715 ASSERT(expr->expression()->AsVariableProxy()->var() != NULL);
3779 AccumulatorValueContext context(this); 3716 AccumulatorValueContext context(this);
3780 EmitVariableLoad(expr->expression()->AsVariableProxy()->var()); 3717 EmitVariableLoad(expr->expression()->AsVariableProxy()->var());
3781 } else { 3718 } else {
3782 // Reserve space for result of postfix operation. 3719 // Reserve space for result of postfix operation.
3783 if (expr->is_postfix() && !context()->IsEffect()) { 3720 if (expr->is_postfix() && !context()->IsEffect()) {
3784 __ Push(Smi::FromInt(0)); 3721 __ Push(Smi::FromInt(0));
3785 } 3722 }
3786 if (assign_type == NAMED_PROPERTY) { 3723 if (assign_type == NAMED_PROPERTY) {
3787 VisitForAccumulatorValue(prop->obj()); 3724 VisitForAccumulatorValue(prop->obj());
3788 __ push(rax); // Copy of receiver, needed for later store. 3725 __ push(rax); // Copy of receiver, needed for later store.
3789 EmitNamedPropertyLoad(prop); 3726 EmitNamedPropertyLoad(prop);
3790 } else { 3727 } else {
3791 if (prop->is_arguments_access()) { 3728 VisitForStackValue(prop->obj());
3792 VariableProxy* obj_proxy = prop->obj()->AsVariableProxy(); 3729 VisitForAccumulatorValue(prop->key());
3793 MemOperand slot_operand =
3794 EmitSlotSearch(obj_proxy->var()->AsSlot(), rcx);
3795 __ push(slot_operand);
3796 __ Move(rax, prop->key()->AsLiteral()->handle());
3797 } else {
3798 VisitForStackValue(prop->obj());
3799 VisitForAccumulatorValue(prop->key());
3800 }
3801 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack 3730 __ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack
3802 __ push(rax); // Copy of key, needed for later store. 3731 __ push(rax); // Copy of key, needed for later store.
3803 EmitKeyedPropertyLoad(prop); 3732 EmitKeyedPropertyLoad(prop);
3804 } 3733 }
3805 } 3734 }
3806 3735
3807 // We need a second deoptimization point after loading the value 3736 // We need a second deoptimization point after loading the value
3808 // in case evaluating the property load my have a side effect. 3737 // in case evaluating the property load my have a side effect.
3809 if (assign_type == VARIABLE) { 3738 if (assign_type == VARIABLE) {
3810 PrepareForBailout(expr->expression(), TOS_REG); 3739 PrepareForBailout(expr->expression(), TOS_REG);
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
4309 __ ret(0); 4238 __ ret(0);
4310 } 4239 }
4311 4240
4312 4241
4313 #undef __ 4242 #undef __
4314 4243
4315 4244
4316 } } // namespace v8::internal 4245 } } // namespace v8::internal
4317 4246
4318 #endif // V8_TARGET_ARCH_X64 4247 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/code-stubs-x64.cc ('k') | src/x64/ic-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698