1// Copyright 2021 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_BASELINE_BYTECODE_OFFSET_ITERATOR_H_
6#define V8_BASELINE_BYTECODE_OFFSET_ITERATOR_H_
7
8#include "src/base/vlq.h"
9#include "src/common/globals.h"
10#include "src/interpreter/bytecode-array-iterator.h"
11#include "src/objects/code.h"
12#include "src/objects/fixed-array.h"
13
14namespace v8 {
15namespace internal {
16
17class BytecodeArray;
18
19namespace baseline {
20
21class V8_EXPORT_PRIVATE BytecodeOffsetIterator {
22 public:
23  explicit BytecodeOffsetIterator(Handle<ByteArray> mapping_table,
24                                  Handle<BytecodeArray> bytecodes);
25  // Non-handlified version for use when no GC can happen.
26  explicit BytecodeOffsetIterator(ByteArray mapping_table,
27                                  BytecodeArray bytecodes);
28  ~BytecodeOffsetIterator();
29
30  inline void Advance() {
31    DCHECK(!done());
32    current_pc_start_offset_ = current_pc_end_offset_;
33    current_pc_end_offset_ += ReadPosition();
34    current_bytecode_offset_ = bytecode_iterator_.current_offset();
35    bytecode_iterator_.Advance();
36  }
37
38  inline void AdvanceToBytecodeOffset(int bytecode_offset) {
39    while (current_bytecode_offset() < bytecode_offset) {
40      Advance();
41    }
42    DCHECK_EQ(bytecode_offset, current_bytecode_offset());
43  }
44
45  inline void AdvanceToPCOffset(Address pc_offset) {
46    while (current_pc_end_offset() < pc_offset) {
47      Advance();
48    }
49    DCHECK_GT(pc_offset, current_pc_start_offset());
50    DCHECK_LE(pc_offset, current_pc_end_offset());
51  }
52
53  // For this iterator, done() means that it is not safe to Advance().
54  // Values are cached, so reads are always allowed.
55  inline bool done() const { return current_index_ >= data_length_; }
56
57  inline Address current_pc_start_offset() const {
58    return current_pc_start_offset_;
59  }
60
61  inline Address current_pc_end_offset() const {
62    return current_pc_end_offset_;
63  }
64
65  inline int current_bytecode_offset() const {
66    return current_bytecode_offset_;
67  }
68
69  static void UpdatePointersCallback(void* iterator) {
70    reinterpret_cast<BytecodeOffsetIterator*>(iterator)->UpdatePointers();
71  }
72
73  void UpdatePointers();
74
75 private:
76  void Initialize();
77  inline int ReadPosition() {
78    return base::VLQDecodeUnsigned(data_start_address_, &current_index_);
79  }
80
81  Handle<ByteArray> mapping_table_;
82  byte* data_start_address_;
83  int data_length_;
84  int current_index_;
85  Address current_pc_start_offset_;
86  Address current_pc_end_offset_;
87  int current_bytecode_offset_;
88  BytecodeArray bytecode_handle_storage_;
89  interpreter::BytecodeArrayIterator bytecode_iterator_;
90  LocalHeap* local_heap_;
91  base::Optional<DisallowGarbageCollection> no_gc_;
92};
93
94}  // namespace baseline
95}  // namespace internal
96}  // namespace v8
97
98#endif  // V8_BASELINE_BYTECODE_OFFSET_ITERATOR_H_
99