Refactor construction of switch statements to avoid subgraphs.

Refactor construction of switch statements so it doesn't use class
HSubgraph.

There are also a few improvements.  We do not use an auxiliary list of
comparisons because they're embedded as a linked list in the graph
under construction.  We share a common break block for all breaks from
the same switch.  We do not insert empty blocks unless necessary to
maintain edge-split form.

There is also a bug fix.  The entry to a clause body is a potential
join and must have a join ID set, otherwise deoptimization within the
body can go to an unpredictable place in the unoptimized code.

Review URL: http://codereview.chromium.org/6650021

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@7099 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 23777e1b
...@@ -878,6 +878,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -878,6 +878,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
Comment cmnt(masm_, "[ Case body"); Comment cmnt(masm_, "[ Case body");
CaseClause* clause = clauses->at(i); CaseClause* clause = clauses->at(i);
__ bind(clause->body_target()->entry_label()); __ bind(clause->body_target()->entry_label());
PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
VisitStatements(clause->statements()); VisitStatements(clause->statements());
} }
......
...@@ -1062,6 +1062,8 @@ CaseClause::CaseClause(Expression* label, ...@@ -1062,6 +1062,8 @@ CaseClause::CaseClause(Expression* label,
: label_(label), : label_(label),
statements_(statements), statements_(statements),
position_(pos), position_(pos),
compare_type_(NONE) {} compare_type_(NONE),
entry_id_(AstNode::GetNextId()) {
}
} } // namespace v8::internal } } // namespace v8::internal
...@@ -175,6 +175,8 @@ class AstNode: public ZoneObject { ...@@ -175,6 +175,8 @@ class AstNode: public ZoneObject {
static unsigned current_id_; static unsigned current_id_;
static unsigned count_; static unsigned count_;
unsigned id_; unsigned id_;
friend class CaseClause; // Generates AST IDs.
}; };
...@@ -694,6 +696,8 @@ class CaseClause: public ZoneObject { ...@@ -694,6 +696,8 @@ class CaseClause: public ZoneObject {
int position() { return position_; } int position() { return position_; }
void set_position(int pos) { position_ = pos; } void set_position(int pos) { position_ = pos; }
int EntryId() { return entry_id_; }
// Type feedback information. // Type feedback information.
void RecordTypeFeedback(TypeFeedbackOracle* oracle); void RecordTypeFeedback(TypeFeedbackOracle* oracle);
bool IsSmiCompare() { return compare_type_ == SMI_ONLY; } bool IsSmiCompare() { return compare_type_ == SMI_ONLY; }
...@@ -706,6 +710,7 @@ class CaseClause: public ZoneObject { ...@@ -706,6 +710,7 @@ class CaseClause: public ZoneObject {
int position_; int position_;
enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY }; enum CompareTypeFeedback { NONE, SMI_ONLY, OBJECT_ONLY };
CompareTypeFeedback compare_type_; CompareTypeFeedback compare_type_;
int entry_id_;
}; };
......
This diff is collapsed.
...@@ -794,7 +794,6 @@ class HGraphBuilder: public AstVisitor { ...@@ -794,7 +794,6 @@ class HGraphBuilder: public AstVisitor {
#undef DECLARE_VISIT #undef DECLARE_VISIT
HBasicBlock* CreateBasicBlock(HEnvironment* env); HBasicBlock* CreateBasicBlock(HEnvironment* env);
HSubgraph* CreateEmptySubgraph();
HBasicBlock* CreateLoopHeaderBlock(); HBasicBlock* CreateLoopHeaderBlock();
// Helpers for flow graph construction. // Helpers for flow graph construction.
...@@ -887,10 +886,6 @@ class HGraphBuilder: public AstVisitor { ...@@ -887,10 +886,6 @@ class HGraphBuilder: public AstVisitor {
HValue* val, HValue* val,
Expression* expr); Expression* expr);
HCompare* BuildSwitchCompare(HSubgraph* subgraph,
HValue* switch_value,
CaseClause* clause);
HValue* BuildContextChainWalk(Variable* var); HValue* BuildContextChainWalk(Variable* var);
void AddCheckConstantFunction(Call* expr, void AddCheckConstantFunction(Call* expr,
......
...@@ -825,6 +825,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -825,6 +825,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
Comment cmnt(masm_, "[ Case body"); Comment cmnt(masm_, "[ Case body");
CaseClause* clause = clauses->at(i); CaseClause* clause = clauses->at(i);
__ bind(clause->body_target()->entry_label()); __ bind(clause->body_target()->entry_label());
PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
VisitStatements(clause->statements()); VisitStatements(clause->statements());
} }
......
...@@ -837,6 +837,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) { ...@@ -837,6 +837,7 @@ void FullCodeGenerator::VisitSwitchStatement(SwitchStatement* stmt) {
Comment cmnt(masm_, "[ Case body"); Comment cmnt(masm_, "[ Case body");
CaseClause* clause = clauses->at(i); CaseClause* clause = clauses->at(i);
__ bind(clause->body_target()->entry_label()); __ bind(clause->body_target()->entry_label());
PrepareForBailoutForId(clause->EntryId(), NO_REGISTERS);
VisitStatements(clause->statements()); VisitStatements(clause->statements());
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment