1 // Copyright 2012 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_X64_FRAMES_X64_H_
6 #define V8_X64_FRAMES_X64_H_
7 
8 namespace v8 {
9 namespace internal {
10 
11 const int kNumRegs = 16;
12 const RegList kJSCallerSaved =
13     1 << 0 |  // rax
14     1 << 1 |  // rcx
15     1 << 2 |  // rdx
16     1 << 3 |  // rbx - used as a caller-saved register in JavaScript code
17     1 << 7;   // rdi - callee function
18 
19 const int kNumJSCallerSaved = 5;
20 
21 // Number of registers for which space is reserved in safepoints.
22 const int kNumSafepointRegisters = 16;
23 
24 // ----------------------------------------------------
25 
26 class EntryFrameConstants : public AllStatic {
27  public:
28 #ifdef _WIN64
29   static const int kCalleeSaveXMMRegisters = 10;
30   static const int kXMMRegisterSize = 16;
31   static const int kXMMRegistersBlockSize =
32       kXMMRegisterSize * kCalleeSaveXMMRegisters;
33   static const int kCallerFPOffset =
34       -3 * kPointerSize + -7 * kRegisterSize - kXMMRegistersBlockSize;
35 #else
36   // We have 3 Push and 5 pushq in the JSEntryStub::GenerateBody.
37   static const int kCallerFPOffset = -3 * kPointerSize + -5 * kRegisterSize;
38 #endif
39   static const int kArgvOffset     = 6 * kPointerSize;
40 };
41 
42 
43 class ExitFrameConstants : public AllStatic {
44  public:
45   static const int kFrameSize       = 2 * kPointerSize;
46 
47   static const int kCodeOffset      = -2 * kPointerSize;
48   static const int kSPOffset        = -1 * kPointerSize;
49 
50   static const int kCallerFPOffset  = +0 * kPointerSize;
51   static const int kCallerPCOffset  = kFPOnStackSize;
52 
53   // FP-relative displacement of the caller's SP.  It points just
54   // below the saved PC.
55   static const int kCallerSPDisplacement = kCallerPCOffset + kPCOnStackSize;
56 
57   static const int kConstantPoolOffset   = 0;  // Not used
58 };
59 
60 
61 class JavaScriptFrameConstants : public AllStatic {
62  public:
63   // FP-relative.
64   static const int kLocal0Offset = StandardFrameConstants::kExpressionsOffset;
65   static const int kLastParameterOffset = kFPOnStackSize + kPCOnStackSize;
66   static const int kFunctionOffset = StandardFrameConstants::kMarkerOffset;
67 
68   // Caller SP-relative.
69   static const int kParam0Offset   = -2 * kPointerSize;
70   static const int kReceiverOffset = -1 * kPointerSize;
71 };
72 
73 
74 class ArgumentsAdaptorFrameConstants : public AllStatic {
75  public:
76   // FP-relative.
77   static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
78 
79   static const int kFrameSize =
80       StandardFrameConstants::kFixedFrameSize + kPointerSize;
81 };
82 
83 
84 class ConstructFrameConstants : public AllStatic {
85  public:
86   // FP-relative.
87   static const int kImplicitReceiverOffset = -5 * kPointerSize;
88   static const int kConstructorOffset      = kMinInt;
89   static const int kLengthOffset           = -4 * kPointerSize;
90   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
91 
92   static const int kFrameSize =
93       StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
94 };
95 
96 
97 class InternalFrameConstants : public AllStatic {
98  public:
99   // FP-relative.
100   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
101 };
102 
103 
function_slot_object()104 inline Object* JavaScriptFrame::function_slot_object() const {
105   const int offset = JavaScriptFrameConstants::kFunctionOffset;
106   return Memory::Object_at(fp() + offset);
107 }
108 
109 
SetFp(Address slot,Address fp)110 inline void StackHandler::SetFp(Address slot, Address fp) {
111   if (kFPOnStackSize == 2 * kPointerSize) {
112     // Zero out the high-32 bit of FP for x32 port.
113     Memory::Address_at(slot + kPointerSize) = 0;
114   }
115   Memory::Address_at(slot) = fp;
116 }
117 
118 
119 } }  // namespace v8::internal
120 
121 #endif  // V8_X64_FRAMES_X64_H_
122