From: kmillikin@chromium.org Date: Tue, 27 Oct 2009 13:38:57 +0000 (+0000) Subject: Make it more pleasant to work with expression locations in the X-Git-Tag: upstream/4.7.83~23072 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a73bbe605e31f57db805a55c391457db9de117fe;p=platform%2Fupstream%2Fv8.git Make it more pleasant to work with expression locations in the top-level code generator backend. Introduce function to move one location to another (source cannot be nowhere); to move registers, slots, and literals into a location; and to move a location to a register or slot. Review URL: http://codereview.chromium.org/338043 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3146 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arm/fast-codegen-arm.cc b/src/arm/fast-codegen-arm.cc index e5d9bd1..02557d3 100644 --- a/src/arm/fast-codegen-arm.cc +++ b/src/arm/fast-codegen-arm.cc @@ -120,6 +120,42 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { } +void FastCodeGenerator::Move(Location destination, Slot* source) { + switch (destination.type()) { + case Location::NOWHERE: + break; + case Location::TEMP: + __ ldr(ip, MemOperand(fp, SlotOffset(source))); + __ push(ip); + break; + } +} + + +void FastCodeGenerator::Move(Location destination, Literal* expr) { + switch (destination.type()) { + case Location::NOWHERE: + break; + case Location::TEMP: + __ mov(ip, Operand(expr->handle())); + __ push(ip); + break; + } +} + + +void FastCodeGenerator::Move(Slot* destination, Location source) { + switch (source.type()) { + case Location::NOWHERE: + UNREACHABLE(); + case Location::TEMP: + __ pop(ip); + __ str(ip, MemOperand(fp, SlotOffset(destination))); + break; + } +} + + void FastCodeGenerator::DeclareGlobals(Handle pairs) { // Call the runtime to declare the globals. // The context is the first argument. @@ -131,20 +167,6 @@ void FastCodeGenerator::DeclareGlobals(Handle pairs) { } -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); @@ -154,8 +176,7 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { __ mov(r0, Operand(expr->AsLiteral()->handle())); } else { Visit(expr); - ASSERT(expr->location().is_temporary()); - __ pop(r0); + Move(r0, expr->location()); } if (FLAG_trace) { @@ -185,12 +206,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { __ mov(r0, Operand(boilerplate)); __ stm(db_w, sp, cp.bit() | r0.bit()); __ CallRuntime(Runtime::kNewClosure, 2); - - if (expr->location().is_temporary()) { - __ push(r0); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), r0); } @@ -206,34 +222,19 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { __ mov(r2, Operand(expr->name())); Handle ic(Builtins::builtin(Builtins::LoadIC_Initialize)); __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); - if (expr->location().is_temporary()) { - // Replace the global object with the result. - __ str(r0, MemOperand(sp)); - } else { - ASSERT(expr->location().is_nowhere()); - __ pop(); + switch (expr->location().type()) { + case Location::NOWHERE: + __ pop(); + break; + case Location::TEMP: + // Replace the global object with the result. + __ str(r0, MemOperand(sp)); + break; } } else { Comment cmnt(masm_, "Stack slot"); - Slot* slot = rewrite->AsSlot(); - ASSERT(slot != NULL); - if (expr->location().is_temporary()) { - __ ldr(ip, MemOperand(fp, SlotOffset(slot))); - __ push(ip); - } else { - ASSERT(expr->location().is_nowhere()); - } - } -} - - -void FastCodeGenerator::VisitLiteral(Literal* expr) { - if (expr->location().is_temporary()) { - __ mov(ip, Operand(expr->AsLiteral()->handle())); - __ push(ip); - } else { - ASSERT(expr->location().is_nowhere()); + Move(expr->location(), rewrite->AsSlot()); } } @@ -315,11 +316,13 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { default: UNREACHABLE(); } } - if (expr->location().is_nowhere() && result_saved) { - __ pop(); - } else if (expr->location().is_temporary() && !result_saved) { - ASSERT(expr->location().is_temporary()); - __ push(r0); + switch (expr->location().type()) { + case Location::NOWHERE: + if (result_saved) __ pop(); + break; + case Location::TEMP: + if (!result_saved) __ push(r0); + break; } } @@ -347,11 +350,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { __ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit()); __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); __ bind(&done); - if (expr->location().is_temporary()) { - __ push(r0); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), r0); } @@ -419,11 +418,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { __ RecordWrite(r1, r2, r0); } - Location destination = expr->location(); - if (destination.is_nowhere() && result_saved) { - __ pop(); - } else if (destination.is_temporary() && !result_saved) { - __ push(r0); + switch (expr->location().type()) { + case Location::NOWHERE: + if (result_saved) __ pop(); + break; + case Location::TEMP: + if (!result_saved) __ push(r0); + break; } } @@ -458,11 +459,13 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { Handle 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()) { - __ str(r0, MemOperand(sp)); - } else { - ASSERT(destination.is_nowhere()); - __ pop(); + switch (expr->location().type()) { + case Location::NOWHERE: + __ pop(); + break; + case Location::TEMP: + __ str(r0, MemOperand(sp)); + break; } } else { @@ -474,22 +477,23 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { // discarded result. Always perform the assignment. __ mov(ip, Operand(rhs->AsLiteral()->handle())); __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); - if (destination.is_temporary()) { - // Case 'temp <- (var = constant)'. Save result. - __ push(ip); - } + Move(expr->location(), ip); } else { ASSERT(rhs->location().is_temporary()); Visit(rhs); - if (destination.is_temporary()) { - // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side - // temporary on the stack. - __ ldr(ip, MemOperand(sp)); - } else { - ASSERT(destination.is_nowhere()); - // Case 'var = temp'. Discard right-hand-side temporary. - __ pop(ip); + // Load right-hand side into ip. + switch (expr->location().type()) { + case Location::NOWHERE: + // Case 'var = temp'. Discard right-hand-side temporary. + __ pop(ip); + break; + case Location::TEMP: + // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side + // temporary on the stack. + __ ldr(ip, MemOperand(sp)); + break; } + // Do the slot assignment. __ str(ip, MemOperand(fp, SlotOffset(var->slot()))); } } @@ -521,11 +525,13 @@ void FastCodeGenerator::VisitCall(Call* expr) { __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); // Restore context register. __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); - if (expr->location().is_temporary()) { - __ str(r0, MemOperand(sp)); - } else { - ASSERT(expr->location().is_nowhere()); - __ pop(); + switch (expr->location().type()) { + case Location::NOWHERE: + __ pop(); + break; + case Location::TEMP: + __ str(r0, MemOperand(sp)); + break; } } @@ -545,11 +551,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { } __ CallRuntime(function, arg_count); - if (expr->location().is_temporary()) { - __ push(r0); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), r0); } @@ -591,20 +593,10 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { if (destination.is_temporary()) __ pop(); // Save or discard the right-hand value as needed. if (right->AsLiteral() != NULL) { - if (destination.is_temporary()) { - __ mov(ip, Operand(right->AsLiteral()->handle())); - __ push(ip); - } else { - ASSERT(destination.is_nowhere()); - } + Move(destination, right->AsLiteral()); } else { Visit(right); - ASSERT(right->location().is_temporary()); - if (destination.is_nowhere()) { - __ pop(); - } else { - ASSERT(destination.is_temporary()); - } + Move(destination, right->location()); } __ bind(&done); diff --git a/src/fast-codegen.cc b/src/fast-codegen.cc index d5952e5..a93e911 100644 --- a/src/fast-codegen.cc +++ b/src/fast-codegen.cc @@ -53,6 +53,7 @@ Handle FastCodeGenerator::MakeCode(FunctionLiteral* fun, int FastCodeGenerator::SlotOffset(Slot* slot) { + ASSERT(slot != NULL); // Offset is negative because higher indexes are at lower addresses. int offset = -slot->index() * kPointerSize; // Adjust by a (parameter or local) base offset. @@ -70,6 +71,48 @@ int FastCodeGenerator::SlotOffset(Slot* slot) { } +void FastCodeGenerator::Move(Location destination, Location source) { + switch (destination.type()) { + case Location::NOWHERE: + break; + + case Location::TEMP: + switch (source.type()) { + case Location::NOWHERE: + UNREACHABLE(); + case Location::TEMP: + break; + } + break; + } +} + + +// All platform macro assemblers in {ia32,x64,arm} have a push(Register) +// function. +void FastCodeGenerator::Move(Location destination, Register source) { + switch (destination.type()) { + case Location::NOWHERE: + break; + case Location::TEMP: + masm_->push(source); + break; + } +} + + +// All platform macro assemblers in {ia32,x64,arm} have a pop(Register) +// function. +void FastCodeGenerator::Move(Register destination, Location source) { + switch (source.type()) { + case Location::NOWHERE: + UNREACHABLE(); + case Location::TEMP: + masm_->pop(destination); + } +} + + void FastCodeGenerator::VisitDeclarations( ZoneList* declarations) { int length = declarations->length(); @@ -191,6 +234,20 @@ void FastCodeGenerator::VisitDeclaration(Declaration* decl) { } +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::VisitEmptyStatement(EmptyStatement* stmt) { Comment cmnt(masm_, "[ EmptyStatement"); SetStatementPosition(stmt); @@ -279,6 +336,11 @@ void FastCodeGenerator::VisitSlot(Slot* expr) { } +void FastCodeGenerator::VisitLiteral(Literal* expr) { + Move(expr->location(), expr); +} + + void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) { UNREACHABLE(); } diff --git a/src/fast-codegen.h b/src/fast-codegen.h index 42d6cde..c502392 100644 --- a/src/fast-codegen.h +++ b/src/fast-codegen.h @@ -51,6 +51,15 @@ class FastCodeGenerator: public AstVisitor { private: int SlotOffset(Slot* slot); + void Move(Location destination, Location source); + + void Move(Location destination, Register source); + void Move(Location destination, Slot* source); + void Move(Location destination, Literal* source); + + void Move(Register destination, Location source); + void Move(Slot* destination, Location source); + void VisitDeclarations(ZoneList* declarations); Handle BuildBoilerplate(FunctionLiteral* fun); void DeclareGlobals(Handle pairs); diff --git a/src/ia32/fast-codegen-ia32.cc b/src/ia32/fast-codegen-ia32.cc index ee940b3..9b53223 100644 --- a/src/ia32/fast-codegen-ia32.cc +++ b/src/ia32/fast-codegen-ia32.cc @@ -108,6 +108,39 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { } +void FastCodeGenerator::Move(Location destination, Slot* source) { + switch (destination.type()) { + case Location::NOWHERE: + break; + case Location::TEMP: + __ push(Operand(ebp, SlotOffset(source))); + break; + } +} + + +void FastCodeGenerator::Move(Location destination, Literal* expr) { + switch (destination.type()) { + case Location::NOWHERE: + break; + case Location::TEMP: + __ push(Immediate(expr->handle())); + break; + } +} + + +void FastCodeGenerator::Move(Slot* destination, Location source) { + switch (source.type()) { + case Location::NOWHERE: + UNREACHABLE(); + case Location::TEMP: + __ pop(Operand(ebp, SlotOffset(destination))); + break; + } +} + + void FastCodeGenerator::DeclareGlobals(Handle pairs) { // Call the runtime to declare the globals. __ push(esi); // The context is the first argument. @@ -118,20 +151,6 @@ void FastCodeGenerator::DeclareGlobals(Handle pairs) { } -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); @@ -141,8 +160,7 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { __ mov(eax, expr->AsLiteral()->handle()); } else { Visit(expr); - ASSERT(expr->location().is_temporary()); - __ pop(eax); + Move(eax, expr->location()); } if (FLAG_trace) { @@ -172,12 +190,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { __ push(esi); __ push(Immediate(boilerplate)); __ CallRuntime(Runtime::kNewClosure, 2); - - if (expr->location().is_temporary()) { - __ push(eax); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), eax); } @@ -197,32 +210,19 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { // indicate that the inobject property case was inlined. Ensure there // is no test eax instruction here. Remember that the assembler may // choose to do peephole optimization (eg, push/pop elimination). - if (expr->location().is_temporary()) { - // Replace the global object with the result. - __ mov(Operand(esp, 0), eax); - } else { - ASSERT(expr->location().is_nowhere()); - __ add(Operand(esp), Immediate(kPointerSize)); + switch (expr->location().type()) { + case Location::NOWHERE: + __ add(Operand(esp), Immediate(kPointerSize)); + break; + case Location::TEMP: + // Replace the global object with the result. + __ mov(Operand(esp, 0), eax); + break; } } else { Comment cmnt(masm_, "Stack slot"); - Slot* slot = rewrite->AsSlot(); - ASSERT(slot != NULL); - if (expr->location().is_temporary()) { - __ push(Operand(ebp, SlotOffset(slot))); - } else { - ASSERT(expr->location().is_nowhere()); - } - } -} - - -void FastCodeGenerator::VisitLiteral(Literal* expr) { - if (expr->location().is_temporary()) { - __ push(Immediate(expr->handle())); - } else { - ASSERT(expr->location().is_nowhere()); + Move(expr->location(), rewrite->AsSlot()); } } @@ -283,8 +283,7 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { case ObjectLiteral::Property::COMPUTED: if (key->handle()->IsSymbol()) { Visit(value); - ASSERT(value->location().is_temporary()); - __ pop(eax); + Move(eax, value->location()); __ mov(ecx, Immediate(key->handle())); Handle ic(Builtins::builtin(Builtins::StoreIC_Initialize)); __ call(ic, RelocInfo::CODE_TARGET); @@ -317,10 +316,13 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { default: UNREACHABLE(); } } - if (expr->location().is_nowhere() && result_saved) { - __ add(Operand(esp), Immediate(kPointerSize)); - } else if (expr->location().is_temporary() && !result_saved) { - __ push(eax); + switch (expr->location().type()) { + case Location::NOWHERE: + if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); + break; + case Location::TEMP: + if (!result_saved) __ push(eax); + break; } } @@ -348,11 +350,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { __ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4); // Label done: __ bind(&done); - if (expr->location().is_temporary()) { - __ push(eax); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), eax); } @@ -417,11 +415,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { __ RecordWrite(ebx, offset, eax, ecx); } - Location destination = expr->location(); - if (destination.is_nowhere() && result_saved) { - __ add(Operand(esp), Immediate(kPointerSize)); - } else if (destination.is_temporary() && !result_saved) { - __ push(eax); + switch (expr->location().type()) { + case Location::NOWHERE: + if (result_saved) __ add(Operand(esp), Immediate(kPointerSize)); + break; + case Location::TEMP: + if (!result_saved) __ push(eax); + break; } } @@ -436,7 +436,6 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { ASSERT(var->is_global() || var->slot() != NULL); Expression* rhs = expr->value(); - Location destination = expr->location(); if (var->is_global()) { // Assignment to a global variable, use inline caching. Right-hand-side // value is passed in eax, variable name in ecx, and the global object @@ -455,11 +454,13 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { Handle 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()) { - __ mov(Operand(esp, 0), eax); - } else { - ASSERT(destination.is_nowhere()); - __ add(Operand(esp), Immediate(kPointerSize)); + switch (expr->location().type()) { + case Location::NOWHERE: + __ add(Operand(esp), Immediate(kPointerSize)); + break; + case Location::TEMP: + __ mov(Operand(esp, 0), eax); + break; } } else { // Local or parameter assignment. @@ -470,22 +471,21 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { // discarded result. Always perform the assignment. __ mov(eax, rhs->AsLiteral()->handle()); __ mov(Operand(ebp, SlotOffset(var->slot())), eax); - if (destination.is_temporary()) { - // Case 'temp <- (var = constant)'. Save result. - __ push(eax); - } + Move(expr->location(), eax); } else { ASSERT(rhs->location().is_temporary()); Visit(rhs); - if (destination.is_temporary()) { - // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side - // temporary on the stack. - __ mov(eax, Operand(esp, 0)); - __ mov(Operand(ebp, SlotOffset(var->slot())), eax); - } else { - ASSERT(destination.is_nowhere()); - // Case 'var = temp'. Discard right-hand-side temporary. - __ pop(Operand(ebp, 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. + __ mov(eax, Operand(esp, 0)); + __ mov(Operand(ebp, SlotOffset(var->slot())), eax); + break; } } } @@ -516,11 +516,13 @@ void FastCodeGenerator::VisitCall(Call* expr) { // Restore context register. __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); // Discard the function left on TOS. - if (expr->location().is_temporary()) { - __ mov(Operand(esp, 0), eax); - } else { - ASSERT(expr->location().is_nowhere()); - __ add(Operand(esp), Immediate(kPointerSize)); + switch (expr->location().type()) { + case Location::NOWHERE: + __ add(Operand(esp), Immediate(kPointerSize)); + break; + case Location::TEMP: + __ mov(Operand(esp, 0), eax); + break; } } @@ -540,11 +542,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { } __ CallRuntime(function, arg_count); - if (expr->location().is_temporary()) { - __ push(eax); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), eax); } @@ -572,14 +570,17 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { } else { Visit(left); ASSERT(left->location().is_temporary()); - if (destination.is_temporary()) { - // Copy the left-hand value into eax because we may need it as the - // final result. - __ mov(eax, Operand(esp, 0)); - } else { - // Pop the left-hand value into eax because we will not need it as the - // final result. - __ pop(eax); + switch (destination.type()) { + case Location::NOWHERE: + // Pop the left-hand value into eax because we will not need it as the + // final result. + __ pop(eax); + break; + case Location::TEMP: + // Copy the left-hand value into eax because we may need it as the + // final result. + __ mov(eax, Operand(esp, 0)); + break; } } // The left-hand value is in eax. It is also on the stack iff the @@ -612,19 +613,10 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { } // Save or discard the right-hand value as needed. if (right->AsLiteral() != NULL) { - if (destination.is_temporary()) { - __ push(Immediate(right->AsLiteral()->handle())); - } else { - ASSERT(destination.is_nowhere()); - } + Move(destination, right->AsLiteral()); } else { Visit(right); - ASSERT(right->location().is_temporary()); - if (destination.is_nowhere()) { - __ add(Operand(esp), Immediate(kPointerSize)); - } else { - ASSERT(destination.is_temporary()); - } + Move(destination, right->location()); } __ bind(&done); diff --git a/src/location.h b/src/location.h index 1a7b5c7..c4a77cb 100644 --- a/src/location.h +++ b/src/location.h @@ -35,15 +35,17 @@ namespace internal { class Location BASE_EMBEDDED { public: + enum Type { NOWHERE, TEMP }; + static Location Temporary() { return Location(TEMP); } static Location Nowhere() { return Location(NOWHERE); } bool is_temporary() { return type_ == TEMP; } bool is_nowhere() { return type_ == NOWHERE; } - private: - enum Type { TEMP, NOWHERE }; + Type type() { return type_; } + private: explicit Location(Type type) : type_(type) {} Type type_; diff --git a/src/x64/fast-codegen-x64.cc b/src/x64/fast-codegen-x64.cc index d64fb92..802635f 100644 --- a/src/x64/fast-codegen-x64.cc +++ b/src/x64/fast-codegen-x64.cc @@ -116,6 +116,39 @@ void FastCodeGenerator::Generate(FunctionLiteral* fun) { } +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 pairs) { // Call the runtime to declare the globals. __ push(rsi); // The context is the first argument. @@ -126,20 +159,6 @@ void FastCodeGenerator::DeclareGlobals(Handle pairs) { } -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); @@ -149,8 +168,7 @@ void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { __ Move(rax, expr->AsLiteral()->handle()); } else { Visit(expr); - ASSERT(expr->location().is_temporary()); - __ pop(rax); + Move(rax, expr->location()); } if (FLAG_trace) { @@ -189,12 +207,7 @@ void FastCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) { __ 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,32 +226,19 @@ void FastCodeGenerator::VisitVariableProxy(VariableProxy* expr) { // 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()); - } - } -} - - -void FastCodeGenerator::VisitLiteral(Literal* expr) { - if (expr->location().is_temporary()) { - __ Push(expr->handle()); - } else { - ASSERT(expr->location().is_nowhere()); + Move(expr->location(), rewrite->AsSlot()); } } @@ -329,10 +329,13 @@ void FastCodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) { 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 +363,7 @@ void FastCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) { __ 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 +428,13 @@ void FastCodeGenerator::VisitArrayLiteral(ArrayLiteral* expr) { __ 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 +468,13 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { Handle 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 +485,21 @@ void FastCodeGenerator::VisitAssignment(Assignment* expr) { // 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 +530,13 @@ void FastCodeGenerator::VisitCall(Call* expr) { // 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 +556,7 @@ void FastCodeGenerator::VisitCallRuntime(CallRuntime* expr) { } __ CallRuntime(function, arg_count); - if (expr->location().is_temporary()) { - __ push(rax); - } else { - ASSERT(expr->location().is_nowhere()); - } + Move(expr->location(), rax); } @@ -583,14 +584,17 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { } 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 +628,10 @@ void FastCodeGenerator::VisitBinaryOperation(BinaryOperation* expr) { } // 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);