c1f2966d4c
This is a reland of 4d3bc552b5
Original change's description:
> [coverage] add coverage for binary expressions
>
> Adds block-level coverage tracking for binary && and ||
> expressions. Introduces a BinaryOperation source-range
> for tracking the operations themselves and an Expression
> source-range, used for tracking NaryLogical expressions.
>
> This builds on work by jgruber@chromium.org in
> the issue.
>
> TBR=marja@chromium.org
> R=jgruber@chromium.org, rmcilroy@chromium.org
>
> Bug: v8:6660
> Change-Id: I83a81f13a3514a734c06948b2d3e91138fb00e18
> Reviewed-on: https://chromium-review.googlesource.com/754564
> Commit-Queue: Jakob Gruber <jgruber@chromium.org>
> Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#49304}
Bug: v8:6660
Change-Id: I1c8571660d6c501d526886867bd841c49d5c44fd
Reviewed-on: https://chromium-review.googlesource.com/778288
Reviewed-by: Marja Hölttä <marja@chromium.org>
Reviewed-by: Jakob Gruber <jgruber@chromium.org>
Reviewed-by: Ross McIlroy <rmcilroy@chromium.org>
Commit-Queue: Jakob Gruber <jgruber@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49613}
82 lines
2.6 KiB
C++
82 lines
2.6 KiB
C++
// 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_
|