2017-08-03 09:35:57 +00:00
|
|
|
// Copyright 2017 the V8 project authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
|
|
|
#ifndef V8_FRAME_CONSTANTS_H_
|
|
|
|
#define V8_FRAME_CONSTANTS_H_
|
|
|
|
|
|
|
|
#include "src/flags.h"
|
|
|
|
#include "src/globals.h"
|
|
|
|
|
|
|
|
namespace v8 {
|
|
|
|
namespace internal {
|
|
|
|
|
|
|
|
// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
|
|
|
|
// two slots.
|
|
|
|
//
|
|
|
|
// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
|
|
|
|
// the callee's saved return address and 1 corresponding to the saved frame
|
|
|
|
// pointer. Some frames have additional information stored in the fixed header,
|
|
|
|
// for example JSFunctions store the function context and marker in the fixed
|
|
|
|
// header, with slot index 2 corresponding to the current function context and 3
|
|
|
|
// corresponding to the frame marker/JSFunction.
|
|
|
|
//
|
|
|
|
// slot JS frame
|
|
|
|
// +-----------------+--------------------------------
|
|
|
|
// -n-1 | parameter 0 | ^
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -n | | Caller
|
|
|
|
// ... | ... | frame slots
|
|
|
|
// -2 | parameter n-1 | (slot < 0)
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -1 | parameter n | v
|
|
|
|
// -----+-----------------+--------------------------------
|
|
|
|
// 0 | return addr | ^ ^
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 1 | saved frame ptr | Fixed |
|
|
|
|
// |- - - - - - - - -| Header <-- frame ptr |
|
|
|
|
// 2 | [Constant Pool] | | |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 2+cp |Context/Frm. Type| v if a constant pool |
|
|
|
|
// |-----------------+---- is used, cp = 1, |
|
|
|
|
// 3+cp | | ^ otherwise, cp = 0 |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 4+cp | | | Callee
|
|
|
|
// |- - - - - - - - -| | frame slots
|
|
|
|
// ... | | Frame slots (slot >= 0)
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// | | v |
|
|
|
|
// -----+-----------------+----- <-- stack ptr -------------
|
|
|
|
//
|
|
|
|
class CommonFrameConstants : public AllStatic {
|
|
|
|
public:
|
|
|
|
static const int kCallerFPOffset = 0 * kPointerSize;
|
|
|
|
static const int kCallerPCOffset = kCallerFPOffset + 1 * kFPOnStackSize;
|
|
|
|
static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
|
|
|
|
|
|
|
|
// Fixed part of the frame consists of return address, caller fp,
|
|
|
|
// constant pool (if FLAG_enable_embedded_constant_pool), context, and
|
|
|
|
// function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
|
|
|
|
// is the last object pointer.
|
|
|
|
static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
|
|
|
|
static const int kFixedSlotCountAboveFp =
|
|
|
|
kFixedFrameSizeAboveFp / kPointerSize;
|
|
|
|
static const int kCPSlotSize =
|
|
|
|
FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
|
|
|
|
static const int kCPSlotCount = kCPSlotSize / kPointerSize;
|
|
|
|
static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
|
|
|
|
static const int kContextOrFrameTypeSize = kPointerSize;
|
|
|
|
static const int kContextOrFrameTypeOffset =
|
|
|
|
-(kCPSlotSize + kContextOrFrameTypeSize);
|
|
|
|
};
|
|
|
|
|
|
|
|
// StandardFrames are used for interpreted, full-codegen and optimized
|
|
|
|
// JavaScript frames. They always have a context below the saved fp/constant
|
|
|
|
// pool and below that the JSFunction of the executing function.
|
|
|
|
//
|
|
|
|
// slot JS frame
|
|
|
|
// +-----------------+--------------------------------
|
|
|
|
// -n-1 | parameter 0 | ^
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -n | | Caller
|
|
|
|
// ... | ... | frame slots
|
|
|
|
// -2 | parameter n-1 | (slot < 0)
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -1 | parameter n | v
|
|
|
|
// -----+-----------------+--------------------------------
|
|
|
|
// 0 | return addr | ^ ^
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 1 | saved frame ptr | Fixed |
|
|
|
|
// |- - - - - - - - -| Header <-- frame ptr |
|
|
|
|
// 2 | [Constant Pool] | | |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 2+cp | Context | | if a constant pool |
|
|
|
|
// |- - - - - - - - -| | is used, cp = 1, |
|
|
|
|
// 3+cp | JSFunction | v otherwise, cp = 0 |
|
|
|
|
// +-----------------+---- |
|
|
|
|
// 4+cp | | ^ Callee
|
|
|
|
// |- - - - - - - - -| | frame slots
|
|
|
|
// ... | | Frame slots (slot >= 0)
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// | | v |
|
|
|
|
// -----+-----------------+----- <-- stack ptr -------------
|
|
|
|
//
|
|
|
|
class StandardFrameConstants : public CommonFrameConstants {
|
|
|
|
public:
|
|
|
|
static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
|
|
|
|
static const int kFixedFrameSize =
|
|
|
|
kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
|
|
|
|
static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
|
|
|
|
static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
|
|
|
|
static const int kContextOffset = kContextOrFrameTypeOffset;
|
|
|
|
static const int kFunctionOffset = -2 * kPointerSize - kCPSlotSize;
|
|
|
|
static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
|
|
|
|
static const int kLastObjectOffset = kContextOffset;
|
|
|
|
};
|
|
|
|
|
|
|
|
// OptimizedBuiltinFrameConstants are used for TF-generated builtins. They
|
|
|
|
// always have a context below the saved fp/constant pool and below that the
|
|
|
|
// JSFunction of the executing function and below that an integer (not a Smi)
|
|
|
|
// containing the number of arguments passed to the builtin.
|
|
|
|
//
|
|
|
|
// slot JS frame
|
|
|
|
// +-----------------+--------------------------------
|
|
|
|
// -n-1 | parameter 0 | ^
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -n | | Caller
|
|
|
|
// ... | ... | frame slots
|
|
|
|
// -2 | parameter n-1 | (slot < 0)
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -1 | parameter n | v
|
|
|
|
// -----+-----------------+--------------------------------
|
|
|
|
// 0 | return addr | ^ ^
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 1 | saved frame ptr | Fixed |
|
|
|
|
// |- - - - - - - - -| Header <-- frame ptr |
|
|
|
|
// 2 | [Constant Pool] | | |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 2+cp | Context | | if a constant pool |
|
|
|
|
// |- - - - - - - - -| | is used, cp = 1, |
|
|
|
|
// 3+cp | JSFunction | | otherwise, cp = 0 |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 4+cp | argc | v |
|
|
|
|
// +-----------------+---- |
|
|
|
|
// 5+cp | | ^ Callee
|
|
|
|
// |- - - - - - - - -| | frame slots
|
|
|
|
// ... | | Frame slots (slot >= 0)
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// | | v |
|
|
|
|
// -----+-----------------+----- <-- stack ptr -------------
|
|
|
|
//
|
|
|
|
class OptimizedBuiltinFrameConstants : public StandardFrameConstants {
|
|
|
|
public:
|
|
|
|
static const int kArgCSize = kPointerSize;
|
|
|
|
static const int kArgCOffset = -3 * kPointerSize - kCPSlotSize;
|
|
|
|
static const int kFixedFrameSize = kFixedFrameSizeAboveFp - kArgCOffset;
|
|
|
|
static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
// TypedFrames have a SMI type maker value below the saved FP/constant pool to
|
|
|
|
// distinguish them from StandardFrames, which have a context in that position
|
|
|
|
// instead.
|
|
|
|
//
|
|
|
|
// slot JS frame
|
|
|
|
// +-----------------+--------------------------------
|
|
|
|
// -n-1 | parameter 0 | ^
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -n | | Caller
|
|
|
|
// ... | ... | frame slots
|
|
|
|
// -2 | parameter n-1 | (slot < 0)
|
|
|
|
// |- - - - - - - - -| |
|
|
|
|
// -1 | parameter n | v
|
|
|
|
// -----+-----------------+--------------------------------
|
|
|
|
// 0 | return addr | ^ ^
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 1 | saved frame ptr | Fixed |
|
|
|
|
// |- - - - - - - - -| Header <-- frame ptr |
|
|
|
|
// 2 | [Constant Pool] | | |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 2+cp |Frame Type Marker| v if a constant pool |
|
|
|
|
// |-----------------+---- is used, cp = 1, |
|
|
|
|
// 3+cp | | ^ otherwise, cp = 0 |
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// 4+cp | | | Callee
|
|
|
|
// |- - - - - - - - -| | frame slots
|
|
|
|
// ... | | Frame slots (slot >= 0)
|
|
|
|
// |- - - - - - - - -| | |
|
|
|
|
// | | v |
|
|
|
|
// -----+-----------------+----- <-- stack ptr -------------
|
|
|
|
//
|
|
|
|
class TypedFrameConstants : public CommonFrameConstants {
|
|
|
|
public:
|
|
|
|
static const int kFrameTypeSize = kContextOrFrameTypeSize;
|
|
|
|
static const int kFrameTypeOffset = kContextOrFrameTypeOffset;
|
|
|
|
static const int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
|
|
|
|
static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
|
|
|
|
static const int kFixedFrameSize =
|
|
|
|
StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
|
|
|
|
static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
|
|
|
|
static const int kFirstPushedFrameValueOffset =
|
|
|
|
-StandardFrameConstants::kCPSlotSize - kFrameTypeSize - kPointerSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
#define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
|
|
|
|
(TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kPointerSize)
|
|
|
|
#define TYPED_FRAME_SIZE(count) \
|
|
|
|
(TypedFrameConstants::kFixedFrameSize + (count)*kPointerSize)
|
|
|
|
#define TYPED_FRAME_SIZE_FROM_SP(count) \
|
|
|
|
(TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kPointerSize)
|
|
|
|
#define DEFINE_TYPED_FRAME_SIZES(count) \
|
|
|
|
static const int kFixedFrameSize = TYPED_FRAME_SIZE(count); \
|
|
|
|
static const int kFixedSlotCount = kFixedFrameSize / kPointerSize; \
|
|
|
|
static const int kFixedFrameSizeFromFp = TYPED_FRAME_SIZE_FROM_SP(count); \
|
|
|
|
static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize
|
|
|
|
|
|
|
|
class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
|
|
|
static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(2);
|
|
|
|
};
|
|
|
|
|
|
|
|
class BuiltinFrameConstants : public TypedFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
|
|
|
static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(2);
|
|
|
|
};
|
|
|
|
|
|
|
|
class InternalFrameConstants : public TypedFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(1);
|
|
|
|
};
|
|
|
|
|
|
|
|
class FrameDropperFrameConstants : public InternalFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(2);
|
|
|
|
};
|
|
|
|
|
|
|
|
class ConstructFrameConstants : public TypedFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
|
|
|
static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
|
|
|
static const int kConstructorOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
|
|
|
|
static const int kNewTargetOrImplicitReceiverOffset =
|
|
|
|
TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(4);
|
|
|
|
};
|
|
|
|
|
|
|
|
class BuiltinContinuationFrameConstants : public TypedFrameConstants {
|
|
|
|
public:
|
|
|
|
// FP-relative.
|
|
|
|
static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
|
|
|
|
static const int kBuiltinOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
|
|
|
|
static const int kArgCOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
|
|
|
|
DEFINE_TYPED_FRAME_SIZES(2);
|
|
|
|
};
|
|
|
|
|
|
|
|
// Behaves like an exit frame but with target and new target args.
|
|
|
|
class BuiltinExitFrameConstants : public CommonFrameConstants {
|
|
|
|
public:
|
|
|
|
static const int kNewTargetOffset = kCallerPCOffset + 1 * kPointerSize;
|
|
|
|
static const int kTargetOffset = kNewTargetOffset + 1 * kPointerSize;
|
|
|
|
static const int kArgcOffset = kTargetOffset + 1 * kPointerSize;
|
|
|
|
};
|
|
|
|
|
|
|
|
class InterpreterFrameConstants : public AllStatic {
|
|
|
|
public:
|
2017-08-11 15:16:31 +00:00
|
|
|
// Fixed frame includes bytecode array and bytecode offset.
|
2017-08-03 09:35:57 +00:00
|
|
|
static const int kFixedFrameSize =
|
2017-08-11 15:16:31 +00:00
|
|
|
StandardFrameConstants::kFixedFrameSize + 2 * kPointerSize;
|
2017-08-03 09:35:57 +00:00
|
|
|
static const int kFixedFrameSizeFromFp =
|
2017-08-11 15:16:31 +00:00
|
|
|
StandardFrameConstants::kFixedFrameSizeFromFp + 2 * kPointerSize;
|
2017-08-03 09:35:57 +00:00
|
|
|
|
|
|
|
// FP-relative.
|
|
|
|
static const int kLastParamFromFp = StandardFrameConstants::kCallerSPOffset;
|
|
|
|
static const int kCallerPCOffsetFromFp =
|
|
|
|
StandardFrameConstants::kCallerPCOffset;
|
|
|
|
static const int kBytecodeArrayFromFp =
|
2017-08-11 15:16:31 +00:00
|
|
|
-StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
|
2017-08-03 09:35:57 +00:00
|
|
|
static const int kBytecodeOffsetFromFp =
|
2017-08-11 15:16:31 +00:00
|
|
|
-StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
|
2017-08-03 09:35:57 +00:00
|
|
|
static const int kRegisterFileFromFp =
|
2017-08-11 15:16:31 +00:00
|
|
|
-StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
|
2017-08-03 09:35:57 +00:00
|
|
|
|
|
|
|
static const int kExpressionsOffset = kRegisterFileFromFp;
|
|
|
|
|
|
|
|
// Number of fixed slots in addition to a {StandardFrame}.
|
|
|
|
static const int kExtraSlotCount =
|
|
|
|
InterpreterFrameConstants::kFixedFrameSize / kPointerSize -
|
|
|
|
StandardFrameConstants::kFixedFrameSize / kPointerSize;
|
|
|
|
|
|
|
|
// Expression index for {StandardFrame::GetExpressionAddress}.
|
|
|
|
static const int kBytecodeArrayExpressionIndex = -2;
|
|
|
|
static const int kBytecodeOffsetExpressionIndex = -1;
|
|
|
|
static const int kRegisterFileExpressionIndex = 0;
|
|
|
|
};
|
|
|
|
|
|
|
|
inline static int FPOffsetToFrameSlot(int frame_offset) {
|
|
|
|
return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
|
|
|
|
frame_offset / kPointerSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static int FrameSlotToFPOffset(int slot) {
|
|
|
|
return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
|
|
|
|
kPointerSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace v8
|
|
|
|
|
|
|
|
#if V8_TARGET_ARCH_IA32
|
|
|
|
#include "src/ia32/frame-constants-ia32.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_X64
|
|
|
|
#include "src/x64/frame-constants-x64.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_ARM64
|
|
|
|
#include "src/arm64/frame-constants-arm64.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_ARM
|
|
|
|
#include "src/arm/frame-constants-arm.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_PPC
|
|
|
|
#include "src/ppc/frame-constants-ppc.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_MIPS
|
|
|
|
#include "src/mips/frame-constants-mips.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_MIPS64
|
|
|
|
#include "src/mips64/frame-constants-mips64.h" // NOLINT
|
|
|
|
#elif V8_TARGET_ARCH_S390
|
|
|
|
#include "src/s390/frame-constants-s390.h" // NOLINT
|
|
|
|
#else
|
|
|
|
#error Unsupported target architecture.
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif // V8_FRAME_CONSTANTS_H_
|