xref: /aosp_15_r20/external/vixl/src/code-generation-scopes-vixl.h (revision f5c631da2f1efdd72b5fd1e20510e4042af13d77)
1*f5c631daSSadaf Ebrahimi // Copyright 2016, VIXL authors
2*f5c631daSSadaf Ebrahimi // All rights reserved.
3*f5c631daSSadaf Ebrahimi //
4*f5c631daSSadaf Ebrahimi // Redistribution and use in source and binary forms, with or without
5*f5c631daSSadaf Ebrahimi // modification, are permitted provided that the following conditions are met:
6*f5c631daSSadaf Ebrahimi //
7*f5c631daSSadaf Ebrahimi //   * Redistributions of source code must retain the above copyright notice,
8*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer.
9*f5c631daSSadaf Ebrahimi //   * Redistributions in binary form must reproduce the above copyright notice,
10*f5c631daSSadaf Ebrahimi //     this list of conditions and the following disclaimer in the documentation
11*f5c631daSSadaf Ebrahimi //     and/or other materials provided with the distribution.
12*f5c631daSSadaf Ebrahimi //   * Neither the name of ARM Limited nor the names of its contributors may be
13*f5c631daSSadaf Ebrahimi //     used to endorse or promote products derived from this software without
14*f5c631daSSadaf Ebrahimi //     specific prior written permission.
15*f5c631daSSadaf Ebrahimi //
16*f5c631daSSadaf Ebrahimi // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17*f5c631daSSadaf Ebrahimi // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18*f5c631daSSadaf Ebrahimi // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19*f5c631daSSadaf Ebrahimi // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20*f5c631daSSadaf Ebrahimi // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*f5c631daSSadaf Ebrahimi // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22*f5c631daSSadaf Ebrahimi // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23*f5c631daSSadaf Ebrahimi // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24*f5c631daSSadaf Ebrahimi // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25*f5c631daSSadaf Ebrahimi // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*f5c631daSSadaf Ebrahimi 
27*f5c631daSSadaf Ebrahimi 
28*f5c631daSSadaf Ebrahimi #ifndef VIXL_CODE_GENERATION_SCOPES_H_
29*f5c631daSSadaf Ebrahimi #define VIXL_CODE_GENERATION_SCOPES_H_
30*f5c631daSSadaf Ebrahimi 
31*f5c631daSSadaf Ebrahimi 
32*f5c631daSSadaf Ebrahimi #include "assembler-base-vixl.h"
33*f5c631daSSadaf Ebrahimi #include "macro-assembler-interface.h"
34*f5c631daSSadaf Ebrahimi 
35*f5c631daSSadaf Ebrahimi 
36*f5c631daSSadaf Ebrahimi namespace vixl {
37*f5c631daSSadaf Ebrahimi 
38*f5c631daSSadaf Ebrahimi // This scope will:
39*f5c631daSSadaf Ebrahimi // - Allow code emission from the specified `Assembler`.
40*f5c631daSSadaf Ebrahimi // - Optionally reserve space in the `CodeBuffer` (if it is managed by VIXL).
41*f5c631daSSadaf Ebrahimi // - Optionally, on destruction, check the size of the generated code.
42*f5c631daSSadaf Ebrahimi //   (The size can be either exact or a maximum size.)
43*f5c631daSSadaf Ebrahimi class CodeBufferCheckScope {
44*f5c631daSSadaf Ebrahimi  public:
45*f5c631daSSadaf Ebrahimi   // Tell whether or not the scope needs to ensure the associated CodeBuffer
46*f5c631daSSadaf Ebrahimi   // has enough space for the requested size.
47*f5c631daSSadaf Ebrahimi   enum BufferSpacePolicy {
48*f5c631daSSadaf Ebrahimi     kReserveBufferSpace,
49*f5c631daSSadaf Ebrahimi     kDontReserveBufferSpace,
50*f5c631daSSadaf Ebrahimi 
51*f5c631daSSadaf Ebrahimi     // Deprecated, but kept for backward compatibility.
52*f5c631daSSadaf Ebrahimi     kCheck = kReserveBufferSpace,
53*f5c631daSSadaf Ebrahimi     kNoCheck = kDontReserveBufferSpace
54*f5c631daSSadaf Ebrahimi   };
55*f5c631daSSadaf Ebrahimi 
56*f5c631daSSadaf Ebrahimi   // Tell whether or not the scope should assert the amount of code emitted
57*f5c631daSSadaf Ebrahimi   // within the scope is consistent with the requested amount.
58*f5c631daSSadaf Ebrahimi   enum SizePolicy {
59*f5c631daSSadaf Ebrahimi     kNoAssert,    // Do not check the size of the code emitted.
60*f5c631daSSadaf Ebrahimi     kExactSize,   // The code emitted must be exactly size bytes.
61*f5c631daSSadaf Ebrahimi     kMaximumSize  // The code emitted must be at most size bytes.
62*f5c631daSSadaf Ebrahimi   };
63*f5c631daSSadaf Ebrahimi 
64*f5c631daSSadaf Ebrahimi   // This constructor implicitly calls `Open` to initialise the scope
65*f5c631daSSadaf Ebrahimi   // (`assembler` must not be `NULL`), so it is ready to use immediately after
66*f5c631daSSadaf Ebrahimi   // it has been constructed.
67*f5c631daSSadaf Ebrahimi   CodeBufferCheckScope(internal::AssemblerBase* assembler,
68*f5c631daSSadaf Ebrahimi                        size_t size,
69*f5c631daSSadaf Ebrahimi                        BufferSpacePolicy check_policy = kReserveBufferSpace,
70*f5c631daSSadaf Ebrahimi                        SizePolicy size_policy = kMaximumSize)
assembler_(NULL)71*f5c631daSSadaf Ebrahimi       : assembler_(NULL), initialised_(false) {
72*f5c631daSSadaf Ebrahimi     Open(assembler, size, check_policy, size_policy);
73*f5c631daSSadaf Ebrahimi   }
74*f5c631daSSadaf Ebrahimi 
75*f5c631daSSadaf Ebrahimi   // This constructor does not implicitly initialise the scope. Instead, the
76*f5c631daSSadaf Ebrahimi   // user is required to explicitly call the `Open` function before using the
77*f5c631daSSadaf Ebrahimi   // scope.
CodeBufferCheckScope()78*f5c631daSSadaf Ebrahimi   CodeBufferCheckScope() : assembler_(NULL), initialised_(false) {
79*f5c631daSSadaf Ebrahimi     // Nothing to do.
80*f5c631daSSadaf Ebrahimi   }
81*f5c631daSSadaf Ebrahimi 
~CodeBufferCheckScope()82*f5c631daSSadaf Ebrahimi   virtual ~CodeBufferCheckScope() { Close(); }
83*f5c631daSSadaf Ebrahimi 
84*f5c631daSSadaf Ebrahimi   // This function performs the actual initialisation work.
85*f5c631daSSadaf Ebrahimi   void Open(internal::AssemblerBase* assembler,
86*f5c631daSSadaf Ebrahimi             size_t size,
87*f5c631daSSadaf Ebrahimi             BufferSpacePolicy check_policy = kReserveBufferSpace,
88*f5c631daSSadaf Ebrahimi             SizePolicy size_policy = kMaximumSize) {
89*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!initialised_);
90*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(assembler != NULL);
91*f5c631daSSadaf Ebrahimi     assembler_ = assembler;
92*f5c631daSSadaf Ebrahimi     if (check_policy == kReserveBufferSpace) {
93*f5c631daSSadaf Ebrahimi       assembler->GetBuffer()->EnsureSpaceFor(size);
94*f5c631daSSadaf Ebrahimi     }
95*f5c631daSSadaf Ebrahimi #ifdef VIXL_DEBUG
96*f5c631daSSadaf Ebrahimi     limit_ = assembler_->GetSizeOfCodeGenerated() + size;
97*f5c631daSSadaf Ebrahimi     assert_policy_ = size_policy;
98*f5c631daSSadaf Ebrahimi     previous_allow_assembler_ = assembler_->AllowAssembler();
99*f5c631daSSadaf Ebrahimi     assembler_->SetAllowAssembler(true);
100*f5c631daSSadaf Ebrahimi #else
101*f5c631daSSadaf Ebrahimi     USE(size_policy);
102*f5c631daSSadaf Ebrahimi #endif
103*f5c631daSSadaf Ebrahimi     initialised_ = true;
104*f5c631daSSadaf Ebrahimi   }
105*f5c631daSSadaf Ebrahimi 
106*f5c631daSSadaf Ebrahimi   // This function performs the cleaning-up work. It must succeed even if the
107*f5c631daSSadaf Ebrahimi   // scope has not been opened. It is safe to call multiple times.
Close()108*f5c631daSSadaf Ebrahimi   void Close() {
109*f5c631daSSadaf Ebrahimi #ifdef VIXL_DEBUG
110*f5c631daSSadaf Ebrahimi     if (!initialised_) {
111*f5c631daSSadaf Ebrahimi       return;
112*f5c631daSSadaf Ebrahimi     }
113*f5c631daSSadaf Ebrahimi     assembler_->SetAllowAssembler(previous_allow_assembler_);
114*f5c631daSSadaf Ebrahimi     switch (assert_policy_) {
115*f5c631daSSadaf Ebrahimi       case kNoAssert:
116*f5c631daSSadaf Ebrahimi         break;
117*f5c631daSSadaf Ebrahimi       case kExactSize:
118*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(assembler_->GetSizeOfCodeGenerated() == limit_);
119*f5c631daSSadaf Ebrahimi         break;
120*f5c631daSSadaf Ebrahimi       case kMaximumSize:
121*f5c631daSSadaf Ebrahimi         VIXL_ASSERT(assembler_->GetSizeOfCodeGenerated() <= limit_);
122*f5c631daSSadaf Ebrahimi         break;
123*f5c631daSSadaf Ebrahimi       default:
124*f5c631daSSadaf Ebrahimi         VIXL_UNREACHABLE();
125*f5c631daSSadaf Ebrahimi     }
126*f5c631daSSadaf Ebrahimi #endif
127*f5c631daSSadaf Ebrahimi     initialised_ = false;
128*f5c631daSSadaf Ebrahimi   }
129*f5c631daSSadaf Ebrahimi 
130*f5c631daSSadaf Ebrahimi  protected:
131*f5c631daSSadaf Ebrahimi   internal::AssemblerBase* assembler_;
132*f5c631daSSadaf Ebrahimi   SizePolicy assert_policy_;
133*f5c631daSSadaf Ebrahimi   size_t limit_;
134*f5c631daSSadaf Ebrahimi   bool previous_allow_assembler_;
135*f5c631daSSadaf Ebrahimi   bool initialised_;
136*f5c631daSSadaf Ebrahimi };
137*f5c631daSSadaf Ebrahimi 
138*f5c631daSSadaf Ebrahimi 
139*f5c631daSSadaf Ebrahimi // This scope will:
140*f5c631daSSadaf Ebrahimi // - Do the same as `CodeBufferCheckSCope`, but:
141*f5c631daSSadaf Ebrahimi //   - If managed by VIXL, always reserve space in the `CodeBuffer`.
142*f5c631daSSadaf Ebrahimi //   - Always check the size (exact or maximum) of the generated code on
143*f5c631daSSadaf Ebrahimi //     destruction.
144*f5c631daSSadaf Ebrahimi // - Emit pools if the specified size would push them out of range.
145*f5c631daSSadaf Ebrahimi // - Block pools emission for the duration of the scope.
146*f5c631daSSadaf Ebrahimi // This scope allows the `Assembler` and `MacroAssembler` to be freely and
147*f5c631daSSadaf Ebrahimi // safely mixed for its duration.
148*f5c631daSSadaf Ebrahimi class EmissionCheckScope : public CodeBufferCheckScope {
149*f5c631daSSadaf Ebrahimi  public:
150*f5c631daSSadaf Ebrahimi   // This constructor implicitly calls `Open` (when `masm` is not `NULL`) to
151*f5c631daSSadaf Ebrahimi   // initialise the scope, so it is ready to use immediately after it has been
152*f5c631daSSadaf Ebrahimi   // constructed.
153*f5c631daSSadaf Ebrahimi   EmissionCheckScope(MacroAssemblerInterface* masm,
154*f5c631daSSadaf Ebrahimi                      size_t size,
155*f5c631daSSadaf Ebrahimi                      SizePolicy size_policy = kMaximumSize) {
156*f5c631daSSadaf Ebrahimi     Open(masm, size, size_policy);
157*f5c631daSSadaf Ebrahimi   }
158*f5c631daSSadaf Ebrahimi 
159*f5c631daSSadaf Ebrahimi   // This constructor does not implicitly initialise the scope. Instead, the
160*f5c631daSSadaf Ebrahimi   // user is required to explicitly call the `Open` function before using the
161*f5c631daSSadaf Ebrahimi   // scope.
EmissionCheckScope()162*f5c631daSSadaf Ebrahimi   EmissionCheckScope() {}
163*f5c631daSSadaf Ebrahimi 
~EmissionCheckScope()164*f5c631daSSadaf Ebrahimi   virtual ~EmissionCheckScope() { Close(); }
165*f5c631daSSadaf Ebrahimi 
166*f5c631daSSadaf Ebrahimi   enum PoolPolicy {
167*f5c631daSSadaf Ebrahimi     // Do not forbid pool emission inside the scope. Pools will not be emitted
168*f5c631daSSadaf Ebrahimi     // on `Open` either.
169*f5c631daSSadaf Ebrahimi     kIgnorePools,
170*f5c631daSSadaf Ebrahimi     // Force pools to be generated on `Open` if necessary and block their
171*f5c631daSSadaf Ebrahimi     // emission inside the scope.
172*f5c631daSSadaf Ebrahimi     kBlockPools,
173*f5c631daSSadaf Ebrahimi     // Deprecated, but kept for backward compatibility.
174*f5c631daSSadaf Ebrahimi     kCheckPools = kBlockPools
175*f5c631daSSadaf Ebrahimi   };
176*f5c631daSSadaf Ebrahimi 
177*f5c631daSSadaf Ebrahimi   void Open(MacroAssemblerInterface* masm,
178*f5c631daSSadaf Ebrahimi             size_t size,
179*f5c631daSSadaf Ebrahimi             SizePolicy size_policy = kMaximumSize) {
180*f5c631daSSadaf Ebrahimi     Open(masm, size, size_policy, kBlockPools);
181*f5c631daSSadaf Ebrahimi   }
182*f5c631daSSadaf Ebrahimi 
Close()183*f5c631daSSadaf Ebrahimi   void Close() {
184*f5c631daSSadaf Ebrahimi     if (!initialised_) {
185*f5c631daSSadaf Ebrahimi       return;
186*f5c631daSSadaf Ebrahimi     }
187*f5c631daSSadaf Ebrahimi     if (masm_ == NULL) {
188*f5c631daSSadaf Ebrahimi       // Nothing to do.
189*f5c631daSSadaf Ebrahimi       return;
190*f5c631daSSadaf Ebrahimi     }
191*f5c631daSSadaf Ebrahimi     // Perform the opposite of `Open`, which is:
192*f5c631daSSadaf Ebrahimi     //   - Check the code generation limit was not exceeded.
193*f5c631daSSadaf Ebrahimi     //   - Release the pools.
194*f5c631daSSadaf Ebrahimi     CodeBufferCheckScope::Close();
195*f5c631daSSadaf Ebrahimi     if (pool_policy_ == kBlockPools) {
196*f5c631daSSadaf Ebrahimi       masm_->ReleasePools();
197*f5c631daSSadaf Ebrahimi     }
198*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(!initialised_);
199*f5c631daSSadaf Ebrahimi   }
200*f5c631daSSadaf Ebrahimi 
201*f5c631daSSadaf Ebrahimi  protected:
Open(MacroAssemblerInterface * masm,size_t size,SizePolicy size_policy,PoolPolicy pool_policy)202*f5c631daSSadaf Ebrahimi   void Open(MacroAssemblerInterface* masm,
203*f5c631daSSadaf Ebrahimi             size_t size,
204*f5c631daSSadaf Ebrahimi             SizePolicy size_policy,
205*f5c631daSSadaf Ebrahimi             PoolPolicy pool_policy) {
206*f5c631daSSadaf Ebrahimi     if (masm == NULL) {
207*f5c631daSSadaf Ebrahimi       // Nothing to do.
208*f5c631daSSadaf Ebrahimi       // We may reach this point in a context of conditional code generation.
209*f5c631daSSadaf Ebrahimi       // See `aarch64::MacroAssembler::MoveImmediateHelper()` for an example.
210*f5c631daSSadaf Ebrahimi       return;
211*f5c631daSSadaf Ebrahimi     }
212*f5c631daSSadaf Ebrahimi     masm_ = masm;
213*f5c631daSSadaf Ebrahimi     pool_policy_ = pool_policy;
214*f5c631daSSadaf Ebrahimi     if (pool_policy_ == kBlockPools) {
215*f5c631daSSadaf Ebrahimi       // To avoid duplicating the work to check that enough space is available
216*f5c631daSSadaf Ebrahimi       // in the buffer, do not use the more generic `EnsureEmitFor()`. It is
217*f5c631daSSadaf Ebrahimi       // done below when opening `CodeBufferCheckScope`.
218*f5c631daSSadaf Ebrahimi       masm->EnsureEmitPoolsFor(size);
219*f5c631daSSadaf Ebrahimi       masm->BlockPools();
220*f5c631daSSadaf Ebrahimi     }
221*f5c631daSSadaf Ebrahimi     // The buffer should be checked *after* we emit the pools.
222*f5c631daSSadaf Ebrahimi     CodeBufferCheckScope::Open(masm->AsAssemblerBase(),
223*f5c631daSSadaf Ebrahimi                                size,
224*f5c631daSSadaf Ebrahimi                                kReserveBufferSpace,
225*f5c631daSSadaf Ebrahimi                                size_policy);
226*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(initialised_);
227*f5c631daSSadaf Ebrahimi   }
228*f5c631daSSadaf Ebrahimi 
229*f5c631daSSadaf Ebrahimi   // This constructor should only be used from code that is *currently
230*f5c631daSSadaf Ebrahimi   // generating* the pools, to avoid an infinite loop.
EmissionCheckScope(MacroAssemblerInterface * masm,size_t size,SizePolicy size_policy,PoolPolicy pool_policy)231*f5c631daSSadaf Ebrahimi   EmissionCheckScope(MacroAssemblerInterface* masm,
232*f5c631daSSadaf Ebrahimi                      size_t size,
233*f5c631daSSadaf Ebrahimi                      SizePolicy size_policy,
234*f5c631daSSadaf Ebrahimi                      PoolPolicy pool_policy) {
235*f5c631daSSadaf Ebrahimi     Open(masm, size, size_policy, pool_policy);
236*f5c631daSSadaf Ebrahimi   }
237*f5c631daSSadaf Ebrahimi 
238*f5c631daSSadaf Ebrahimi   MacroAssemblerInterface* masm_;
239*f5c631daSSadaf Ebrahimi   PoolPolicy pool_policy_;
240*f5c631daSSadaf Ebrahimi };
241*f5c631daSSadaf Ebrahimi 
242*f5c631daSSadaf Ebrahimi // Use this scope when you need a one-to-one mapping between methods and
243*f5c631daSSadaf Ebrahimi // instructions. This scope will:
244*f5c631daSSadaf Ebrahimi // - Do the same as `EmissionCheckScope`.
245*f5c631daSSadaf Ebrahimi // - Block access to the MacroAssemblerInterface (using run-time assertions).
246*f5c631daSSadaf Ebrahimi class ExactAssemblyScope : public EmissionCheckScope {
247*f5c631daSSadaf Ebrahimi  public:
248*f5c631daSSadaf Ebrahimi   // This constructor implicitly calls `Open` (when `masm` is not `NULL`) to
249*f5c631daSSadaf Ebrahimi   // initialise the scope, so it is ready to use immediately after it has been
250*f5c631daSSadaf Ebrahimi   // constructed.
251*f5c631daSSadaf Ebrahimi   ExactAssemblyScope(MacroAssemblerInterface* masm,
252*f5c631daSSadaf Ebrahimi                      size_t size,
253*f5c631daSSadaf Ebrahimi                      SizePolicy size_policy = kExactSize) {
254*f5c631daSSadaf Ebrahimi     Open(masm, size, size_policy);
255*f5c631daSSadaf Ebrahimi   }
256*f5c631daSSadaf Ebrahimi 
257*f5c631daSSadaf Ebrahimi   // This constructor does not implicitly initialise the scope. Instead, the
258*f5c631daSSadaf Ebrahimi   // user is required to explicitly call the `Open` function before using the
259*f5c631daSSadaf Ebrahimi   // scope.
ExactAssemblyScope()260*f5c631daSSadaf Ebrahimi   ExactAssemblyScope() {}
261*f5c631daSSadaf Ebrahimi 
~ExactAssemblyScope()262*f5c631daSSadaf Ebrahimi   virtual ~ExactAssemblyScope() { Close(); }
263*f5c631daSSadaf Ebrahimi 
264*f5c631daSSadaf Ebrahimi   void Open(MacroAssemblerInterface* masm,
265*f5c631daSSadaf Ebrahimi             size_t size,
266*f5c631daSSadaf Ebrahimi             SizePolicy size_policy = kExactSize) {
267*f5c631daSSadaf Ebrahimi     Open(masm, size, size_policy, kBlockPools);
268*f5c631daSSadaf Ebrahimi   }
269*f5c631daSSadaf Ebrahimi 
Close()270*f5c631daSSadaf Ebrahimi   void Close() {
271*f5c631daSSadaf Ebrahimi     if (!initialised_) {
272*f5c631daSSadaf Ebrahimi       return;
273*f5c631daSSadaf Ebrahimi     }
274*f5c631daSSadaf Ebrahimi     if (masm_ == NULL) {
275*f5c631daSSadaf Ebrahimi       // Nothing to do.
276*f5c631daSSadaf Ebrahimi       return;
277*f5c631daSSadaf Ebrahimi     }
278*f5c631daSSadaf Ebrahimi #ifdef VIXL_DEBUG
279*f5c631daSSadaf Ebrahimi     masm_->SetAllowMacroInstructions(previous_allow_macro_assembler_);
280*f5c631daSSadaf Ebrahimi #else
281*f5c631daSSadaf Ebrahimi     USE(previous_allow_macro_assembler_);
282*f5c631daSSadaf Ebrahimi #endif
283*f5c631daSSadaf Ebrahimi     EmissionCheckScope::Close();
284*f5c631daSSadaf Ebrahimi   }
285*f5c631daSSadaf Ebrahimi 
286*f5c631daSSadaf Ebrahimi  protected:
287*f5c631daSSadaf Ebrahimi   // This protected constructor allows overriding the pool policy. It is
288*f5c631daSSadaf Ebrahimi   // available to allow this scope to be used in code that handles generation
289*f5c631daSSadaf Ebrahimi   // of pools.
ExactAssemblyScope(MacroAssemblerInterface * masm,size_t size,SizePolicy assert_policy,PoolPolicy pool_policy)290*f5c631daSSadaf Ebrahimi   ExactAssemblyScope(MacroAssemblerInterface* masm,
291*f5c631daSSadaf Ebrahimi                      size_t size,
292*f5c631daSSadaf Ebrahimi                      SizePolicy assert_policy,
293*f5c631daSSadaf Ebrahimi                      PoolPolicy pool_policy) {
294*f5c631daSSadaf Ebrahimi     Open(masm, size, assert_policy, pool_policy);
295*f5c631daSSadaf Ebrahimi   }
296*f5c631daSSadaf Ebrahimi 
Open(MacroAssemblerInterface * masm,size_t size,SizePolicy size_policy,PoolPolicy pool_policy)297*f5c631daSSadaf Ebrahimi   void Open(MacroAssemblerInterface* masm,
298*f5c631daSSadaf Ebrahimi             size_t size,
299*f5c631daSSadaf Ebrahimi             SizePolicy size_policy,
300*f5c631daSSadaf Ebrahimi             PoolPolicy pool_policy) {
301*f5c631daSSadaf Ebrahimi     VIXL_ASSERT(size_policy != kNoAssert);
302*f5c631daSSadaf Ebrahimi     if (masm == NULL) {
303*f5c631daSSadaf Ebrahimi       // Nothing to do.
304*f5c631daSSadaf Ebrahimi       return;
305*f5c631daSSadaf Ebrahimi     }
306*f5c631daSSadaf Ebrahimi     // Rely on EmissionCheckScope::Open to initialise `masm_` and
307*f5c631daSSadaf Ebrahimi     // `pool_policy_`.
308*f5c631daSSadaf Ebrahimi     EmissionCheckScope::Open(masm, size, size_policy, pool_policy);
309*f5c631daSSadaf Ebrahimi #ifdef VIXL_DEBUG
310*f5c631daSSadaf Ebrahimi     previous_allow_macro_assembler_ = masm->AllowMacroInstructions();
311*f5c631daSSadaf Ebrahimi     masm->SetAllowMacroInstructions(false);
312*f5c631daSSadaf Ebrahimi #endif
313*f5c631daSSadaf Ebrahimi   }
314*f5c631daSSadaf Ebrahimi 
315*f5c631daSSadaf Ebrahimi  private:
316*f5c631daSSadaf Ebrahimi   bool previous_allow_macro_assembler_;
317*f5c631daSSadaf Ebrahimi };
318*f5c631daSSadaf Ebrahimi 
319*f5c631daSSadaf Ebrahimi 
320*f5c631daSSadaf Ebrahimi }  // namespace vixl
321*f5c631daSSadaf Ebrahimi 
322*f5c631daSSadaf Ebrahimi #endif  // VIXL_CODE_GENERATION_SCOPES_H_
323