OSDN Git Service

Thumb2: Fix EmitJumpTables() to extend buffer only if needed.
authorVladimir Marko <vmarko@google.com>
Wed, 20 Apr 2016 13:39:47 +0000 (14:39 +0100)
committerVladimir Marko <vmarko@google.com>
Wed, 20 Apr 2016 14:38:03 +0000 (15:38 +0100)
Bug: 28256882

(cherry picked from commit 9152fed693f5d823ef29c373d658adc67fa92fe7)

Change-Id: I804e45c8c6a7bc97fcec5a380ccc1bdf70de8b00

compiler/utils/arm/assembler_thumb2.cc
compiler/utils/assembler.cc
compiler/utils/assembler.h

index 26f7d0d..2c73fb8 100644 (file)
@@ -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
index c2aa574..e6c3a18 100644 (file)
@@ -47,7 +47,7 @@ namespace art {
 AssemblerBuffer::AssemblerBuffer(ArenaAllocator* arena)
     : arena_(arena) {
   static const size_t kInitialBufferCapacity = 4 * KB;
-  contents_ = arena_->AllocArray<uint8_t>(kInitialBufferCapacity);
+  contents_ = arena_->AllocArray<uint8_t>(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);
 
index 4ea85a2..96da03d 100644 (file)
@@ -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.