Commit b6bbfaec authored by jgruber's avatar jgruber Committed by Commit Bot

[coverage] Add support for jumps (Break,Continue,Return)

Drive-by-fixes: Singleton ranges past EOF, disable optimization
for block count mode.

Bug: v8:6000
Change-Id: I718891f8821285ce3d7d8360faaa91a43de5b93d
Reviewed-on: https://chromium-review.googlesource.com/541300Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46168}
parent 8d921ca7
...@@ -775,8 +775,13 @@ class JumpStatement : public Statement { ...@@ -775,8 +775,13 @@ class JumpStatement : public Statement {
public: public:
bool IsJump() const { return true; } bool IsJump() const { return true; }
int32_t continuation_pos() const { return continuation_pos_; }
protected: protected:
JumpStatement(int pos, NodeType type) : Statement(pos, type) {} JumpStatement(int pos, NodeType type, int32_t continuation_pos)
: Statement(pos, type), continuation_pos_(continuation_pos) {}
int32_t continuation_pos_;
}; };
...@@ -787,8 +792,9 @@ class ContinueStatement final : public JumpStatement { ...@@ -787,8 +792,9 @@ class ContinueStatement final : public JumpStatement {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
ContinueStatement(IterationStatement* target, int pos) ContinueStatement(IterationStatement* target, int pos, int continuation_pos)
: JumpStatement(pos, kContinueStatement), target_(target) {} : JumpStatement(pos, kContinueStatement, continuation_pos),
target_(target) {}
IterationStatement* target_; IterationStatement* target_;
}; };
...@@ -801,8 +807,9 @@ class BreakStatement final : public JumpStatement { ...@@ -801,8 +807,9 @@ class BreakStatement final : public JumpStatement {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
BreakStatement(BreakableStatement* target, int pos) BreakStatement(BreakableStatement* target, int pos, int continuation_pos)
: JumpStatement(pos, kBreakStatement), target_(target) {} : JumpStatement(pos, kBreakStatement, continuation_pos),
target_(target) {}
BreakableStatement* target_; BreakableStatement* target_;
}; };
...@@ -820,8 +827,10 @@ class ReturnStatement final : public JumpStatement { ...@@ -820,8 +827,10 @@ class ReturnStatement final : public JumpStatement {
private: private:
friend class AstNodeFactory; friend class AstNodeFactory;
ReturnStatement(Expression* expression, Type type, int pos) ReturnStatement(Expression* expression, Type type, int pos,
: JumpStatement(pos, kReturnStatement), expression_(expression) { int continuation_pos)
: JumpStatement(pos, kReturnStatement, continuation_pos),
expression_(expression) {
bit_field_ |= TypeField::encode(type); bit_field_ |= TypeField::encode(type);
} }
...@@ -3110,22 +3119,29 @@ class AstNodeFactory final BASE_EMBEDDED { ...@@ -3110,22 +3119,29 @@ class AstNodeFactory final BASE_EMBEDDED {
return new (zone_) ExpressionStatement(expression, pos); return new (zone_) ExpressionStatement(expression, pos);
} }
ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) { ContinueStatement* NewContinueStatement(
return new (zone_) ContinueStatement(target, pos); IterationStatement* target, int pos,
int continuation_pos = kNoSourcePosition) {
return new (zone_) ContinueStatement(target, pos, continuation_pos);
} }
BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) { BreakStatement* NewBreakStatement(BreakableStatement* target, int pos,
return new (zone_) BreakStatement(target, pos); int continuation_pos = kNoSourcePosition) {
return new (zone_) BreakStatement(target, pos, continuation_pos);
} }
ReturnStatement* NewReturnStatement(Expression* expression, int pos) { ReturnStatement* NewReturnStatement(
return new (zone_) Expression* expression, int pos,
ReturnStatement(expression, ReturnStatement::kNormal, pos); int continuation_pos = kNoSourcePosition) {
return new (zone_) ReturnStatement(expression, ReturnStatement::kNormal,
pos, continuation_pos);
} }
ReturnStatement* NewAsyncReturnStatement(Expression* expression, int pos) { ReturnStatement* NewAsyncReturnStatement(
return new (zone_) Expression* expression, int pos,
ReturnStatement(expression, ReturnStatement::kAsyncReturn, pos); int continuation_pos = kNoSourcePosition) {
return new (zone_) ReturnStatement(
expression, ReturnStatement::kAsyncReturn, pos, continuation_pos);
} }
WithStatement* NewWithStatement(Scope* scope, WithStatement* NewWithStatement(Scope* scope,
......
...@@ -155,6 +155,13 @@ void RewritePositionSingletonsToRanges(CoverageFunction* function) { ...@@ -155,6 +155,13 @@ void RewritePositionSingletonsToRanges(CoverageFunction* function) {
for (int i = 0; i < blocks_count; i++) { for (int i = 0; i < blocks_count; i++) {
CoverageBlock& block = function->blocks[i]; CoverageBlock& block = function->blocks[i];
if (block.start >= function->end) {
// Continuation singletons past the end of the source file.
DCHECK_EQ(block.end, kNoSourcePosition);
nesting_stack.resize(1);
break;
}
while (nesting_stack.back().end <= block.start) { while (nesting_stack.back().end <= block.start) {
nesting_stack.pop_back(); nesting_stack.pop_back();
} }
......
...@@ -1277,16 +1277,22 @@ void BytecodeGenerator::VisitSloppyBlockFunctionStatement( ...@@ -1277,16 +1277,22 @@ void BytecodeGenerator::VisitSloppyBlockFunctionStatement(
} }
void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) { void BytecodeGenerator::VisitContinueStatement(ContinueStatement* stmt) {
AllocateBlockCoverageSlotIfEnabled(
{stmt->continuation_pos(), kNoSourcePosition});
builder()->SetStatementPosition(stmt); builder()->SetStatementPosition(stmt);
execution_control()->Continue(stmt->target()); execution_control()->Continue(stmt->target());
} }
void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) { void BytecodeGenerator::VisitBreakStatement(BreakStatement* stmt) {
AllocateBlockCoverageSlotIfEnabled(
{stmt->continuation_pos(), kNoSourcePosition});
builder()->SetStatementPosition(stmt); builder()->SetStatementPosition(stmt);
execution_control()->Break(stmt->target()); execution_control()->Break(stmt->target());
} }
void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) { void BytecodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
AllocateBlockCoverageSlotIfEnabled(
{stmt->continuation_pos(), kNoSourcePosition});
builder()->SetStatementPosition(stmt); builder()->SetStatementPosition(stmt);
VisitForAccumulatorValue(stmt->expression()); VisitForAccumulatorValue(stmt->expression());
if (stmt->is_async_return()) { if (stmt->is_async_return()) {
......
...@@ -3001,7 +3001,8 @@ Map* Isolate::get_initial_js_array_map(ElementsKind kind) { ...@@ -3001,7 +3001,8 @@ Map* Isolate::get_initial_js_array_map(ElementsKind kind) {
bool Isolate::use_optimizer() { bool Isolate::use_optimizer() {
return FLAG_opt && !serializer_enabled_ && return FLAG_opt && !serializer_enabled_ &&
CpuFeatures::SupportsCrankshaft() && !is_precise_count_code_coverage(); CpuFeatures::SupportsCrankshaft() &&
!is_precise_count_code_coverage() && !is_block_count_code_coverage();
} }
bool Isolate::NeedsSourcePositionsForProfiling() const { bool Isolate::NeedsSourcePositionsForProfiling() const {
......
...@@ -1423,11 +1423,12 @@ class ParserBase { ...@@ -1423,11 +1423,12 @@ class ParserBase {
// Convenience method which determines the type of return statement to emit // Convenience method which determines the type of return statement to emit
// depending on the current function type. // depending on the current function type.
inline StatementT BuildReturnStatement(ExpressionT expr, int pos) { inline StatementT BuildReturnStatement(
ExpressionT expr, int pos, int continuation_pos = kNoSourcePosition) {
if (is_async_function()) { if (is_async_function()) {
return factory()->NewAsyncReturnStatement(expr, pos); return factory()->NewAsyncReturnStatement(expr, pos, continuation_pos);
} }
return factory()->NewReturnStatement(expr, pos); return factory()->NewReturnStatement(expr, pos, continuation_pos);
} }
inline SuspendExpressionT BuildSuspend( inline SuspendExpressionT BuildSuspend(
...@@ -5230,7 +5231,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement( ...@@ -5230,7 +5231,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseContinueStatement(
return impl()->NullStatement(); return impl()->NullStatement();
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return factory()->NewContinueStatement(target, pos); int continuation_pos = scanner_->location().end_pos;
return factory()->NewContinueStatement(target, pos, continuation_pos);
} }
template <typename Impl> template <typename Impl>
...@@ -5268,7 +5270,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement( ...@@ -5268,7 +5270,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseBreakStatement(
return impl()->NullStatement(); return impl()->NullStatement();
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return factory()->NewBreakStatement(target, pos); int continuation_pos = scanner_->location().end_pos;
return factory()->NewBreakStatement(target, pos, continuation_pos);
} }
template <typename Impl> template <typename Impl>
...@@ -5322,7 +5325,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement( ...@@ -5322,7 +5325,8 @@ typename ParserBase<Impl>::StatementT ParserBase<Impl>::ParseReturnStatement(
} }
ExpectSemicolon(CHECK_OK); ExpectSemicolon(CHECK_OK);
return_value = impl()->RewriteReturn(return_value, loc.beg_pos); return_value = impl()->RewriteReturn(return_value, loc.beg_pos);
return BuildReturnStatement(return_value, loc.beg_pos); int continuation_pos = scanner_->location().end_pos;
return BuildReturnStatement(return_value, loc.beg_pos, continuation_pos);
} }
template <typename Impl> template <typename Impl>
......
...@@ -675,12 +675,14 @@ class PreParserFactory { ...@@ -675,12 +675,14 @@ class PreParserFactory {
int pos) { int pos) {
return PreParserExpression::Default(); return PreParserExpression::Default();
} }
PreParserStatement NewReturnStatement(PreParserExpression expression, PreParserStatement NewReturnStatement(
int pos) { PreParserExpression expression, int pos,
int continuation_pos = kNoSourcePosition) {
return PreParserStatement::Jump(); return PreParserStatement::Jump();
} }
PreParserStatement NewAsyncReturnStatement(PreParserExpression expression, PreParserStatement NewAsyncReturnStatement(
int pos) { PreParserExpression expression, int pos,
int continuation_pos = kNoSourcePosition) {
return PreParserStatement::Jump(); return PreParserStatement::Jump();
} }
PreParserExpression NewFunctionLiteral( PreParserExpression NewFunctionLiteral(
...@@ -729,11 +731,15 @@ class PreParserFactory { ...@@ -729,11 +731,15 @@ class PreParserFactory {
return else_statement.IsJumpStatement() ? then_statement : else_statement; return else_statement.IsJumpStatement() ? then_statement : else_statement;
} }
PreParserStatement NewBreakStatement(PreParserStatement target, int pos) { PreParserStatement NewBreakStatement(
PreParserStatement target, int pos,
int continuation_pos = kNoSourcePosition) {
return PreParserStatement::Jump(); return PreParserStatement::Jump();
} }
PreParserStatement NewContinueStatement(PreParserStatement target, int pos) { PreParserStatement NewContinueStatement(
PreParserStatement target, int pos,
int continuation_pos = kNoSourcePosition) {
return PreParserStatement::Jump(); return PreParserStatement::Jump();
} }
......
...@@ -77,9 +77,14 @@ Running test: testPreciseCountCoverage ...@@ -77,9 +77,14 @@ Running test: testPreciseCountCoverage
} }
[2] : { [2] : {
count : 7 count : 7
endOffset : 73 endOffset : 71
startOffset : 41 startOffset : 41
} }
[3] : {
count : 0
endOffset : 73
startOffset : 71
}
] ]
} }
[2] : { [2] : {
...@@ -102,6 +107,11 @@ Running test: testPreciseCountCoverage ...@@ -102,6 +107,11 @@ Running test: testPreciseCountCoverage
endOffset : 208 endOffset : 208
startOffset : 177 startOffset : 177
} }
[1] : {
count : 0
endOffset : 208
startOffset : 206
}
] ]
} }
] ]
...@@ -385,9 +395,14 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled ...@@ -385,9 +395,14 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled
} }
[2] : { [2] : {
count : 7 count : 7
endOffset : 73 endOffset : 71
startOffset : 41 startOffset : 41
} }
[3] : {
count : 0
endOffset : 73
startOffset : 71
}
] ]
} }
[2] : { [2] : {
...@@ -410,6 +425,11 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled ...@@ -410,6 +425,11 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled
endOffset : 208 endOffset : 208
startOffset : 177 startOffset : 177
} }
[1] : {
count : 0
endOffset : 208
startOffset : 206
}
] ]
} }
] ]
...@@ -469,9 +489,14 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled ...@@ -469,9 +489,14 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled
} }
[2] : { [2] : {
count : 7 count : 7
endOffset : 73 endOffset : 71
startOffset : 41 startOffset : 41
} }
[3] : {
count : 0
endOffset : 73
startOffset : 71
}
] ]
} }
[2] : { [2] : {
...@@ -494,6 +519,11 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled ...@@ -494,6 +519,11 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled
endOffset : 208 endOffset : 208
startOffset : 177 startOffset : 177
} }
[1] : {
count : 0
endOffset : 208
startOffset : 206
}
] ]
} }
] ]
...@@ -804,6 +834,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -804,6 +834,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 224 endOffset : 224
startOffset : 10 startOffset : 10
} }
[1] : {
count : 0
endOffset : 224
startOffset : 222
}
] ]
} }
[2] : { [2] : {
...@@ -815,6 +850,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -815,6 +850,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 176 endOffset : 176
startOffset : 31 startOffset : 31
} }
[1] : {
count : 0
endOffset : 176
startOffset : 172
}
] ]
} }
[3] : { [3] : {
...@@ -826,6 +866,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -826,6 +866,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 172 endOffset : 172
startOffset : 64 startOffset : 64
} }
[1] : {
count : 0
endOffset : 172
startOffset : 166
}
] ]
} }
[4] : { [4] : {
...@@ -837,6 +882,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -837,6 +882,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 166 endOffset : 166
startOffset : 99 startOffset : 99
} }
[1] : {
count : 0
endOffset : 166
startOffset : 158
}
] ]
} }
[5] : { [5] : {
...@@ -883,6 +933,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -883,6 +933,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 172 endOffset : 172
startOffset : 64 startOffset : 64
} }
[1] : {
count : 0
endOffset : 172
startOffset : 166
}
] ]
} }
[1] : { [1] : {
...@@ -894,6 +949,11 @@ Running test: testPreciseCountCoveragePartial ...@@ -894,6 +949,11 @@ Running test: testPreciseCountCoveragePartial
endOffset : 166 endOffset : 166
startOffset : 99 startOffset : 99
} }
[1] : {
count : 0
endOffset : 166
startOffset : 158
}
] ]
} }
] ]
......
...@@ -103,6 +103,7 @@ TestCoverage( ...@@ -103,6 +103,7 @@ TestCoverage(
[{"start":0,"end":399,"count":1}, [{"start":0,"end":399,"count":1},
{"start":1,"end":351,"count":1}, {"start":1,"end":351,"count":1},
{"start":62,"end":253,"count":1}, {"start":62,"end":253,"count":1},
{"start":161,"end":253,"count":0},
{"start":253,"end":351,"count":0}] {"start":253,"end":351,"count":0}]
); );
...@@ -231,10 +232,13 @@ TestCoverage( ...@@ -231,10 +232,13 @@ TestCoverage(
[{"start":0,"end":999,"count":1}, [{"start":0,"end":999,"count":1},
{"start":1,"end":951,"count":1}, {"start":1,"end":951,"count":1},
{"start":81,"end":253,"count":10}, {"start":81,"end":253,"count":10},
{"start":163,"end":253,"count":0},
{"start":253,"end":361,"count":1}, {"start":253,"end":361,"count":1},
{"start":361,"end":553,"count":1}, {"start":361,"end":553,"count":1},
{"start":460,"end":553,"count":0},
{"start":553,"end":661,"count":1}, {"start":553,"end":661,"count":1},
{"start":661,"end":853,"count":1}, {"start":661,"end":853,"count":1},
{"start":761,"end":853,"count":0},
{"start":853,"end":951,"count":0}] {"start":853,"end":951,"count":0}]
); );
...@@ -274,6 +278,7 @@ function g() {} // 0000 ...@@ -274,6 +278,7 @@ function g() {} // 0000
{"start":562,"end":570,"count":1}, {"start":562,"end":570,"count":1},
{"start":570,"end":612,"count":1}, {"start":570,"end":612,"count":1},
{"start":612,"end":622,"count":1}, {"start":612,"end":622,"count":1},
{"start":620,"end":622,"count":0},
{"start":622,"end":651,"count":1}] {"start":622,"end":651,"count":1}]
); );
...@@ -305,10 +310,13 @@ TestCoverage( ...@@ -305,10 +310,13 @@ TestCoverage(
[{"start":0,"end":1049,"count":1}, [{"start":0,"end":1049,"count":1},
{"start":1,"end":1001,"count":1}, {"start":1,"end":1001,"count":1},
{"start":117,"end":303,"count":10}, {"start":117,"end":303,"count":10},
{"start":213,"end":303,"count":0},
{"start":303,"end":415,"count":1}, {"start":303,"end":415,"count":1},
{"start":415,"end":603,"count":1}, {"start":415,"end":603,"count":1},
{"start":510,"end":603,"count":0},
{"start":603,"end":715,"count":1}, {"start":603,"end":715,"count":1},
{"start":715,"end":903,"count":1}, {"start":715,"end":903,"count":1},
{"start":811,"end":903,"count":0},
{"start":903,"end":1001,"count":0}] {"start":903,"end":1001,"count":0}]
); );
...@@ -340,11 +348,28 @@ TestCoverage( ...@@ -340,11 +348,28 @@ TestCoverage(
[{"start":0,"end":1049,"count":1}, [{"start":0,"end":1049,"count":1},
{"start":1,"end":1001,"count":1}, {"start":1,"end":1001,"count":1},
{"start":105,"end":303,"count":10}, {"start":105,"end":303,"count":10},
{"start":213,"end":303,"count":0},
{"start":303,"end":405,"count":1}, {"start":303,"end":405,"count":1},
{"start":405,"end":603,"count":1}, {"start":405,"end":603,"count":1},
{"start":510,"end":603,"count":0},
{"start":603,"end":705,"count":1}, {"start":603,"end":705,"count":1},
{"start":705,"end":903,"count":1}, {"start":705,"end":903,"count":1},
{"start":811,"end":903,"count":0},
{"start":903,"end":1001,"count":0}] {"start":903,"end":1001,"count":0}]
); );
TestCoverage(
"return statements",
`
!function() { nop(); return; nop(); }(); // 0000
!function() { nop(); return 42; // 0050
nop(); }(); // 0100
`,
[{"start":0,"end":149,"count":1},
{"start":1,"end":37,"count":1},
{"start":28,"end":37,"count":0},
{"start":51,"end":122,"count":1},
{"start":81,"end":122,"count":0}]
);
%DebugToggleBlockCoverage(false); %DebugToggleBlockCoverage(false);
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