v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
bytecode-array-iterator.h
Go to the documentation of this file.
1// Copyright 2016 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_BYTECODE_ARRAY_ITERATOR_H_
6#define V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_
7
8#include <memory>
9
11#include "src/common/globals.h"
12#include "src/handles/handles.h"
15#include "src/objects/objects.h"
16#include "src/objects/smi.h"
17#include "src/runtime/runtime.h"
18
19namespace v8 {
20namespace internal {
21
22class BytecodeArray;
23
24namespace interpreter {
25
26class BytecodeArrayIterator;
27
32
34 public:
35 // Minimal iterator implementation for use in ranged-for.
37 public:
38 iterator(int case_value, int table_offset, int table_end,
40
41 JumpTableTargetOffset operator*();
43 bool operator!=(const iterator& other);
44
45 private:
46 void UpdateAndAdvanceToValid();
47
50 int index_;
53 };
54
56 int table_size, int case_value_base);
57
58 iterator begin() const;
59 iterator end() const;
60
61 int size() const;
62
63 private:
68};
69
71 public:
72 explicit BytecodeArrayIterator(Handle<BytecodeArray> bytecode_array,
73 int initial_offset = 0);
75 int initial_offset, DisallowGarbageCollection& no_gc);
77
80
81 inline void Advance() {
82 cursor_ += current_bytecode_size_without_prefix();
83 UpdateOperandScale();
84 }
85 // Prefer AdvanceTo over SetOffset if the new offset is greater than the
86 // current offset as it is more efficient.
87 void AdvanceTo(int offset);
88 void SetOffset(int offset);
89 void Reset();
90
91 // Whether the given offset is reachable in this bytecode array.
92 static bool IsValidOffset(Handle<BytecodeArray> bytecode_array, int offset);
93
94 static bool IsValidOSREntryOffset(Handle<BytecodeArray> bytecode_array,
95 int offset);
96 bool CurrentBytecodeIsValidOSREntry() const;
97
98 void ApplyDebugBreak();
99
100 inline Bytecode current_bytecode() const {
101 DCHECK(!done());
102 uint8_t current_byte = *cursor_;
103 Bytecode current_bytecode = Bytecodes::FromByte(current_byte);
104 DCHECK(!Bytecodes::IsPrefixScalingBytecode(current_bytecode));
105 return current_bytecode;
106 }
108 return prefix_size_ + current_bytecode_size_without_prefix();
109 }
111 return Bytecodes::Size(current_bytecode(), current_operand_scale());
112 }
113 int current_offset() const {
114 return static_cast<int>(cursor_ - start_ - prefix_size_);
115 }
116 uint8_t* current_address() const { return cursor_ - prefix_size_; }
117 int next_offset() const { return current_offset() + current_bytecode_size(); }
119 uint8_t* next_cursor = cursor_ + current_bytecode_size_without_prefix();
120 if (next_cursor == end_) return Bytecode::kIllegal;
121 Bytecode next_bytecode = Bytecodes::FromByte(*next_cursor);
122 if (Bytecodes::IsPrefixScalingBytecode(next_bytecode)) {
123 next_bytecode = Bytecodes::FromByte(*(next_cursor + 1));
124 }
125 return next_bytecode;
126 }
127 OperandScale current_operand_scale() const { return operand_scale_; }
128 DirectHandle<BytecodeArray> bytecode_array() const { return bytecode_array_; }
129
130 uint32_t GetFlag8Operand(int operand_index) const;
131 uint32_t GetFlag16Operand(int operand_index) const;
132 uint32_t GetUnsignedImmediateOperand(int operand_index) const;
133 int32_t GetImmediateOperand(int operand_index) const;
134 uint32_t GetIndexOperand(int operand_index) const;
135 FeedbackSlot GetSlotOperand(int operand_index) const;
136 Register GetParameter(int parameter_index) const;
137 uint32_t GetRegisterCountOperand(int operand_index) const;
138 Register GetRegisterOperand(int operand_index) const;
139 Register GetStarTargetRegister() const;
140 std::pair<Register, Register> GetRegisterPairOperand(int operand_index) const;
141 RegisterList GetRegisterListOperand(int operand_index) const;
142 int GetRegisterOperandRange(int operand_index) const;
143 Runtime::FunctionId GetRuntimeIdOperand(int operand_index) const;
144 Runtime::FunctionId GetIntrinsicIdOperand(int operand_index) const;
145 uint32_t GetNativeContextIndexOperand(int operand_index) const;
146 template <typename IsolateT>
147 Handle<Object> GetConstantAtIndex(int offset, IsolateT* isolate) const;
148 bool IsConstantAtIndexSmi(int offset) const;
149 Tagged<Smi> GetConstantAtIndexAsSmi(int offset) const;
150 template <typename IsolateT>
151 Handle<Object> GetConstantForIndexOperand(int operand_index,
152 IsolateT* isolate) const;
153
154 // Returns the relative offset of the branch target at the current bytecode.
155 // It is an error to call this method if the bytecode is not for a jump or
156 // conditional jump. Returns a negative offset for backward jumps.
157 int GetRelativeJumpTargetOffset() const;
158 // Returns the absolute offset of the branch target at the current bytecode.
159 // It is an error to call this method if the bytecode is not for a jump or
160 // conditional jump.
161 int GetJumpTargetOffset() const;
162 // Returns an iterator over the absolute offsets of the targets of the current
163 // switch bytecode's jump table. It is an error to call this method if the
164 // bytecode is not a switch.
165 JumpTableTargetOffsets GetJumpTableTargetOffsets() const;
166
167 // Returns the absolute offset of the bytecode at the given relative offset
168 // from the current bytecode.
169 int GetAbsoluteOffset(int relative_offset) const;
170
171 std::ostream& PrintTo(std::ostream& os) const;
172
173 static void UpdatePointersCallback(void* iterator) {
174 reinterpret_cast<BytecodeArrayIterator*>(iterator)->UpdatePointers();
175 }
176
177 void UpdatePointers();
178
179 inline bool done() const { return cursor_ >= end_; }
180
181 bool operator==(const BytecodeArrayIterator& other) const {
182 return cursor_ == other.cursor_;
183 }
184 bool operator!=(const BytecodeArrayIterator& other) const {
185 return cursor_ != other.cursor_;
186 }
187
188 protected:
189 void SetOffsetUnchecked(int offset);
190
191 private:
192 uint32_t GetUnsignedOperand(int operand_index,
193 OperandType operand_type) const;
194 int32_t GetSignedOperand(int operand_index, OperandType operand_type) const;
195
196 inline void UpdateOperandScale() {
197 if (done()) return;
198 uint8_t current_byte = *cursor_;
199 Bytecode current_bytecode = Bytecodes::FromByte(current_byte);
200 if (Bytecodes::IsPrefixScalingBytecode(current_bytecode)) {
201 operand_scale_ =
202 Bytecodes::PrefixBytecodeToOperandScale(current_bytecode);
203 ++cursor_;
204 prefix_size_ = 1;
205 } else {
206 operand_scale_ = OperandScale::kSingle;
207 prefix_size_ = 0;
208 }
209 }
210
212 uint8_t* start_;
213 uint8_t* end_;
214 // The cursor always points to the active bytecode. If there's a prefix, the
215 // prefix is at (cursor - 1).
216 uint8_t* cursor_;
220};
221
222} // namespace interpreter
223} // namespace internal
224} // namespace v8
225
226#endif // V8_INTERPRETER_BYTECODE_ARRAY_ITERATOR_H_
BytecodeArrayIterator(const BytecodeArrayIterator &)=delete
bool operator==(const BytecodeArrayIterator &other) const
bool operator!=(const BytecodeArrayIterator &other) const
BytecodeArrayIterator & operator=(const BytecodeArrayIterator &)=delete
DirectHandle< BytecodeArray > bytecode_array() const
uint8_t *const start_
Definition assembler.cc:131
const v8::base::TimeTicks end_
Definition sweeper.cc:54
int end
int32_t offset
bool operator!=(ExternalReference lhs, ExternalReference rhs)
V8_INLINE Builtin operator++(Builtin &builtin)
Definition builtins.h:80
#define DCHECK(condition)
Definition logging.h:482
#define V8_EXPORT_PRIVATE
Definition macros.h:460