Home | History | Annotate | Download | only in src
      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 
    327 inline static int FPOffsetToFrameSlot(int frame_offset) {
    328   return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
    329          frame_offset / kPointerSize;
    330 }
    331 
    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