• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 * kPointerSize;
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 / kPointerSize;
64   static constexpr int kCPSlotSize =
65       FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
66   static constexpr int kCPSlotCount = kCPSlotSize / kPointerSize;
67   static constexpr int kConstantPoolOffset =
68       kCPSlotSize ? -1 * kPointerSize : 0;
69   static constexpr int kContextOrFrameTypeSize = kPointerSize;
70   static constexpr int kContextOrFrameTypeOffset =
71       -(kCPSlotSize + kContextOrFrameTypeSize);
72 };
73 
74 // StandardFrames are used for interpreted, full-codegen and optimized
75 // JavaScript 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 = 2 * kPointerSize + kCPSlotSize;
108   static constexpr int kFixedFrameSize =
109       kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
110   static constexpr int kFixedSlotCountFromFp =
111       kFixedFrameSizeFromFp / kPointerSize;
112   static constexpr int kFixedSlotCount = kFixedFrameSize / kPointerSize;
113   static constexpr int kContextOffset = kContextOrFrameTypeOffset;
114   static constexpr int kFunctionOffset = -2 * kPointerSize - kCPSlotSize;
115   static constexpr int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
116   static constexpr int kLastObjectOffset = kContextOffset;
117 };
118 
119 // OptimizedBuiltinFrameConstants are used for TF-generated builtins. They
120 // always have a context below the saved fp/constant pool and below that the
121 // JSFunction of the executing function and below that an integer (not a Smi)
122 // containing the number of arguments passed to the builtin.
123 //
124 //  slot      JS frame
125 //       +-----------------+--------------------------------
126 //  -n-1 |   parameter 0   |                            ^
127 //       |- - - - - - - - -|                            |
128 //  -n   |                 |                          Caller
129 //  ...  |       ...       |                       frame slots
130 //  -2   |  parameter n-1  |                       (slot < 0)
131 //       |- - - - - - - - -|                            |
132 //  -1   |   parameter n   |                            v
133 //  -----+-----------------+--------------------------------
134 //   0   |   return addr   |   ^                        ^
135 //       |- - - - - - - - -|   |                        |
136 //   1   | saved frame ptr | Fixed                      |
137 //       |- - - - - - - - -| Header <-- frame ptr       |
138 //   2   | [Constant Pool] |   |                        |
139 //       |- - - - - - - - -|   |                        |
140 // 2+cp  |     Context     |   |   if a constant pool   |
141 //       |- - - - - - - - -|   |    is used, cp = 1,    |
142 // 3+cp  |    JSFunction   |   |   otherwise, cp = 0    |
143 //       |- - - - - - - - -|   |                        |
144 // 4+cp  |      argc       |   v                        |
145 //       +-----------------+----                        |
146 // 5+cp  |                 |   ^                      Callee
147 //       |- - - - - - - - -|   |                   frame slots
148 //  ...  |                 | Frame slots           (slot >= 0)
149 //       |- - - - - - - - -|   |                        |
150 //       |                 |   v                        |
151 //  -----+-----------------+----- <-- stack ptr -------------
152 //
153 class OptimizedBuiltinFrameConstants : public StandardFrameConstants {
154  public:
155   static constexpr int kArgCSize = kPointerSize;
156   static constexpr int kArgCOffset = -3 * kPointerSize - kCPSlotSize;
157   static constexpr int kFixedFrameSize = kFixedFrameSizeAboveFp - kArgCOffset;
158   static constexpr int kFixedSlotCount = kFixedFrameSize / kPointerSize;
159 };
160 
161 // TypedFrames have a SMI type maker value below the saved FP/constant pool to
162 // distinguish them from StandardFrames, which have a context in that position
163 // instead.
164 //
165 //  slot      JS frame
166 //       +-----------------+--------------------------------
167 //  -n-1 |   parameter 0   |                            ^
168 //       |- - - - - - - - -|                            |
169 //  -n   |                 |                          Caller
170 //  ...  |       ...       |                       frame slots
171 //  -2   |  parameter n-1  |                       (slot < 0)
172 //       |- - - - - - - - -|                            |
173 //  -1   |   parameter n   |                            v
174 //  -----+-----------------+--------------------------------
175 //   0   |   return addr   |   ^                        ^
176 //       |- - - - - - - - -|   |                        |
177 //   1   | saved frame ptr | Fixed                      |
178 //       |- - - - - - - - -| Header <-- frame ptr       |
179 //   2   | [Constant Pool] |   |                        |
180 //       |- - - - - - - - -|   |                        |
181 // 2+cp  |Frame Type Marker|   v   if a constant pool   |
182 //       |-----------------+----    is used, cp = 1,    |
183 // 3+cp  |                 |   ^   otherwise, cp = 0    |
184 //       |- - - - - - - - -|   |                        |
185 // 4+cp  |                 |   |                      Callee
186 //       |- - - - - - - - -|   |                   frame slots
187 //  ...  |                 | Frame slots           (slot >= 0)
188 //       |- - - - - - - - -|   |                        |
189 //       |                 |   v                        |
190 //  -----+-----------------+----- <-- stack ptr -------------
191 //
192 class TypedFrameConstants : public CommonFrameConstants {
193  public:
194   static constexpr int kFrameTypeSize = kContextOrFrameTypeSize;
195   static constexpr int kFrameTypeOffset = kContextOrFrameTypeOffset;
196   static constexpr int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
197   static constexpr int kFixedSlotCountFromFp =
198       kFixedFrameSizeFromFp / kPointerSize;
199   static constexpr int kFixedFrameSize =
200       StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
201   static constexpr int kFixedSlotCount = kFixedFrameSize / kPointerSize;
202   static constexpr int kFirstPushedFrameValueOffset =
203       -StandardFrameConstants::kCPSlotSize - kFrameTypeSize - kPointerSize;
204 };
205 
206 #define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
207   (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kPointerSize)
208 #define TYPED_FRAME_SIZE(count) \
209   (TypedFrameConstants::kFixedFrameSize + (count)*kPointerSize)
210 #define TYPED_FRAME_SIZE_FROM_SP(count) \
211   (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kPointerSize)
212 #define DEFINE_TYPED_FRAME_SIZES(count)                                  \
213   static constexpr int kFixedFrameSize = TYPED_FRAME_SIZE(count);        \
214   static constexpr int kFixedSlotCount = kFixedFrameSize / kPointerSize; \
215   static constexpr int kFixedFrameSizeFromFp =                           \
216       TYPED_FRAME_SIZE_FROM_SP(count);                                   \
217   static constexpr int kFixedSlotCountFromFp =                           \
218       kFixedFrameSizeFromFp / kPointerSize
219 
220 class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
221  public:
222   // FP-relative.
223   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
224   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
225   static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
226   DEFINE_TYPED_FRAME_SIZES(3);
227 };
228 
229 class BuiltinFrameConstants : public TypedFrameConstants {
230  public:
231   // FP-relative.
232   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
233   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
234   DEFINE_TYPED_FRAME_SIZES(2);
235 };
236 
237 class ConstructFrameConstants : public TypedFrameConstants {
238  public:
239   // FP-relative.
240   static constexpr int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
241   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
242   static constexpr int kConstructorOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
243   static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
244   static constexpr int kNewTargetOrImplicitReceiverOffset =
245       TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
246   DEFINE_TYPED_FRAME_SIZES(5);
247 };
248 
249 class WasmCompiledFrameConstants : public TypedFrameConstants {
250  public:
251   // FP-relative.
252   static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
253   DEFINE_TYPED_FRAME_SIZES(1);
254 };
255 
256 class BuiltinContinuationFrameConstants : public TypedFrameConstants {
257  public:
258   // FP-relative.
259   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
260   static constexpr int kFrameSPtoFPDeltaAtDeoptimize =
261       TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
262   static constexpr int kBuiltinContextOffset =
263       TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
264   static constexpr int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
265 
266   // The argument count is in the first allocatable register, stored below the
267   // fixed part of the frame and therefore is not part of the fixed frame size.
268   static constexpr int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
269   DEFINE_TYPED_FRAME_SIZES(4);
270 
271   // Returns the number of padding stack slots needed when we have
272   // 'register_count' register slots.
273   // This is needed on some architectures to ensure the stack pointer is
274   // aligned.
275   static int PaddingSlotCount(int register_count);
276 };
277 
278 // Behaves like an exit frame but with target and new target args.
279 class BuiltinExitFrameConstants : public CommonFrameConstants {
280  public:
281   static constexpr int kNewTargetOffset = kCallerPCOffset + 1 * kPointerSize;
282   static constexpr int kTargetOffset = kNewTargetOffset + 1 * kPointerSize;
283   static constexpr int kArgcOffset = kTargetOffset + 1 * kPointerSize;
284   static constexpr int kPaddingOffset = kArgcOffset + 1 * kPointerSize;
285   static constexpr int kFirstArgumentOffset = kPaddingOffset + 1 * kPointerSize;
286   static constexpr int kNumExtraArgsWithReceiver = 5;
287 };
288 
289 class InterpreterFrameConstants : public AllStatic {
290  public:
291   // Fixed frame includes bytecode array and bytecode offset.
292   static constexpr int kFixedFrameSize =
293       StandardFrameConstants::kFixedFrameSize + 2 * kPointerSize;
294   static constexpr int kFixedFrameSizeFromFp =
295       StandardFrameConstants::kFixedFrameSizeFromFp + 2 * kPointerSize;
296 
297   // FP-relative.
298   static constexpr int kLastParamFromFp =
299       StandardFrameConstants::kCallerSPOffset;
300   static constexpr int kCallerPCOffsetFromFp =
301       StandardFrameConstants::kCallerPCOffset;
302   static constexpr int kBytecodeArrayFromFp =
303       -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
304   static constexpr int kBytecodeOffsetFromFp =
305       -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
306   static constexpr int kRegisterFileFromFp =
307       -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
308 
309   static constexpr int kExpressionsOffset = kRegisterFileFromFp;
310 
311   // Number of fixed slots in addition to a {StandardFrame}.
312   static constexpr int kExtraSlotCount =
313       InterpreterFrameConstants::kFixedFrameSize / kPointerSize -
314       StandardFrameConstants::kFixedFrameSize / kPointerSize;
315 
316   // Expression index for {StandardFrame::GetExpressionAddress}.
317   static constexpr int kBytecodeArrayExpressionIndex = -2;
318   static constexpr int kBytecodeOffsetExpressionIndex = -1;
319   static constexpr int kRegisterFileExpressionIndex = 0;
320 
321   // Returns the number of stack slots needed for 'register_count' registers.
322   // This is needed because some architectures must pad the stack frame with
323   // additional stack slots to ensure the stack pointer is aligned.
324   static int RegisterStackSlotCount(int register_count);
325 };
326 
FPOffsetToFrameSlot(int frame_offset)327 inline static int FPOffsetToFrameSlot(int frame_offset) {
328   return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
329          frame_offset / kPointerSize;
330 }
331 
FrameSlotToFPOffset(int slot)332 inline static int FrameSlotToFPOffset(int slot) {
333   return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
334          kPointerSize;
335 }
336 
337 }  // namespace internal
338 }  // namespace v8
339 
340 #if V8_TARGET_ARCH_IA32
341 #include "src/ia32/frame-constants-ia32.h"  // NOLINT
342 #elif V8_TARGET_ARCH_X64
343 #include "src/x64/frame-constants-x64.h"  // NOLINT
344 #elif V8_TARGET_ARCH_ARM64
345 #include "src/arm64/frame-constants-arm64.h"  // NOLINT
346 #elif V8_TARGET_ARCH_ARM
347 #include "src/arm/frame-constants-arm.h"  // NOLINT
348 #elif V8_TARGET_ARCH_PPC
349 #include "src/ppc/frame-constants-ppc.h"  // NOLINT
350 #elif V8_TARGET_ARCH_MIPS
351 #include "src/mips/frame-constants-mips.h"  // NOLINT
352 #elif V8_TARGET_ARCH_MIPS64
353 #include "src/mips64/frame-constants-mips64.h"  // NOLINT
354 #elif V8_TARGET_ARCH_S390
355 #include "src/s390/frame-constants-s390.h"  // NOLINT
356 #else
357 #error Unsupported target architecture.
358 #endif
359 
360 #endif  // V8_FRAME_CONSTANTS_H_
361