1// Copyright 2017 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_DEBUG_DEBUG_COVERAGE_H_
6#define V8_DEBUG_DEBUG_COVERAGE_H_
7
8#include <memory>
9#include <vector>
10
11#include "src/debug/debug-interface.h"
12#include "src/handles/handles.h"
13#include "src/objects/objects.h"
14
15namespace v8 {
16namespace internal {
17
18// Forward declaration.
19class Isolate;
20
21struct CoverageBlock {
22  CoverageBlock(int s, int e, uint32_t c) : start(s), end(e), count(c) {}
23  CoverageBlock() : CoverageBlock(kNoSourcePosition, kNoSourcePosition, 0) {}
24
25  int start;
26  int end;
27  uint32_t count;
28};
29
30struct CoverageFunction {
31  CoverageFunction(int s, int e, uint32_t c, Handle<String> n)
32      : start(s), end(e), count(c), name(n), has_block_coverage(false) {}
33
34  bool HasNonEmptySourceRange() const { return start < end && start >= 0; }
35  bool HasBlocks() const { return !blocks.empty(); }
36
37  int start;
38  int end;
39  uint32_t count;
40  Handle<String> name;
41  // Blocks are sorted by start position, from outer to inner blocks.
42  std::vector<CoverageBlock> blocks;
43  bool has_block_coverage;
44};
45
46struct CoverageScript {
47  // Initialize top-level function in case it has been garbage-collected.
48  explicit CoverageScript(Handle<Script> s) : script(s) {}
49  Handle<Script> script;
50  // Functions are sorted by start position, from outer to inner function.
51  std::vector<CoverageFunction> functions;
52};
53
54class Coverage : public std::vector<CoverageScript> {
55 public:
56  // Collecting precise coverage only works if the modes kPreciseCount or
57  // kPreciseBinary is selected. The invocation count is reset on collection.
58  // In case of kPreciseCount, an updated count since last collection is
59  // returned. In case of kPreciseBinary, a count of 1 is returned if a
60  // function has been executed for the first time since last collection.
61  static std::unique_ptr<Coverage> CollectPrecise(Isolate* isolate);
62  // Collecting best effort coverage always works, but may be imprecise
63  // depending on selected mode. The invocation count is not reset.
64  static std::unique_ptr<Coverage> CollectBestEffort(Isolate* isolate);
65
66  // Select code coverage mode.
67  static void SelectMode(Isolate* isolate, debug::CoverageMode mode);
68
69 private:
70  static std::unique_ptr<Coverage> Collect(
71      Isolate* isolate, v8::debug::CoverageMode collectionMode);
72
73  Coverage() = default;
74};
75
76}  // namespace internal
77}  // namespace v8
78
79#endif  // V8_DEBUG_DEBUG_COVERAGE_H_
80