• 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_EXECUTION_FRAME_CONSTANTS_H_
6 #define V8_EXECUTION_FRAME_CONSTANTS_H_
7 
8 #include "src/common/globals.h"
9 #include "src/flags/flags.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 n   |                            ^
27 //       |- - - - - - - - -|                            |
28 //  -n   |  parameter n-1  |                          Caller
29 //  ...  |       ...       |                       frame slots
30 //  -2   |   parameter 1   |                       (slot < 0)
31 //       |- - - - - - - - -|                            |
32 //  -1   |   parameter 0   |                            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. CommonFrame::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, below that the JSFunction of the executing function and below that an
77 // integer (not a Smi) containing the actual number of arguments passed to the
78 // JavaScript code.
79 //
80 //  slot      JS frame
81 //       +-----------------+--------------------------------
82 //  -n-1 |   parameter n   |                            ^
83 //       |- - - - - - - - -|                            |
84 //  -n   |  parameter n-1  |                          Caller
85 //  ...  |       ...       |                       frame slots
86 //  -2   |   parameter 1   |                       (slot < 0)
87 //       |- - - - - - - - -|                            |
88 //  -1   |   parameter 0   |                            v
89 //  -----+-----------------+--------------------------------
90 //   0   |   return addr   |   ^                        ^
91 //       |- - - - - - - - -|   |                        |
92 //   1   | saved frame ptr | Fixed                      |
93 //       |- - - - - - - - -| Header <-- frame ptr       |
94 //   2   | [Constant Pool] |   |                        |
95 //       |- - - - - - - - -|   |                        |
96 // 2+cp  |     Context     |   |   if a constant pool   |
97 //       |- - - - - - - - -|   |    is used, cp = 1,    |
98 // 3+cp  |    JSFunction   |   |   otherwise, cp = 0    |
99 //       |- - - - - - - - -|   |                        |
100 // 4+cp  |      argc       |   v                        |
101 //       +-----------------+----                        |
102 // 5+cp  |  expressions or |   ^                      Callee
103 //       |- - - - - - - - -|   |                   frame slots
104 //  ...  |  pushed values  | Frame slots           (slot >= 0)
105 //       |- - - - - - - - -|   |                        |
106 //       |                 |   v                        |
107 //  -----+-----------------+----- <-- stack ptr -------------
108 //
109 class StandardFrameConstants : public CommonFrameConstants {
110  public:
111   static constexpr int kFixedFrameSizeFromFp =
112       3 * kSystemPointerSize + kCPSlotSize;
113   static constexpr int kFixedFrameSize =
114       kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
115   static constexpr int kFixedSlotCountFromFp =
116       kFixedFrameSizeFromFp / kSystemPointerSize;
117   static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize;
118   static constexpr int kContextOffset = kContextOrFrameTypeOffset;
119   static constexpr int kFunctionOffset = -2 * kSystemPointerSize - kCPSlotSize;
120   static constexpr int kArgCOffset = -3 * kSystemPointerSize - kCPSlotSize;
121   static constexpr int kExpressionsOffset =
122       -4 * kSystemPointerSize - kCPSlotSize;
123   static constexpr int kFirstPushedFrameValueOffset = kExpressionsOffset;
124   static constexpr int kLastObjectOffset = kContextOffset;
125 };
126 
127 // TypedFrames have a type maker value below the saved FP/constant pool to
128 // distinguish them from StandardFrames, which have a context in that position
129 // instead.
130 //
131 //  slot      JS frame
132 //       +-----------------+--------------------------------
133 //  -n-1 |   parameter n   |                            ^
134 //       |- - - - - - - - -|                            |
135 //  -n   |  parameter n-1  |                          Caller
136 //  ...  |       ...       |                       frame slots
137 //  -2   |   parameter 1   |                       (slot < 0)
138 //       |- - - - - - - - -|                            |
139 //  -1   |   parameter 0   |                            v
140 //  -----+-----------------+--------------------------------
141 //   0   |   return addr   |   ^                        ^
142 //       |- - - - - - - - -|   |                        |
143 //   1   | saved frame ptr | Fixed                      |
144 //       |- - - - - - - - -| Header <-- frame ptr       |
145 //   2   | [Constant Pool] |   |                        |
146 //       |- - - - - - - - -|   |                        |
147 // 2+cp  |Frame Type Marker|   v   if a constant pool   |
148 //       |-----------------+----    is used, cp = 1,    |
149 // 3+cp  |  pushed value 0 |   ^   otherwise, cp = 0    |
150 //       |- - - - - - - - -|   |                        |
151 // 4+cp  |  pushed value 1 |   |                      Callee
152 //       |- - - - - - - - -|   |                   frame slots
153 //  ...  |                 | Frame slots           (slot >= 0)
154 //       |- - - - - - - - -|   |                        |
155 //       |                 |   v                        |
156 //  -----+-----------------+----- <-- stack ptr -------------
157 //
158 class TypedFrameConstants : public CommonFrameConstants {
159  public:
160   static constexpr int kFrameTypeSize = kContextOrFrameTypeSize;
161   static constexpr int kFrameTypeOffset = kContextOrFrameTypeOffset;
162   static constexpr int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
163   static constexpr int kFixedSlotCountFromFp =
164       kFixedFrameSizeFromFp / kSystemPointerSize;
165   static constexpr int kFixedFrameSize =
166       StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
167   static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize;
168   static constexpr int kFirstPushedFrameValueOffset =
169       -kFixedFrameSizeFromFp - kSystemPointerSize;
170 };
171 
172 #define FRAME_PUSHED_VALUE_OFFSET(parent, x) \
173   (parent::kFirstPushedFrameValueOffset - (x)*kSystemPointerSize)
174 #define FRAME_SIZE(parent, count) \
175   (parent::kFixedFrameSize + (count)*kSystemPointerSize)
176 #define FRAME_SIZE_FROM_FP(parent, count) \
177   (parent::kFixedFrameSizeFromFp + (count)*kSystemPointerSize)
178 #define DEFINE_FRAME_SIZES(parent, count)                                      \
179   static constexpr int kFixedFrameSize = FRAME_SIZE(parent, count);            \
180   static constexpr int kFixedSlotCount = kFixedFrameSize / kSystemPointerSize; \
181   static constexpr int kFixedFrameSizeFromFp =                                 \
182       FRAME_SIZE_FROM_FP(parent, count);                                       \
183   static constexpr int kFixedSlotCountFromFp =                                 \
184       kFixedFrameSizeFromFp / kSystemPointerSize;                              \
185   static constexpr int kExtraSlotCount =                                       \
186       kFixedFrameSize / kSystemPointerSize -                                   \
187       parent::kFixedFrameSize / kSystemPointerSize
188 
189 #define STANDARD_FRAME_EXTRA_PUSHED_VALUE_OFFSET(x) \
190   FRAME_PUSHED_VALUE_OFFSET(StandardFrameConstants, x)
191 #define DEFINE_STANDARD_FRAME_SIZES(count) \
192   DEFINE_FRAME_SIZES(StandardFrameConstants, count)
193 
194 #define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
195   FRAME_PUSHED_VALUE_OFFSET(TypedFrameConstants, x)
196 #define DEFINE_TYPED_FRAME_SIZES(count) \
197   DEFINE_FRAME_SIZES(TypedFrameConstants, count)
198 
199 class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
200  public:
201   // FP-relative.
202   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
203   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
204   static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
205   DEFINE_TYPED_FRAME_SIZES(3);
206 };
207 
208 class BuiltinFrameConstants : public TypedFrameConstants {
209  public:
210   // FP-relative.
211   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
212   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
213   DEFINE_TYPED_FRAME_SIZES(2);
214 };
215 
216 class ConstructFrameConstants : public TypedFrameConstants {
217  public:
218   // FP-relative.
219   static constexpr int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
220   static constexpr int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
221   static constexpr int kConstructorOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
222   static constexpr int kPaddingOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
223   static constexpr int kNewTargetOrImplicitReceiverOffset =
224       TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
225   DEFINE_TYPED_FRAME_SIZES(5);
226 };
227 
228 class CWasmEntryFrameConstants : public TypedFrameConstants {
229  public:
230   // FP-relative:
231   static constexpr int kCEntryFPOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
232   DEFINE_TYPED_FRAME_SIZES(1);
233 };
234 
235 class WasmFrameConstants : public TypedFrameConstants {
236  public:
237   // FP-relative.
238   static constexpr int kWasmInstanceOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
239   DEFINE_TYPED_FRAME_SIZES(1);
240 };
241 
242 class WasmExitFrameConstants : public WasmFrameConstants {
243  public:
244   // FP-relative.
245   static const int kCallingPCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
246   DEFINE_TYPED_FRAME_SIZES(2);
247 };
248 
249 class BuiltinContinuationFrameConstants : public TypedFrameConstants {
250  public:
251   // FP-relative.
252   static constexpr int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
253   static constexpr int kFrameSPtoFPDeltaAtDeoptimize =
254       TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
255   static constexpr int kBuiltinContextOffset =
256       TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
257   static constexpr int kBuiltinIndexOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
258 
259   // The argument count is in the first allocatable register, stored below the
260   // fixed part of the frame and therefore is not part of the fixed frame size.
261   static constexpr int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(4);
262   DEFINE_TYPED_FRAME_SIZES(4);
263 
264   // Returns the number of padding stack slots needed when we have
265   // 'register_count' register slots.
266   // This is needed on some architectures to ensure the stack pointer is
267   // aligned.
268   static int PaddingSlotCount(int register_count);
269 };
270 
271 class ExitFrameConstants : public TypedFrameConstants {
272  public:
273   static constexpr int kSPOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
274   static constexpr int kLastExitFrameField = kSPOffset;
275   DEFINE_TYPED_FRAME_SIZES(1);
276 
277   // FP-relative displacement of the caller's SP.  It points just
278   // below the saved PC.
279   static constexpr int kCallerSPDisplacement = kCallerSPOffset;
280 };
281 
282 // Behaves like an exit frame but with target and new target args.
283 class BuiltinExitFrameConstants : public ExitFrameConstants {
284  public:
285   static constexpr int kNewTargetOffset =
286       kCallerPCOffset + 1 * kSystemPointerSize;
287   static constexpr int kTargetOffset =
288       kNewTargetOffset + 1 * kSystemPointerSize;
289   static constexpr int kArgcOffset = kTargetOffset + 1 * kSystemPointerSize;
290   static constexpr int kPaddingOffset = kArgcOffset + 1 * kSystemPointerSize;
291   static constexpr int kFirstArgumentOffset =
292       kPaddingOffset + 1 * kSystemPointerSize;
293   static constexpr int kNumExtraArgsWithReceiver = 5;
294 };
295 
296 class InterpreterFrameConstants : public StandardFrameConstants {
297  public:
298   // FP-relative.
299   static constexpr int kBytecodeArrayFromFp =
300       STANDARD_FRAME_EXTRA_PUSHED_VALUE_OFFSET(0);
301   static constexpr int kBytecodeOffsetFromFp =
302       STANDARD_FRAME_EXTRA_PUSHED_VALUE_OFFSET(1);
303   DEFINE_STANDARD_FRAME_SIZES(2);
304 
305   static constexpr int kFirstParamFromFp =
306       StandardFrameConstants::kCallerSPOffset;
307   static constexpr int kRegisterFileFromFp =
308       -kFixedFrameSizeFromFp - kSystemPointerSize;
309   static constexpr int kExpressionsOffset = kRegisterFileFromFp;
310 
311   // Expression index for {JavaScriptFrame::GetExpressionAddress}.
312   static constexpr int kBytecodeArrayExpressionIndex = -2;
313   static constexpr int kBytecodeOffsetExpressionIndex = -1;
314   static constexpr int kRegisterFileExpressionIndex = 0;
315 
316   // Returns the number of stack slots needed for 'register_count' registers.
317   // This is needed because some architectures must pad the stack frame with
318   // additional stack slots to ensure the stack pointer is aligned.
319   static int RegisterStackSlotCount(int register_count);
320 };
321 
FPOffsetToFrameSlot(int frame_offset)322 inline static int FPOffsetToFrameSlot(int frame_offset) {
323   return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
324          frame_offset / kSystemPointerSize;
325 }
326 
FrameSlotToFPOffset(int slot)327 inline static int FrameSlotToFPOffset(int slot) {
328   return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
329          kSystemPointerSize;
330 }
331 
332 }  // namespace internal
333 }  // namespace v8
334 
335 #if V8_TARGET_ARCH_IA32
336 #include "src/execution/ia32/frame-constants-ia32.h"  // NOLINT
337 #elif V8_TARGET_ARCH_X64
338 #include "src/execution/x64/frame-constants-x64.h"  // NOLINT
339 #elif V8_TARGET_ARCH_ARM64
340 #include "src/execution/arm64/frame-constants-arm64.h"  // NOLINT
341 #elif V8_TARGET_ARCH_ARM
342 #include "src/execution/arm/frame-constants-arm.h"  // NOLINT
343 #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
344 #include "src/execution/ppc/frame-constants-ppc.h"  // NOLINT
345 #elif V8_TARGET_ARCH_MIPS
346 #include "src/execution/mips/frame-constants-mips.h"  // NOLINT
347 #elif V8_TARGET_ARCH_MIPS64
348 #include "src/execution/mips64/frame-constants-mips64.h"  // NOLINT
349 #elif V8_TARGET_ARCH_S390
350 #include "src/execution/s390/frame-constants-s390.h"  // NOLINT
351 #else
352 #error Unsupported target architecture.
353 #endif
354 
355 #endif  // V8_EXECUTION_FRAME_CONSTANTS_H_
356