• 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_MACRO_ASSEMBLER_H_
6 #define V8_MACRO_ASSEMBLER_H_
7 
8 
9 // Helper types to make boolean flag easier to read at call-site.
10 enum InvokeFlag {
11   CALL_FUNCTION,
12   JUMP_FUNCTION
13 };
14 
15 
16 // Flags used for the AllocateInNewSpace functions.
17 enum AllocationFlags {
18   // No special flags.
19   NO_ALLOCATION_FLAGS = 0,
20   // Return the pointer to the allocated already tagged as a heap object.
21   TAG_OBJECT = 1 << 0,
22   // The content of the result register already contains the allocation top in
23   // new space.
24   RESULT_CONTAINS_TOP = 1 << 1,
25   // Specify that the requested size of the space to allocate is specified in
26   // words instead of bytes.
27   SIZE_IN_WORDS = 1 << 2,
28   // Align the allocation to a multiple of kDoubleSize
29   DOUBLE_ALIGNMENT = 1 << 3,
30   // Directly allocate in old pointer space
31   PRETENURE_OLD_POINTER_SPACE = 1 << 4,
32   // Directly allocate in old data space
33   PRETENURE_OLD_DATA_SPACE = 1 << 5
34 };
35 
36 
37 // Invalid depth in prototype chain.
38 const int kInvalidProtoDepth = -1;
39 
40 #if V8_TARGET_ARCH_IA32
41 #include "src/assembler.h"
42 #include "src/ia32/assembler-ia32.h"
43 #include "src/ia32/assembler-ia32-inl.h"
44 #include "src/code.h"  // must be after assembler_*.h
45 #include "src/ia32/macro-assembler-ia32.h"
46 #elif V8_TARGET_ARCH_X64
47 #include "src/assembler.h"
48 #include "src/x64/assembler-x64.h"
49 #include "src/x64/assembler-x64-inl.h"
50 #include "src/code.h"  // must be after assembler_*.h
51 #include "src/x64/macro-assembler-x64.h"
52 #elif V8_TARGET_ARCH_ARM64
53 #include "src/arm64/constants-arm64.h"
54 #include "src/assembler.h"
55 #include "src/arm64/assembler-arm64.h"
56 #include "src/arm64/assembler-arm64-inl.h"
57 #include "src/code.h"  // must be after assembler_*.h
58 #include "src/arm64/macro-assembler-arm64.h"
59 #include "src/arm64/macro-assembler-arm64-inl.h"
60 #elif V8_TARGET_ARCH_ARM
61 #include "src/arm/constants-arm.h"
62 #include "src/assembler.h"
63 #include "src/arm/assembler-arm.h"
64 #include "src/arm/assembler-arm-inl.h"
65 #include "src/code.h"  // must be after assembler_*.h
66 #include "src/arm/macro-assembler-arm.h"
67 #elif V8_TARGET_ARCH_MIPS
68 #include "src/mips/constants-mips.h"
69 #include "src/assembler.h"
70 #include "src/mips/assembler-mips.h"
71 #include "src/mips/assembler-mips-inl.h"
72 #include "src/code.h"  // must be after assembler_*.h
73 #include "src/mips/macro-assembler-mips.h"
74 #elif V8_TARGET_ARCH_X87
75 #include "src/assembler.h"
76 #include "src/x87/assembler-x87.h"
77 #include "src/x87/assembler-x87-inl.h"
78 #include "src/code.h"  // must be after assembler_*.h
79 #include "src/x87/macro-assembler-x87.h"
80 #else
81 #error Unsupported target architecture.
82 #endif
83 
84 namespace v8 {
85 namespace internal {
86 
87 class FrameScope {
88  public:
FrameScope(MacroAssembler * masm,StackFrame::Type type)89   explicit FrameScope(MacroAssembler* masm, StackFrame::Type type)
90       : masm_(masm), type_(type), old_has_frame_(masm->has_frame()) {
91     masm->set_has_frame(true);
92     if (type != StackFrame::MANUAL && type_ != StackFrame::NONE) {
93       masm->EnterFrame(type);
94     }
95   }
96 
~FrameScope()97   ~FrameScope() {
98     if (type_ != StackFrame::MANUAL && type_ != StackFrame::NONE) {
99       masm_->LeaveFrame(type_);
100     }
101     masm_->set_has_frame(old_has_frame_);
102   }
103 
104   // Normally we generate the leave-frame code when this object goes
105   // out of scope.  Sometimes we may need to generate the code somewhere else
106   // in addition.  Calling this will achieve that, but the object stays in
107   // scope, the MacroAssembler is still marked as being in a frame scope, and
108   // the code will be generated again when it goes out of scope.
GenerateLeaveFrame()109   void GenerateLeaveFrame() {
110     ASSERT(type_ != StackFrame::MANUAL && type_ != StackFrame::NONE);
111     masm_->LeaveFrame(type_);
112   }
113 
114  private:
115   MacroAssembler* masm_;
116   StackFrame::Type type_;
117   bool old_has_frame_;
118 };
119 
120 
121 class AllowExternalCallThatCantCauseGC: public FrameScope {
122  public:
AllowExternalCallThatCantCauseGC(MacroAssembler * masm)123   explicit AllowExternalCallThatCantCauseGC(MacroAssembler* masm)
124       : FrameScope(masm, StackFrame::NONE) { }
125 };
126 
127 
128 class NoCurrentFrameScope {
129  public:
NoCurrentFrameScope(MacroAssembler * masm)130   explicit NoCurrentFrameScope(MacroAssembler* masm)
131       : masm_(masm), saved_(masm->has_frame()) {
132     masm->set_has_frame(false);
133   }
134 
~NoCurrentFrameScope()135   ~NoCurrentFrameScope() {
136     masm_->set_has_frame(saved_);
137   }
138 
139  private:
140   MacroAssembler* masm_;
141   bool saved_;
142 };
143 
144 
145 // Support for "structured" code comments.
146 #ifdef DEBUG
147 
148 class Comment {
149  public:
150   Comment(MacroAssembler* masm, const char* msg);
151   ~Comment();
152 
153  private:
154   MacroAssembler* masm_;
155   const char* msg_;
156 };
157 
158 #else
159 
160 class Comment {
161  public:
Comment(MacroAssembler *,const char *)162   Comment(MacroAssembler*, const char*)  {}
163 };
164 
165 #endif  // DEBUG
166 
167 
168 class AllocationUtils {
169  public:
GetAllocationTopReference(Isolate * isolate,AllocationFlags flags)170   static ExternalReference GetAllocationTopReference(
171       Isolate* isolate, AllocationFlags flags) {
172     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
173       return ExternalReference::old_pointer_space_allocation_top_address(
174           isolate);
175     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
176       return ExternalReference::old_data_space_allocation_top_address(isolate);
177     }
178     return ExternalReference::new_space_allocation_top_address(isolate);
179   }
180 
181 
GetAllocationLimitReference(Isolate * isolate,AllocationFlags flags)182   static ExternalReference GetAllocationLimitReference(
183       Isolate* isolate, AllocationFlags flags) {
184     if ((flags & PRETENURE_OLD_POINTER_SPACE) != 0) {
185       return ExternalReference::old_pointer_space_allocation_limit_address(
186           isolate);
187     } else if ((flags & PRETENURE_OLD_DATA_SPACE) != 0) {
188       return ExternalReference::old_data_space_allocation_limit_address(
189           isolate);
190     }
191     return ExternalReference::new_space_allocation_limit_address(isolate);
192   }
193 };
194 
195 
196 } }  // namespace v8::internal
197 
198 #endif  // V8_MACRO_ASSEMBLER_H_
199