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

Unified Diff: src/cfg.cc

Issue 255022: Remove obsolete support for an experimental multipass compiler. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 3 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
« no previous file with comments | « src/cfg.h ('k') | src/compiler.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/cfg.cc
===================================================================
--- src/cfg.cc (revision 2994)
+++ src/cfg.cc (working copy)
@@ -1,758 +0,0 @@
-// Copyright 2009 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 "v8.h"
-
-#include "bootstrapper.h"
-#include "cfg.h"
-#include "scopeinfo.h"
-#include "scopes.h"
-
-namespace v8 {
-namespace internal {
-
-
-CfgGlobals* CfgGlobals::top_ = NULL;
-
-
-CfgGlobals::CfgGlobals(FunctionLiteral* fun)
- : global_fun_(fun),
- global_exit_(new ExitNode()),
- nowhere_(new Nowhere()),
-#ifdef DEBUG
- node_counter_(0),
- temp_counter_(0),
-#endif
- previous_(top_) {
- top_ = this;
-}
-
-
-#define BAILOUT(reason) \
- do { return NULL; } while (false)
-
-Cfg* Cfg::Build() {
- FunctionLiteral* fun = CfgGlobals::current()->fun();
- if (fun->scope()->num_heap_slots() > 0) {
- BAILOUT("function has context slots");
- }
- if (fun->scope()->num_stack_slots() > kBitsPerPointer) {
- BAILOUT("function has too many locals");
- }
- if (fun->scope()->num_parameters() > kBitsPerPointer - 1) {
- BAILOUT("function has too many parameters");
- }
- if (fun->scope()->arguments() != NULL) {
- BAILOUT("function uses .arguments");
- }
-
- ZoneList<Statement*>* body = fun->body();
- if (body->is_empty()) {
- BAILOUT("empty function body");
- }
-
- StatementCfgBuilder builder;
- builder.VisitStatements(body);
- Cfg* graph = builder.graph();
- if (graph == NULL) {
- BAILOUT("unsupported statement type");
- }
- if (graph->is_empty()) {
- BAILOUT("function body produces empty cfg");
- }
- if (graph->has_exit()) {
- BAILOUT("control path without explicit return");
- }
- graph->PrependEntryNode();
- return graph;
-}
-
-#undef BAILOUT
-
-
-void Cfg::PrependEntryNode() {
- ASSERT(!is_empty());
- entry_ = new EntryNode(InstructionBlock::cast(entry()));
-}
-
-
-void Cfg::Append(Instruction* instr) {
- ASSERT(is_empty() || has_exit());
- if (is_empty()) {
- entry_ = exit_ = new InstructionBlock();
- }
- InstructionBlock::cast(exit_)->Append(instr);
-}
-
-
-void Cfg::AppendReturnInstruction(Value* value) {
- Append(new ReturnInstr(value));
- ExitNode* global_exit = CfgGlobals::current()->exit();
- InstructionBlock::cast(exit_)->set_successor(global_exit);
- exit_ = NULL;
-}
-
-
-void Cfg::Concatenate(Cfg* other) {
- ASSERT(is_empty() || has_exit());
- if (other->is_empty()) return;
-
- if (is_empty()) {
- entry_ = other->entry();
- exit_ = other->exit();
- } else {
- // We have a pair of nonempty fragments and this has an available exit.
- // Destructively glue the fragments together.
- InstructionBlock* first = InstructionBlock::cast(exit_);
- InstructionBlock* second = InstructionBlock::cast(other->entry());
- first->instructions()->AddAll(*second->instructions());
- if (second->successor() != NULL) {
- first->set_successor(second->successor());
- exit_ = other->exit();
- }
- }
-}
-
-
-void InstructionBlock::Unmark() {
- if (is_marked_) {
- is_marked_ = false;
- successor_->Unmark();
- }
-}
-
-
-void EntryNode::Unmark() {
- if (is_marked_) {
- is_marked_ = false;
- successor_->Unmark();
- }
-}
-
-
-void ExitNode::Unmark() {
- is_marked_ = false;
-}
-
-
-Handle<Code> Cfg::Compile(Handle<Script> script) {
- const int kInitialBufferSize = 4 * KB;
- MacroAssembler* masm = new MacroAssembler(NULL, kInitialBufferSize);
- entry()->Compile(masm);
- entry()->Unmark();
- CodeDesc desc;
- masm->GetCode(&desc);
- FunctionLiteral* fun = CfgGlobals::current()->fun();
- ZoneScopeInfo info(fun->scope());
- InLoopFlag in_loop = fun->loop_nesting() ? IN_LOOP : NOT_IN_LOOP;
- Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, in_loop);
- Handle<Code> code = Factory::NewCode(desc, &info, flags, masm->CodeObject());
-
- // Add unresolved entries in the code to the fixup list.
- Bootstrapper::AddFixup(*code, masm);
-
-#ifdef ENABLE_DISASSEMBLER
- if (FLAG_print_code) {
- // Print the source code if available.
- if (!script->IsUndefined() && !script->source()->IsUndefined()) {
- PrintF("--- Raw source ---\n");
- StringInputBuffer stream(String::cast(script->source()));
- stream.Seek(fun->start_position());
- // fun->end_position() points to the last character in the
- // stream. We need to compensate by adding one to calculate the
- // length.
- int source_len = fun->end_position() - fun->start_position() + 1;
- for (int i = 0; i < source_len; i++) {
- if (stream.has_more()) PrintF("%c", stream.GetNext());
- }
- PrintF("\n\n");
- }
- PrintF("--- Code ---\n");
- code->Disassemble(*fun->name()->ToCString());
- }
-#endif
-
- return code;
-}
-
-
-void ZeroOperandInstruction::FastAllocate(TempLocation* temp) {
- temp->set_where(TempLocation::STACK);
-}
-
-
-void OneOperandInstruction::FastAllocate(TempLocation* temp) {
- temp->set_where((temp == value_)
- ? TempLocation::ACCUMULATOR
- : TempLocation::STACK);
-}
-
-
-void TwoOperandInstruction::FastAllocate(TempLocation* temp) {
- temp->set_where((temp == value0_ || temp == value1_)
- ? TempLocation::ACCUMULATOR
- : TempLocation::STACK);
-}
-
-
-void PositionInstr::Compile(MacroAssembler* masm) {
- if (FLAG_debug_info && pos_ != RelocInfo::kNoPosition) {
- masm->RecordStatementPosition(pos_);
- masm->RecordPosition(pos_);
- }
-}
-
-
-void MoveInstr::Compile(MacroAssembler* masm) {
- location()->Move(masm, value());
-}
-
-
-// The expression builder should not be used for declarations or statements.
-void ExpressionCfgBuilder::VisitDeclaration(Declaration* decl) {
- UNREACHABLE();
-}
-
-#define DEFINE_VISIT(type) \
- void ExpressionCfgBuilder::Visit##type(type* stmt) { UNREACHABLE(); }
-STATEMENT_NODE_LIST(DEFINE_VISIT)
-#undef DEFINE_VISIT
-
-
-// Macros (temporarily) handling unsupported expression types.
-#define BAILOUT(reason) \
- do { \
- graph_ = NULL; \
- return; \
- } while (false)
-
-void ExpressionCfgBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
- BAILOUT("FunctionLiteral");
-}
-
-
-void ExpressionCfgBuilder::VisitFunctionBoilerplateLiteral(
- FunctionBoilerplateLiteral* expr) {
- BAILOUT("FunctionBoilerplateLiteral");
-}
-
-
-void ExpressionCfgBuilder::VisitConditional(Conditional* expr) {
- BAILOUT("Conditional");
-}
-
-
-void ExpressionCfgBuilder::VisitSlot(Slot* expr) {
- BAILOUT("Slot");
-}
-
-
-void ExpressionCfgBuilder::VisitVariableProxy(VariableProxy* expr) {
- Expression* rewrite = expr->var()->rewrite();
- if (rewrite == NULL || rewrite->AsSlot() == NULL) {
- BAILOUT("unsupported variable (not a slot)");
- }
- Slot* slot = rewrite->AsSlot();
- if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) {
- BAILOUT("unsupported slot type (not a parameter or local)");
- }
- // Ignore the passed destination.
- value_ = new SlotLocation(slot->type(), slot->index());
-}
-
-
-void ExpressionCfgBuilder::VisitLiteral(Literal* expr) {
- // Ignore the passed destination.
- value_ = new Constant(expr->handle());
-}
-
-
-void ExpressionCfgBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
- BAILOUT("RegExpLiteral");
-}
-
-
-void ExpressionCfgBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
- BAILOUT("ObjectLiteral");
-}
-
-
-void ExpressionCfgBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
- BAILOUT("ArrayLiteral");
-}
-
-
-void ExpressionCfgBuilder::VisitCatchExtensionObject(
- CatchExtensionObject* expr) {
- BAILOUT("CatchExtensionObject");
-}
-
-
-void ExpressionCfgBuilder::VisitAssignment(Assignment* expr) {
- if (expr->op() != Token::ASSIGN && expr->op() != Token::INIT_VAR) {
- BAILOUT("unsupported compound assignment");
- }
- Expression* lhs = expr->target();
- if (lhs->AsProperty() != NULL) {
- BAILOUT("unsupported property assignment");
- }
-
- Variable* var = lhs->AsVariableProxy()->AsVariable();
- if (var == NULL) {
- BAILOUT("unsupported invalid left-hand side");
- }
- if (var->is_global()) {
- BAILOUT("unsupported global variable");
- }
- Slot* slot = var->slot();
- ASSERT(slot != NULL);
- if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) {
- BAILOUT("unsupported slot lhs (not a parameter or local)");
- }
-
- // Parameter and local slot assignments.
- ExpressionCfgBuilder builder;
- SlotLocation* loc = new SlotLocation(slot->type(), slot->index());
- builder.Build(expr->value(), loc);
- if (builder.graph() == NULL) {
- BAILOUT("unsupported expression in assignment");
- }
- // If the expression did not come back in the slot location, append
- // a move to the CFG.
- graph_ = builder.graph();
- if (builder.value() != loc) {
- graph()->Append(new MoveInstr(loc, builder.value()));
- }
- // Record the assignment.
- assigned_vars_.AddElement(loc);
- // Ignore the destination passed to us.
- value_ = loc;
-}
-
-
-void ExpressionCfgBuilder::VisitThrow(Throw* expr) {
- BAILOUT("Throw");
-}
-
-
-void ExpressionCfgBuilder::VisitProperty(Property* expr) {
- ExpressionCfgBuilder object, key;
- object.Build(expr->obj(), NULL);
- if (object.graph() == NULL) {
- BAILOUT("unsupported object subexpression in propload");
- }
- key.Build(expr->key(), NULL);
- if (key.graph() == NULL) {
- BAILOUT("unsupported key subexpression in propload");
- }
-
- if (destination_ == NULL) destination_ = new TempLocation();
-
- graph_ = object.graph();
- // Insert a move to a fresh temporary if the object value is in a slot
- // that's assigned in the key.
- Location* temp = NULL;
- if (object.value()->is_slot() &&
- key.assigned_vars()->Contains(SlotLocation::cast(object.value()))) {
- temp = new TempLocation();
- graph()->Append(new MoveInstr(temp, object.value()));
- }
- graph()->Concatenate(key.graph());
- graph()->Append(new PropLoadInstr(destination_,
- temp == NULL ? object.value() : temp,
- key.value()));
-
- assigned_vars_ = *object.assigned_vars();
- assigned_vars()->Union(key.assigned_vars());
-
- value_ = destination_;
-}
-
-
-void ExpressionCfgBuilder::VisitCall(Call* expr) {
- BAILOUT("Call");
-}
-
-
-void ExpressionCfgBuilder::VisitCallNew(CallNew* expr) {
- BAILOUT("CallNew");
-}
-
-
-void ExpressionCfgBuilder::VisitCallRuntime(CallRuntime* expr) {
- BAILOUT("CallRuntime");
-}
-
-
-void ExpressionCfgBuilder::VisitUnaryOperation(UnaryOperation* expr) {
- BAILOUT("UnaryOperation");
-}
-
-
-void ExpressionCfgBuilder::VisitCountOperation(CountOperation* expr) {
- BAILOUT("CountOperation");
-}
-
-
-void ExpressionCfgBuilder::VisitBinaryOperation(BinaryOperation* expr) {
- Token::Value op = expr->op();
- switch (op) {
- case Token::COMMA:
- case Token::OR:
- case Token::AND:
- BAILOUT("unsupported binary operation");
-
- 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: {
- ExpressionCfgBuilder left, right;
- left.Build(expr->left(), NULL);
- if (left.graph() == NULL) {
- BAILOUT("unsupported left subexpression in binop");
- }
- right.Build(expr->right(), NULL);
- if (right.graph() == NULL) {
- BAILOUT("unsupported right subexpression in binop");
- }
-
- if (destination_ == NULL) destination_ = new TempLocation();
-
- graph_ = left.graph();
- // Insert a move to a fresh temporary if the left value is in a
- // slot that's assigned on the right.
- Location* temp = NULL;
- if (left.value()->is_slot() &&
- right.assigned_vars()->Contains(SlotLocation::cast(left.value()))) {
- temp = new TempLocation();
- graph()->Append(new MoveInstr(temp, left.value()));
- }
- graph()->Concatenate(right.graph());
- graph()->Append(new BinaryOpInstr(destination_, op,
- temp == NULL ? left.value() : temp,
- right.value()));
-
- assigned_vars_ = *left.assigned_vars();
- assigned_vars()->Union(right.assigned_vars());
-
- value_ = destination_;
- return;
- }
-
- default:
- UNREACHABLE();
- }
-}
-
-
-void ExpressionCfgBuilder::VisitCompareOperation(CompareOperation* expr) {
- BAILOUT("CompareOperation");
-}
-
-
-void ExpressionCfgBuilder::VisitThisFunction(ThisFunction* expr) {
- BAILOUT("ThisFunction");
-}
-
-#undef BAILOUT
-
-
-// Macros (temporarily) handling unsupported statement types.
-#define BAILOUT(reason) \
- do { \
- graph_ = NULL; \
- return; \
- } while (false)
-
-#define CHECK_BAILOUT() \
- if (graph() == NULL) { return; } else {}
-
-void StatementCfgBuilder::VisitStatements(ZoneList<Statement*>* stmts) {
- for (int i = 0, len = stmts->length(); i < len; i++) {
- Visit(stmts->at(i));
- CHECK_BAILOUT();
- if (!graph()->has_exit()) return;
- }
-}
-
-
-// The statement builder should not be used for declarations or expressions.
-void StatementCfgBuilder::VisitDeclaration(Declaration* decl) { UNREACHABLE(); }
-
-#define DEFINE_VISIT(type) \
- void StatementCfgBuilder::Visit##type(type* expr) { UNREACHABLE(); }
-EXPRESSION_NODE_LIST(DEFINE_VISIT)
-#undef DEFINE_VISIT
-
-
-void StatementCfgBuilder::VisitBlock(Block* stmt) {
- VisitStatements(stmt->statements());
-}
-
-
-void StatementCfgBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
- ExpressionCfgBuilder builder;
- builder.Build(stmt->expression(), CfgGlobals::current()->nowhere());
- if (builder.graph() == NULL) {
- BAILOUT("unsupported expression in expression statement");
- }
- graph()->Append(new PositionInstr(stmt->statement_pos()));
- graph()->Concatenate(builder.graph());
-}
-
-
-void StatementCfgBuilder::VisitEmptyStatement(EmptyStatement* stmt) {
- // Nothing to do.
-}
-
-
-void StatementCfgBuilder::VisitIfStatement(IfStatement* stmt) {
- BAILOUT("IfStatement");
-}
-
-
-void StatementCfgBuilder::VisitContinueStatement(ContinueStatement* stmt) {
- BAILOUT("ContinueStatement");
-}
-
-
-void StatementCfgBuilder::VisitBreakStatement(BreakStatement* stmt) {
- BAILOUT("BreakStatement");
-}
-
-
-void StatementCfgBuilder::VisitReturnStatement(ReturnStatement* stmt) {
- ExpressionCfgBuilder builder;
- builder.Build(stmt->expression(), NULL);
- if (builder.graph() == NULL) {
- BAILOUT("unsupported expression in return statement");
- }
-
- graph()->Append(new PositionInstr(stmt->statement_pos()));
- graph()->Concatenate(builder.graph());
- graph()->AppendReturnInstruction(builder.value());
-}
-
-
-void StatementCfgBuilder::VisitWithEnterStatement(WithEnterStatement* stmt) {
- BAILOUT("WithEnterStatement");
-}
-
-
-void StatementCfgBuilder::VisitWithExitStatement(WithExitStatement* stmt) {
- BAILOUT("WithExitStatement");
-}
-
-
-void StatementCfgBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
- BAILOUT("SwitchStatement");
-}
-
-
-void StatementCfgBuilder::VisitLoopStatement(LoopStatement* stmt) {
- BAILOUT("LoopStatement");
-}
-
-
-void StatementCfgBuilder::VisitForInStatement(ForInStatement* stmt) {
- BAILOUT("ForInStatement");
-}
-
-
-void StatementCfgBuilder::VisitTryCatch(TryCatch* stmt) {
- BAILOUT("TryCatch");
-}
-
-
-void StatementCfgBuilder::VisitTryFinally(TryFinally* stmt) {
- BAILOUT("TryFinally");
-}
-
-
-void StatementCfgBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) {
- BAILOUT("DebuggerStatement");
-}
-
-
-#ifdef DEBUG
-// CFG printing support (via depth-first, preorder block traversal).
-
-void Cfg::Print() {
- entry_->Print();
- entry_->Unmark();
-}
-
-
-void Constant::Print() {
- PrintF("Constant ");
- handle_->Print();
-}
-
-
-void Nowhere::Print() {
- PrintF("Nowhere");
-}
-
-
-void SlotLocation::Print() {
- PrintF("Slot ");
- switch (type_) {
- case Slot::PARAMETER:
- PrintF("(PARAMETER, %d)", index_);
- break;
- case Slot::LOCAL:
- PrintF("(LOCAL, %d)", index_);
- break;
- default:
- UNREACHABLE();
- }
-}
-
-
-void TempLocation::Print() {
- PrintF("Temp %d", number());
-}
-
-
-void OneOperandInstruction::Print() {
- PrintF("(");
- location()->Print();
- PrintF(", ");
- value_->Print();
- PrintF(")");
-}
-
-
-void TwoOperandInstruction::Print() {
- PrintF("(");
- location()->Print();
- PrintF(", ");
- value0_->Print();
- PrintF(", ");
- value1_->Print();
- PrintF(")");
-}
-
-
-void MoveInstr::Print() {
- PrintF("Move ");
- OneOperandInstruction::Print();
- PrintF("\n");
-}
-
-
-void PropLoadInstr::Print() {
- PrintF("PropLoad ");
- TwoOperandInstruction::Print();
- PrintF("\n");
-}
-
-
-void BinaryOpInstr::Print() {
- switch (op()) {
- case Token::OR:
- // Two character operand.
- PrintF("BinaryOp[OR] ");
- break;
- case Token::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:
- // Three character operands.
- PrintF("BinaryOp[%s] ", Token::Name(op()));
- break;
- case Token::COMMA:
- // Five character operand.
- PrintF("BinaryOp[COMMA] ");
- break;
- case Token::BIT_OR:
- // Six character operand.
- PrintF("BinaryOp[BIT_OR] ");
- break;
- case Token::BIT_XOR:
- case Token::BIT_AND:
- // Seven character operands.
- PrintF("BinaryOp[%s] ", Token::Name(op()));
- break;
- default:
- UNREACHABLE();
- }
- TwoOperandInstruction::Print();
- PrintF("\n");
-}
-
-
-void ReturnInstr::Print() {
- PrintF("Return ");
- OneOperandInstruction::Print();
- PrintF("\n");
-}
-
-
-void InstructionBlock::Print() {
- if (!is_marked_) {
- is_marked_ = true;
- PrintF("L%d:\n", number());
- for (int i = 0, len = instructions_.length(); i < len; i++) {
- instructions_[i]->Print();
- }
- PrintF("Goto L%d\n\n", successor_->number());
- successor_->Print();
- }
-}
-
-
-void EntryNode::Print() {
- if (!is_marked_) {
- is_marked_ = true;
- successor_->Print();
- }
-}
-
-
-void ExitNode::Print() {
- if (!is_marked_) {
- is_marked_ = true;
- PrintF("L%d:\nExit\n\n", number());
- }
-}
-
-#endif // DEBUG
-
-} } // namespace v8::internal
« no previous file with comments | « src/cfg.h ('k') | src/compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698