• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_CODEGEN_MACRO_ASSEMBLER_H_
6 #define V8_CODEGEN_MACRO_ASSEMBLER_H_
7 
8 #include "src/codegen/turbo-assembler.h"
9 #include "src/execution/frames.h"
10 #include "src/heap/heap.h"
11 
12 // Helper types to make boolean flag easier to read at call-site.
13 enum class InvokeType { kCall, kJump };
14 
15 // Flags used for the AllocateInNewSpace functions.
16 enum AllocationFlags {
17   // No special flags.
18   NO_ALLOCATION_FLAGS = 0,
19   // The content of the result register already contains the allocation top in
20   // new space.
21   RESULT_CONTAINS_TOP = 1 << 0,
22   // Specify that the requested size of the space to allocate is specified in
23   // words instead of bytes.
24   SIZE_IN_WORDS = 1 << 1,
25   // Align the allocation to a multiple of kDoubleSize
26   DOUBLE_ALIGNMENT = 1 << 2,
27   // Directly allocate in old space
28   PRETENURE = 1 << 3,
29 };
30 
31 enum class JumpMode {
32   kJump,          // Does a direct jump to the given address
33   kPushAndReturn  // Pushes the given address as the current return address and
34                   // does a return
35 };
36 
37 enum class SmiCheck { kOmit, kInline };
38 
39 // This is the only place allowed to include the platform-specific headers.
40 #define INCLUDED_FROM_MACRO_ASSEMBLER_H
41 #if V8_TARGET_ARCH_IA32
42 #include "src/codegen/ia32/macro-assembler-ia32.h"
43 #elif V8_TARGET_ARCH_X64
44 #include "src/codegen/x64/macro-assembler-x64.h"
45 #elif V8_TARGET_ARCH_ARM64
46 #include "src/codegen/arm64/constants-arm64.h"
47 #include "src/codegen/arm64/macro-assembler-arm64.h"
48 #elif V8_TARGET_ARCH_ARM
49 #include "src/codegen/arm/constants-arm.h"
50 #include "src/codegen/arm/macro-assembler-arm.h"
51 #elif V8_TARGET_ARCH_PPC || V8_TARGET_ARCH_PPC64
52 #include "src/codegen/ppc/constants-ppc.h"
53 #include "src/codegen/ppc/macro-assembler-ppc.h"
54 #elif V8_TARGET_ARCH_MIPS
55 #include "src/codegen/mips/constants-mips.h"
56 #include "src/codegen/mips/macro-assembler-mips.h"
57 #elif V8_TARGET_ARCH_MIPS64
58 #include "src/codegen/mips64/constants-mips64.h"
59 #include "src/codegen/mips64/macro-assembler-mips64.h"
60 #elif V8_TARGET_ARCH_LOONG64
61 #include "src/codegen/loong64/constants-loong64.h"
62 #include "src/codegen/loong64/macro-assembler-loong64.h"
63 #elif V8_TARGET_ARCH_S390
64 #include "src/codegen/s390/constants-s390.h"
65 #include "src/codegen/s390/macro-assembler-s390.h"
66 #elif V8_TARGET_ARCH_RISCV64
67 #include "src/codegen/riscv64/constants-riscv64.h"
68 #include "src/codegen/riscv64/macro-assembler-riscv64.h"
69 #else
70 #error Unsupported target architecture.
71 #endif
72 #undef INCLUDED_FROM_MACRO_ASSEMBLER_H
73 
74 namespace v8 {
75 namespace internal {
76 
77 // Maximum number of parameters supported in calls to C/C++. The C++ standard
78 // defines a limit of 256 parameters but in simulator builds we provide only
79 // limited support.
80 #ifdef USE_SIMULATOR
81 static constexpr int kMaxCParameters = 20;
82 #else
83 static constexpr int kMaxCParameters = 256;
84 #endif
85 
86 class V8_NODISCARD FrameScope {
87  public:
FrameScope(TurboAssembler * tasm,StackFrame::Type type)88   explicit FrameScope(TurboAssembler* tasm, StackFrame::Type type)
89       :
90 #ifdef V8_CODE_COMMENTS
91         comment_(tasm, frame_name(type)),
92 #endif
93         tasm_(tasm),
94         type_(type),
95         old_has_frame_(tasm->has_frame()) {
96     tasm->set_has_frame(true);
97     if (type != StackFrame::MANUAL && type_ != StackFrame::NO_FRAME_TYPE) {
98       tasm->EnterFrame(type);
99     }
100   }
101 
~FrameScope()102   ~FrameScope() {
103     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NO_FRAME_TYPE) {
104       tasm_->LeaveFrame(type_);
105     }
106     tasm_->set_has_frame(old_has_frame_);
107   }
108 
109  private:
110 #ifdef V8_CODE_COMMENTS
frame_name(StackFrame::Type type)111   const char* frame_name(StackFrame::Type type) {
112     switch (type) {
113       case StackFrame::NO_FRAME_TYPE:
114         return "Frame: NO_FRAME_TYPE";
115       case StackFrame::MANUAL:
116         return "Frame: MANUAL";
117 #define FRAME_TYPE_CASE(type, field) \
118   case StackFrame::type:             \
119     return "Frame: " #type;
120         STACK_FRAME_TYPE_LIST(FRAME_TYPE_CASE)
121 #undef FRAME_TYPE_CASE
122       case StackFrame::NUMBER_OF_TYPES:
123         break;
124     }
125     return "Frame";
126   }
127 
128   Assembler::CodeComment comment_;
129 #endif  // V8_CODE_COMMENTS
130 
131   TurboAssembler* tasm_;
132   StackFrame::Type const type_;
133   bool const old_has_frame_;
134 };
135 
136 class V8_NODISCARD FrameAndConstantPoolScope {
137  public:
FrameAndConstantPoolScope(MacroAssembler * masm,StackFrame::Type type)138   FrameAndConstantPoolScope(MacroAssembler* masm, StackFrame::Type type)
139       : masm_(masm),
140         type_(type),
141         old_has_frame_(masm->has_frame()),
142         old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
143                                      masm->is_constant_pool_available()) {
144     masm->set_has_frame(true);
145     if (FLAG_enable_embedded_constant_pool) {
146       masm->set_constant_pool_available(true);
147     }
148     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NO_FRAME_TYPE) {
149       masm->EnterFrame(type, !old_constant_pool_available_);
150     }
151   }
152 
~FrameAndConstantPoolScope()153   ~FrameAndConstantPoolScope() {
154     masm_->LeaveFrame(type_);
155     masm_->set_has_frame(old_has_frame_);
156     if (FLAG_enable_embedded_constant_pool) {
157       masm_->set_constant_pool_available(old_constant_pool_available_);
158     }
159   }
160 
161  private:
162   MacroAssembler* masm_;
163   StackFrame::Type type_;
164   bool old_has_frame_;
165   bool old_constant_pool_available_;
166 
167   DISALLOW_IMPLICIT_CONSTRUCTORS(FrameAndConstantPoolScope);
168 };
169 
170 // Class for scoping the the unavailability of constant pool access.
171 class V8_NODISCARD ConstantPoolUnavailableScope {
172  public:
ConstantPoolUnavailableScope(Assembler * assembler)173   explicit ConstantPoolUnavailableScope(Assembler* assembler)
174       : assembler_(assembler),
175         old_constant_pool_available_(FLAG_enable_embedded_constant_pool &&
176                                      assembler->is_constant_pool_available()) {
177     if (FLAG_enable_embedded_constant_pool) {
178       assembler->set_constant_pool_available(false);
179     }
180   }
~ConstantPoolUnavailableScope()181   ~ConstantPoolUnavailableScope() {
182     if (FLAG_enable_embedded_constant_pool) {
183       assembler_->set_constant_pool_available(old_constant_pool_available_);
184     }
185   }
186 
187  private:
188   Assembler* assembler_;
189   int old_constant_pool_available_;
190 
191   DISALLOW_IMPLICIT_CONSTRUCTORS(ConstantPoolUnavailableScope);
192 };
193 
194 class V8_NODISCARD AllowExternalCallThatCantCauseGC : public FrameScope {
195  public:
AllowExternalCallThatCantCauseGC(MacroAssembler * masm)196   explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
197       : FrameScope(masm, StackFrame::NO_FRAME_TYPE) {}
198 };
199 
200 // Prevent the use of the RootArray during the lifetime of this
201 // scope object.
202 class V8_NODISCARD NoRootArrayScope {
203  public:
NoRootArrayScope(TurboAssembler * masm)204   explicit NoRootArrayScope(TurboAssembler* masm)
205       : masm_(masm), old_value_(masm->root_array_available()) {
206     masm->set_root_array_available(false);
207   }
208 
~NoRootArrayScope()209   ~NoRootArrayScope() { masm_->set_root_array_available(old_value_); }
210 
211  private:
212   TurboAssembler* masm_;
213   bool old_value_;
214 };
215 
216 }  // namespace internal
217 }  // namespace v8
218 
219 #endif  // V8_CODEGEN_MACRO_ASSEMBLER_H_
220