diff options
author | Pierre Langlois <pierre.langlois@arm.com> | 2017-01-11 14:00:39 +0000 |
---|---|---|
committer | Pierre Langlois <pierre.langlois@arm.com> | 2017-01-13 10:45:33 +0000 |
commit | d56f609907e454dd41bb8b2d98e078e69c4feafa (patch) | |
tree | 87f14ddcb4f5681b2e2899b5f3a82d2808af3e3c | |
parent | d87b1134b5be7b7fb5518180efb3b20b37a7923b (diff) |
ExactAssemblyScope: Force the pools not to be emitted
There was a bug where the AArch32 MacroAssembler would still generate
pools inside ExactAssemblyScope. In order to avoid this, this patch
renames the `kCheckPools` policy to `kBlockPools`. Saying "check"
implies we only assert that pools are not generated, which is not the case.
Change-Id: Ica717f56f99c7363add5361076174e8e827dd81c
-rw-r--r-- | src/aarch32/macro-assembler-aarch32.cc | 7 | ||||
-rw-r--r-- | src/aarch32/macro-assembler-aarch32.h | 3 | ||||
-rw-r--r-- | src/code-generation-scopes-vixl.h | 17 |
3 files changed, 20 insertions, 7 deletions
diff --git a/src/aarch32/macro-assembler-aarch32.cc b/src/aarch32/macro-assembler-aarch32.cc index 1e7a6b52..86d26064 100644 --- a/src/aarch32/macro-assembler-aarch32.cc +++ b/src/aarch32/macro-assembler-aarch32.cc @@ -302,6 +302,7 @@ void VeneerPoolManager::RemoveLabel(Label* label) { void VeneerPoolManager::EmitLabel(Label* label, Label::Offset emitted_target) { + VIXL_ASSERT(!IsBlocked()); // Define the veneer. Label veneer; masm_->Bind(&veneer); @@ -419,7 +420,7 @@ void MacroAssembler::PerformEnsureEmit(Label::Offset target, uint32_t size) { generate_veneers = true; } } - if (generate_veneers) { + if (!veneer_pool_manager_.IsBlocked() && generate_veneers) { { ExactAssemblyScopeWithoutPoolsCheck guard(this, @@ -433,7 +434,8 @@ void MacroAssembler::PerformEnsureEmit(Label::Offset target, uint32_t size) { // Check if the macro-assembler's internal literal pool should be emitted // to avoid any overflow. If we already generated the veneers, we can // emit the pool (the branch is already done). - if ((target > literal_target) || (option == kNoBranchRequired)) { + if (!literal_pool_manager_.IsBlocked() && + ((target > literal_target) || (option == kNoBranchRequired))) { EmitLiteralPool(option); } BindHelper(&after_pools); @@ -458,6 +460,7 @@ void MacroAssembler::ComputeCheckpoint() { void MacroAssembler::EmitLiteralPool(LiteralPool* const literal_pool, EmitOption option) { + VIXL_ASSERT(!literal_pool_manager_.IsBlocked()); if (literal_pool->GetSize() > 0) { #ifdef VIXL_DEBUG for (LiteralPool::RawLiteralListIterator literal_it = diff --git a/src/aarch32/macro-assembler-aarch32.h b/src/aarch32/macro-assembler-aarch32.h index 706b5a5e..9bb725f3 100644 --- a/src/aarch32/macro-assembler-aarch32.h +++ b/src/aarch32/macro-assembler-aarch32.h @@ -435,7 +435,8 @@ class MacroAssembler : public Assembler, public MacroAssemblerInterface { ITScope it_scope(this, &c); instr_callback.emit(this, c, literal); } - if (!literal->IsManuallyPlaced() && !literal->IsBound()) { + if (!literal->IsManuallyPlaced() && !literal->IsBound() && + !literal_pool_manager_.IsBlocked()) { if (WasInsertedTooFar(literal)) { // The instruction's data is too far: revert the emission GetBuffer()->Rewind(cursor); diff --git a/src/code-generation-scopes-vixl.h b/src/code-generation-scopes-vixl.h index 7e47d5ed..40c288c5 100644 --- a/src/code-generation-scopes-vixl.h +++ b/src/code-generation-scopes-vixl.h @@ -163,12 +163,21 @@ class EmissionCheckScope : public CodeBufferCheckScope { virtual ~EmissionCheckScope() { Close(); } - enum PoolPolicy { kIgnorePools, kCheckPools }; + enum PoolPolicy { + // Do not forbid pool emission inside the scope. Pools will not be emitted + // on `Open` either. + kIgnorePools, + // Force pools to be generated on `Open` if necessary and block their + // emission inside the scope. + kBlockPools, + // Deprecated, but kept for backward compatibility. + kCheckPools = kBlockPools + }; void Open(MacroAssemblerInterface* masm, size_t size, SizePolicy size_policy = kMaximumSize) { - Open(masm, size, size_policy, kCheckPools); + Open(masm, size, size_policy, kBlockPools); } void Close() { @@ -183,7 +192,7 @@ class EmissionCheckScope : public CodeBufferCheckScope { // - Check the code generation limit was not exceeded. // - Release the pools. CodeBufferCheckScope::Close(); - if (pool_policy_ == kCheckPools) { + if (pool_policy_ == kBlockPools) { masm_->ReleasePools(); } VIXL_ASSERT(!initialised_); @@ -202,7 +211,7 @@ class EmissionCheckScope : public CodeBufferCheckScope { } masm_ = masm; pool_policy_ = pool_policy; - if (pool_policy_ == kCheckPools) { + if (pool_policy_ == kBlockPools) { // To avoid duplicating the work to check that enough space is available // in the buffer, do not use the more generic `EnsureEmitFor()`. It is // done below when opening `CodeBufferCheckScope`. |