| Index: src/x64/fast-codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/fast-codegen-x64.cc (revision 3140)
|
| +++ src/x64/fast-codegen-x64.cc (working copy)
|
| @@ -116,6 +116,39 @@
|
| }
|
|
|
|
|
| +void FastCodeGenerator::Move(Location destination, Slot* source) {
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + break;
|
| + case Location::TEMP:
|
| + __ push(Operand(rbp, SlotOffset(source)));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::Move(Location destination, Literal* expr) {
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + break;
|
| + case Location::TEMP:
|
| + __ Push(expr->handle());
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| +void FastCodeGenerator::Move(Slot* destination, Location source) {
|
| + switch (source.type()) {
|
| + case Location::NOWHERE:
|
| + UNREACHABLE();
|
| + case Location::TEMP:
|
| + __ pop(Operand(rbp, SlotOffset(destination)));
|
| + break;
|
| + }
|
| +}
|
| +
|
| +
|
| void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
|
| // Call the runtime to declare the globals.
|
| __ push(rsi); // The context is the first argument.
|
| @@ -126,20 +159,6 @@
|
| }
|
|
|
|
|
| -void FastCodeGenerator::VisitBlock(Block* stmt) {
|
| - Comment cmnt(masm_, "[ Block");
|
| - SetStatementPosition(stmt);
|
| - VisitStatements(stmt->statements());
|
| -}
|
| -
|
| -
|
| -void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
|
| - Comment cmnt(masm_, "[ ExpressionStatement");
|
| - SetStatementPosition(stmt);
|
| - Visit(stmt->expression());
|
| -}
|
| -
|
| -
|
| void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
|
| Comment cmnt(masm_, "[ ReturnStatement");
|
| SetStatementPosition(stmt);
|
| @@ -189,12 +208,7 @@
|
| __ push(rsi);
|
| __ Push(boilerplate);
|
| __ CallRuntime(Runtime::kNewClosure, 2);
|
| -
|
| - if (expr->location().is_temporary()) {
|
| - __ push(rax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), rax);
|
| }
|
|
|
|
|
| @@ -213,36 +227,23 @@
|
| // A test rax instruction following the call is used by the IC to
|
| // indicate that the inobject property case was inlined. Ensure there
|
| // is no test rax instruction here.
|
| - if (expr->location().is_temporary()) {
|
| - // Replace the global object with the result.
|
| - __ movq(Operand(rsp, 0), rax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ addq(rsp, Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + // Replace the global object with the result.
|
| + __ movq(Operand(rsp, 0), rax);
|
| + break;
|
| }
|
|
|
| } else {
|
| Comment cmnt(masm_, "Stack slot");
|
| - Slot* slot = rewrite->AsSlot();
|
| - ASSERT(slot != NULL);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(Operand(rbp, SlotOffset(slot)));
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), rewrite->AsSlot());
|
| }
|
| }
|
|
|
|
|
| -void FastCodeGenerator::VisitLiteral(Literal* expr) {
|
| - if (expr->location().is_temporary()) {
|
| - __ Push(expr->handle());
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| -}
|
| -
|
| -
|
| void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
|
| Comment cmnt(masm_, "[ ObjectLiteral");
|
| Label boilerplate_exists;
|
| @@ -329,10 +330,13 @@
|
| default: UNREACHABLE();
|
| }
|
| }
|
| - if (expr->location().is_nowhere() && result_saved) {
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| - } else if (expr->location().is_temporary() && !result_saved) {
|
| - __ push(rax);
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + if (result_saved) __ addq(rsp, Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + if (!result_saved) __ push(rax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -360,11 +364,7 @@
|
| __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
|
| // Label done:
|
| __ bind(&done);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(rax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), rax);
|
| }
|
|
|
|
|
| @@ -429,11 +429,13 @@
|
| __ RecordWrite(rbx, offset, rax, rcx);
|
| }
|
|
|
| - Location destination = expr->location();
|
| - if (destination.is_nowhere() && result_saved) {
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| - } else if (destination.is_temporary() && !result_saved) {
|
| - __ push(rax);
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + if (result_saved) __ addq(rsp, Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + if (!result_saved) __ push(rax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -467,10 +469,13 @@
|
| 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()) {
|
| - __ movq(Operand(rsp, 0), rax);
|
| - } else {
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ addq(rsp, Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + __ movq(Operand(rsp, 0), rax);
|
| + break;
|
| }
|
| } else {
|
| // Local or parameter assignment.
|
| @@ -481,22 +486,21 @@
|
| // 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);
|
| - }
|
| + Move(expr->location(), kScratchRegister);
|
| } else {
|
| ASSERT(rhs->location().is_temporary());
|
| Visit(rhs);
|
| - 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())));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + // Case 'var = temp'. Discard right-hand-side temporary.
|
| + Move(var->slot(), rhs->location());
|
| + break;
|
| + case Location::TEMP:
|
| + // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
|
| + // temporary on the stack.
|
| + __ movq(kScratchRegister, Operand(rsp, 0));
|
| + __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
|
| + break;
|
| }
|
| }
|
| }
|
| @@ -527,11 +531,13 @@
|
| // Restore context register.
|
| __ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
|
| // Discard the function left on TOS.
|
| - if (expr->location().is_temporary()) {
|
| - __ movq(Operand(rsp, 0), rax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| + switch (expr->location().type()) {
|
| + case Location::NOWHERE:
|
| + __ addq(rsp, Immediate(kPointerSize));
|
| + break;
|
| + case Location::TEMP:
|
| + __ movq(Operand(rsp, 0), rax);
|
| + break;
|
| }
|
| }
|
|
|
| @@ -551,11 +557,7 @@
|
| }
|
|
|
| __ CallRuntime(function, arg_count);
|
| - if (expr->location().is_temporary()) {
|
| - __ push(rax);
|
| - } else {
|
| - ASSERT(expr->location().is_nowhere());
|
| - }
|
| + Move(expr->location(), rax);
|
| }
|
|
|
|
|
| @@ -583,14 +585,17 @@
|
| } else {
|
| Visit(left);
|
| ASSERT(left->location().is_temporary());
|
| - if (destination.is_temporary()) {
|
| - // Copy the left-hand value into rax because we may need it as the
|
| - // final result.
|
| - __ movq(rax, Operand(rsp, 0));
|
| - } else {
|
| - // Pop the left-hand value into rax because we will not need it as the
|
| - // final result.
|
| - __ pop(rax);
|
| + switch (destination.type()) {
|
| + case Location::NOWHERE:
|
| + // Pop the left-hand value into rax because we will not need it as the
|
| + // final result.
|
| + __ pop(rax);
|
| + break;
|
| + case Location::TEMP:
|
| + // Copy the left-hand value into rax because we may need it as the
|
| + // final result.
|
| + __ movq(rax, Operand(rsp, 0));
|
| + break;
|
| }
|
| }
|
| // The left-hand value is in rax. It is also on the stack iff the
|
| @@ -624,19 +629,10 @@
|
| }
|
| // Save or discard the right-hand value as needed.
|
| if (right->AsLiteral() != NULL) {
|
| - if (destination.is_temporary()) {
|
| - __ Push(right->AsLiteral()->handle());
|
| - } else {
|
| - ASSERT(destination.is_nowhere());
|
| - }
|
| + Move(destination, right->AsLiteral());
|
| } else {
|
| Visit(right);
|
| - ASSERT(right->location().is_temporary());
|
| - if (destination.is_nowhere()) {
|
| - __ addq(rsp, Immediate(kPointerSize));
|
| - } else {
|
| - ASSERT(destination.is_temporary());
|
| - }
|
| + Move(destination, right->location());
|
| }
|
|
|
| __ bind(&done);
|
|
|