v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
baseline-compiler.h
Go to the documentation of this file.
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_BASELINE_COMPILER_H_
6#define V8_BASELINE_BASELINE_COMPILER_H_
7
8#include "src/base/logging.h"
11#include "src/base/vlq.h"
14#include "src/handles/handles.h"
19#include "src/objects/map.h"
22
23namespace v8 {
24namespace internal {
25
26class BytecodeArray;
27
28namespace baseline {
29
31 public:
32 void AddPosition(size_t pc_offset) {
33 size_t pc_diff = pc_offset - previous_pc_;
34 DCHECK_GE(pc_diff, 0);
35 DCHECK_LE(pc_diff, std::numeric_limits<uint32_t>::max());
36 base::VLQEncodeUnsigned(&bytes_, static_cast<uint32_t>(pc_diff));
38 }
39
40 template <typename IsolateT>
42
43 void Reserve(size_t size) { bytes_.reserve(size); }
44
45 private:
46 size_t previous_pc_ = 0;
47 std::vector<uint8_t> bytes_;
48};
49
51 public:
52 explicit BaselineCompiler(LocalIsolate* local_isolate,
53 Handle<SharedFunctionInfo> shared_function_info,
54 Handle<BytecodeArray> bytecode);
55
56 void GenerateCode();
59
60 private:
61 void Prologue();
62 void PrologueFillFrame();
64
67
68 void VerifyFrame();
69 void VerifyFrameSize();
70
71 // Register operands.
72 interpreter::Register RegisterOperand(int operand_index);
73 void LoadRegister(Register output, int operand_index);
74 void StoreRegister(int operand_index, Register value);
75 void StoreRegisterPair(int operand_index, Register val0, Register val1);
76
77 // Constant pool operands.
78 template <typename Type>
79 Handle<Type> Constant(int operand_index);
80 Tagged<Smi> ConstantSmi(int operand_index);
81 template <typename Type>
82 void LoadConstant(Register output, int operand_index);
83
84 // Immediate value operands.
85 uint32_t Uint(int operand_index);
86 int32_t Int(int operand_index);
87 uint32_t Index(int operand_index);
88 uint32_t Flag8(int operand_index);
89 uint32_t Flag16(int operand_index);
90 uint32_t RegisterCount(int operand_index);
91 Tagged<TaggedIndex> IndexAsTagged(int operand_index);
92 Tagged<TaggedIndex> UintAsTagged(int operand_index);
93 Tagged<Smi> IndexAsSmi(int operand_index);
94 Tagged<Smi> IntAsSmi(int operand_index);
95 Tagged<Smi> UintAsSmi(int operand_index);
96 Tagged<Smi> Flag8AsSmi(int operand_index);
97 Tagged<Smi> Flag16AsSmi(int operand_index);
98
99 // Jump helpers.
107 int weight, Label* label, Label* skip_interrupt_label,
108 StackCheckBehavior stack_check_behavior);
109 void JumpIfRoot(RootIndex root);
110 void JumpIfNotRoot(RootIndex root);
111
112 // Feedback vector.
114 void LoadFeedbackVector(Register output);
116
117 // Position mapping.
118 void AddPosition();
119
120 // Misc. helpers.
121
122 // Select the root boolean constant based on the jump in the given
123 // `jump_func` -- the function should jump to the given label if we want to
124 // select "true", otherwise it should fall through.
126 Register output, std::function<void(Label*, Label::Distance)> jump_func);
127
128 // Jumps based on calling ToBoolean on kInterpreterAccumulatorRegister.
129 void JumpIfToBoolean(bool do_jump_if_true, Label* label,
130 Label::Distance distance = Label::kFar);
131
132 // Call helpers.
133 template <Builtin kBuiltin, typename... Args>
134 void CallBuiltin(Args... args);
135 template <typename... Args>
136 void CallRuntime(Runtime::FunctionId function, Args... args);
137
138 template <Builtin kBuiltin, typename... Args>
139 void TailCallBuiltin(Args... args);
140
141 template <ConvertReceiverMode kMode, typename... Args>
142 void BuildCall(uint32_t slot, uint32_t arg_count, Args... args);
143
144#ifdef V8_TRACE_UNOPTIMIZED
145 void TraceBytecode(Runtime::FunctionId function_id);
146#endif
147
148 // Single bytecode visitors.
149#define DECLARE_VISITOR(name, ...) void Visit##name();
151#undef DECLARE_VISITOR
152
153 // Intrinsic call visitors.
154#define DECLARE_VISITOR(name, ...) \
155 void VisitIntrinsic##name(interpreter::RegisterList args);
157#undef DECLARE_VISITOR
158
160
171
172 // Mark location as a jump target reachable via indirect branches, required
173 // for CFI.
175
179 if (!label_tags_.Contains(offset * 2)) {
181 new (label) Label();
182 }
183 if (mark == MarkAsIndirectJumpTarget::kYes) {
185 }
186 return label;
187 }
188 bool IsJumpTarget(int offset) const {
189 return label_tags_.Contains(offset * 2);
190 }
191 bool IsIndirectJumpTarget(int offset) const {
192 return label_tags_.Contains(offset * 2 + 1);
193 }
195
198
199#ifdef DEBUG
200 friend class SaveAccumulatorScope;
201
202 struct EffectState {
203 bool may_have_deopted = false;
204 bool accumulator_on_stack = false;
205 bool safe_to_skip = false;
206
207 void MayDeopt() {
208 // If this check fails, you might need to update `BuiltinMayDeopt` if
209 // applicable.
210 DCHECK(!accumulator_on_stack);
211 may_have_deopted = true;
212 }
213
214 void CheckEffect() { DCHECK(!may_have_deopted || safe_to_skip); }
215
216 void clear() {
217 DCHECK(!accumulator_on_stack);
218 *this = EffectState();
219 }
220 } effect_state_;
221#endif
222};
223
225 public:
227 BaselineAssembler* assembler);
228
230
231 private:
232#ifdef DEBUG
234#endif
236};
237
238} // namespace baseline
239} // namespace internal
240} // namespace v8
241
242#endif // V8_BASELINE_BASELINE_COMPILER_H_
#define DECLARE_VISITOR(name,...)
#define BYTECODE_LIST(V, V_TSA)
Definition bytecodes.h:479
bool Contains(int i) const
Definition bit-vector.h:180
Tagged< TaggedIndex > IndexAsTagged(int operand_index)
Handle< Type > Constant(int operand_index)
void BuildCall(uint32_t slot, uint32_t arg_count, Args... args)
void LoadRegister(Register output, int operand_index)
void JumpIfToBoolean(bool do_jump_if_true, Label *label, Label::Distance distance=Label::kFar)
const interpreter::BytecodeArrayIterator & iterator()
void StoreRegister(int operand_index, Register value)
Handle< SharedFunctionInfo > shared_function_info_
Tagged< Smi > IntAsSmi(int operand_index)
BytecodeOffsetTableBuilder bytecode_offset_table_builder_
Tagged< Smi > Flag8AsSmi(int operand_index)
Tagged< Smi > UintAsSmi(int operand_index)
BaselineCompiler(LocalIsolate *local_isolate, Handle< SharedFunctionInfo > shared_function_info, Handle< BytecodeArray > bytecode)
void PrologueHandleOptimizationState(Register feedback_vector)
void SelectBooleanConstant(Register output, std::function< void(Label *, Label::Distance)> jump_func)
static int EstimateInstructionSize(Tagged< BytecodeArray > bytecode)
interpreter::BytecodeArrayIterator iterator_
void StoreRegisterPair(int operand_index, Register val0, Register val1)
Label * EnsureLabel(int offset, MarkAsIndirectJumpTarget mark=MarkAsIndirectJumpTarget::kNo)
void UpdateInterruptBudgetAndJumpToLabel(int weight, Label *label, Label *skip_interrupt_label, StackCheckBehavior stack_check_behavior)
void CallRuntime(Runtime::FunctionId function, Args... args)
Tagged< Smi > IndexAsSmi(int operand_index)
void LoadConstant(Register output, int operand_index)
Tagged< Smi > Flag16AsSmi(int operand_index)
Tagged< Smi > ConstantSmi(int operand_index)
Tagged< TaggedIndex > UintAsTagged(int operand_index)
interpreter::Register RegisterOperand(int operand_index)
Handle< TrustedByteArray > ToBytecodeOffsetTable(IsolateT *isolate)
SaveAccumulatorScope(BaselineCompiler *compiler, BaselineAssembler *assembler)
base::Vector< const DirectHandle< Object > > args
Definition execution.cc:74
Label label
int32_t offset
#define INTRINSICS_LIST(V)
int pc_offset
void VLQEncodeUnsigned(Function &&process_byte, uint32_t value)
Definition vlq.h:23
RegExpCompiler * compiler_
#define DCHECK_LE(v1, v2)
Definition logging.h:490
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define DCHECK(condition)
Definition logging.h:482