diff --git a/common.gypi b/common.gypi index 773dd3be7786d7..e683760a4a9188 100644 --- a/common.gypi +++ b/common.gypi @@ -38,7 +38,7 @@ # Reset this number to 0 on major V8 upgrades. # Increment by one for each non-official patch applied to deps/v8. - 'v8_embedder_string': '-node.9', + 'v8_embedder_string': '-node.10', ##### V8 defaults for Node.js ##### diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn index 83f1fdb0bf75dd..6bb77db7ea96d5 100644 --- a/deps/v8/BUILD.gn +++ b/deps/v8/BUILD.gn @@ -1589,6 +1589,8 @@ v8_source_set("v8_base") { "src/ast/scopes-inl.h", "src/ast/scopes.cc", "src/ast/scopes.h", + "src/ast/source-range-ast-visitor.cc", + "src/ast/source-range-ast-visitor.h", "src/ast/variables.cc", "src/ast/variables.h", "src/bailout-reason.cc", diff --git a/deps/v8/gypfiles/v8.gyp b/deps/v8/gypfiles/v8.gyp index 23721881c6fa3f..dd0f6799d5ae90 100644 --- a/deps/v8/gypfiles/v8.gyp +++ b/deps/v8/gypfiles/v8.gyp @@ -611,6 +611,8 @@ '../src/ast/scopes-inl.h', '../src/ast/scopes.cc', '../src/ast/scopes.h', + '../src/ast/source-range-ast-visitor.cc', + '../src/ast/source-range-ast-visitor.h', '../src/ast/variables.cc', '../src/ast/variables.h', '../src/bailout-reason.cc', diff --git a/deps/v8/src/ast/ast-source-ranges.h b/deps/v8/src/ast/ast-source-ranges.h index 60222a403555f2..a04e68fa2f651d 100644 --- a/deps/v8/src/ast/ast-source-ranges.h +++ b/deps/v8/src/ast/ast-source-ranges.h @@ -59,6 +59,8 @@ class AstNodeSourceRanges : public ZoneObject { public: virtual ~AstNodeSourceRanges() = default; virtual SourceRange GetRange(SourceRangeKind kind) = 0; + virtual bool HasRange(SourceRangeKind kind) = 0; + virtual void RemoveContinuationRange() { UNREACHABLE(); } }; class BinaryOperationSourceRanges final : public AstNodeSourceRanges { @@ -67,10 +69,14 @@ class BinaryOperationSourceRanges final : public AstNodeSourceRanges { : right_range_(right_range) {} SourceRange GetRange(SourceRangeKind kind) override { - DCHECK_EQ(kind, SourceRangeKind::kRight); + DCHECK(HasRange(kind)); return right_range_; } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kRight; + } + private: SourceRange right_range_; }; @@ -81,10 +87,19 @@ class ContinuationSourceRanges : public AstNodeSourceRanges { : continuation_position_(continuation_position) {} SourceRange GetRange(SourceRangeKind kind) override { - DCHECK_EQ(kind, SourceRangeKind::kContinuation); + DCHECK(HasRange(kind)); return SourceRange::OpenEnded(continuation_position_); } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kContinuation; + } + + void RemoveContinuationRange() override { + DCHECK(HasRange(SourceRangeKind::kContinuation)); + continuation_position_ = kNoSourcePosition; + } + private: int32_t continuation_position_; }; @@ -101,10 +116,14 @@ class CaseClauseSourceRanges final : public AstNodeSourceRanges { : body_range_(body_range) {} SourceRange GetRange(SourceRangeKind kind) override { - DCHECK_EQ(kind, SourceRangeKind::kBody); + DCHECK(HasRange(kind)); return body_range_; } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kBody; + } + private: SourceRange body_range_; }; @@ -116,6 +135,7 @@ class ConditionalSourceRanges final : public AstNodeSourceRanges { : then_range_(then_range), else_range_(else_range) {} SourceRange GetRange(SourceRangeKind kind) override { + DCHECK(HasRange(kind)); switch (kind) { case SourceRangeKind::kThen: return then_range_; @@ -126,6 +146,10 @@ class ConditionalSourceRanges final : public AstNodeSourceRanges { } } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse; + } + private: SourceRange then_range_; SourceRange else_range_; @@ -138,12 +162,14 @@ class IfStatementSourceRanges final : public AstNodeSourceRanges { : then_range_(then_range), else_range_(else_range) {} SourceRange GetRange(SourceRangeKind kind) override { + DCHECK(HasRange(kind)); switch (kind) { case SourceRangeKind::kElse: return else_range_; case SourceRangeKind::kThen: return then_range_; case SourceRangeKind::kContinuation: { + if (!has_continuation_) return SourceRange::Empty(); const SourceRange& trailing_range = else_range_.IsEmpty() ? then_range_ : else_range_; return SourceRange::ContinuationOf(trailing_range); @@ -153,9 +179,20 @@ class IfStatementSourceRanges final : public AstNodeSourceRanges { } } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kThen || kind == SourceRangeKind::kElse || + kind == SourceRangeKind::kContinuation; + } + + void RemoveContinuationRange() override { + DCHECK(HasRange(SourceRangeKind::kContinuation)); + has_continuation_ = false; + } + private: SourceRange then_range_; SourceRange else_range_; + bool has_continuation_ = true; }; class IterationStatementSourceRanges final : public AstNodeSourceRanges { @@ -164,18 +201,31 @@ class IterationStatementSourceRanges final : public AstNodeSourceRanges { : body_range_(body_range) {} SourceRange GetRange(SourceRangeKind kind) override { + DCHECK(HasRange(kind)); switch (kind) { case SourceRangeKind::kBody: return body_range_; case SourceRangeKind::kContinuation: + if (!has_continuation_) return SourceRange::Empty(); return SourceRange::ContinuationOf(body_range_); default: UNREACHABLE(); } } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kBody || + kind == SourceRangeKind::kContinuation; + } + + void RemoveContinuationRange() override { + DCHECK(HasRange(SourceRangeKind::kContinuation)); + has_continuation_ = false; + } + private: SourceRange body_range_; + bool has_continuation_ = true; }; class JumpStatementSourceRanges final : public ContinuationSourceRanges { @@ -200,6 +250,7 @@ class NaryOperationSourceRanges final : public AstNodeSourceRanges { size_t RangeCount() const { return ranges_.size(); } SourceRange GetRange(SourceRangeKind kind) override { UNREACHABLE(); } + bool HasRange(SourceRangeKind kind) override { return false; } private: ZoneVector ranges_; @@ -229,18 +280,31 @@ class TryCatchStatementSourceRanges final : public AstNodeSourceRanges { : catch_range_(catch_range) {} SourceRange GetRange(SourceRangeKind kind) override { + DCHECK(HasRange(kind)); switch (kind) { case SourceRangeKind::kCatch: return catch_range_; case SourceRangeKind::kContinuation: + if (!has_continuation_) return SourceRange::Empty(); return SourceRange::ContinuationOf(catch_range_); default: UNREACHABLE(); } } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kCatch || + kind == SourceRangeKind::kContinuation; + } + + void RemoveContinuationRange() override { + DCHECK(HasRange(SourceRangeKind::kContinuation)); + has_continuation_ = false; + } + private: SourceRange catch_range_; + bool has_continuation_ = true; }; class TryFinallyStatementSourceRanges final : public AstNodeSourceRanges { @@ -249,18 +313,31 @@ class TryFinallyStatementSourceRanges final : public AstNodeSourceRanges { : finally_range_(finally_range) {} SourceRange GetRange(SourceRangeKind kind) override { + DCHECK(HasRange(kind)); switch (kind) { case SourceRangeKind::kFinally: return finally_range_; case SourceRangeKind::kContinuation: + if (!has_continuation_) return SourceRange::Empty(); return SourceRange::ContinuationOf(finally_range_); default: UNREACHABLE(); } } + bool HasRange(SourceRangeKind kind) override { + return kind == SourceRangeKind::kFinally || + kind == SourceRangeKind::kContinuation; + } + + void RemoveContinuationRange() override { + DCHECK(HasRange(SourceRangeKind::kContinuation)); + has_continuation_ = false; + } + private: SourceRange finally_range_; + bool has_continuation_ = true; }; // Maps ast node pointers to associated source ranges. The parser creates these diff --git a/deps/v8/src/ast/source-range-ast-visitor.cc b/deps/v8/src/ast/source-range-ast-visitor.cc new file mode 100644 index 00000000000000..b6acbddf0a6a5a --- /dev/null +++ b/deps/v8/src/ast/source-range-ast-visitor.cc @@ -0,0 +1,68 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "src/ast/source-range-ast-visitor.h" + +#include "src/ast/ast-source-ranges.h" + +namespace v8 { +namespace internal { + +SourceRangeAstVisitor::SourceRangeAstVisitor(uintptr_t stack_limit, + Expression* root, + SourceRangeMap* source_range_map) + : AstTraversalVisitor(stack_limit, root), + source_range_map_(source_range_map) {} + +void SourceRangeAstVisitor::VisitBlock(Block* stmt) { + AstTraversalVisitor::VisitBlock(stmt); + ZonePtrList* stmts = stmt->statements(); + AstNodeSourceRanges* enclosingSourceRanges = source_range_map_->Find(stmt); + if (enclosingSourceRanges != nullptr) { + CHECK(enclosingSourceRanges->HasRange(SourceRangeKind::kContinuation)); + MaybeRemoveLastContinuationRange(stmts); + } +} + +void SourceRangeAstVisitor::VisitFunctionLiteral(FunctionLiteral* expr) { + AstTraversalVisitor::VisitFunctionLiteral(expr); + ZonePtrList* stmts = expr->body(); + MaybeRemoveLastContinuationRange(stmts); +} + +bool SourceRangeAstVisitor::VisitNode(AstNode* node) { + AstNodeSourceRanges* range = source_range_map_->Find(node); + + if (range == nullptr) return true; + if (!range->HasRange(SourceRangeKind::kContinuation)) return true; + + // Called in pre-order. In case of conflicting continuation ranges, only the + // outermost range may survive. + + SourceRange continuation = range->GetRange(SourceRangeKind::kContinuation); + if (continuation_positions_.find(continuation.start) != + continuation_positions_.end()) { + range->RemoveContinuationRange(); + } else { + continuation_positions_.emplace(continuation.start); + } + + return true; +} + +void SourceRangeAstVisitor::MaybeRemoveLastContinuationRange( + ZonePtrList* statements) { + if (statements == nullptr || statements->is_empty()) return; + + Statement* last_statement = statements->last(); + AstNodeSourceRanges* last_range = source_range_map_->Find(last_statement); + if (last_range == nullptr) return; + + if (last_range->HasRange(SourceRangeKind::kContinuation)) { + last_range->RemoveContinuationRange(); + } +} + +} // namespace internal +} // namespace v8 diff --git a/deps/v8/src/ast/source-range-ast-visitor.h b/deps/v8/src/ast/source-range-ast-visitor.h new file mode 100644 index 00000000000000..4ea36a947f58e6 --- /dev/null +++ b/deps/v8/src/ast/source-range-ast-visitor.h @@ -0,0 +1,49 @@ +// Copyright 2018 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef V8_AST_SOURCE_RANGE_AST_VISITOR_H_ +#define V8_AST_SOURCE_RANGE_AST_VISITOR_H_ + +#include + +#include "src/ast/ast-traversal-visitor.h" + +namespace v8 { +namespace internal { + +class SourceRangeMap; + +// Post-processes generated source ranges while the AST structure still exists. +// +// In particular, SourceRangeAstVisitor +// +// 1. deduplicates continuation source ranges, only keeping the outermost one. +// See also: https://crbug.com/v8/8539. +// +// 2. removes the source range associated with the final statement in a block +// or function body if the parent itself has a source range associated with it. +// See also: https://crbug.com/v8/8381. +class SourceRangeAstVisitor final + : public AstTraversalVisitor { + public: + SourceRangeAstVisitor(uintptr_t stack_limit, Expression* root, + SourceRangeMap* source_range_map); + + private: + friend class AstTraversalVisitor; + + void VisitBlock(Block* stmt); + void VisitFunctionLiteral(FunctionLiteral* expr); + bool VisitNode(AstNode* node); + + void MaybeRemoveLastContinuationRange(ZonePtrList* stmts); + + SourceRangeMap* source_range_map_ = nullptr; + std::unordered_set continuation_positions_; +}; + +} // namespace internal +} // namespace v8 + +#endif // V8_AST_SOURCE_RANGE_AST_VISITOR_H_ diff --git a/deps/v8/src/debug/debug-coverage.cc b/deps/v8/src/debug/debug-coverage.cc index 57c5f310797f9c..9e0791babc2e30 100644 --- a/deps/v8/src/debug/debug-coverage.cc +++ b/deps/v8/src/debug/debug-coverage.cc @@ -81,11 +81,6 @@ std::vector GetSortedBlockData(SharedFunctionInfo* shared) { std::vector result; if (coverage_info->SlotCount() == 0) return result; - if (FLAG_trace_block_coverage) { - PrintF("Collecting coverage data\n"); - coverage_info->Print(shared->DebugName()->ToCString()); - } - for (int i = 0; i < coverage_info->SlotCount(); i++) { const int start_pos = coverage_info->StartSourcePosition(i); const int until_pos = coverage_info->EndSourcePosition(i); @@ -176,6 +171,12 @@ class CoverageBlockIterator final { return function_->blocks[read_index_ + 1]; } + CoverageBlock& GetPreviousBlock() { + DCHECK(IsActive()); + DCHECK_GT(read_index_, 0); + return function_->blocks[read_index_ - 1]; + } + CoverageBlock& GetParent() { DCHECK(IsActive()); return nesting_stack_.back(); @@ -232,25 +233,6 @@ bool HaveSameSourceRange(const CoverageBlock& lhs, const CoverageBlock& rhs) { return lhs.start == rhs.start && lhs.end == rhs.end; } -void MergeDuplicateSingletons(CoverageFunction* function) { - CoverageBlockIterator iter(function); - - while (iter.Next() && iter.HasNext()) { - CoverageBlock& block = iter.GetBlock(); - CoverageBlock& next_block = iter.GetNextBlock(); - - // Identical ranges should only occur through singleton ranges. Consider the - // ranges for `for (.) break;`: continuation ranges for both the `break` and - // `for` statements begin after the trailing semicolon. - // Such ranges are merged and keep the maximal execution count. - if (!HaveSameSourceRange(block, next_block)) continue; - - DCHECK_EQ(kNoSourcePosition, block.end); // Singleton range. - next_block.count = std::max(block.count, next_block.count); - iter.DeleteBlock(); - } -} - void MergeDuplicateRanges(CoverageFunction* function) { CoverageBlockIterator iter(function); @@ -330,6 +312,30 @@ void MergeNestedRanges(CoverageFunction* function) { } } +void FilterAliasedSingletons(CoverageFunction* function) { + CoverageBlockIterator iter(function); + + iter.Next(); // Advance once since we reference the previous block later. + + while (iter.Next()) { + CoverageBlock& previous_block = iter.GetPreviousBlock(); + CoverageBlock& block = iter.GetBlock(); + + bool is_singleton = block.end == kNoSourcePosition; + bool aliases_start = block.start == previous_block.start; + + if (is_singleton && aliases_start) { + // The previous block must have a full range since duplicate singletons + // have already been merged. + DCHECK_NE(previous_block.end, kNoSourcePosition); + // Likewise, the next block must have another start position since + // singletons are sorted to the end. + DCHECK_IMPLIES(iter.HasNext(), iter.GetNextBlock().start != block.start); + iter.DeleteBlock(); + } + } +} + void FilterUncoveredRanges(CoverageFunction* function) { CoverageBlockIterator iter(function); @@ -399,8 +405,14 @@ void CollectBlockCoverage(CoverageFunction* function, SharedFunctionInfo* info, // If in binary mode, only report counts of 0/1. if (mode == debug::Coverage::kBlockBinary) ClampToBinary(function); - // Remove duplicate singleton ranges, keeping the max count. - MergeDuplicateSingletons(function); + // Remove singleton ranges with the same start position as a full range and + // throw away their counts. + // Singleton ranges are only intended to split existing full ranges and should + // never expand into a full range. Consider 'if (cond) { ... } else { ... }' + // as a problematic example; if the then-block produces a continuation + // singleton, it would incorrectly expand into the else range. + // For more context, see https://crbug.com/v8/8237. + FilterAliasedSingletons(function); // Rewrite all singletons (created e.g. by continuations and unconditional // control flow) to ranges. diff --git a/deps/v8/src/interpreter/bytecode-generator.cc b/deps/v8/src/interpreter/bytecode-generator.cc index b00d3773cda579..48682439fb1862 100644 --- a/deps/v8/src/interpreter/bytecode-generator.cc +++ b/deps/v8/src/interpreter/bytecode-generator.cc @@ -368,7 +368,6 @@ class BytecodeGenerator::ControlScopeForBreakable final protected: bool Execute(Command command, Statement* statement, int source_position) override { - control_builder_->set_needs_continuation_counter(); if (statement != statement_) return false; switch (command) { case CMD_BREAK: diff --git a/deps/v8/src/interpreter/control-flow-builders.cc b/deps/v8/src/interpreter/control-flow-builders.cc index bada935e4a22fb..6b1bdc34240d83 100644 --- a/deps/v8/src/interpreter/control-flow-builders.cc +++ b/deps/v8/src/interpreter/control-flow-builders.cc @@ -13,7 +13,7 @@ namespace interpreter { BreakableControlFlowBuilder::~BreakableControlFlowBuilder() { BindBreakTarget(); DCHECK(break_labels_.empty() || break_labels_.is_bound()); - if (block_coverage_builder_ != nullptr && needs_continuation_counter()) { + if (block_coverage_builder_ != nullptr) { block_coverage_builder_->IncrementBlockCounter( node_, SourceRangeKind::kContinuation); } diff --git a/deps/v8/src/interpreter/control-flow-builders.h b/deps/v8/src/interpreter/control-flow-builders.h index fdc57776a89239..8359f0d1ee303b 100644 --- a/deps/v8/src/interpreter/control-flow-builders.h +++ b/deps/v8/src/interpreter/control-flow-builders.h @@ -58,11 +58,6 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder BytecodeLabels* break_labels() { return &break_labels_; } - void set_needs_continuation_counter() { needs_continuation_counter_ = true; } - bool needs_continuation_counter() const { - return needs_continuation_counter_; - } - protected: void EmitJump(BytecodeLabels* labels); void EmitJumpIfTrue(BytecodeArrayBuilder::ToBooleanMode mode, @@ -81,7 +76,6 @@ class V8_EXPORT_PRIVATE BreakableControlFlowBuilder // A continuation counter (for block coverage) is needed e.g. when // encountering a break statement. AstNode* node_; - bool needs_continuation_counter_ = false; BlockCoverageBuilder* block_coverage_builder_; }; @@ -107,7 +101,6 @@ class V8_EXPORT_PRIVATE LoopBuilder final : public BreakableControlFlowBuilder { : BreakableControlFlowBuilder(builder, block_coverage_builder, node), continue_labels_(builder->zone()) { if (block_coverage_builder_ != nullptr) { - set_needs_continuation_counter(); block_coverage_body_slot_ = block_coverage_builder_->AllocateBlockCoverageSlot( node, SourceRangeKind::kBody); diff --git a/deps/v8/src/objects/debug-objects.cc b/deps/v8/src/objects/debug-objects.cc index 43fcdb5aee7549..b77b6e136e53d5 100644 --- a/deps/v8/src/objects/debug-objects.cc +++ b/deps/v8/src/objects/debug-objects.cc @@ -375,7 +375,7 @@ void CoverageInfo::Print(std::unique_ptr function_name) { for (int i = 0; i < SlotCount(); i++) { os << "{" << StartSourcePosition(i) << "," << EndSourcePosition(i) << "}" - << ": " << BlockCount(i) << std::endl; + << std::endl; } } diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h index d1ad0e9d131cb6..bfb056e0c8c797 100644 --- a/deps/v8/src/parsing/parser-base.h +++ b/deps/v8/src/parsing/parser-base.h @@ -5116,7 +5116,6 @@ typename ParserBase::BlockT ParserBase::ParseBlock( Expect(Token::LBRACE, CHECK_OK_CUSTOM(NullStatement)); { BlockState block_state(zone(), &scope_); - // Scope starts before opening brace. scope()->set_start_position(scanner()->location().beg_pos); typename Types::Target target(this, body); @@ -5128,10 +5127,9 @@ typename ParserBase::BlockT ParserBase::ParseBlock( } Expect(Token::RBRACE, CHECK_OK_CUSTOM(NullStatement)); - // Scope ends after closing brace. - scope()->set_end_position(scanner()->location().end_pos); - // Coverage range uses position before closing brace. - impl()->RecordBlockSourceRange(body, scanner()->location().beg_pos); + int end_pos = end_position(); + scope()->set_end_position(end_pos); + impl()->RecordBlockSourceRange(body, end_pos); body->set_scope(scope()->FinalizeBlockScope()); } return body; diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc index 6d0d9fff21245e..5687633f2f0e89 100644 --- a/deps/v8/src/parsing/parser.cc +++ b/deps/v8/src/parsing/parser.cc @@ -10,6 +10,7 @@ #include "src/ast/ast-function-literal-id-reindexer.h" #include "src/ast/ast-traversal-visitor.h" #include "src/ast/ast.h" +#include "src/ast/source-range-ast-visitor.h" #include "src/bailout-reason.h" #include "src/base/platform/platform.h" #include "src/char-predicates-inl.h" @@ -441,6 +442,15 @@ void MaybeResetCharacterStream(ParseInfo* info, FunctionLiteral* literal) { } } +void MaybeProcessSourceRanges(ParseInfo* parse_info, Expression* root, + uintptr_t stack_limit_) { + if (root != nullptr && parse_info->source_range_map() != nullptr) { + SourceRangeAstVisitor visitor(stack_limit_, root, + parse_info->source_range_map()); + visitor.Run(); + } +} + } // namespace FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { @@ -464,6 +474,7 @@ FunctionLiteral* Parser::ParseProgram(Isolate* isolate, ParseInfo* info) { scanner_.Initialize(); FunctionLiteral* result = DoParseProgram(isolate, info); MaybeResetCharacterStream(info, result); + MaybeProcessSourceRanges(info, result, stack_limit_); HandleSourceURLComments(isolate, info->script()); @@ -660,6 +671,7 @@ FunctionLiteral* Parser::ParseFunction(Isolate* isolate, ParseInfo* info, FunctionLiteral* result = DoParseFunction(isolate, info, info->function_name()); MaybeResetCharacterStream(info, result); + MaybeProcessSourceRanges(info, result, stack_limit_); if (result != nullptr) { Handle inferred_name(shared_info->inferred_name(), isolate); result->set_inferred_name(inferred_name); diff --git a/deps/v8/test/inspector/cpu-profiler/coverage-block-expected.txt b/deps/v8/test/inspector/cpu-profiler/coverage-block-expected.txt index a631e72c69c8f7..cc48cfa85b320f 100644 --- a/deps/v8/test/inspector/cpu-profiler/coverage-block-expected.txt +++ b/deps/v8/test/inspector/cpu-profiler/coverage-block-expected.txt @@ -34,7 +34,7 @@ Running test: testPreciseCountCoverage [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -60,13 +60,8 @@ Running test: testPreciseCountCoverage } [2] : { count : 7 - endOffset : 71 - startOffset : 41 - } - [3] : { - count : 0 endOffset : 72 - startOffset : 71 + startOffset : 41 } ] } @@ -90,11 +85,6 @@ Running test: testPreciseCountCoverage endOffset : 208 startOffset : 177 } - [1] : { - count : 0 - endOffset : 207 - startOffset : 206 - } ] } ] @@ -104,7 +94,7 @@ Running test: testPreciseCountCoverage [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -116,7 +106,7 @@ Running test: testPreciseCountCoverage } ] scriptId : - url : + url : } ] } @@ -147,7 +137,7 @@ Running test: testPreciseCountCoverageIncremental [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -173,13 +163,8 @@ Running test: testPreciseCountCoverageIncremental } [2] : { count : 7 - endOffset : 71 - startOffset : 41 - } - [3] : { - count : 0 endOffset : 72 - startOffset : 71 + startOffset : 41 } ] } @@ -203,11 +188,6 @@ Running test: testPreciseCountCoverageIncremental endOffset : 208 startOffset : 177 } - [1] : { - count : 0 - endOffset : 207 - startOffset : 206 - } ] } ] @@ -267,13 +247,8 @@ Running test: testPreciseCountCoverageIncremental } [2] : { count : 10945 - endOffset : 71 - startOffset : 41 - } - [3] : { - count : 0 endOffset : 72 - startOffset : 71 + startOffset : 41 } ] } @@ -291,11 +266,6 @@ Running test: testPreciseCountCoverageIncremental endOffset : 156 startOffset : 143 } - [2] : { - count : 0 - endOffset : 174 - startOffset : 173 - } ] } ] @@ -305,7 +275,7 @@ Running test: testPreciseCountCoverageIncremental [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -317,12 +287,12 @@ Running test: testPreciseCountCoverageIncremental } ] scriptId : - url : + url : } [2] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -334,7 +304,7 @@ Running test: testPreciseCountCoverageIncremental } ] scriptId : - url : + url : } ] } @@ -403,7 +373,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -453,7 +423,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -465,7 +435,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled } ] scriptId : - url : + url : } ] } @@ -477,7 +447,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -527,7 +497,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -539,7 +509,7 @@ Running test: testBestEffortCoverageWithPreciseBinaryEnabled } ] scriptId : - url : + url : } ] } @@ -563,7 +533,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -613,7 +583,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -625,7 +595,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled } ] scriptId : - url : + url : } ] } @@ -637,7 +607,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -687,7 +657,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : false ranges : [ [0] : { @@ -699,7 +669,7 @@ Running test: testBestEffortCoverageWithPreciseCountEnabled } ] scriptId : - url : + url : } ] } @@ -721,7 +691,7 @@ Running test: testEnablePreciseCountCoverageAtPause [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -733,7 +703,7 @@ Running test: testEnablePreciseCountCoverageAtPause } ] scriptId : - url : + url : } ] } @@ -757,7 +727,7 @@ Running test: testPreciseBinaryCoverage [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -776,11 +746,6 @@ Running test: testPreciseBinaryCoverage endOffset : 73 startOffset : 1 } - [1] : { - count : 0 - endOffset : 72 - startOffset : 71 - } ] } [2] : { @@ -803,11 +768,6 @@ Running test: testPreciseBinaryCoverage endOffset : 208 startOffset : 177 } - [1] : { - count : 0 - endOffset : 207 - startOffset : 206 - } ] } ] @@ -862,7 +822,7 @@ Running test: testPreciseBinaryCoverage } [1] : { count : 1 - endOffset : 71 + endOffset : 72 startOffset : 32 } ] @@ -876,11 +836,6 @@ Running test: testPreciseBinaryCoverage endOffset : 175 startOffset : 74 } - [1] : { - count : 0 - endOffset : 174 - startOffset : 173 - } ] } ] @@ -890,7 +845,7 @@ Running test: testPreciseBinaryCoverage [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -902,12 +857,12 @@ Running test: testPreciseBinaryCoverage } ] scriptId : - url : + url : } [2] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -919,7 +874,7 @@ Running test: testPreciseBinaryCoverage } ] scriptId : - url : + url : } ] } @@ -950,7 +905,7 @@ Running test: testPreciseCountCoveragePartial [0] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -969,11 +924,6 @@ Running test: testPreciseCountCoveragePartial endOffset : 224 startOffset : 10 } - [1] : { - count : 0 - endOffset : 223 - startOffset : 222 - } ] } [2] : { @@ -985,11 +935,6 @@ Running test: testPreciseCountCoveragePartial endOffset : 176 startOffset : 31 } - [1] : { - count : 0 - endOffset : 175 - startOffset : 172 - } ] } [3] : { @@ -1001,11 +946,6 @@ Running test: testPreciseCountCoveragePartial endOffset : 172 startOffset : 64 } - [1] : { - count : 0 - endOffset : 171 - startOffset : 166 - } ] } [4] : { @@ -1017,11 +957,6 @@ Running test: testPreciseCountCoveragePartial endOffset : 166 startOffset : 99 } - [1] : { - count : 0 - endOffset : 165 - startOffset : 158 - } ] } [5] : { @@ -1068,11 +1003,6 @@ Running test: testPreciseCountCoveragePartial endOffset : 172 startOffset : 64 } - [1] : { - count : 0 - endOffset : 171 - startOffset : 166 - } ] } [1] : { @@ -1093,7 +1023,7 @@ Running test: testPreciseCountCoveragePartial [1] : { functions : [ [0] : { - functionName : + functionName : isBlockCoverage : true ranges : [ [0] : { @@ -1105,7 +1035,7 @@ Running test: testPreciseCountCoveragePartial } ] scriptId : - url : + url : } ] } diff --git a/deps/v8/test/mjsunit/code-coverage-block-opt.js b/deps/v8/test/mjsunit/code-coverage-block-opt.js index e02775bd45e234..5477a18dd5eac1 100644 --- a/deps/v8/test/mjsunit/code-coverage-block-opt.js +++ b/deps/v8/test/mjsunit/code-coverage-block-opt.js @@ -17,7 +17,7 @@ f(); f(); f(); f(); f(); f(); // 0150 `, [{"start":0,"end":199,"count":1}, {"start":0,"end":33,"count":4}, // TODO(jgruber): Invocation count is off. - {"start":25,"end":32,"count":16}, + {"start":25,"end":31,"count":16}, {"start":50,"end":76,"count":2}] // TODO(jgruber): Invocation count is off. ); @@ -39,7 +39,7 @@ TestCoverage("Partial coverage collection", }(); // 0400 `, [{"start":52,"end":153,"count":0}, - {"start":121,"end":152,"count":1}] + {"start":121,"end":137,"count":1}] ); %DebugToggleBlockCoverage(false); diff --git a/deps/v8/test/mjsunit/code-coverage-block.js b/deps/v8/test/mjsunit/code-coverage-block.js index 61ed87fc13e154..1291a50d978ceb 100644 --- a/deps/v8/test/mjsunit/code-coverage-block.js +++ b/deps/v8/test/mjsunit/code-coverage-block.js @@ -246,8 +246,7 @@ function g() {} // 0000 {"start":224,"end":237,"count":12}, {"start":273,"end":277,"count":0}, {"start":412,"end":416,"count":12}, - {"start":462,"end":475,"count":12}, - {"start":620,"end":622,"count":0}] + {"start":462,"end":475,"count":12}] ); TestCoverage( @@ -357,7 +356,7 @@ TestCoverage( {"start":219,"end":222,"count":0}, {"start":254,"end":274,"count":0}, {"start":369,"end":372,"count":0}, - {"start":390,"end":404,"count":0}, + {"start":403,"end":404,"count":0}, {"start":513,"end":554,"count":0}] ); @@ -376,10 +375,10 @@ TestCoverage("try/catch/finally statements with early return", [{"start":0,"end":449,"count":1}, {"start":1,"end":151,"count":1}, {"start":67,"end":70,"count":0}, - {"start":89,"end":150,"count":0}, + {"start":91,"end":150,"count":0}, {"start":201,"end":401,"count":1}, {"start":267,"end":270,"count":0}, - {"start":319,"end":400,"count":0}] + {"start":321,"end":400,"count":0}] ); TestCoverage( @@ -411,11 +410,11 @@ TestCoverage( [{"start":0,"end":1099,"count":1}, {"start":1,"end":151,"count":1}, {"start":67,"end":70,"count":0}, - {"start":89,"end":150,"count":0}, + {"start":91,"end":150,"count":0}, {"start":201,"end":351,"count":1}, - {"start":284,"end":350,"count":0}, + {"start":286,"end":350,"count":0}, {"start":401,"end":701,"count":1}, - {"start":569,"end":700,"count":0}, + {"start":603,"end":700,"count":0}, {"start":561,"end":568,"count":0}, // TODO(jgruber): Sorting. {"start":751,"end":1051,"count":1}, {"start":817,"end":820,"count":0}, @@ -437,7 +436,7 @@ TestCoverage( [{"start":0,"end":399,"count":1}, {"start":1,"end":351,"count":1}, {"start":154,"end":204,"count":0}, - {"start":226,"end":303,"count":0}] + {"start":226,"end":350,"count":0}] ); TestCoverage( @@ -467,11 +466,7 @@ TestCoverage( [{"start":0,"end":999,"count":1}, {"start":1,"end":951,"count":1}, {"start":152,"end":202,"count":0}, - {"start":285,"end":353,"count":0}, - {"start":472,"end":503,"count":0}, - {"start":626,"end":653,"count":0}, - {"start":768,"end":803,"count":0}, - {"start":867,"end":868,"count":0}] + {"start":285,"end":353,"count":0}] ); TestCoverage( @@ -496,11 +491,8 @@ TestCoverage( [{"start":0,"end":749,"count":1}, {"start":1,"end":701,"count":1}, {"start":87,"end":153,"count":2}, - {"start":125,"end":153,"count":0}, {"start":271,"end":403,"count":2}, - {"start":379,"end":403,"count":0}, - {"start":509,"end":653,"count":2}, - {"start":621,"end":653,"count":0}] + {"start":509,"end":653,"count":2}] ); TestCoverage( @@ -570,6 +562,7 @@ try { // 0200 } catch (e) {} // 0450 `, [{"start":0,"end":499,"count":1}, + {"start":451,"end":452,"count":0}, {"start":12,"end":101,"count":3}, {"start":60,"end":100,"count":0}, {"start":264,"end":353,"count":3}, @@ -648,6 +641,7 @@ try { // 0200 } catch (e) {} // 0450 `, [{"start":0,"end":499,"count":1}, + {"start":451,"end":452,"count":0}, {"start":12,"end":101,"count":3}, {"start":65,"end":100,"count":0}, {"start":264,"end":353,"count":3}, @@ -846,8 +840,168 @@ Util.escape("foo.bar"); // 0400 `, [{"start":0,"end":449,"count":1}, {"start":64,"end":351,"count":1}, - {"start":112,"end":203,"count":0}, - {"start":268,"end":350,"count":0}] + {"start":112,"end":203,"count":0}] +); + +TestCoverage( +"https://crbug.com/v8/8237", +` +!function() { // 0000 + if (true) // 0050 + while (false) return; else nop(); // 0100 +}(); // 0150 +!function() { // 0200 + if (true) l0: { break l0; } else // 0250 + if (nop()) { } // 0300 +}(); // 0350 +!function() { // 0400 + if (true) { if (false) { return; } // 0450 + } else if (nop()) { } }(); // 0500 +!function(){ // 0550 + if(true)while(false)return;else nop() // 0600 +}(); // 0650 +!function(){ // 0700 + if(true) l0:{break l0}else if (nop()){} // 0750 +}(); // 0800 +!function(){ // 0850 + if(true){if(false){return}}else // 0900 + if(nop()){} // 0950 +}(); // 1000 +`, +[{"start":0,"end":1049,"count":1}, + {"start":1,"end":151,"count":1}, + {"start":118,"end":137,"count":0}, + {"start":201,"end":351,"count":1}, + {"start":279,"end":318,"count":0}, + {"start":401,"end":525,"count":1}, + {"start":475,"end":486,"count":0}, + {"start":503,"end":523,"count":0}, + {"start":551,"end":651,"count":1}, + {"start":622,"end":639,"count":0}, + {"start":701,"end":801,"count":1}, + {"start":774,"end":791,"count":0}, + {"start":851,"end":1001,"count":1}, + {"start":920,"end":928,"count":0}, + {"start":929,"end":965,"count":0}] +); + +TestCoverage( +"terminal break statement", +` +while (true) { // 0000 + const b = false // 0050 + break // 0100 +} // 0150 +let stop = false // 0200 +while (true) { // 0250 + if (stop) { // 0300 + break // 0350 + } // 0400 + stop = true // 0450 +} // 0500 +`, +[{"start":0,"end":549,"count":1}, + {"start":263,"end":501,"count":2}, + {"start":312,"end":501,"count":1}] +); + +TestCoverage( +"terminal return statement", +` +function a () { // 0000 + const b = false // 0050 + return 1 // 0100 +} // 0150 +const b = (early) => { // 0200 + if (early) { // 0250 + return 2 // 0300 + } // 0350 + return 3 // 0400 +} // 0450 +const c = () => { // 0500 + if (true) { // 0550 + return // 0600 + } // 0650 +} // 0700 +a(); b(false); b(true); c() // 0750 +`, +[{"start":0,"end":799,"count":1}, + {"start":0,"end":151,"count":1}, + {"start":210,"end":451,"count":2}, + {"start":263,"end":450,"count":1}, + {"start":510,"end":701,"count":1}] +); + +TestCoverage( +"terminal blocks", +` +function a () { // 0000 + { // 0050 + return 'a' // 0100 + } // 0150 +} // 0200 +function b () { // 0250 + { // 0300 + { // 0350 + return 'b' // 0400 + } // 0450 + } // 0500 +} // 0550 +a(); b() // 0600 +`, +[{"start":0,"end":649,"count":1}, + {"start":0,"end":201,"count":1}, + {"start":250,"end":551,"count":1}] +); + +TestCoverage( +"terminal if statements", +` +function a (branch) { // 0000 + if (branch) { // 0050 + return 'a' // 0100 + } else { // 0150 + return 'b' // 0200 + } // 0250 +} // 0300 +function b (branch) { // 0350 + if (branch) { // 0400 + if (branch) { // 0450 + return 'c' // 0500 + } // 0550 + } // 0600 +} // 0650 +function c (branch) { // 0700 + if (branch) { // 0750 + return 'c' // 0800 + } else { // 0850 + return 'd' // 0900 + } // 0950 +} // 1000 +function d (branch) { // 1050 + if (branch) { // 1100 + if (!branch) { // 1150 + return 'e' // 1200 + } else { // 1250 + return 'f' // 1300 + } // 1350 + } else { // 1400 + // noop // 1450 + } // 1500 +} // 1550 +a(true); a(false); b(true); b(false) // 1600 +c(true); d(true); // 1650 +`, +[{"start":0,"end":1699,"count":1}, + {"start":0,"end":301,"count":2}, + {"start":64,"end":253,"count":1}, + {"start":350,"end":651,"count":2}, + {"start":414,"end":603,"count":1}, + {"start":700,"end":1001,"count":1}, + {"start":853,"end":953,"count":0}, + {"start":1050,"end":1551,"count":1}, + {"start":1167,"end":1255,"count":0}, + {"start":1403,"end":1503,"count":0}] ); %DebugToggleBlockCoverage(false); diff --git a/deps/v8/test/mjsunit/regress/regress-8237.js b/deps/v8/test/mjsunit/regress/regress-8237.js deleted file mode 100644 index c3abd17e8a9646..00000000000000 --- a/deps/v8/test/mjsunit/regress/regress-8237.js +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2018 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// Flags: --allow-natives-syntax --no-always-opt -// Files: test/mjsunit/code-coverage-utils.js - -%DebugToggleBlockCoverage(true); - -TestCoverage( -"Repro for the bug", -` -function lib (n) { // 0000 - if (n >= 0) { // 0050 - if (n < 0) { // 0100 - return; // 0150 - } // 0200 - } else if (foo()) { // 0250 - } // 0300 -} // 0350 -function foo () { // 0400 - console.log('foo') // 0450 - return false // 0500 -} // 0550 -lib(1) // 0600 -`, -[{"start":0,"end":649,"count":1}, -{"start":0,"end":351,"count":1}, -{"start":115,"end":205,"count":0}, -{"start":253,"end":303,"count":0}, -{"start":400,"end":551,"count":0}] -); - -TestCoverage( -"Variant with omitted brackets", -` -function lib (n) { // 0000 - if (n >= 0) { // 0050 - if (n < 0) // 0100 - return; // 0150 - } // 0200 - else if (foo()); // 0250 -} // 0300 -function foo () { // 0350 - console.log('foo') // 0400 - return false // 0450 -} // 0500 -lib(1) // 0550 -`, -[{"start":0,"end":599,"count":1}, -{"start":0,"end":301,"count":1}, -{"start":156,"end":163,"count":0}, -{"start":203,"end":268,"count":0}, -{"start":350,"end":501,"count":0}] -); - -%DebugToggleBlockCoverage(false);