// Copyright 2017 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_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
|
#define V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
|
|
#include "src/ast/ast-source-ranges.h"
|
#include "src/interpreter/bytecode-array-builder.h"
|
|
#include "src/zone/zone-containers.h"
|
|
namespace v8 {
|
namespace internal {
|
namespace interpreter {
|
|
// Used to generate IncBlockCounter bytecodes and the {source range, slot}
|
// mapping for block coverage.
|
class BlockCoverageBuilder final : public ZoneObject {
|
public:
|
BlockCoverageBuilder(Zone* zone, BytecodeArrayBuilder* builder,
|
SourceRangeMap* source_range_map)
|
: slots_(0, zone),
|
builder_(builder),
|
source_range_map_(source_range_map) {
|
DCHECK_NOT_NULL(builder);
|
DCHECK_NOT_NULL(source_range_map);
|
}
|
|
static constexpr int kNoCoverageArraySlot = -1;
|
|
int AllocateBlockCoverageSlot(ZoneObject* node, SourceRangeKind kind) {
|
AstNodeSourceRanges* ranges = source_range_map_->Find(node);
|
if (ranges == nullptr) return kNoCoverageArraySlot;
|
|
SourceRange range = ranges->GetRange(kind);
|
if (range.IsEmpty()) return kNoCoverageArraySlot;
|
|
const int slot = static_cast<int>(slots_.size());
|
slots_.emplace_back(range);
|
return slot;
|
}
|
|
int AllocateNaryBlockCoverageSlot(NaryOperation* node, size_t index) {
|
NaryOperationSourceRanges* ranges =
|
static_cast<NaryOperationSourceRanges*>(source_range_map_->Find(node));
|
if (ranges == nullptr) return kNoCoverageArraySlot;
|
|
SourceRange range = ranges->GetRangeAtIndex(index);
|
if (range.IsEmpty()) return kNoCoverageArraySlot;
|
|
const int slot = static_cast<int>(slots_.size());
|
slots_.emplace_back(range);
|
return slot;
|
}
|
|
void IncrementBlockCounter(int coverage_array_slot) {
|
if (coverage_array_slot == kNoCoverageArraySlot) return;
|
builder_->IncBlockCounter(coverage_array_slot);
|
}
|
|
void IncrementBlockCounter(ZoneObject* node, SourceRangeKind kind) {
|
int slot = AllocateBlockCoverageSlot(node, kind);
|
IncrementBlockCounter(slot);
|
}
|
|
const ZoneVector<SourceRange>& slots() const { return slots_; }
|
|
private:
|
// Contains source range information for allocated block coverage counter
|
// slots. Slot i covers range slots_[i].
|
ZoneVector<SourceRange> slots_;
|
BytecodeArrayBuilder* builder_;
|
SourceRangeMap* source_range_map_;
|
};
|
|
} // namespace interpreter
|
} // namespace internal
|
} // namespace v8
|
|
#endif // V8_INTERPRETER_BLOCK_COVERAGE_BUILDER_H_
|