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

Unified Diff: src/flow-graph.cc

Issue 3146037: Cleanup the AST code by removing unused parts and get rid of the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 4 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 side-by-side diff with in-line comments
Download patch
Index: src/flow-graph.cc
===================================================================
--- src/flow-graph.cc (revision 5322)
+++ src/flow-graph.cc (working copy)
@@ -1,763 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "flow-graph.h"
-#include "scopes.h"
-
-namespace v8 {
-namespace internal {
-
-void BasicBlock::BuildTraversalOrder(ZoneList<BasicBlock*>* preorder,
- ZoneList<BasicBlock*>* postorder,
- bool mark) {
- if (mark_ == mark) return;
- mark_ = mark;
- preorder->Add(this);
- if (right_successor_ != NULL) {
- right_successor_->BuildTraversalOrder(preorder, postorder, mark);
- }
- if (left_successor_ != NULL) {
- left_successor_->BuildTraversalOrder(preorder, postorder, mark);
- }
- postorder->Add(this);
-}
-
-
-FlowGraph* FlowGraphBuilder::Build(FunctionLiteral* lit) {
- // Create new entry and exit nodes. These will not change during
- // construction.
- entry_ = new BasicBlock(NULL);
- exit_ = new BasicBlock(NULL);
- // Begin accumulating instructions in the entry block.
- current_ = entry_;
-
- VisitDeclarations(lit->scope()->declarations());
- VisitStatements(lit->body());
- // In the event of stack overflow or failure to handle a syntactic
- // construct, return an invalid flow graph.
- if (HasStackOverflow()) return new FlowGraph(NULL, NULL);
-
- // If current is not the exit, add a link to the exit.
- if (current_ != exit_) {
- // If current already has a successor (i.e., will be a branch node) and
- // if the exit already has a predecessor, insert an empty block to
- // maintain edge split form.
- if (current_->HasSuccessor() && exit_->HasPredecessor()) {
- current_ = new BasicBlock(current_);
- }
- Literal* undefined = new Literal(Factory::undefined_value());
- current_->AddInstruction(new ReturnStatement(undefined));
- exit_->AddPredecessor(current_);
- }
-
- FlowGraph* graph = new FlowGraph(entry_, exit_);
- bool mark = !entry_->GetMark();
- entry_->BuildTraversalOrder(graph->preorder(), graph->postorder(), mark);
-
-#ifdef DEBUG
- // Number the nodes in reverse postorder.
- int n = 0;
- for (int i = graph->postorder()->length() - 1; i >= 0; --i) {
- graph->postorder()->at(i)->set_number(n++);
- }
-#endif
-
- return graph;
-}
-
-
-void FlowGraphBuilder::VisitDeclaration(Declaration* decl) {
- Variable* var = decl->proxy()->AsVariable();
- Slot* slot = var->slot();
- // We allow only declarations that do not require code generation.
- // The following all require code generation: global variables and
- // functions, variables with slot type LOOKUP, declarations with
- // mode CONST, and functions.
-
- if (var->is_global() ||
- (slot != NULL && slot->type() == Slot::LOOKUP) ||
- decl->mode() == Variable::CONST ||
- decl->fun() != NULL) {
- // Here and in the rest of the flow graph builder we indicate an
- // unsupported syntactic construct by setting the stack overflow
- // flag on the visitor. This causes bailout of the visitor.
- SetStackOverflow();
- }
-}
-
-
-void FlowGraphBuilder::VisitBlock(Block* stmt) {
- VisitStatements(stmt->statements());
-}
-
-
-void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
- Visit(stmt->expression());
-}
-
-
-void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
- // Nothing to do.
-}
-
-
-void FlowGraphBuilder::VisitIfStatement(IfStatement* stmt) {
- // Build a diamond in the flow graph. First accumulate the instructions
- // of the test in the current basic block.
- Visit(stmt->condition());
-
- // Remember the branch node and accumulate the true branch as its left
- // successor. This relies on the successors being added left to right.
- BasicBlock* branch = current_;
- current_ = new BasicBlock(branch);
- Visit(stmt->then_statement());
-
- // Construct a join node and then accumulate the false branch in a fresh
- // successor of the branch node.
- BasicBlock* join = new BasicBlock(current_);
- current_ = new BasicBlock(branch);
- Visit(stmt->else_statement());
- join->AddPredecessor(current_);
-
- current_ = join;
-}
-
-
-void FlowGraphBuilder::VisitContinueStatement(ContinueStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitBreakStatement(BreakStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitForStatement(ForStatement* stmt) {
- // Build a loop in the flow graph. First accumulate the instructions of
- // the initializer in the current basic block.
- if (stmt->init() != NULL) Visit(stmt->init());
-
- // Create a new basic block for the test. This will be the join node.
- BasicBlock* join = new BasicBlock(current_);
- current_ = join;
- if (stmt->cond() != NULL) Visit(stmt->cond());
-
- // The current node is the branch node. Create a new basic block to begin
- // the body.
- BasicBlock* branch = current_;
- current_ = new BasicBlock(branch);
- Visit(stmt->body());
- if (stmt->next() != NULL) Visit(stmt->next());
-
- // Add the backward edge from the end of the body and continue with the
- // false arm of the branch.
- join->AddPredecessor(current_);
- current_ = new BasicBlock(branch);
-}
-
-
-void FlowGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitSharedFunctionInfoLiteral(
- SharedFunctionInfoLiteral* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitConditional(Conditional* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitSlot(Slot* expr) {
- // Slots do not appear in the AST.
- UNREACHABLE();
-}
-
-
-void FlowGraphBuilder::VisitVariableProxy(VariableProxy* expr) {
- current_->AddInstruction(expr);
-}
-
-
-void FlowGraphBuilder::VisitLiteral(Literal* expr) {
- current_->AddInstruction(expr);
-}
-
-
-void FlowGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitCatchExtensionObject(CatchExtensionObject* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitAssignment(Assignment* expr) {
- // There are three basic kinds of assignment: variable assignments,
- // property assignments, and invalid left-hand sides (which are translated
- // to "throw ReferenceError" by the parser).
- Variable* var = expr->target()->AsVariableProxy()->AsVariable();
- Property* prop = expr->target()->AsProperty();
- ASSERT(var == NULL || prop == NULL);
- if (var != NULL) {
- if (expr->is_compound() && !expr->target()->IsTrivial()) {
- Visit(expr->target());
- }
- if (!expr->value()->IsTrivial()) Visit(expr->value());
- current_->AddInstruction(expr);
-
- } else if (prop != NULL) {
- if (!prop->obj()->IsTrivial()) Visit(prop->obj());
- if (!prop->key()->IsPropertyName() && !prop->key()->IsTrivial()) {
- Visit(prop->key());
- }
- if (!expr->value()->IsTrivial()) Visit(expr->value());
- current_->AddInstruction(expr);
-
- } else {
- Visit(expr->target());
- }
-}
-
-
-void FlowGraphBuilder::VisitThrow(Throw* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitProperty(Property* expr) {
- if (!expr->obj()->IsTrivial()) Visit(expr->obj());
- if (!expr->key()->IsPropertyName() && !expr->key()->IsTrivial()) {
- Visit(expr->key());
- }
- current_->AddInstruction(expr);
-}
-
-
-void FlowGraphBuilder::VisitCall(Call* expr) {
- Visit(expr->expression());
- VisitExpressions(expr->arguments());
- current_->AddInstruction(expr);
-}
-
-
-void FlowGraphBuilder::VisitCallNew(CallNew* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
- SetStackOverflow();
-}
-
-
-void FlowGraphBuilder::VisitUnaryOperation(UnaryOperation* expr) {
- switch (expr->op()) {
- case Token::NOT:
- case Token::BIT_NOT:
- case Token::DELETE:
- case Token::TYPEOF:
- case Token::VOID:
- SetStackOverflow();
- break;
-
- case Token::ADD:
- case Token::SUB:
- Visit(expr->expression());
- current_->AddInstruction(expr);
- break;
-
- default:
- UNREACHABLE();
- }
-}
-
-
-void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) {
- Visit(expr->expression());
- current_->AddInstruction(expr);
-}
-
-
-void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) {
- switch (expr->op()) {
- case Token::COMMA:
- case Token::OR:
- case Token::AND:
- SetStackOverflow();
- break;
-
- case Token::BIT_OR:
- case Token::BIT_XOR:
- case Token::BIT_AND:
- case Token::SHL:
- case Token::SAR:
- case Token::SHR:
- case Token::ADD:
- case Token::SUB:
- case Token::MUL:
- case Token::DIV:
- case Token::MOD:
- if (!expr->left()->IsTrivial()) Visit(expr->left());
- if (!expr->right()->IsTrivial()) Visit(expr->right());
- current_->AddInstruction(expr);
- break;
-
- default:
- UNREACHABLE();
- }
-}
-
-
-void FlowGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
- switch (expr->op()) {
- case Token::EQ:
- case Token::NE:
- case Token::EQ_STRICT:
- case Token::NE_STRICT:
- case Token::INSTANCEOF:
- case Token::IN:
- SetStackOverflow();
- break;
-
- case Token::LT:
- case Token::GT:
- case Token::LTE:
- case Token::GTE:
- if (!expr->left()->IsTrivial()) Visit(expr->left());
- if (!expr->right()->IsTrivial()) Visit(expr->right());
- current_->AddInstruction(expr);
- break;
-
- default:
- UNREACHABLE();
- }
-}
-
-
-void FlowGraphBuilder::VisitThisFunction(ThisFunction* expr) {
- SetStackOverflow();
-}
-
-
-#ifdef DEBUG
-
-// Print a textual representation of an instruction in a flow graph.
-class InstructionPrinter: public AstVisitor {
- public:
- InstructionPrinter() {}
-
- private:
- // Overridden from the base class.
- virtual void VisitExpressions(ZoneList<Expression*>* exprs);
-
- // AST node visit functions.
-#define DECLARE_VISIT(type) virtual void Visit##type(type* node);
- AST_NODE_LIST(DECLARE_VISIT)
-#undef DECLARE_VISIT
-
- DISALLOW_COPY_AND_ASSIGN(InstructionPrinter);
-};
-
-
-static void PrintSubexpression(Expression* expr) {
- if (!expr->IsTrivial()) {
- PrintF("@%d", expr->num());
- } else if (expr->AsLiteral() != NULL) {
- expr->AsLiteral()->handle()->Print();
- } else if (expr->AsVariableProxy() != NULL) {
- PrintF("%s", *expr->AsVariableProxy()->name()->ToCString());
- } else {
- UNREACHABLE();
- }
-}
-
-
-void InstructionPrinter::VisitExpressions(ZoneList<Expression*>* exprs) {
- for (int i = 0; i < exprs->length(); ++i) {
- if (i != 0) PrintF(", ");
- PrintF("@%d", exprs->at(i)->num());
- }
-}
-
-
-// We only define printing functions for the node types that can occur as
-// instructions in a flow graph. The rest are unreachable.
-void InstructionPrinter::VisitDeclaration(Declaration* decl) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitBlock(Block* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitExpressionStatement(ExpressionStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitEmptyStatement(EmptyStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitIfStatement(IfStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitContinueStatement(ContinueStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitBreakStatement(BreakStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitReturnStatement(ReturnStatement* stmt) {
- PrintF("return ");
- PrintSubexpression(stmt->expression());
-}
-
-
-void InstructionPrinter::VisitWithEnterStatement(WithEnterStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitWithExitStatement(WithExitStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitSwitchStatement(SwitchStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitDoWhileStatement(DoWhileStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitWhileStatement(WhileStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitForStatement(ForStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitForInStatement(ForInStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitTryCatchStatement(TryCatchStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitSharedFunctionInfoLiteral(
- SharedFunctionInfoLiteral* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitConditional(Conditional* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitSlot(Slot* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitVariableProxy(VariableProxy* expr) {
- Variable* var = expr->AsVariable();
- if (var != NULL) {
- PrintF("%s", *var->name()->ToCString());
- } else {
- ASSERT(expr->AsProperty() != NULL);
- Visit(expr->AsProperty());
- }
-}
-
-
-void InstructionPrinter::VisitLiteral(Literal* expr) {
- expr->handle()->Print();
-}
-
-
-void InstructionPrinter::VisitRegExpLiteral(RegExpLiteral* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitObjectLiteral(ObjectLiteral* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitArrayLiteral(ArrayLiteral* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitCatchExtensionObject(
- CatchExtensionObject* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitAssignment(Assignment* expr) {
- Variable* var = expr->target()->AsVariableProxy()->AsVariable();
- Property* prop = expr->target()->AsProperty();
-
- // Print the left-hand side.
- Visit(expr->target());
- if (var == NULL && prop == NULL) return; // Throw reference error.
- PrintF(" = ");
- // For compound assignments, print the left-hand side again and the
- // corresponding binary operator.
- if (expr->is_compound()) {
- PrintSubexpression(expr->target());
- PrintF(" %s ", Token::String(expr->binary_op()));
- }
-
- // Print the right-hand side.
- PrintSubexpression(expr->value());
-}
-
-
-void InstructionPrinter::VisitThrow(Throw* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitProperty(Property* expr) {
- PrintSubexpression(expr->obj());
- if (expr->key()->IsPropertyName()) {
- PrintF(".");
- ASSERT(expr->key()->AsLiteral() != NULL);
- expr->key()->AsLiteral()->handle()->Print();
- } else {
- PrintF("[");
- PrintSubexpression(expr->key());
- PrintF("]");
- }
-}
-
-
-void InstructionPrinter::VisitCall(Call* expr) {
- PrintF("@%d(", expr->expression()->num());
- VisitExpressions(expr->arguments());
- PrintF(")");
-}
-
-
-void InstructionPrinter::VisitCallNew(CallNew* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitCallRuntime(CallRuntime* expr) {
- UNREACHABLE();
-}
-
-
-void InstructionPrinter::VisitUnaryOperation(UnaryOperation* expr) {
- PrintF("%s(@%d)", Token::String(expr->op()), expr->expression()->num());
-}
-
-
-void InstructionPrinter::VisitCountOperation(CountOperation* expr) {
- if (expr->is_prefix()) {
- PrintF("%s@%d", Token::String(expr->op()), expr->expression()->num());
- } else {
- PrintF("@%d%s", expr->expression()->num(), Token::String(expr->op()));
- }
-}
-
-
-void InstructionPrinter::VisitBinaryOperation(BinaryOperation* expr) {
- PrintSubexpression(expr->left());
- PrintF(" %s ", Token::String(expr->op()));
- PrintSubexpression(expr->right());
-}
-
-
-void InstructionPrinter::VisitCompareOperation(CompareOperation* expr) {
- PrintSubexpression(expr->left());
- PrintF(" %s ", Token::String(expr->op()));
- PrintSubexpression(expr->right());
-}
-
-
-void InstructionPrinter::VisitThisFunction(ThisFunction* expr) {
- UNREACHABLE();
-}
-
-
-int BasicBlock::PrintAsText(int instruction_number) {
- // Print a label for all blocks except the entry.
- if (HasPredecessor()) {
- PrintF("L%d:", number());
- }
-
- // Number and print the instructions. Since AST child nodes are visited
- // before their parents, the parent nodes can refer to them by number.
- InstructionPrinter printer;
- for (int i = 0; i < instructions_.length(); ++i) {
- PrintF("\n%d ", instruction_number);
- instructions_[i]->set_num(instruction_number++);
- instructions_[i]->Accept(&printer);
- }
-
- // If this is the exit, print "exit". If there is a single successor,
- // print "goto" successor on a separate line. If there are two
- // successors, print "goto" successor on the same line as the last
- // instruction in the block. There is a blank line between blocks (and
- // after the last one).
- if (left_successor_ == NULL) {
- PrintF("\nexit\n\n");
- } else if (right_successor_ == NULL) {
- PrintF("\ngoto L%d\n\n", left_successor_->number());
- } else {
- PrintF(", goto (L%d, L%d)\n\n",
- left_successor_->number(),
- right_successor_->number());
- }
-
- return instruction_number;
-}
-
-
-void FlowGraph::PrintAsText(Handle<String> name) {
- PrintF("\n==== name = \"%s\" ====\n", *name->ToCString());
- // Print nodes in reverse postorder. Note that AST node numbers are used
- // during printing of instructions and thus their current values are
- // destroyed.
- int number = 0;
- for (int i = postorder_.length() - 1; i >= 0; --i) {
- number = postorder_[i]->PrintAsText(number);
- }
-}
-
-#endif // DEBUG
-
-
-} } // namespace v8::internal
« no previous file with comments | « src/flow-graph.h ('k') | src/full-codegen.cc » ('j') | src/x64/full-codegen-x64.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698