• 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