diff options
Diffstat (limited to 'compiler/utils/assembler.h')
| -rw-r--r-- | compiler/utils/assembler.h | 64 |
1 files changed, 43 insertions, 21 deletions
diff --git a/compiler/utils/assembler.h b/compiler/utils/assembler.h index 1dbc142391..80aa630424 100644 --- a/compiler/utils/assembler.h +++ b/compiler/utils/assembler.h @@ -21,17 +21,20 @@ #include "arch/instruction_set.h" #include "arch/instruction_set_features.h" +#include "arm/constants_arm.h" +#include "base/arena_allocator.h" +#include "base/arena_object.h" #include "base/logging.h" #include "base/macros.h" -#include "arm/constants_arm.h" +#include "debug/dwarf/debug_frame_opcode_writer.h" #include "label.h" #include "managed_register.h" #include "memory_region.h" #include "mips/constants_mips.h" #include "offsets.h" +#include "utils/array_ref.h" #include "x86/constants_x86.h" #include "x86_64/constants_x86_64.h" -#include "dwarf/debug_frame_opcode_writer.h" namespace art { @@ -60,7 +63,7 @@ class AssemblerFixup { }; // Parent of all queued slow paths, emitted during finalization -class SlowPath { +class SlowPath : public DeletableArenaObject<kArenaAllocAssembler> { public: SlowPath() : next_(nullptr) {} virtual ~SlowPath() {} @@ -85,9 +88,13 @@ class SlowPath { class AssemblerBuffer { public: - AssemblerBuffer(); + explicit AssemblerBuffer(ArenaAllocator* arena); ~AssemblerBuffer(); + ArenaAllocator* GetArena() { + return arena_; + } + // Basic support for emitting, loading, and storing. template<typename T> void Emit(T value) { CHECK(HasEnsuredCapacity()); @@ -172,8 +179,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 @@ -213,7 +220,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); + } } }; @@ -227,7 +236,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. @@ -235,6 +251,7 @@ class AssemblerBuffer { // for a single, fast space check per instruction. static const int kMinimumGap = 32; + ArenaAllocator* arena_; uint8_t* contents_; uint8_t* cursor_; uint8_t* limit_; @@ -248,10 +265,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. @@ -299,8 +312,10 @@ class DebugFrameOpCodeWriterForAssembler FINAL // Override the last delayed PC. The new PC can be out of order. void OverrideDelayedPC(size_t pc) { DCHECK(delay_emitting_advance_pc_); - DCHECK(!delayed_advance_pcs_.empty()); - delayed_advance_pcs_.back().pc = pc; + if (enabled_) { + DCHECK(!delayed_advance_pcs_.empty()); + delayed_advance_pcs_.back().pc = pc; + } } // Return the number of delayed advance PC entries. @@ -338,10 +353,12 @@ class DebugFrameOpCodeWriterForAssembler FINAL std::vector<DelayedAdvancePC> delayed_advance_pcs_; }; -class Assembler { +class Assembler : public DeletableArenaObject<kArenaAllocAssembler> { public: - static Assembler* Create(InstructionSet instruction_set, - const InstructionSetFeatures* instruction_set_features = nullptr); + static std::unique_ptr<Assembler> Create( + ArenaAllocator* arena, + InstructionSet instruction_set, + const InstructionSetFeatures* instruction_set_features = nullptr); // Finalize the code; emit slow paths, fixup branches, add literal pool, etc. virtual void FinalizeCode() { buffer_.EmitSlowPaths(this); } @@ -359,13 +376,14 @@ class Assembler { virtual void Comment(const char* format ATTRIBUTE_UNUSED, ...) {} // Emit code that will create an activation on the stack - virtual void BuildFrame(size_t frame_size, ManagedRegister method_reg, - const std::vector<ManagedRegister>& callee_save_regs, + virtual void BuildFrame(size_t frame_size, + ManagedRegister method_reg, + ArrayRef<const ManagedRegister> callee_save_regs, const ManagedRegisterEntrySpills& entry_spills) = 0; // Emit code that will remove an activation from the stack virtual void RemoveFrame(size_t frame_size, - const std::vector<ManagedRegister>& callee_save_regs) = 0; + ArrayRef<const ManagedRegister> callee_save_regs) = 0; virtual void IncreaseFrameSize(size_t adjust) = 0; virtual void DecreaseFrameSize(size_t adjust) = 0; @@ -504,7 +522,11 @@ class Assembler { DebugFrameOpCodeWriterForAssembler& cfi() { return cfi_; } protected: - Assembler() : buffer_(), cfi_(this) {} + explicit Assembler(ArenaAllocator* arena) : buffer_(arena), cfi_(this) {} + + ArenaAllocator* GetArena() { + return buffer_.GetArena(); + } AssemblerBuffer buffer_; |