11cb0ef41Sopenharmony_ci// Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
61cb0ef41Sopenharmony_ci#define V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/ast/ast-source-ranges.h"
91cb0ef41Sopenharmony_ci#include "src/interpreter/bytecode-array-builder.h"
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_ci#include "src/zone/zone-containers.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_cinamespace interpreter {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci// Used to generate IncBlockCounter bytecodes and the {source range, slot}
181cb0ef41Sopenharmony_ci// mapping for block coverage.
191cb0ef41Sopenharmony_ciclass BlockCoverageBuilder final : public ZoneObject {
201cb0ef41Sopenharmony_ci public:
211cb0ef41Sopenharmony_ci  BlockCoverageBuilder(Zone* zone, BytecodeArrayBuilder* builder,
221cb0ef41Sopenharmony_ci                       SourceRangeMap* source_range_map)
231cb0ef41Sopenharmony_ci      : slots_(0, zone),
241cb0ef41Sopenharmony_ci        builder_(builder),
251cb0ef41Sopenharmony_ci        source_range_map_(source_range_map) {
261cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(builder);
271cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(source_range_map);
281cb0ef41Sopenharmony_ci  }
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  static constexpr int kNoCoverageArraySlot = -1;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  int AllocateBlockCoverageSlot(ZoneObject* node, SourceRangeKind kind) {
331cb0ef41Sopenharmony_ci    AstNodeSourceRanges* ranges = source_range_map_->Find(node);
341cb0ef41Sopenharmony_ci    if (ranges == nullptr) return kNoCoverageArraySlot;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci    SourceRange range = ranges->GetRange(kind);
371cb0ef41Sopenharmony_ci    if (range.IsEmpty()) return kNoCoverageArraySlot;
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci    const int slot = static_cast<int>(slots_.size());
401cb0ef41Sopenharmony_ci    slots_.emplace_back(range);
411cb0ef41Sopenharmony_ci    return slot;
421cb0ef41Sopenharmony_ci  }
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci  int AllocateNaryBlockCoverageSlot(NaryOperation* node, size_t index) {
451cb0ef41Sopenharmony_ci    NaryOperationSourceRanges* ranges =
461cb0ef41Sopenharmony_ci        static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
471cb0ef41Sopenharmony_ci    if (ranges == nullptr) return kNoCoverageArraySlot;
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    SourceRange range = ranges->GetRangeAtIndex(index);
501cb0ef41Sopenharmony_ci    if (range.IsEmpty()) return kNoCoverageArraySlot;
511cb0ef41Sopenharmony_ci
521cb0ef41Sopenharmony_ci    const int slot = static_cast<int>(slots_.size());
531cb0ef41Sopenharmony_ci    slots_.emplace_back(range);
541cb0ef41Sopenharmony_ci    return slot;
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  void IncrementBlockCounter(int coverage_array_slot) {
581cb0ef41Sopenharmony_ci    if (coverage_array_slot == kNoCoverageArraySlot) return;
591cb0ef41Sopenharmony_ci    builder_->IncBlockCounter(coverage_array_slot);
601cb0ef41Sopenharmony_ci  }
611cb0ef41Sopenharmony_ci
621cb0ef41Sopenharmony_ci  void IncrementBlockCounter(ZoneObject* node, SourceRangeKind kind) {
631cb0ef41Sopenharmony_ci    int slot = AllocateBlockCoverageSlot(node, kind);
641cb0ef41Sopenharmony_ci    IncrementBlockCounter(slot);
651cb0ef41Sopenharmony_ci  }
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  const ZoneVector<SourceRange>& slots() const { return slots_; }
681cb0ef41Sopenharmony_ci
691cb0ef41Sopenharmony_ci private:
701cb0ef41Sopenharmony_ci  // Contains source range information for allocated block coverage counter
711cb0ef41Sopenharmony_ci  // slots. Slot i covers range slots_[i].
721cb0ef41Sopenharmony_ci  ZoneVector<SourceRange> slots_;
731cb0ef41Sopenharmony_ci  BytecodeArrayBuilder* builder_;
741cb0ef41Sopenharmony_ci  SourceRangeMap* source_range_map_;
751cb0ef41Sopenharmony_ci};
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci}  // namespace interpreter
781cb0ef41Sopenharmony_ci}  // namespace internal
791cb0ef41Sopenharmony_ci}  // namespace v8
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci#endif  // V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
82