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