Chromium Code Reviews| Index: src/full-codegen.cc |
| diff --git a/src/full-codegen.cc b/src/full-codegen.cc |
| index 180d8a8e799189954603646424d6ab1c78d3de01..cca7694af412a9bbe2d5981382e96dfedf8757a2 100644 |
| --- a/src/full-codegen.cc |
| +++ b/src/full-codegen.cc |
| @@ -21,269 +21,6 @@ |
| namespace v8 { |
| namespace internal { |
| -void BreakableStatementChecker::Check(Statement* stmt) { |
| - Visit(stmt); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::Check(Expression* expr) { |
| - Visit(expr); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitVariableDeclaration( |
| - VariableDeclaration* decl) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitFunctionDeclaration( |
| - FunctionDeclaration* decl) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitImportDeclaration( |
| - ImportDeclaration* decl) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitExportDeclaration( |
| - ExportDeclaration* decl) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitBlock(Block* stmt) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitExpressionStatement( |
| - ExpressionStatement* stmt) { |
| - // Check if expression is breakable. |
| - Visit(stmt->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitEmptyStatement(EmptyStatement* stmt) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitIfStatement(IfStatement* stmt) { |
| - // If the condition is breakable the if statement is breakable. |
| - Visit(stmt->condition()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitContinueStatement( |
| - ContinueStatement* stmt) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitBreakStatement(BreakStatement* stmt) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitReturnStatement(ReturnStatement* stmt) { |
| - // Return is breakable if the expression is. |
| - Visit(stmt->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitWithStatement(WithStatement* stmt) { |
| - Visit(stmt->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitSwitchStatement(SwitchStatement* stmt) { |
| - // Switch statements breakable if the tag expression is. |
| - Visit(stmt->tag()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| - // Mark do while as breakable to avoid adding a break slot in front of it. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitWhileStatement(WhileStatement* stmt) { |
| - // Mark while statements breakable if the condition expression is. |
| - Visit(stmt->cond()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitForStatement(ForStatement* stmt) { |
| - // We set positions for both init and condition, if they exist. |
| - if (stmt->cond() != NULL || stmt->init() != NULL) is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) { |
| - // For-in is breakable because we set the position for the enumerable. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitForOfStatement(ForOfStatement* stmt) { |
| - // For-of is breakable because we set the position for the next() call. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitTryCatchStatement( |
| - TryCatchStatement* stmt) { |
| - // Mark try catch as breakable to avoid adding a break slot in front of it. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitTryFinallyStatement( |
| - TryFinallyStatement* stmt) { |
| - // Mark try finally as breakable to avoid adding a break slot in front of it. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitDebuggerStatement( |
| - DebuggerStatement* stmt) { |
| - // The debugger statement is breakable. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCaseClause(CaseClause* clause) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitFunctionLiteral(FunctionLiteral* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitClassLiteral(ClassLiteral* expr) { |
| - if (expr->extends() != NULL) { |
| - Visit(expr->extends()); |
| - } |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitNativeFunctionLiteral( |
| - NativeFunctionLiteral* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitConditional(Conditional* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitVariableProxy(VariableProxy* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitLiteral(Literal* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitRegExpLiteral(RegExpLiteral* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitObjectLiteral(ObjectLiteral* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitArrayLiteral(ArrayLiteral* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitAssignment(Assignment* expr) { |
| - // If assigning to a property (including a global property) the assignment is |
| - // breakable. |
| - VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| - Property* prop = expr->target()->AsProperty(); |
| - if (prop != NULL || (proxy != NULL && proxy->var()->IsUnallocated())) { |
| - is_breakable_ = true; |
| - return; |
| - } |
| - |
| - // Otherwise the assignment is breakable if the assigned value is. |
| - Visit(expr->value()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitYield(Yield* expr) { |
| - // Yield is breakable if the expression is. |
| - Visit(expr->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitThrow(Throw* expr) { |
| - // Throw is breakable if the expression is. |
| - Visit(expr->exception()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitProperty(Property* expr) { |
| - // Property load is breakable. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCall(Call* expr) { |
| - // Function calls both through IC and call stub are breakable. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCallNew(CallNew* expr) { |
| - // Function calls through new are breakable. |
| - is_breakable_ = true; |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCallRuntime(CallRuntime* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitUnaryOperation(UnaryOperation* expr) { |
| - Visit(expr->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCountOperation(CountOperation* expr) { |
| - Visit(expr->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitBinaryOperation(BinaryOperation* expr) { |
| - Visit(expr->left()); |
| - if (expr->op() != Token::AND && |
| - expr->op() != Token::OR) { |
| - Visit(expr->right()); |
| - } |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) { |
| - Visit(expr->left()); |
| - Visit(expr->right()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitSpread(Spread* expr) { |
| - Visit(expr->expression()); |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) { |
| -} |
| - |
| - |
| -void BreakableStatementChecker::VisitSuperPropertyReference( |
| - SuperPropertyReference* expr) {} |
| - |
| - |
| -void BreakableStatementChecker::VisitSuperCallReference( |
| - SuperCallReference* expr) {} |
| - |
| - |
| #define __ ACCESS_MASM(masm()) |
| bool FullCodeGenerator::MakeCode(CompilationInfo* info) { |
| @@ -670,79 +407,62 @@ int FullCodeGenerator::DeclareGlobalsFlags() { |
| } |
| +bool RecordPositions(MacroAssembler* masm, int pos, bool statement = true) { |
|
ulan
2015/07/06 09:24:18
Please use enum instead of bool and avoid implicit
Yang
2015/07/06 10:05:08
Done.
|
| + if (pos != RelocInfo::kNoPosition) { |
| + if (statement) masm->positions_recorder()->RecordStatementPosition(pos); |
| + masm->positions_recorder()->RecordPosition(pos); |
| + return masm->positions_recorder()->WriteRecordedPositions(); |
| + } |
| + return false; |
| +} |
| + |
| + |
| void FullCodeGenerator::SetFunctionPosition(FunctionLiteral* fun) { |
| - CodeGenerator::RecordPositions(masm_, fun->start_position()); |
| + RecordPositions(masm_, fun->start_position(), false); |
| } |
| void FullCodeGenerator::SetReturnPosition(FunctionLiteral* fun) { |
| - CodeGenerator::RecordPositions(masm_, fun->end_position() - 1); |
| + RecordPositions(masm_, fun->end_position() - 1); |
| } |
| -void FullCodeGenerator::SetStatementPosition(Statement* stmt) { |
| - if (!info_->is_debug()) { |
| - CodeGenerator::RecordPositions(masm_, stmt->position()); |
| - } else { |
| - // Check if the statement will be breakable without adding a debug break |
| - // slot. |
| - BreakableStatementChecker checker(info_->isolate(), zone()); |
| - checker.Check(stmt); |
| - // Record the statement position right here if the statement is not |
| - // breakable. For breakable statements the actual recording of the |
| - // position will be postponed to the breakable code (typically an IC). |
| - bool position_recorded = CodeGenerator::RecordPositions( |
| - masm_, stmt->position(), !checker.is_breakable()); |
| - // If the position recording did record a new position generate a debug |
| - // break slot to make the statement breakable. |
| - if (position_recorded) { |
| - DebugCodegen::GenerateSlot(masm_); |
| - } |
| +void FullCodeGenerator::SetStatementPosition( |
| + Statement* stmt, FullCodeGenerator::InsertBreak insert_break) { |
| + if (stmt->position() == RelocInfo::kNoPosition) return; |
| + bool recorded = RecordPositions(masm_, stmt->position()); |
| + if (recorded && insert_break == INSERT_BREAK && info_->is_debug() && |
| + !stmt->IsDebuggerStatement()) { |
| + DebugCodegen::GenerateSlot(masm_); |
| } |
| } |
| -void FullCodeGenerator::VisitSuperPropertyReference( |
| - SuperPropertyReference* super) { |
| - __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
| +void FullCodeGenerator::SetExpressionPosition( |
| + Expression* expr, FullCodeGenerator::InsertBreak insert_break) { |
| + if (expr->position() == RelocInfo::kNoPosition) return; |
| + bool recorded = RecordPositions(masm_, expr->position(), false); |
| + if (recorded && insert_break == INSERT_BREAK && info_->is_debug()) { |
| + DebugCodegen::GenerateSlot(masm_); |
| + } |
| } |
| -void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { |
| - __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
| +void FullCodeGenerator::SetExpressionAsStatementPosition(Expression* expr) { |
| + if (expr->position() == RelocInfo::kNoPosition) return; |
| + bool recorded = RecordPositions(masm_, expr->position()); |
| + if (recorded && info_->is_debug()) DebugCodegen::GenerateSlot(masm_); |
| } |
| -void FullCodeGenerator::SetExpressionPosition(Expression* expr) { |
| - if (!info_->is_debug()) { |
| - CodeGenerator::RecordPositions(masm_, expr->position()); |
| - } else { |
| - // Check if the expression will be breakable without adding a debug break |
| - // slot. |
| - BreakableStatementChecker checker(info_->isolate(), zone()); |
| - checker.Check(expr); |
| - // Record a statement position right here if the expression is not |
| - // breakable. For breakable expressions the actual recording of the |
| - // position will be postponed to the breakable code (typically an IC). |
| - // NOTE this will record a statement position for something which might |
| - // not be a statement. As stepping in the debugger will only stop at |
| - // statement positions this is used for e.g. the condition expression of |
| - // a do while loop. |
| - bool position_recorded = CodeGenerator::RecordPositions( |
| - masm_, expr->position(), !checker.is_breakable()); |
| - // If the position recording did record a new position generate a debug |
| - // break slot to make the statement breakable. |
| - if (position_recorded) { |
| - DebugCodegen::GenerateSlot(masm_); |
| - } |
| - } |
| +void FullCodeGenerator::VisitSuperPropertyReference( |
| + SuperPropertyReference* super) { |
| + __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
| } |
| -void FullCodeGenerator::SetSourcePosition(int pos) { |
| - if (pos != RelocInfo::kNoPosition) { |
| - masm_->positions_recorder()->RecordPosition(pos); |
| - } |
| +void FullCodeGenerator::VisitSuperCallReference(SuperCallReference* super) { |
| + __ CallRuntime(Runtime::kThrowUnsupportedSuperError, 0); |
| } |
| @@ -878,7 +598,7 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) { |
| VisitForStackValue(left); |
| VisitForAccumulatorValue(right); |
| - SetSourcePosition(expr->position()); |
| + SetExpressionPosition(expr); |
| if (ShouldInlineSmiCase(op)) { |
| EmitInlineSmiBinaryOp(expr, op, left, right); |
| } else { |
| @@ -1060,7 +780,8 @@ void FullCodeGenerator::VisitWithStatement(WithStatement* stmt) { |
| void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| Comment cmnt(masm_, "[ DoWhileStatement"); |
| - SetStatementPosition(stmt); |
| + SetStatementPosition(stmt, SKIP_BREAK); |
|
ulan
2015/07/06 09:24:18
Please add a comment that the break is added below
Yang
2015/07/06 10:05:08
Done.
|
| + |
| Label body, book_keeping; |
| Iteration loop_statement(this, stmt); |
| @@ -1073,7 +794,9 @@ void FullCodeGenerator::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| // possible to break on the condition. |
| __ bind(loop_statement.continue_label()); |
| PrepareForBailoutForId(stmt->ContinueId(), NO_REGISTERS); |
| - SetExpressionPosition(stmt->cond()); |
| + |
| + // Here is the actual 'while' keyword. |
| + SetExpressionAsStatementPosition(stmt->cond()); |
| VisitForControl(stmt->cond(), |
| &book_keeping, |
| loop_statement.break_label(), |
| @@ -1100,7 +823,7 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
| __ bind(&loop); |
| - SetExpressionPosition(stmt->cond()); |
| + SetExpressionAsStatementPosition(stmt->cond()); |
| VisitForControl(stmt->cond(), |
| &body, |
| loop_statement.break_label(), |
| @@ -1124,13 +847,12 @@ void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) { |
| void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
| Comment cmnt(masm_, "[ ForStatement"); |
| + SetStatementPosition(stmt, SKIP_BREAK); |
|
ulan
2015/07/06 09:24:18
Please add a comment that the break is added below
Yang
2015/07/06 10:05:08
Done.
|
| + |
| Label test, body; |
| Iteration loop_statement(this, stmt); |
| - // Set statement position for a break slot before entering the for-body. |
| - SetStatementPosition(stmt); |
| - |
| if (stmt->init() != NULL) { |
| SetStatementPosition(stmt->init()); |
| Visit(stmt->init()); |
| @@ -1151,16 +873,12 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
| Visit(stmt->next()); |
| } |
| - // Emit the statement position here as this is where the for |
| - // statement code starts. |
| - SetStatementPosition(stmt); |
| - |
| // Check stack before looping. |
| EmitBackEdgeBookkeeping(stmt, &body); |
| __ bind(&test); |
| if (stmt->cond() != NULL) { |
| - SetExpressionPosition(stmt->cond()); |
| + SetExpressionAsStatementPosition(stmt->cond()); |
| VisitForControl(stmt->cond(), |
| &body, |
| loop_statement.break_label(), |
| @@ -1177,7 +895,6 @@ void FullCodeGenerator::VisitForStatement(ForStatement* stmt) { |
| void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| Comment cmnt(masm_, "[ ForOfStatement"); |
| - SetStatementPosition(stmt); |
| Iteration loop_statement(this, stmt); |
| increment_loop_depth(); |
| @@ -1189,7 +906,7 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| __ bind(loop_statement.continue_label()); |
| // result = iterator.next() |
| - SetExpressionPosition(stmt->next_result()); |
| + SetExpressionAsStatementPosition(stmt->next_result()); |
| VisitForEffect(stmt->next_result()); |
| // if (result.done) break; |
| @@ -1218,7 +935,8 @@ void FullCodeGenerator::VisitForOfStatement(ForOfStatement* stmt) { |
| void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| Comment cmnt(masm_, "[ TryCatchStatement"); |
| - SetStatementPosition(stmt); |
| + SetStatementPosition(stmt, SKIP_BREAK); |
| + |
| // The try block adds a handler to the exception handler chain before |
| // entering, and removes it again when exiting normally. If an exception |
| // is thrown during execution of the try block, the handler is consumed |
| @@ -1271,7 +989,8 @@ void FullCodeGenerator::VisitTryCatchStatement(TryCatchStatement* stmt) { |
| void FullCodeGenerator::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
| Comment cmnt(masm_, "[ TryFinallyStatement"); |
| - SetStatementPosition(stmt); |
| + SetStatementPosition(stmt, SKIP_BREAK); |
| + |
| // Try finally is compiled by setting up a try-handler on the stack while |
| // executing the try body, and removing it again afterwards. |
| // |
| @@ -1487,7 +1206,7 @@ void FullCodeGenerator::VisitNativeFunctionLiteral( |
| void FullCodeGenerator::VisitThrow(Throw* expr) { |
| Comment cmnt(masm_, "[ Throw"); |
| VisitForStackValue(expr->exception()); |
| - SetSourcePosition(expr->position()); |
| + SetExpressionPosition(expr); |
| __ CallRuntime(Runtime::kThrow, 1); |
| // Never returns here. |
| } |