Line data Source code
1 : // Copyright 2017 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_FRAME_CONSTANTS_H_
6 : #define V8_FRAME_CONSTANTS_H_
7 :
8 : #include "src/flags.h"
9 : #include "src/globals.h"
10 :
11 : namespace v8 {
12 : namespace internal {
13 :
14 : // Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
15 : // two slots.
16 : //
17 : // Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
18 : // the callee's saved return address and 1 corresponding to the saved frame
19 : // pointer. Some frames have additional information stored in the fixed header,
20 : // for example JSFunctions store the function context and marker in the fixed
21 : // header, with slot index 2 corresponding to the current function context and 3
22 : // corresponding to the frame marker/JSFunction.
23 : //
24 : // slot JS frame
25 : // +-----------------+--------------------------------
26 : // -n-1 | parameter 0 | ^
27 : // |- - - - - - - - -| |
28 : // -n | | Caller
29 : // ... | ... | frame slots
30 : // -2 | parameter n-1 | (slot < 0)
31 : // |- - - - - - - - -| |
32 : // -1 | parameter n | v
33 : // -----+-----------------+--------------------------------
34 : // 0 | return addr | ^ ^
35 : // |- - - - - - - - -| | |
36 : // 1 | saved frame ptr | Fixed |
37 : // |- - - - - - - - -| Header <-- frame ptr |
38 : // 2 | [Constant Pool] | | |
39 : // |- - - - - - - - -| | |
40 : // 2+cp |Context/Frm. Type| v if a constant pool |
41 : // |-----------------+---- is used, cp = 1, |
42 : // 3+cp | | ^ otherwise, cp = 0 |
43 : // |- - - - - - - - -| | |
44 : // 4+cp | | | Callee
45 : // |- - - - - - - - -| | frame slots
46 : // ... | | Frame slots (slot >= 0)
47 : // |- - - - - - - - -| | |
48 : // | | v |
49 : // -----+-----------------+----- <-- stack ptr -------------
50 : //
51 : class CommonFrameConstants : public AllStatic {
52 : public:
53 : static constexpr int kCallerFPOffset = 0 * kSystemPointerSize;
54 : static constexpr int kCallerPCOffset = kCallerFPOffset + 1 * kFPOnStackSize;
55 : static constexpr int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
56 :
57 : // Fixed part of the frame consists of return address, caller fp,
58 : // constant pool (if FLAG_enable_embedded_constant_pool), context, and
59 : // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
60 : // is the last object pointer.
61 : static constexpr int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
62 : static constexpr int kFixedSlotCountAboveFp =
63 : kFixedFrameSizeAboveFp / kSystemPointerSize;
64 : static constexpr int kCPSlotSize =
65 : FLAG_enable_embedded_constant_pool ? kSystemPointerSize : 0;
66 : static constexpr int kCPSlotCount = kCPSlotSize / kSystemPointerSize;
67 : static constexpr int kConstantPoolOffset =
68 : kCPSlotSize ? -1 * kSystemPointerSize : 0;
69 : static constexpr int kContextOrFrameTypeSize = kSystemPointerSize;
70 : static constexpr int kContextOrFrameTypeOffset =
71 : -(kCPSlotSize + kContextOrFrameTypeSize);
72 : };
73 :
74 : // StandardFrames are used for interpreted and optimized JavaScript
75 : // frames. They always have a context below the saved fp/constant
76 : // pool and below that the JSFunction of the executing function.
77 : //
78 : // slot JS frame
79 : // +-----------------+--------------------------------
80 : // -n-1 | parameter 0 | ^
81 : // |- - - - - - - - -| |
82 : // -n | | Caller
83 : // ... | ... | frame slots
84 : // -2 | parameter n-1 | (slot < 0)
85 : // |- - - - - - - - -| |
86 : // -1 | parameter n | v
87 : // -----+-----------------+--------------------------------
88 : // 0 | return addr | ^ ^
89 : // |- - - - - - - - -| | |
90 : // 1 | saved frame ptr | Fixed |
91 : // |- - - - - - - - -| Header <-- frame ptr |
92 : // 2 | [Constant Pool] | | |
93 : // |- - - - - - - - -| | |
94 : // 2+cp | Context | | if a constant pool |
95 : // |- - - - - - - - -| | is used, cp = 1, |
96 : // 3+cp | JSFunction | v otherwise, cp = 0 |
97 : // +-----------------+---- |
98 : // 4+cp | | ^ Callee
99 : // |- - - - - - - - -| | frame slots
100 : // ... | | Frame slots (slot >= 0)
101 : // |- - - - - - - - -| | |
102 : // | | v |
103 : // -----+-----------------+----- <-- stack ptr -------------
104 : //
105 : class StandardFrameConstants : public CommonFrameConstants {
106 : public:
107 : static constexpr int kFixedFrameSizeFromFp =
108 : 2 * kSystemPointerSize + kCPSlotSize;
109 : static constexpr int kFixedFrameSize =
110 : kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
111 : static constexpr int kFixedSlotCountFromFp =
112 : kFixedFrameSizeFromFp / kSystemPointerSize;
113 : static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize;
114 : static constexpr int kContextOffset = kContextOrFrameTypeOffset;
115 : static constexpr int kFunctionOffset = -2 * kSystemPointerSize - kCPSlotSize;
116 : static constexpr int kExpressionsOffset =
117 : -3 * kSystemPointerSize - kCPSlotSize;
118 : static constexpr int kLastObjectOffset = kContextOffset;
119 : };
120 :
121 : // OptimizedBuiltinFrameConstants are used for TF-generated builtins. They
122 : // always have a context below the saved fp/constant pool and below that the
123 : // JSFunction of the executing function and below that an integer (not a Smi)
124 : // containing the number of arguments passed to the builtin.
125 : //
126 : // slot JS frame
127 : // +-----------------+--------------------------------
128 : // -n-1 | parameter 0 | ^
129 : // |- - - - - - - - -| |
130 : // -n | | Caller
131 : // ... | ... | frame slots
132 : // -2 | parameter n-1 | (slot < 0)
133 : // |- - - - - - - - -| |
134 : // -1 | parameter n | v
135 : // -----+-----------------+--------------------------------
136 : // 0 | return addr | ^ ^
137 : // |- - - - - - - - -| | |
138 : // 1 | saved frame ptr | Fixed |
139 : // |- - - - - - - - -| Header <-- frame ptr |
140 : // 2 | [Constant Pool] | | |
141 : // |- - - - - - - - -| | |
142 : // 2+cp | Context | | if a constant pool |
143 : // |- - - - - - - - -| | is used, cp = 1, |
144 : // 3+cp | JSFunction | | otherwise, cp = 0 |
145 : // |- - - - - - - - -| | |
146 : // 4+cp | argc | v |
147 : // +-----------------+---- |
148 : // 5+cp | | ^ Callee
149 : // |- - - - - - - - -| | frame slots
150 : // ... | | Frame slots (slot >= 0)
151 : // |- - - - - - - - -| | |
152 : // | | v |
153 : // -----+-----------------+----- <-- stack ptr -------------
154 : //
155 : class OptimizedBuiltinFrameConstants : public StandardFrameConstants {
156 : public:
157 : static constexpr int kArgCSize = kSystemPointerSize;
158 : static constexpr int kArgCOffset = -3 * kSystemPointerSize - kCPSlotSize;
159 : static constexpr int kFixedFrameSize = kFixedFrameSizeAboveFp - kArgCOffset;
160 : static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize;
161 : };
162 :
163 : // TypedFrames have a SMI type maker value below the saved FP/constant pool to
164 : // distinguish them from StandardFrames, which have a context in that position
165 : // instead.
166 : //
167 : // slot JS frame
168 : // +-----------------+--------------------------------
169 : // -n-1 | parameter 0 | ^
170 : // |- - - - - - - - -| |
171 : // -n | | Caller
172 : // ... | ... | frame slots
173 : // -2 | parameter n-1 | (slot < 0)
174 : // |- - - - - - - - -| |
175 : // -1 | parameter n | v
176 : // -----+-----------------+--------------------------------
177 : // 0 | return addr | ^ ^
178 : // |- - - - - - - - -| | |
179 : // 1 | saved frame ptr | Fixed |
180 : // |- - - - - - - - -| Header <-- frame ptr |
181 : // 2 | [Constant Pool] | | |
182 : // |- - - - - - - - -| | |
183 : // 2+cp |Frame Type Marker| v if a constant pool |
184 : // |-----------------+---- is used, cp = 1, |
185 : // 3+cp | | ^ otherwise, cp = 0 |
186 : // |- - - - - - - - -| | |
187 : // 4+cp | | | Callee
188 : // |- - - - - - - - -| | frame slots
189 : // ... | | Frame slots (slot >= 0)
190 : // |- - - - - - - - -| | |
191 : // | | v |
192 : // -----+-----------------+----- <-- stack ptr -------------
193 : //
194 : class TypedFrameConstants : public CommonFrameConstants {
195 : public:
196 : static constexpr int kFrameTypeSize = kContextOrFrameTypeSize;
197 : static constexpr int kFrameTypeOffset = kContextOrFrameTypeOffset;
198 : static constexpr int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
199 : static constexpr int kFixedSlotCountFromFp =
200 : kFixedFrameSizeFromFp / kSystemPointerSize;
201 : static constexpr int kFixedFrameSize =
202 : StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
203 : static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize;
204 : static constexpr int kFirstPushedFrameValueOffset =
205 : -StandardFrameConstants::kCPSlotSize - kFrameTypeSize -
206 : kSystemPointerSize;
207 : };
208 :
209 : #define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
210 : (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kSystemPointerSize)
211 : #define TYPED_FRAME_SIZE(count) \
212 : (TypedFrameConstants::kFixedFrameSize + (count)*kSystemPointerSize)
213 : #define TYPED_FRAME_SIZE_FROM_SP(count) \
214 : (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kSystemPointerSize)
215 : #define DEFINE_TYPED_FRAME_SIZES(count) \
216 : static constexpr int kFixedFrameSize = TYPED_FRAME_SIZE(count); \
217 : static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize; \
218 : static constexpr int kFixedFrameSizeFromFp = \
219 : TYPED_FRAME_SIZE_FROM_SP(count); \
220 : static constexpr int kFixedSlotCountFromFp = \
221 : kFixedFrameSizeFromFp / kSystemPointerSize
222 :
223 : class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
224 : public:
225 : // FP-relative.
226 : static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
227 : static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
228 : static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
229 : DEFINE_TYPED_FRAME_SIZES(3);
230 : };
231 :
232 : class BuiltinFrameConstants : public TypedFrameConstants {
233 : public:
234 : // FP-relative.
235 : static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
236 : static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
237 : DEFINE_TYPED_FRAME_SIZES(2);
238 : };
239 :
240 : class ConstructFrameConstants : public TypedFrameConstants {
241 : public:
242 : // FP-relative.
243 : static constexpr int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
244 : static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
245 : static constexpr int kConstructorOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
246 : static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
247 : static constexpr int kNewTargetOrImplicitReceiverOffset =
248 : TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
249 : DEFINE_TYPED_FRAME_SIZES(5);
250 : };
251 :
252 : class WasmCompiledFrameConstants : public TypedFrameConstants {
253 : public:
254 : // FP-relative.
255 : static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
256 : DEFINE_TYPED_FRAME_SIZES(1);
257 : };
258 :
259 : class BuiltinContinuationFrameConstants : public TypedFrameConstants {
260 : public:
261 : // FP-relative.
262 : static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
263 : static constexpr int kFrameSPtoFPDeltaAtDeoptimize =
264 : TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
265 : static constexpr int kBuiltinContextOffset =
266 : TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
267 : static constexpr int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
268 :
269 : // The argument count is in the first allocatable register, stored below the
270 : // fixed part of the frame and therefore is not part of the fixed frame size.
271 : static constexpr int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
272 : DEFINE_TYPED_FRAME_SIZES(4);
273 :
274 : // Returns the number of padding stack slots needed when we have
275 : // 'register_count' register slots.
276 : // This is needed on some architectures to ensure the stack pointer is
277 : // aligned.
278 : static int PaddingSlotCount(int register_count);
279 : };
280 :
281 : // Behaves like an exit frame but with target and new target args.
282 : class BuiltinExitFrameConstants : public CommonFrameConstants {
283 : public:
284 : static constexpr int kNewTargetOffset =
285 : kCallerPCOffset + 1 * kSystemPointerSize;
286 : static constexpr int kTargetOffset =
287 : kNewTargetOffset + 1 * kSystemPointerSize;
288 : static constexpr int kArgcOffset = kTargetOffset + 1 * kSystemPointerSize;
289 : static constexpr int kPaddingOffset = kArgcOffset + 1 * kSystemPointerSize;
290 : static constexpr int kFirstArgumentOffset =
291 : kPaddingOffset + 1 * kSystemPointerSize;
292 : static constexpr int kNumExtraArgsWithReceiver = 5;
293 : };
294 :
295 : class InterpreterFrameConstants : public AllStatic {
296 : public:
297 : // Fixed frame includes bytecode array and bytecode offset.
298 : static constexpr int kFixedFrameSize =
299 : StandardFrameConstants::kFixedFrameSize + 2 * kSystemPointerSize;
300 : static constexpr int kFixedFrameSizeFromFp =
301 : StandardFrameConstants::kFixedFrameSizeFromFp + 2 * kSystemPointerSize;
302 :
303 : // FP-relative.
304 : static constexpr int kLastParamFromFp =
305 : StandardFrameConstants::kCallerSPOffset;
306 : static constexpr int kCallerPCOffsetFromFp =
307 : StandardFrameConstants::kCallerPCOffset;
308 : static constexpr int kBytecodeArrayFromFp =
309 : -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kSystemPointerSize;
310 : static constexpr int kBytecodeOffsetFromFp =
311 : -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kSystemPointerSize;
312 : static constexpr int kRegisterFileFromFp =
313 : -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kSystemPointerSize;
314 :
315 : static constexpr int kExpressionsOffset = kRegisterFileFromFp;
316 :
317 : // Number of fixed slots in addition to a {StandardFrame}.
318 : static constexpr int kExtraSlotCount =
319 : InterpreterFrameConstants::kFixedFrameSize / kSystemPointerSize -
320 : StandardFrameConstants::kFixedFrameSize / kSystemPointerSize;
321 :
322 : // Expression index for {StandardFrame::GetExpressionAddress}.
323 : static constexpr int kBytecodeArrayExpressionIndex = -2;
324 : static constexpr int kBytecodeOffsetExpressionIndex = -1;
325 : static constexpr int kRegisterFileExpressionIndex = 0;
326 :
327 : // Returns the number of stack slots needed for 'register_count' registers.
328 : // This is needed because some architectures must pad the stack frame with
329 : // additional stack slots to ensure the stack pointer is aligned.
330 : static int RegisterStackSlotCount(int register_count);
331 : };
332 :
333 : inline static int FPOffsetToFrameSlot(int frame_offset) {
334 : return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
335 : frame_offset / kSystemPointerSize;
336 : }
337 :
338 : inline static int FrameSlotToFPOffset(int slot) {
339 14373582 : return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
340 14373582 : kSystemPointerSize;
341 : }
342 :
343 : } // namespace internal
344 : } // namespace v8
345 :
346 : #if V8_TARGET_ARCH_IA32
347 : #include "src/ia32/frame-constants-ia32.h" // NOLINT
348 : #elif V8_TARGET_ARCH_X64
349 : #include "src/x64/frame-constants-x64.h" // NOLINT
350 : #elif V8_TARGET_ARCH_ARM64
351 : #include "src/arm64/frame-constants-arm64.h" // NOLINT
352 : #elif V8_TARGET_ARCH_ARM
353 : #include "src/arm/frame-constants-arm.h" // NOLINT
354 : #elif V8_TARGET_ARCH_PPC
355 : #include "src/ppc/frame-constants-ppc.h" // NOLINT
356 : #elif V8_TARGET_ARCH_MIPS
357 : #include "src/mips/frame-constants-mips.h" // NOLINT
358 : #elif V8_TARGET_ARCH_MIPS64
359 : #include "src/mips64/frame-constants-mips64.h" // NOLINT
360 : #elif V8_TARGET_ARCH_S390
361 : #include "src/s390/frame-constants-s390.h" // NOLINT
362 : #else
363 : #error Unsupported target architecture.
364 : #endif
365 :
366 : #endif // V8_FRAME_CONSTANTS_H_
|