v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
frame-description.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_DEOPTIMIZER_FRAME_DESCRIPTION_H_
6#define V8_DEOPTIMIZER_FRAME_DESCRIPTION_H_
7
8#include "src/base/memory.h"
11#include "src/common/simd128.h"
14
15namespace v8 {
16namespace internal {
17
18// Classes in this file describe the physical stack frame state.
19//
20// RegisterValues: stores gp and fp register values. Can be filled in either by
21// the DeoptimizationEntry builtin (which fills in the input state of the
22// optimized frame); or by the FrameWriter (fills in the output state of the
23// interpreted frame).
24//
25// - FrameDescription: contains RegisterValues and other things.
26
28 public:
29 intptr_t GetRegister(unsigned n) const {
31 return registers_[n];
32 }
33
34 Float32 GetFloatRegister(unsigned n) const;
35 Float64 GetDoubleRegister(unsigned n) const;
36
37 void SetDoubleRegister(unsigned n, Float64 value);
38
43
44 void SetRegister(unsigned n, intptr_t value) {
47 }
48
53
55 // Generated code writes directly into the following array, make sure the
56 // element size matches what the machine instructions expect.
57 static_assert(sizeof(Simd128) == kSimd128Size, "size mismatch");
58
59#if defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_RISCV32)
60 Float64 double_registers_[DoubleRegister::kNumRegisters];
62#else
64#endif
65};
66
68 public:
69 static FrameDescription* Create(uint32_t frame_size, int parameter_count,
70 Isolate* isolate) {
71 return new (frame_size)
72 FrameDescription(frame_size, parameter_count, isolate);
73 }
74
75 void operator delete(void* description) { base::Free(description); }
76
77 uint32_t GetFrameSize() const {
79 DCHECK(static_cast<uint32_t>(frame_size_) == frame_size_);
80 return static_cast<uint32_t>(frame_size_);
81 }
82
83 intptr_t GetFrameSlot(unsigned offset) {
85 }
86
87 unsigned GetLastArgumentSlotOffset(bool pad_arguments = true) {
88 int parameter_slots = parameter_count();
89 if (pad_arguments) {
90 parameter_slots = AddArgumentPaddingSlots(parameter_slots);
91 }
92 return GetFrameSize() - parameter_slots * kSystemPointerSize;
93 }
94
96 // We should not pad arguments in the bottom frame, since this
97 // already contains a padding if necessary and it might contain
98 // extra arguments (actual argument count > parameter count).
99 const bool pad_arguments_bottom_frame = false;
100 int fp_offset = GetLastArgumentSlotOffset(pad_arguments_bottom_frame) -
102 return reinterpret_cast<Address>(GetFrameSlotPointer(fp_offset));
103 }
104
106
107 void SetFrameSlot(unsigned offset, intptr_t value) {
109 }
110
111 // Same as SetFrameSlot but only writes 32 bits. This is needed as liftoff
112 // has 32 bit frame slots.
113 void SetLiftoffFrameSlot32(unsigned offset, int32_t value) {
115 reinterpret_cast<char*>(GetFrameSlotPointer(offset)), value);
116 }
117
118 // Same as SetFrameSlot but also supports the offset to be unaligned (4 Byte
119 // aligned) as liftoff doesn't align frame slots if they aren't references.
120 void SetLiftoffFrameSlot64(unsigned offset, int64_t value) {
122 reinterpret_cast<char*>(GetFrameSlotPointer(offset)), value);
123 }
124
125 void SetLiftoffFrameSlotPointer(unsigned offset, intptr_t value) {
126 if constexpr (Is64()) {
128 } else {
130 }
131 }
132
133 void SetCallerPc(unsigned offset, intptr_t value);
134
135 void SetCallerFp(unsigned offset, intptr_t value);
136
137 void SetCallerConstantPool(unsigned offset, intptr_t value);
138
139 intptr_t GetRegister(unsigned n) const {
141 }
142
143 Float64 GetDoubleRegister(unsigned n) const {
145 }
146
147 void SetRegister(unsigned n, intptr_t value) {
149 }
150
151 void SetDoubleRegister(unsigned n, Float64 value) {
153 }
154
155 void SetSimd128Register(unsigned n, Simd128 value) {
157 }
158
159 intptr_t GetTop() const { return top_; }
160 void SetTop(intptr_t top) { top_ = top; }
161
162 intptr_t GetPc() const { return pc_; }
163 void SetPc(intptr_t pc);
164
165 intptr_t GetFp() const { return fp_; }
166 void SetFp(intptr_t frame_pointer) { fp_ = frame_pointer; }
167
168 intptr_t GetConstantPool() const { return constant_pool_; }
172
173 bool HasCallerPc() const { return caller_pc_ != 0; }
174 intptr_t GetCallerPc() const { return caller_pc_; }
175
176 void SetContinuation(intptr_t pc) { continuation_ = pc; }
177 intptr_t GetContinuation() const { return continuation_; }
178
179 // Argument count, including receiver.
181
182 static int registers_offset() {
184 }
185
186#if defined(V8_TARGET_ARCH_RISCV64) || defined(V8_TARGET_ARCH_RISCV32)
187 static constexpr int double_registers_offset() {
188 return offsetof(FrameDescription, register_values_.double_registers_);
189 }
190#endif
191
192 static constexpr int simd128_registers_offset() {
194 }
195
196 static int frame_size_offset() {
197 return offsetof(FrameDescription, frame_size_);
198 }
199
200 static int pc_offset() { return offsetof(FrameDescription, pc_); }
201
202 static int continuation_offset() {
203 return offsetof(FrameDescription, continuation_);
204 }
205
206 static int frame_content_offset() {
207 return offsetof(FrameDescription, frame_content_);
208 }
209
210 private:
211 FrameDescription(uint32_t frame_size, int parameter_count, Isolate* isolate)
212 : frame_size_(frame_size),
218 isolate_(isolate) {
219 USE(isolate_);
220 // Zap all the registers.
221 for (int r = 0; r < Register::kNumRegisters; r++) {
222 // TODO(jbramley): It isn't safe to use kZapUint32 here. If the register
223 // isn't used before the next safepoint, the GC will try to scan it as a
224 // tagged value. kZapUint32 looks like a valid tagged pointer, but it
225 // isn't.
226#if defined(V8_OS_WIN) && defined(V8_TARGET_ARCH_ARM64)
227 // x18 is reserved as platform register on Windows arm64 platform
228 const int kPlatformRegister = 18;
229 if (r != kPlatformRegister) {
231 }
232#else
234#endif
235 }
236
237 // Zap all the slots.
238 for (unsigned o = 0; o < frame_size; o += kSystemPointerSize) {
240 }
241 }
242
243 void* operator new(size_t size, uint32_t frame_size) {
244 // Subtracts kSystemPointerSize, as the member frame_content_ already
245 // supplies the first element of the area to store the frame.
246 return base::Malloc(size + frame_size - kSystemPointerSize);
247 }
248
249 static const uint32_t kZapUint32 = 0xbeeddead;
250
251 // Frame_size_ must hold a uint32_t value. It is only a uintptr_t to
252 // keep the variable-size array frame_content_ of type intptr_t at
253 // the end of the structure aligned.
254 uintptr_t frame_size_; // Number of bytes.
257 intptr_t top_;
258 intptr_t pc_;
259 intptr_t fp_;
261 intptr_t caller_pc_ = 0;
262
264
265 // Continuation is the PC where the execution continues after
266 // deoptimizing.
268
269 // This must be at the end of the object as the object is allocated larger
270 // than its definition indicates to extend this array.
271 intptr_t frame_content_[1];
272
273 intptr_t* GetFrameSlotPointer(unsigned offset) {
275 return reinterpret_cast<intptr_t*>(reinterpret_cast<Address>(this) +
277 }
278};
279
280} // namespace internal
281} // namespace v8
282
283#endif // V8_DEOPTIMIZER_FRAME_DESCRIPTION_H_
ThreadLocalTop * top
static constexpr int simd128_registers_offset()
unsigned GetLastArgumentSlotOffset(bool pad_arguments=true)
void SetLiftoffFrameSlotPointer(unsigned offset, intptr_t value)
void SetDoubleRegister(unsigned n, Float64 value)
void SetFp(intptr_t frame_pointer)
void SetCallerFp(unsigned offset, intptr_t value)
void SetCallerConstantPool(unsigned offset, intptr_t value)
void SetLiftoffFrameSlot32(unsigned offset, int32_t value)
FrameDescription(uint32_t frame_size, int parameter_count, Isolate *isolate)
intptr_t * GetFrameSlotPointer(unsigned offset)
void SetConstantPool(intptr_t constant_pool)
Float64 GetDoubleRegister(unsigned n) const
static FrameDescription * Create(uint32_t frame_size, int parameter_count, Isolate *isolate)
intptr_t GetFrameSlot(unsigned offset)
void SetRegister(unsigned n, intptr_t value)
void SetLiftoffFrameSlot64(unsigned offset, int64_t value)
intptr_t GetRegister(unsigned n) const
void SetCallerPc(unsigned offset, intptr_t value)
void SetSimd128Register(unsigned n, Simd128 value)
void SetFrameSlot(unsigned offset, intptr_t value)
void SetRegister(unsigned n, intptr_t value)
void SetDoubleRegister(unsigned n, Float64 value)
Float64 GetDoubleRegister(unsigned n) const
intptr_t registers_[Register::kNumRegisters]
Simd128 GetSimd128Register(unsigned n) const
Float32 GetFloatRegister(unsigned n) const
Simd128 simd128_registers_[Simd128Register::kNumRegisters]
void SetSimd128Register(unsigned n, Simd128 value)
intptr_t GetRegister(unsigned n) const
int32_t offset
int n
Definition mul-fft.cc:296
int r
Definition mul-fft.cc:298
static void WriteUnalignedValue(Address p, V value)
Definition memory.h:41
void * Malloc(size_t size)
Definition memory.h:36
void Free(void *memory)
Definition memory.h:63
WordWithBits< 128 > Simd128
Definition index.h:236
constexpr int kSimd128Size
Definition globals.h:706
constexpr int AddArgumentPaddingSlots(int argument_count)
Definition register.h:14
constexpr int kSystemPointerSize
Definition globals.h:410
return value
Definition map-inl.h:893
constexpr bool Is64()
#define DCHECK(condition)
Definition logging.h:482
#define USE(...)
Definition macros.h:293
#define arraysize(array)
Definition macros.h:67
#define V8_ASSUME
Definition v8config.h:533