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_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
6#define V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
7
8#include "src/ast/ast-source-ranges.h"
9#include "src/interpreter/bytecode-array-builder.h"
10
11#include "src/zone/zone-containers.h"
12
13namespace v8 {
14namespace internal {
15namespace interpreter {
16
17// Used to generate IncBlockCounter bytecodes and the {source range, slot}
18// mapping for block coverage.
19class BlockCoverageBuilder final : public ZoneObject {
20 public:
21  BlockCoverageBuilder(Zone* zone, BytecodeArrayBuilder* builder,
22                       SourceRangeMap* source_range_map)
23      : slots_(0, zone),
24        builder_(builder),
25        source_range_map_(source_range_map) {
26    DCHECK_NOT_NULL(builder);
27    DCHECK_NOT_NULL(source_range_map);
28  }
29
30  static constexpr int kNoCoverageArraySlot = -1;
31
32  int AllocateBlockCoverageSlot(ZoneObject* node, SourceRangeKind kind) {
33    AstNodeSourceRanges* ranges = source_range_map_->Find(node);
34    if (ranges == nullptr) return kNoCoverageArraySlot;
35
36    SourceRange range = ranges->GetRange(kind);
37    if (range.IsEmpty()) return kNoCoverageArraySlot;
38
39    const int slot = static_cast<int>(slots_.size());
40    slots_.emplace_back(range);
41    return slot;
42  }
43
44  int AllocateNaryBlockCoverageSlot(NaryOperation* node, size_t index) {
45    NaryOperationSourceRanges* ranges =
46        static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
47    if (ranges == nullptr) return kNoCoverageArraySlot;
48
49    SourceRange range = ranges->GetRangeAtIndex(index);
50    if (range.IsEmpty()) return kNoCoverageArraySlot;
51
52    const int slot = static_cast<int>(slots_.size());
53    slots_.emplace_back(range);
54    return slot;
55  }
56
57  void IncrementBlockCounter(int coverage_array_slot) {
58    if (coverage_array_slot == kNoCoverageArraySlot) return;
59    builder_->IncBlockCounter(coverage_array_slot);
60  }
61
62  void IncrementBlockCounter(ZoneObject* node, SourceRangeKind kind) {
63    int slot = AllocateBlockCoverageSlot(node, kind);
64    IncrementBlockCounter(slot);
65  }
66
67  const ZoneVector<SourceRange>& slots() const { return slots_; }
68
69 private:
70  // Contains source range information for allocated block coverage counter
71  // slots. Slot i covers range slots_[i].
72  ZoneVector<SourceRange> slots_;
73  BytecodeArrayBuilder* builder_;
74  SourceRangeMap* source_range_map_;
75};
76
77}  // namespace interpreter
78}  // namespace internal
79}  // namespace v8
80
81#endif  // V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
82