v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
interpreter-generator-tsa.cc
Go to the documentation of this file.
1// Copyright 2024 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
6
10
12
14
15using namespace compiler::turboshaft; // NOLINT(build/namespaces)
16
17#define IGNITION_HANDLER_TS(Name, BaseAssembler) \
18 class Name##AssemblerTS : public BaseAssembler { \
19 public: \
20 using Base = BaseAssembler; \
21 Name##AssemblerTS(compiler::turboshaft::PipelineData* data, \
22 Isolate* isolate, compiler::turboshaft::Graph& graph, \
23 Zone* phase_zone) \
24 : Base(data, graph, phase_zone) {} \
25 Name##AssemblerTS(const Name##AssemblerTS&) = delete; \
26 Name##AssemblerTS& operator=(const Name##AssemblerTS&) = delete; \
27 void Generate##Name##Impl(); \
28 }; \
29 void Name##AssemblerTS_Generate( \
30 compiler::turboshaft::PipelineData* data, Isolate* isolate, \
31 compiler::turboshaft::Graph& graph, Zone* zone) { \
32 Name##AssemblerTS assembler(data, isolate, graph, zone); \
33 assembler.EmitBytecodeHandlerProlog(); \
34 compiler::turboshaft::Block* catch_block = assembler.NewBlock(); \
35 Name##AssemblerTS::CatchScope catch_scope(assembler, catch_block); \
36 assembler.Generate##Name##Impl(); \
37 assembler.EmitEpilog(catch_block); \
38 } \
39 void Name##AssemblerTS::Generate##Name##Impl()
40
41template <typename Next>
42class BytecodeHandlerReducer : public Next {
43 public:
44 BUILTIN_REDUCER(BytecodeHandler)
45
47 // If the following check fails the handler does not use the
48 // accumulator in the way described in the bytecode definitions in
49 // bytecodes.h.
52 }
53
55 V<BytecodeArray> bytecode_array,
56 V<WordPtr> bytecode_offset,
57 V<WordPtr> dispatch_table) {
58 accumulator_ = accumulator;
59 bytecode_array_ = bytecode_array;
60 bytecode_offset_ = bytecode_offset;
61 dispatch_table_ = dispatch_table;
62 }
63
69
75
79
80 void Dispatch() {
81 __ CodeComment("========= Dispatch");
84 V<WordPtr> target_offset = Advance(CurrentBytecodeSize());
85 V<WordPtr> target_bytecode = LoadBytecode(target_offset);
87 }
88
95
96 void DispatchToBytecode(V<WordPtr> target_bytecode,
97 V<WordPtr> new_bytecode_offset) {
98#ifdef V8_IGNITION_DISPATCH_COUNTING
99 TraceBytecodeDispatch(target_bytecode);
100#endif
101
102 static_assert(kSystemPointerSizeLog2 ==
104 V<WordPtr> target_code_entry =
105 __ LoadOffHeap(DispatchTablePointer(), target_bytecode, 0,
107
108 DispatchToBytecodeHandlerEntry(target_code_entry, new_bytecode_offset);
109 }
110
112 V<WordPtr> bytecode_offset) {
114 InterpreterDispatchDescriptor{}, handler_entry, accumulator_.Get(),
116 }
117
118 void StarDispatchLookahead(V<WordPtr> target_bytecode) { UNIMPLEMENTED(); }
119
120 template <typename... Args>
122 V<WordPtr> target, Args... args) {
123 DCHECK_EQ(descriptor.GetParameterCount(), sizeof...(Args));
125 graph_zone_, descriptor, descriptor.GetStackParameterCount());
126 auto ts_call_descriptor =
129
130 std::initializer_list<const OpIndex> arguments{args...};
131 __ TailCall(target, base::VectorOf(arguments), ts_call_descriptor);
132 }
133
135 V<WordPtr> next_offset = __ WordPtrAdd(BytecodeOffset(), delta);
136 bytecode_offset_ = next_offset;
137 return next_offset;
138 }
139
141 const int offset = reg.ToOperand() * kSystemPointerSize;
142 return __ LoadOffHeap(GetInterpretedFramePointer(), offset,
144 }
145
156
164
167 if (operand_scale() == OperandScale::kSingle) {
168 return offset;
169 }
170
171 // Add one to the offset such that it points to the actual bytecode rather
172 // than the Wide / ExtraWide prefix bytecode.
173 return __ WordPtrAdd(offset, 1);
174 }
175
177 V<WordPtr> bytecode_offset,
178 int additional_offset = 0) {
179 return __ Load(BytecodeArrayTaggedPointer(), bytecode_offset,
180 LoadOp::Kind::TaggedBase(), loaded_rep,
181 additional_offset + kHeapObjectTag);
182 }
183
185 V<Word32> bytecode = __ Load(BytecodeArrayTaggedPointer(), bytecode_offset,
188 return __ ChangeUint32ToUintPtr(bytecode);
189 }
190
193 int index = reg.ToOperand() * kSystemPointerSize;
194 if (SmiValuesAre32Bits()) {
195#if V8_TARGET_LITTLE_ENDIAN
196 index += 4;
197#endif
198 return __ ChangeInt32ToIntPtr(
199 __ LoadOffHeap(base, index, MemoryRepresentation::Int32()));
200 } else {
201 return __ ChangeInt32ToIntPtr(__ UntagSmi(
202 __ LoadOffHeap(base, index, MemoryRepresentation::TaggedSigned())));
203 }
204 }
205
206 // TODO(nicohartmann): Consider providing a V<ExternalReference>.
210 dispatch_table_ = __ ExternalConstant(
211 ExternalReference::interpreter_dispatch_table_address(isolate_));
212 }
213 return dispatch_table_;
214 }
215
217 // Force a re-load of the bytecode array after every call in case the
218 // debugger has been activated.
222 }
224 }
225
227 DCHECK_EQ(OperandType::kIdx,
230 data_.bytecode, operand_index, operand_scale());
231 return BytecodeUnsignedOperand(operand_index, operand_size);
232 }
233
235 OperandSize operand_size) {
236 return BytecodeOperand(operand_index, operand_size);
237 }
238
239 V<Word32> BytecodeOperand(int operand_index, OperandSize operand_size) {
241 DCHECK_EQ(operand_size, Bytecodes::GetOperandSize(bytecode(), operand_index,
242 operand_scale()));
243 MemoryRepresentation loaded_rep;
244 switch (operand_size) {
246 loaded_rep = MemoryRepresentation::Uint8();
247 break;
249 loaded_rep = MemoryRepresentation::Uint16();
250 break;
252 loaded_rep = MemoryRepresentation::Uint32();
253 break;
255 UNREACHABLE();
256 }
257 return LoadFromBytecodeArrayAt(loaded_rep, BytecodeOffset(),
258 OperandOffset(operand_index));
259 }
260
261 int OperandOffset(int operand_index) const {
262 return Bytecodes::GetOperandOffset(bytecode(), operand_index,
263 operand_scale());
264 }
265
266 private:
267 Bytecode bytecode() const { return data_.bytecode; }
269
273
277
280 __ data() -> graph_zone();
281 BytecodeHandlerData& data_ = *__ data() -> bytecode_handler_data();
282 // TODO(nicohartmann): Replace with Var<T>s.
285 template <typename T>
292};
293
294template <template <typename> typename Reducer>
297 Reducer, BytecodeHandlerReducer, BuiltinsReducer,
298 FeedbackCollectorReducer,
299 compiler::turboshaft::MachineLoweringReducer,
300 compiler::turboshaft::VariableReducer> {
301 public:
310
311 using Base::Asm;
312
314 // Bind an entry block.
315 __ Bind(__ NewBlock());
316 // Initialize parameters.
317 V<Object> acc = __ template Parameter<Object>(
318 InterpreterDispatchDescriptor::kAccumulator);
319 V<WordPtr> bytecode_offset = __ template Parameter<WordPtr>(
320 InterpreterDispatchDescriptor::kBytecodeOffset);
321 V<BytecodeArray> bytecode_array = __ template Parameter<BytecodeArray>(
322 InterpreterDispatchDescriptor::kBytecodeArray);
323 V<WordPtr> dispatch_table = __ template Parameter<WordPtr>(
324 InterpreterDispatchDescriptor::kDispatchTable);
325 __ InitializeParameters(acc, bytecode_array, bytecode_offset,
326 dispatch_table);
327 }
328};
329
332
334 V<Object> value = GetAccumulator();
335 V<Context> context = GetContext();
336
337 constexpr int kSlotIndex = 0;
338 SetFeedbackSlot(
339 __ ChangeUint32ToUintPtr(__ BytecodeOperandIdxInt32(kSlotIndex)));
340 LoadFeedbackVectorOrUndefinedIfJitless();
341
342 V<Object> result = BitwiseNot(context, value);
343 SetAccumulator(result);
344
345 UpdateFeedback();
346 Dispatch();
347}
348
350
351} // namespace v8::internal::interpreter
union v8::internal::@341::BuiltinMetadata::KindSpecificData data
static CallDescriptor * GetBytecodeDispatchCallDescriptor(Zone *zone, const CallInterfaceDescriptor &descriptor, int stack_parameter_count)
Definition linkage.cc:686
static constexpr MemoryRepresentation AnyTagged()
static constexpr MemoryRepresentation Uint32()
static constexpr MemoryRepresentation TaggedSigned()
static constexpr MemoryRepresentation Int32()
static constexpr MemoryRepresentation Uint16()
static constexpr MemoryRepresentation UintPtr()
static constexpr MemoryRepresentation Uint8()
static V< T > Cast(V< U > index)
Definition index.h:632
V< WordPtr > LoadBytecode(V< WordPtr > bytecode_offset)
V< Word32 > BytecodeOperand(int operand_index, OperandSize operand_size)
V< Word32 > LoadFromBytecodeArrayAt(MemoryRepresentation loaded_rep, V< WordPtr > bytecode_offset, int additional_offset=0)
void DispatchToBytecodeHandlerEntry(V< WordPtr > handler_entry, V< WordPtr > bytecode_offset)
V< Word32 > BytecodeUnsignedOperand(int operand_index, OperandSize operand_size)
ZoneWithName< compiler::kGraphZoneName > & graph_zone_
void DispatchToBytecodeWithOptionalStarLookahead(V< WordPtr > target_bytecode)
void DispatchToBytecode(V< WordPtr > target_bytecode, V< WordPtr > new_bytecode_offset)
void InitializeParameters(V< Object > accumulator, V< BytecodeArray > bytecode_array, V< WordPtr > bytecode_offset, V< WordPtr > dispatch_table)
void TailCallBytecodeDispatch(const CallInterfaceDescriptor &descriptor, V< WordPtr > target, Args... args)
static ImplicitRegisterUse GetImplicitRegisterUse(Bytecode bytecode)
Definition bytecodes.h:681
static OperandSize GetOperandSize(Bytecode bytecode, int i, OperandScale operand_scale)
Definition bytecodes.h:931
static bool WritesAccumulator(Bytecode bytecode)
Definition bytecodes.h:692
static bool MakesCallAlongCriticalPath(Bytecode bytecode)
Definition bytecodes.cc:207
static int GetOperandOffset(Bytecode bytecode, int i, OperandScale operand_scale)
Definition bytecodes.h:951
static bool ReadsAccumulator(Bytecode bytecode)
Definition bytecodes.h:687
static OperandType GetOperandType(Bytecode bytecode, int i)
Definition bytecodes.h:894
static int Size(Bytecode bytecode, OperandScale operand_scale)
Definition bytecodes.h:964
static int NumberOfOperands(Bytecode bytecode)
Definition bytecodes.h:886
static bool IsStarLookahead(Bytecode bytecode, OperandScale operand_scale)
Definition bytecodes.cc:260
static constexpr Register bytecode_array()
static constexpr Register current_context()
static constexpr Register bytecode_offset()
TurboshaftBytecodeHandlerAssembler(compiler::turboshaft::PipelineData *data, compiler::turboshaft::Graph &graph, Zone *phase_zone)
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Isolate * isolate
Zone * graph_zone
int32_t offset
#define IGNITION_HANDLER_TS(Name, BaseAssembler)
ZoneVector< RpoNumber > & result
LiftoffRegister reg
constexpr Vector< T > VectorOf(T *start, size_t size)
Definition vector.h:360
constexpr int kSystemPointerSizeLog2
Definition globals.h:494
constexpr int kSystemPointerSize
Definition globals.h:410
const int kHeapObjectTag
Definition v8-internal.h:72
other heap size generate builtins concurrently on separate threads in mksnapshot track concurrent recompilation artificial compilation delay in ms max number of threads that concurrent Turbofan can use(0 for unbounded)") DEFINE_BOOL( stress_concurrent_inlining
constexpr bool SmiValuesAre32Bits()
return value
Definition map-inl.h:893
i::Address Load(i::Address address)
Definition unwinder.cc:19
#define DCHECK_IMPLIES(v1, v2)
Definition logging.h:493
#define DCHECK(condition)
Definition logging.h:482
#define DCHECK_LT(v1, v2)
Definition logging.h:489
#define DCHECK_EQ(v1, v2)
Definition logging.h:485
static const TSCallDescriptor * Create(const CallDescriptor *descriptor, CanThrow can_throw, LazyDeoptOnThrow lazy_deopt_on_throw, Zone *graph_zone, const JSWasmCallParameters *js_wasm_call_parameters=nullptr)
#define BUILTIN_REDUCER(name)