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

Unified Diff: src/full-codegen.cc

Issue 2693002: More precise break points and stepping when debugging... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 6 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/full-codegen.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/full-codegen.cc
===================================================================
--- src/full-codegen.cc (revision 4816)
+++ src/full-codegen.cc (working copy)
@@ -439,6 +439,231 @@
#undef CHECK_BAILOUT
+void BreakableStatementChecker::Check(Statement* stmt) {
+ Visit(stmt);
+}
+
+
+void BreakableStatementChecker::Check(Expression* expr) {
+ Visit(expr);
+}
+
+
+void BreakableStatementChecker::VisitDeclaration(Declaration* 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::VisitWithEnterStatement(
+ WithEnterStatement* stmt) {
+ Visit(stmt->expression());
+}
+
+
+void BreakableStatementChecker::VisitWithExitStatement(
+ WithExitStatement* stmt) {
+}
+
+
+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) {
+ // Mark for statements breakable if the condition expression is.
+ if (stmt->cond() != NULL) {
+ Visit(stmt->cond());
+ }
+}
+
+
+void BreakableStatementChecker::VisitForInStatement(ForInStatement* stmt) {
+ // Mark for in statements breakable if the enumerable expression is.
+ Visit(stmt->enumerable());
+}
+
+
+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::VisitFunctionLiteral(FunctionLiteral* expr) {
+}
+
+
+void BreakableStatementChecker::VisitSharedFunctionInfoLiteral(
+ SharedFunctionInfoLiteral* expr) {
+}
+
+
+void BreakableStatementChecker::VisitConditional(Conditional* expr) {
+}
+
+
+void BreakableStatementChecker::VisitSlot(Slot* 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::VisitCatchExtensionObject(
+ CatchExtensionObject* expr) {
+}
+
+
+void BreakableStatementChecker::VisitAssignment(Assignment* expr) {
+ // If assigning to a property (including a global property) the assignment is
+ // breakable.
+ Variable* var = expr->target()->AsVariableProxy()->AsVariable();
+ Property* prop = expr->target()->AsProperty();
+ if (prop != NULL || (var != NULL && var->is_global())) {
+ is_breakable_ = true;
+ return;
+ }
+
+ // Otherwise the assignment is breakable if the assigned value is.
+ Visit(expr->value());
+}
+
+
+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());
+ Visit(expr->right());
+}
+
+
+void BreakableStatementChecker::VisitCompareOperation(CompareOperation* expr) {
+ Visit(expr->left());
+ Visit(expr->right());
+}
+
+
+void BreakableStatementChecker::VisitThisFunction(ThisFunction* expr) {
+}
+
+
#define __ ACCESS_MASM(masm())
Handle<Code> FullCodeGenerator::MakeCode(CompilationInfo* info) {
@@ -552,11 +777,64 @@
void FullCodeGenerator::SetStatementPosition(Statement* stmt) {
if (FLAG_debug_info) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ if (!Debugger::IsDebuggerActive()) {
+ CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
+ } else {
+ // Check if the statement will be breakable without adding a debug break
+ // slot.
+ BreakableStatementChecker checker;
+ 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->statement_pos(), !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) {
+ Debug::GenerateSlot(masm_);
+ }
+ }
+#else
CodeGenerator::RecordPositions(masm_, stmt->statement_pos());
+#endif
}
}
+void FullCodeGenerator::SetExpressionPosition(Expression* expr, int pos) {
+ if (FLAG_debug_info) {
+#ifdef ENABLE_DEBUGGER_SUPPORT
+ if (!Debugger::IsDebuggerActive()) {
+ CodeGenerator::RecordPositions(masm_, pos);
+ } else {
+ // Check if the expression will be breakable without adding a debug break
+ // slot.
+ BreakableStatementChecker checker;
+ 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_, pos, !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) {
+ Debug::GenerateSlot(masm_);
+ }
+ }
+#else
+ CodeGenerator::RecordPositions(masm_, pos);
+#endif
+ }
+}
+
+
void FullCodeGenerator::SetStatementPosition(int pos) {
if (FLAG_debug_info) {
CodeGenerator::RecordPositions(masm_, pos);
@@ -848,7 +1126,11 @@
__ bind(&stack_check_success);
__ bind(loop_statement.continue_target());
- SetStatementPosition(stmt->condition_position());
+
+ // Record the position of the do while condition and make sure it is possible
+ // to break on the condition.
+ SetExpressionPosition(stmt->cond(), stmt->condition_position());
+
VisitForControl(stmt->cond(), &body, loop_statement.break_target());
__ bind(&stack_limit_hit);
@@ -864,7 +1146,6 @@
void FullCodeGenerator::VisitWhileStatement(WhileStatement* stmt) {
Comment cmnt(masm_, "[ WhileStatement");
- SetStatementPosition(stmt);
Label body, stack_limit_hit, stack_check_success;
Iteration loop_statement(this, stmt);
@@ -877,6 +1158,9 @@
Visit(stmt->body());
__ bind(loop_statement.continue_target());
+ // Emit the statement position here as this is where the while statement code
+ // starts.
+ SetStatementPosition(stmt);
// Check stack before looping.
__ StackLimitCheck(&stack_limit_hit);
@@ -896,7 +1180,6 @@
void FullCodeGenerator::VisitForStatement(ForStatement* stmt) {
Comment cmnt(masm_, "[ ForStatement");
- SetStatementPosition(stmt);
Label test, body, stack_limit_hit, stack_check_success;
Iteration loop_statement(this, stmt);
@@ -919,6 +1202,9 @@
}
__ bind(&test);
+ // Emit the statement position here as this is where the for statement code
+ // starts.
+ SetStatementPosition(stmt);
// Check stack before looping.
__ StackLimitCheck(&stack_limit_hit);
@@ -1064,6 +1350,8 @@
VisitForControl(expr->condition(), &true_case, &false_case);
__ bind(&true_case);
+ SetExpressionPosition(expr->then_expression(),
+ expr->then_expression_position());
Visit(expr->then_expression());
// If control flow falls through Visit, jump to done.
if (context_ == Expression::kEffect || context_ == Expression::kValue) {
@@ -1071,6 +1359,8 @@
}
__ bind(&false_case);
+ SetExpressionPosition(expr->else_expression(),
+ expr->else_expression_position());
Visit(expr->else_expression());
// If control flow falls through Visit, merge it with true case here.
if (context_ == Expression::kEffect || context_ == Expression::kValue) {
« no previous file with comments | « src/full-codegen.h ('k') | src/ia32/assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698