diff options
author | Alexandre Rames <alexandre.rames@linaro.org> | 2016-08-04 09:43:39 +0100 |
---|---|---|
committer | Alexandre Rames <alexandre.rames@linaro.org> | 2016-08-09 08:36:59 +0100 |
commit | de5bb0beb4a3342bb9f0d7e7fe16737a171517b0 (patch) | |
tree | 5eca2d7ed06f4d09f1a7ae917822d554a8d826f5 /src/aarch64/macro-assembler-aarch64.h | |
parent | 9fbd11bbc6a56071f455df28e08854a848f46c3b (diff) |
AArch64: Refactor `InstructionAccurateScope` and add a regression test.
The previous implementation was not emitting the pools when it needed to upon
construction, and was not correctly blocking emission of the pools.
Change-Id: I06db5b5891234946b139ba64898929c0e3ced3c4
Diffstat (limited to 'src/aarch64/macro-assembler-aarch64.h')
-rw-r--r-- | src/aarch64/macro-assembler-aarch64.h | 52 |
1 files changed, 45 insertions, 7 deletions
diff --git a/src/aarch64/macro-assembler-aarch64.h b/src/aarch64/macro-assembler-aarch64.h index 5bac71c7..e2206ce2 100644 --- a/src/aarch64/macro-assembler-aarch64.h +++ b/src/aarch64/macro-assembler-aarch64.h @@ -502,11 +502,30 @@ class VeneerPool : public Pool { // * Ensure there is enough space to emit the macro-instruction. class EmissionCheckScope : public CodeBufferCheckScope { public: - EmissionCheckScope(MacroAssembler* masm, size_t size); + EmissionCheckScope(MacroAssembler* masm, + size_t size, + AssertPolicy assert_policy = kMaximumSize); ~EmissionCheckScope(); + enum PoolPolicy { kIgnorePools, kCheckPools }; + protected: + // This constructor should only be used from code that is *currently + // generating* the pools, to avoid an infinite loop. + EmissionCheckScope(MacroAssembler* masm, + size_t size, + AssertPolicy assert_policy, + PoolPolicy pool_policy); + + void Open(MacroAssembler* masm, + size_t size, + AssertPolicy assert_policy = kMaximumSize, + PoolPolicy pool_policy = kCheckPools); + + void Close(); + MacroAssembler* masm_; + PoolPolicy pool_policy_; }; @@ -3153,15 +3172,15 @@ inline void LiteralPool::SetNextRecommendedCheckpoint(ptrdiff_t offset) { // Use this scope when you need a one-to-one mapping between methods and // instructions. This scope prevents the MacroAssembler from being called and -// literal pools from being emitted. It also asserts the number of instructions -// emitted is what you specified when creating the scope. -class InstructionAccurateScope : public CodeBufferCheckScope { +// pools from being emitted. It also asserts the number of instructions emitted +// is what you specified when creating the scope. +class InstructionAccurateScope : public EmissionCheckScope { public: InstructionAccurateScope(MacroAssembler* masm, int64_t count, - AssertPolicy policy = kExactSize) - : CodeBufferCheckScope(masm, (count * kInstructionSize), kCheck, policy) { - VIXL_ASSERT(policy != kNoAssert); + AssertPolicy assert_policy = kExactSize) + : EmissionCheckScope(masm, (count * kInstructionSize), assert_policy) { + VIXL_ASSERT(assert_policy != kNoAssert); #ifdef VIXL_DEBUG old_allow_macro_instructions_ = masm->AllowMacroInstructions(); masm->SetAllowMacroInstructions(false); @@ -3176,6 +3195,25 @@ class InstructionAccurateScope : public CodeBufferCheckScope { } private: + InstructionAccurateScope(MacroAssembler* masm, + int64_t count, + AssertPolicy assert_policy, + PoolPolicy pool_policy) + : EmissionCheckScope(masm, + (count * kInstructionSize), + assert_policy, + pool_policy) { + VIXL_ASSERT(assert_policy != kNoAssert); +#ifdef VIXL_DEBUG + old_allow_macro_instructions_ = masm->AllowMacroInstructions(); + masm->SetAllowMacroInstructions(false); +#endif + } + + // Grant access to the above private constructor for pool emission methods. + friend void LiteralPool::Emit(LiteralPool::EmitOption); + friend void VeneerPool::Emit(VeneerPool::EmitOption, size_t); + #ifdef VIXL_DEBUG bool old_allow_macro_instructions_; #endif |