| Index: src/x64/fast-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/fast-codegen-x64.cc (revision 3091)
|
| +++ src/x64/fast-codegen-x64.cc (working copy)
|
| @@ -166,9 +166,10 @@
|
| Expression* rhs = expr->value();
|
| Visit(rhs);
|
|
|
| - // Left-hand side is always a (parameter or local) slot.
|
| + // Left-hand side can only be a global or a (parameter or local) slot.
|
| Variable* var = expr->target()->AsVariableProxy()->AsVariable();
|
| - ASSERT(var != NULL && var->slot() != NULL);
|
| + ASSERT(var != NULL);
|
| + ASSERT(var->is_global() || var->slot() != NULL);
|
|
|
| // Complete the assignment based on the location of the right-hand-side
|
| // value and the desired location of the assignment value.
|
| @@ -177,27 +178,50 @@
|
| ASSERT(!destination.is_constant());
|
| ASSERT(!source.is_nowhere());
|
|
|
| - if (source.is_temporary()) {
|
| + if (var->is_global()) {
|
| + // Assignment to a global variable, use inline caching. Right-hand-side
|
| + // value is passed in rax, variable name in rcx, and the global object
|
| + // on the stack.
|
| + if (source.is_temporary()) {
|
| + __ pop(rax);
|
| + } else {
|
| + ASSERT(source.is_constant());
|
| + ASSERT(rhs->AsLiteral() != NULL);
|
| + __ Move(rax, rhs->AsLiteral()->handle());
|
| + }
|
| + __ Move(rcx, var->name());
|
| + __ push(CodeGenerator::GlobalObject());
|
| + Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
|
| + __ Call(ic, RelocInfo::CODE_TARGET);
|
| + // Overwrite the global object on the stack with the result if needed.
|
| if (destination.is_temporary()) {
|
| - // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary
|
| - // on the stack.
|
| - __ movq(kScratchRegister, Operand(rsp, 0));
|
| - __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
|
| + __ movq(Operand(rsp, 0), rax);
|
| } else {
|
| - ASSERT(destination.is_nowhere());
|
| - // Case 'var = temp'. Discard right-hand-side temporary.
|
| - __ pop(Operand(rbp, SlotOffset(var->slot())));
|
| + __ pop(rax);
|
| }
|
| } else {
|
| - ASSERT(source.is_constant());
|
| - ASSERT(rhs->AsLiteral() != NULL);
|
| - // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
|
| - // discarded result. Always perform the assignment.
|
| - __ Move(kScratchRegister, rhs->AsLiteral()->handle());
|
| - __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
|
| - if (destination.is_temporary()) {
|
| - // Case 'temp <- (var = constant)'. Save result.
|
| - __ push(kScratchRegister);
|
| + if (source.is_temporary()) {
|
| + if (destination.is_temporary()) {
|
| + // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary
|
| + // on the stack.
|
| + __ movq(kScratchRegister, Operand(rsp, 0));
|
| + __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
|
| + } else {
|
| + ASSERT(destination.is_nowhere());
|
| + // Case 'var = temp'. Discard right-hand-side temporary.
|
| + __ pop(Operand(rbp, SlotOffset(var->slot())));
|
| + }
|
| + } else {
|
| + ASSERT(source.is_constant());
|
| + ASSERT(rhs->AsLiteral() != NULL);
|
| + // Two cases: 'temp <- (var = constant)', or 'var = constant' with a
|
| + // discarded result. Always perform the assignment.
|
| + __ Move(kScratchRegister, rhs->AsLiteral()->handle());
|
| + __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
|
| + if (destination.is_temporary()) {
|
| + // Case 'temp <- (var = constant)'. Save result.
|
| + __ push(kScratchRegister);
|
| + }
|
| }
|
| }
|
| }
|
|
|