From 9152fed693f5d823ef29c373d658adc67fa92fe7 Mon Sep 17 00:00:00 2001 From: Vladimir Marko Date: Wed, 20 Apr 2016 14:39:47 +0100 Subject: [PATCH] Thumb2: Fix EmitJumpTables() to extend buffer only if needed. Bug: 28256882 Change-Id: I15227535c0fcb73c04b0b05160852c4b1bebee49 --- compiler/utils/arm/assembler_thumb2.cc | 5 ++++- compiler/utils/assembler.cc | 3 ++- compiler/utils/assembler.h | 21 +++++++++++++-------- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/compiler/utils/arm/assembler_thumb2.cc b/compiler/utils/arm/assembler_thumb2.cc index 26f7d0dfc..2c73fb809 100644 --- a/compiler/utils/arm/assembler_thumb2.cc +++ b/compiler/utils/arm/assembler_thumb2.cc @@ -256,7 +256,10 @@ void Thumb2Assembler::EmitJumpTables() { for (JumpTable& table : jump_tables_) { // Bulk ensure capacity, as this may be large. size_t orig_size = buffer_.Size(); - buffer_.ExtendCapacity(orig_size + table.GetSize()); + size_t required_capacity = orig_size + table.GetSize(); + if (required_capacity > buffer_.Capacity()) { + buffer_.ExtendCapacity(required_capacity); + } #ifndef NDEBUG buffer_.has_ensured_capacity_ = true; #endif diff --git a/compiler/utils/assembler.cc b/compiler/utils/assembler.cc index c2aa574f7..e6c3a18d0 100644 --- a/compiler/utils/assembler.cc +++ b/compiler/utils/assembler.cc @@ -47,7 +47,7 @@ namespace art { AssemblerBuffer::AssemblerBuffer(ArenaAllocator* arena) : arena_(arena) { static const size_t kInitialBufferCapacity = 4 * KB; - contents_ = arena_->AllocArray(kInitialBufferCapacity); + contents_ = arena_->AllocArray(kInitialBufferCapacity, kArenaAllocAssembler); cursor_ = contents_; limit_ = ComputeLimit(contents_, kInitialBufferCapacity); fixup_ = nullptr; @@ -94,6 +94,7 @@ void AssemblerBuffer::FinalizeInstructions(const MemoryRegion& instructions) { void AssemblerBuffer::ExtendCapacity(size_t min_capacity) { size_t old_size = Size(); size_t old_capacity = Capacity(); + DCHECK_GT(min_capacity, old_capacity); size_t new_capacity = std::min(old_capacity * 2, old_capacity + 1 * MB); new_capacity = std::max(new_capacity, min_capacity); diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h index f70fe04ed..5267dc381 100644 --- a/compiler/utils/assembler.h +++ b/compiler/utils/assembler.h @@ -178,8 +178,8 @@ class AssemblerBuffer { class EnsureCapacity { public: explicit EnsureCapacity(AssemblerBuffer* buffer) { - if (buffer->cursor() >= buffer->limit()) { - buffer->ExtendCapacity(); + if (buffer->cursor() > buffer->limit()) { + buffer->ExtendCapacity(buffer->Size() + kMinimumGap); } // In debug mode, we save the assembler buffer along with the gap // size before we start emitting to the buffer. This allows us to @@ -219,7 +219,9 @@ class AssemblerBuffer { class EnsureCapacity { public: explicit EnsureCapacity(AssemblerBuffer* buffer) { - if (buffer->cursor() >= buffer->limit()) buffer->ExtendCapacity(); + if (buffer->cursor() > buffer->limit()) { + buffer->ExtendCapacity(buffer->Size() + kMinimumGap); + } } }; @@ -233,7 +235,14 @@ class AssemblerBuffer { // Returns the position in the instruction stream. int GetPosition() { return cursor_ - contents_; } - void ExtendCapacity(size_t min_capacity = 0u); + size_t Capacity() const { + CHECK_GE(limit_, contents_); + return (limit_ - contents_) + kMinimumGap; + } + + // Unconditionally increase the capacity. + // The provided `min_capacity` must be higher than current `Capacity()`. + void ExtendCapacity(size_t min_capacity); private: // The limit is set to kMinimumGap bytes before the end of the data area. @@ -255,10 +264,6 @@ class AssemblerBuffer { uint8_t* cursor() const { return cursor_; } uint8_t* limit() const { return limit_; } - size_t Capacity() const { - CHECK_GE(limit_, contents_); - return (limit_ - contents_) + kMinimumGap; - } // Process the fixup chain starting at the given fixup. The offset is // non-zero for fixups in the body if the preamble is non-empty. -- 2.11.0