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 13 namespace v8 { 14 namespace internal { 15 namespace interpreter { 16 17 // Used to generate IncBlockCounter bytecodes and the {source range, slot} 18 // mapping for block coverage. 19 class BlockCoverageBuilder final : public ZoneObject { 20 public: BlockCoverageBuilder(Zone * zone,BytecodeArrayBuilder * builder,SourceRangeMap * source_range_map)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 AllocateBlockCoverageSlot(ZoneObject * node,SourceRangeKind kind)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 AllocateNaryBlockCoverageSlot(NaryOperation * node,size_t index)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 IncrementBlockCounter(int coverage_array_slot)57 void IncrementBlockCounter(int coverage_array_slot) { 58 if (coverage_array_slot == kNoCoverageArraySlot) return; 59 builder_->IncBlockCounter(coverage_array_slot); 60 } 61 IncrementBlockCounter(ZoneObject * node,SourceRangeKind kind)62 void IncrementBlockCounter(ZoneObject* node, SourceRangeKind kind) { 63 int slot = AllocateBlockCoverageSlot(node, kind); 64 IncrementBlockCounter(slot); 65 } 66 slots()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