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