v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
baseline-assembler.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_ASSEMBLER_H_
6#define V8_BASELINE_BASELINE_ASSEMBLER_H_
7
11
12namespace v8 {
13namespace internal {
14namespace baseline {
15
17 public:
19
21 inline static MemOperand RegisterFrameOperand(
22 interpreter::Register interpreter_register);
23 inline void RegisterFrameAddress(interpreter::Register interpreter_register,
24 Register rscratch);
29
30 inline void GetCode(LocalIsolate* isolate, CodeDesc* desc);
31 inline int pc_offset() const;
32 inline void CodeEntry() const;
33 inline void ExceptionHandler() const;
34 V8_INLINE void RecordComment(const char* string);
35 inline void Trap();
36 inline void DebugBreak();
37
38 template <typename Field>
39 inline void DecodeField(Register reg);
40
41 inline void Bind(Label* label);
42 // Marks the current position as a valid jump target on CFI enabled
43 // architectures.
44 inline void JumpTarget();
45 inline void Jump(Label* target, Label::Distance distance = Label::kFar);
46 inline void JumpIfRoot(Register value, RootIndex index, Label* target,
47 Label::Distance distance = Label::kFar);
48 inline void JumpIfNotRoot(Register value, RootIndex index, Label* target,
49 Label ::Distance distance = Label::kFar);
50 inline void JumpIfSmi(Register value, Label* target,
51 Label::Distance distance = Label::kFar);
52 inline void JumpIfNotSmi(Register value, Label* target,
53 Label::Distance distance = Label::kFar);
54
55 inline void TestAndBranch(Register value, int mask, Condition cc,
56 Label* target,
57 Label::Distance distance = Label::kFar);
58
59 inline void JumpIf(Condition cc, Register lhs, const Operand& rhs,
60 Label* target, Label::Distance distance = Label::kFar);
61#if V8_STATIC_ROOTS_BOOL
62 // Fast JS_RECEIVER test which assumes to receive either a primitive object or
63 // a js receiver.
64 inline void JumpIfJSAnyIsPrimitive(Register heap_object, Label* target,
65 Label::Distance distance = Label::kFar);
66#endif
67 inline void JumpIfObjectType(Condition cc, Register object,
68 InstanceType instance_type, Register map,
69 Label* target,
70 Label::Distance distance = Label::kFar);
71 // Might not load the map into the scratch register.
72 inline void JumpIfObjectTypeFast(Condition cc, Register object,
73 InstanceType instance_type, Label* target,
74 Label::Distance distance = Label::kFar);
75 inline void JumpIfInstanceType(Condition cc, Register map,
76 InstanceType instance_type, Label* target,
77 Label::Distance distance = Label::kFar);
78 inline void JumpIfPointer(Condition cc, Register value, MemOperand operand,
79 Label* target,
80 Label::Distance distance = Label::kFar);
82 inline void JumpIfSmi(Condition cc, Register value, Tagged<Smi> smi,
83 Label* target, Label::Distance distance = Label::kFar);
84 inline void JumpIfSmi(Condition cc, Register lhs, Register rhs, Label* target,
85 Label::Distance distance = Label::kFar);
86 inline void JumpIfImmediate(Condition cc, Register left, int right,
87 Label* target,
88 Label::Distance distance = Label::kFar);
89 inline void JumpIfTagged(Condition cc, Register value, MemOperand operand,
90 Label* target,
91 Label::Distance distance = Label::kFar);
92 inline void JumpIfTagged(Condition cc, MemOperand operand, Register value,
93 Label* target,
94 Label::Distance distance = Label::kFar);
95 inline void JumpIfByte(Condition cc, Register value, int32_t byte,
96 Label* target, Label::Distance distance = Label::kFar);
97
98 inline void LoadMap(Register output, Register value);
99 inline void LoadRoot(Register output, RootIndex index);
100 inline void LoadNativeContextSlot(Register output, uint32_t index);
101
102 inline void Move(Register output, Register source);
103 inline void Move(Register output, MemOperand operand);
104 inline void Move(Register output, Tagged<Smi> value);
105 inline void Move(Register output, Tagged<TaggedIndex> value);
106 inline void Move(Register output, interpreter::Register source);
107 inline void Move(interpreter::Register output, Register source);
108 inline void Move(Register output, RootIndex source);
109 inline void Move(MemOperand output, Register source);
110 inline void Move(Register output, ExternalReference reference);
111 inline void Move(Register output, Handle<HeapObject> value);
112 inline void Move(Register output, int32_t immediate);
113 inline void MoveMaybeSmi(Register output, Register source);
114 inline void MoveSmi(Register output, Register source);
115
116 // Push the given values, in the given order. If the stack needs alignment
117 // (looking at you Arm64), the stack is padded from the front (i.e. before the
118 // first value is pushed).
119 //
120 // This supports pushing a RegisterList as the last value -- the list is
121 // iterated and each interpreter Register is pushed.
122 //
123 // The total number of values pushed is returned. Note that this might be
124 // different from sizeof(T...), specifically if there was a RegisterList.
125 template <typename... T>
126 inline int Push(T... vals);
127
128 // Like Push(vals...), but pushes in reverse order, to support our reversed
129 // order argument JS calling convention. Doesn't return the number of
130 // arguments pushed though.
131 //
132 // Note that padding is still inserted before the first pushed value (i.e. the
133 // last value).
134 template <typename... T>
135 inline void PushReverse(T... vals);
136
137 // Pop values off the stack into the given registers.
138 //
139 // Note that this inserts into registers in the given order, i.e. in reverse
140 // order if the registers were pushed. This means that to spill registers,
141 // push and pop have to be in reverse order, e.g.
142 //
143 // Push(r1, r2, ..., rN);
144 // ClobberRegisters();
145 // Pop(rN, ..., r2, r1);
146 //
147 // On stack-alignment architectures, any padding is popped off after the last
148 // register. This the behaviour of Push, which means that the above code still
149 // works even if the number of registers doesn't match stack alignment.
150 template <typename... T>
151 inline void Pop(T... registers);
152
153 inline void CallBuiltin(Builtin builtin);
154 inline void TailCallBuiltin(Builtin builtin);
155 inline void CallRuntime(Runtime::FunctionId function, int nargs);
156
157 inline void LoadTaggedField(Register output, Register source, int offset);
158 inline void LoadTaggedSignedField(Register output, Register source,
159 int offset);
160 inline void LoadTaggedSignedFieldAndUntag(Register output, Register source,
161 int offset);
162 inline void LoadWord16FieldZeroExtend(Register output, Register source,
163 int offset);
164 inline void LoadWord8Field(Register output, Register source, int offset);
165 inline void StoreTaggedSignedField(Register target, int offset,
166 Tagged<Smi> value);
167 inline void StoreTaggedFieldWithWriteBarrier(Register target, int offset,
168 Register value);
169 inline void StoreTaggedFieldNoWriteBarrier(Register target, int offset,
170 Register value);
171 inline void LoadFixedArrayElement(Register output, Register array,
172 int32_t index);
173 inline void LoadPrototype(Register prototype, Register object);
174
175// Loads compressed pointer or loads from compressed pointer. This is because
176// X64 supports complex addressing mode, pointer decompression can be done by
177// [%compressed_base + %r1 + K].
178#if V8_TARGET_ARCH_X64
179 inline void LoadTaggedField(TaggedRegister output, Register source,
180 int offset);
181 inline void LoadTaggedField(TaggedRegister output, TaggedRegister source,
182 int offset);
183 inline void LoadTaggedField(Register output, TaggedRegister source,
184 int offset);
185 inline void LoadFixedArrayElement(Register output, TaggedRegister array,
186 int32_t index);
187 inline void LoadFixedArrayElement(TaggedRegister output, TaggedRegister array,
188 int32_t index);
189#endif
190
191 // Falls through and sets scratch_and_result to 0 on failure, jumps to
192 // on_result on success.
193 inline void TryLoadOptimizedOsrCode(Register scratch_and_result,
194 Register feedback_vector,
195 FeedbackSlot slot, Label* on_result,
196 Label::Distance distance);
197
198 // Loads the feedback cell from the function, and sets flags on add so that
199 // we can compare afterward.
201 int32_t weight, Label* skip_interrupt_label);
203 Register weight, Label* skip_interrupt_label);
204
205 // By default, the output register may be compressed on 64-bit architectures
206 // that support pointer compression.
207 enum class CompressionMode {
208 kDefault,
210 };
211 inline void LdaContextSlot(
212 Register context, uint32_t index, uint32_t depth,
213 CompressionMode compression_mode = CompressionMode::kDefault);
214 inline void StaContextSlot(Register context, Register value, uint32_t index,
215 uint32_t depth);
216 inline void LdaModuleVariable(Register context, int cell_index,
217 uint32_t depth);
218 inline void StaModuleVariable(Register context, Register value,
219 int cell_index, uint32_t depth);
220
221 inline void IncrementSmi(MemOperand lhs);
222 inline void SmiUntag(Register value);
223 inline void SmiUntag(Register output, Register value);
224
225 inline void Word32And(Register output, Register lhs, int rhs);
226
227 inline void Switch(Register reg, int case_value_base, Label** labels,
228 int num_labels);
229
230 // Register operands.
231 inline void LoadRegister(Register output, interpreter::Register source);
232 inline void StoreRegister(interpreter::Register output, Register value);
233
234 // Frame values
235 inline void LoadFunction(Register output);
236 inline void LoadContext(Register output);
237 inline void StoreContext(Register context);
238
239 inline void LoadFeedbackCell(Register output);
240 inline void AssertFeedbackCell(Register object);
241
242#ifdef V8_ENABLE_CET_SHADOW_STACK
243 // If CET shadow stack is enabled, reserves a few bytes as NOP that can be
244 // patched later.
245 inline void MaybeEmitPlaceHolderForDeopt();
246#endif // V8_ENABLE_CET_SHADOW_STACK
247
248 inline static void EmitReturn(MacroAssembler* masm);
249
250 MacroAssembler* masm() { return masm_; }
251
252 private:
255};
256
258 public:
259 inline explicit EnsureAccumulatorPreservedScope(BaselineAssembler* assembler);
260
262
263 private:
265
267#ifdef V8_CODE_COMMENTS
268 Assembler::CodeComment comment_;
269#endif
270};
271
272} // namespace baseline
273} // namespace internal
274} // namespace v8
275
276#endif // V8_BASELINE_BASELINE_ASSEMBLER_H_
void JumpIfByte(Condition cc, Register value, int32_t byte, Label *target, Label::Distance distance=Label::kFar)
V8_INLINE void RecordComment(const char *string)
void CallRuntime(Runtime::FunctionId function, int nargs)
void JumpIf(Condition cc, Register lhs, const Operand &rhs, Label *target, Label::Distance distance=Label::kFar)
void LoadFixedArrayElement(Register output, Register array, int32_t index)
static MemOperand RegisterFrameOperand(interpreter::Register interpreter_register)
Condition CheckSmi(Register value)
void JumpIfNotRoot(Register value, RootIndex index, Label *target, Label ::Distance distance=Label::kFar)
void JumpIfPointer(Condition cc, Register value, MemOperand operand, Label *target, Label::Distance distance=Label::kFar)
void Move(Register output, Register source)
void MoveSmi(Register output, Register source)
void TestAndBranch(Register value, int mask, Condition cc, Label *target, Label::Distance distance=Label::kFar)
void LoadWord8Field(Register output, Register source, int offset)
void LoadWord16FieldZeroExtend(Register output, Register source, int offset)
void LoadMap(Register output, Register value)
void AddToInterruptBudgetAndJumpIfNotExceeded(int32_t weight, Label *skip_interrupt_label)
void LdaContextSlot(Register context, uint32_t index, uint32_t depth, CompressionMode compression_mode=CompressionMode::kDefault)
void LoadRegister(Register output, interpreter::Register source)
void LoadTaggedField(Register output, Register source, int offset)
void StoreRegister(interpreter::Register output, Register value)
void Jump(Label *target, Label::Distance distance=Label::kFar)
void LoadNativeContextSlot(Register output, uint32_t index)
void Switch(Register reg, int case_value_base, Label **labels, int num_labels)
void StaModuleVariable(Register context, Register value, int cell_index, uint32_t depth)
void LoadPrototype(Register prototype, Register object)
void JumpIfObjectTypeFast(Condition cc, Register object, InstanceType instance_type, Label *target, Label::Distance distance=Label::kFar)
void MoveMaybeSmi(Register output, Register source)
void StoreTaggedFieldNoWriteBarrier(Register target, int offset, Register value)
void TryLoadOptimizedOsrCode(Register scratch_and_result, Register feedback_vector, FeedbackSlot slot, Label *on_result, Label::Distance distance)
void LoadTaggedSignedFieldAndUntag(Register output, Register source, int offset)
void GetCode(LocalIsolate *isolate, CodeDesc *desc)
void JumpIfInstanceType(Condition cc, Register map, InstanceType instance_type, Label *target, Label::Distance distance=Label::kFar)
void JumpIfImmediate(Condition cc, Register left, int right, Label *target, Label::Distance distance=Label::kFar)
void LoadRoot(Register output, RootIndex index)
void JumpIfRoot(Register value, RootIndex index, Label *target, Label::Distance distance=Label::kFar)
void JumpIfSmi(Register value, Label *target, Label::Distance distance=Label::kFar)
void JumpIfNotSmi(Register value, Label *target, Label::Distance distance=Label::kFar)
void JumpIfObjectType(Condition cc, Register object, InstanceType instance_type, Register map, Label *target, Label::Distance distance=Label::kFar)
void LdaModuleVariable(Register context, int cell_index, uint32_t depth)
void StoreTaggedFieldWithWriteBarrier(Register target, int offset, Register value)
void LoadTaggedSignedField(Register output, Register source, int offset)
void RegisterFrameAddress(interpreter::Register interpreter_register, Register rscratch)
void Word32And(Register output, Register lhs, int rhs)
void StoreTaggedSignedField(Register target, int offset, Tagged< Smi > value)
void StaContextSlot(Register context, Register value, uint32_t index, uint32_t depth)
void JumpIfTagged(Condition cc, Register value, MemOperand operand, Label *target, Label::Distance distance=Label::kFar)
Label label
int32_t offset
LiftoffRegister reg
uint32_t const mask
RegListBase< RegisterT > registers
#define V8_INLINE
Definition v8config.h:500