OSDN Git Service

Fix: correctly destruct VIXL labels.
authorAlexandre Rames <alexandre.rames@linaro.org>
Fri, 15 Apr 2016 10:54:06 +0000 (11:54 +0100)
committerRoland Levillain <rpl@google.com>
Mon, 18 Apr 2016 11:32:48 +0000 (12:32 +0100)
(cherry picked from commit c01a66465a398ad15da90ab2bdc35b7f4a609b17)

Bug: 27505766
Change-Id: I077465e3d308f4331e7a861902e05865f9d99835

compiler/optimizing/code_generator.cc
compiler/optimizing/code_generator.h
compiler/optimizing/code_generator_arm.h
compiler/optimizing/code_generator_arm64.cc
compiler/optimizing/code_generator_arm64.h
compiler/optimizing/code_generator_mips.h
compiler/optimizing/code_generator_mips64.h
compiler/optimizing/code_generator_x86.h
compiler/optimizing/code_generator_x86_64.h
compiler/utils/arm64/assembler_arm64.cc
compiler/utils/arm64/assembler_arm64.h

index a771cc1..e7fa4e4 100644 (file)
@@ -187,7 +187,8 @@ class DisassemblyScope {
 
 void CodeGenerator::GenerateSlowPaths() {
   size_t code_start = 0;
-  for (SlowPathCode* slow_path : slow_paths_) {
+  for (const std::unique_ptr<SlowPathCode>& slow_path_unique_ptr : slow_paths_) {
+    SlowPathCode* slow_path = slow_path_unique_ptr.get();
     current_slow_path_ = slow_path;
     if (disasm_info_ != nullptr) {
       code_start = GetAssembler()->CodeSize();
index 87832a2..d69c410 100644 (file)
@@ -67,7 +67,7 @@ class CodeAllocator {
   DISALLOW_COPY_AND_ASSIGN(CodeAllocator);
 };
 
-class SlowPathCode : public ArenaObject<kArenaAllocSlowPaths> {
+class SlowPathCode : public DeletableArenaObject<kArenaAllocSlowPaths> {
  public:
   explicit SlowPathCode(HInstruction* instruction) : instruction_(instruction) {
     for (size_t i = 0; i < kMaximumNumberOfExpectedRegisters; ++i) {
@@ -205,7 +205,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
   virtual const Assembler& GetAssembler() const = 0;
   virtual size_t GetWordSize() const = 0;
   virtual size_t GetFloatingPointSpillSlotSize() const = 0;
-  virtual uintptr_t GetAddressOf(HBasicBlock* block) const = 0;
+  virtual uintptr_t GetAddressOf(HBasicBlock* block) = 0;
   void InitializeCodeGeneration(size_t number_of_spill_slots,
                                 size_t maximum_number_of_live_core_registers,
                                 size_t maximum_number_of_live_fpu_registers,
@@ -298,8 +298,9 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
   // save live registers, which may be needed by the runtime to set catch phis.
   bool IsImplicitNullCheckAllowed(HNullCheck* null_check) const;
 
+  // TODO: Avoid creating the `std::unique_ptr` here.
   void AddSlowPath(SlowPathCode* slow_path) {
-    slow_paths_.push_back(slow_path);
+    slow_paths_.push_back(std::unique_ptr<SlowPathCode>(slow_path));
   }
 
   void BuildStackMaps(MemoryRegion region, const DexFile::CodeItem& code_item);
@@ -617,7 +618,7 @@ class CodeGenerator : public DeletableArenaObject<kArenaAllocCodeGenerator> {
   HGraph* const graph_;
   const CompilerOptions& compiler_options_;
 
-  ArenaVector<SlowPathCode*> slow_paths_;
+  ArenaVector<std::unique_ptr<SlowPathCode>> slow_paths_;
 
   // The current slow-path that we're generating code for.
   SlowPathCode* current_slow_path_;
index 144d58d..0020f7b 100644 (file)
@@ -339,7 +339,7 @@ class CodeGeneratorARM : public CodeGenerator {
     return assembler_;
   }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     return GetLabelOf(block)->Position();
   }
 
index efe4c06..e8e6b68 100644 (file)
@@ -899,7 +899,7 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
                     callee_saved_fp_registers.list(),
                     compiler_options,
                     stats),
-      block_labels_(nullptr),
+      block_labels_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
       jump_tables_(graph->GetArena()->Adapter(kArenaAllocCodeGenerator)),
       location_builder_(graph, this),
       instruction_visitor_(graph, this),
@@ -928,7 +928,7 @@ CodeGeneratorARM64::CodeGeneratorARM64(HGraph* graph,
 #define __ GetVIXLAssembler()->
 
 void CodeGeneratorARM64::EmitJumpTables() {
-  for (auto jump_table : jump_tables_) {
+  for (auto&& jump_table : jump_tables_) {
     jump_table->EmitTable(this);
   }
 }
@@ -4784,8 +4784,7 @@ void InstructionCodeGeneratorARM64::VisitPackedSwitch(HPackedSwitch* switch_inst
       __ B(codegen_->GetLabelOf(default_block));
     }
   } else {
-    JumpTableARM64* jump_table = new (GetGraph()->GetArena()) JumpTableARM64(switch_instr);
-    codegen_->AddJumpTable(jump_table);
+    JumpTableARM64* jump_table = codegen_->CreateJumpTable(switch_instr);
 
     UseScratchRegisterScope temps(codegen_->GetVIXLAssembler());
 
index ec46a34..422963e 100644 (file)
@@ -83,7 +83,7 @@ class SlowPathCodeARM64 : public SlowPathCode {
   DISALLOW_COPY_AND_ASSIGN(SlowPathCodeARM64);
 };
 
-class JumpTableARM64 : public ArenaObject<kArenaAllocSwitchTable> {
+class JumpTableARM64 : public DeletableArenaObject<kArenaAllocSwitchTable> {
  public:
   explicit JumpTableARM64(HPackedSwitch* switch_instr)
     : switch_instr_(switch_instr), table_start_() {}
@@ -352,8 +352,9 @@ class CodeGeneratorARM64 : public CodeGenerator {
 
   void Bind(HBasicBlock* block) OVERRIDE;
 
-  vixl::Label* GetLabelOf(HBasicBlock* block) const {
-    return CommonGetLabelOf<vixl::Label>(block_labels_, block);
+  vixl::Label* GetLabelOf(HBasicBlock* block) {
+    block = FirstNonEmptyBlock(block);
+    return &(block_labels_[block->GetBlockId()]);
   }
 
   size_t GetWordSize() const OVERRIDE {
@@ -365,7 +366,7 @@ class CodeGeneratorARM64 : public CodeGenerator {
     return kArm64WordSize;
   }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     vixl::Label* block_entry_label = GetLabelOf(block);
     DCHECK(block_entry_label->IsBound());
     return block_entry_label->location();
@@ -413,11 +414,12 @@ class CodeGeneratorARM64 : public CodeGenerator {
   }
 
   void Initialize() OVERRIDE {
-    block_labels_ = CommonInitializeLabels<vixl::Label>();
+    block_labels_.resize(GetGraph()->GetBlocks().size());
   }
 
-  void AddJumpTable(JumpTableARM64* jump_table) {
-    jump_tables_.push_back(jump_table);
+  JumpTableARM64* CreateJumpTable(HPackedSwitch* switch_instr) {
+    jump_tables_.emplace_back(new (GetGraph()->GetArena()) JumpTableARM64(switch_instr));
+    return jump_tables_.back().get();
   }
 
   void Finalize(CodeAllocator* allocator) OVERRIDE;
@@ -616,9 +618,10 @@ class CodeGeneratorARM64 : public CodeGenerator {
   void EmitJumpTables();
 
   // Labels for each block that will be compiled.
-  vixl::Label* block_labels_;  // Indexed by block id.
+  // We use a deque so that the `vixl::Label` objects do not move in memory.
+  ArenaDeque<vixl::Label> block_labels_;  // Indexed by block id.
   vixl::Label frame_entry_label_;
-  ArenaVector<JumpTableARM64*> jump_tables_;
+  ArenaVector<std::unique_ptr<JumpTableARM64>> jump_tables_;
 
   LocationsBuilderARM64 location_builder_;
   InstructionCodeGeneratorARM64 instruction_visitor_;
index 5e6fec8..435a869 100644 (file)
@@ -275,7 +275,7 @@ class CodeGeneratorMIPS : public CodeGenerator {
 
   size_t GetFloatingPointSpillSlotSize() const OVERRIDE { return kMipsDoublewordSize; }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     return assembler_.GetLabelLocation(GetLabelOf(block));
   }
 
index 4e15cdd..9785a2e 100644 (file)
@@ -271,7 +271,7 @@ class CodeGeneratorMIPS64 : public CodeGenerator {
 
   size_t GetFloatingPointSpillSlotSize() const OVERRIDE { return kMips64DoublewordSize; }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     return assembler_.GetLabelLocation(GetLabelOf(block));
   }
 
index 69a6253..1739eec 100644 (file)
@@ -361,7 +361,7 @@ class CodeGeneratorX86 : public CodeGenerator {
     return assembler_;
   }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     return GetLabelOf(block)->Position();
   }
 
index d7ce7c6..3a211c5 100644 (file)
@@ -346,7 +346,7 @@ class CodeGeneratorX86_64 : public CodeGenerator {
     return &move_resolver_;
   }
 
-  uintptr_t GetAddressOf(HBasicBlock* block) const OVERRIDE {
+  uintptr_t GetAddressOf(HBasicBlock* block) OVERRIDE {
     return GetLabelOf(block)->Position();
   }
 
index eb851f9..eb5112b 100644 (file)
@@ -32,8 +32,8 @@ namespace arm64 {
 #endif
 
 void Arm64Assembler::FinalizeCode() {
-  for (Arm64Exception* exception : exception_blocks_) {
-    EmitExceptionPoll(exception);
+  for (const std::unique_ptr<Arm64Exception>& exception : exception_blocks_) {
+    EmitExceptionPoll(exception.get());
   }
   ___ FinalizeCode();
 }
@@ -611,10 +611,9 @@ void Arm64Assembler::LoadReferenceFromHandleScope(ManagedRegister m_out_reg,
 void Arm64Assembler::ExceptionPoll(ManagedRegister m_scratch, size_t stack_adjust) {
   CHECK_ALIGNED(stack_adjust, kStackAlignment);
   Arm64ManagedRegister scratch = m_scratch.AsArm64();
-  Arm64Exception *current_exception = new Arm64Exception(scratch, stack_adjust);
-  exception_blocks_.push_back(current_exception);
+  exception_blocks_.emplace_back(new Arm64Exception(scratch, stack_adjust));
   LoadFromOffset(scratch.AsXRegister(), TR, Thread::ExceptionOffset<8>().Int32Value());
-  ___ Cbnz(reg_x(scratch.AsXRegister()), current_exception->Entry());
+  ___ Cbnz(reg_x(scratch.AsXRegister()), exception_blocks_.back()->Entry());
 }
 
 void Arm64Assembler::EmitExceptionPoll(Arm64Exception *exception) {
index 03ae996..c4e5de7 100644 (file)
@@ -62,7 +62,25 @@ enum StoreOperandType {
   kStoreDWord
 };
 
-class Arm64Exception;
+class Arm64Exception {
+ private:
+  Arm64Exception(Arm64ManagedRegister scratch, size_t stack_adjust)
+      : scratch_(scratch), stack_adjust_(stack_adjust) {
+    }
+
+  vixl::Label* Entry() { return &exception_entry_; }
+
+  // Register used for passing Thread::Current()->exception_ .
+  const Arm64ManagedRegister scratch_;
+
+  // Stack adjust for ExceptionPool.
+  const size_t stack_adjust_;
+
+  vixl::Label exception_entry_;
+
+  friend class Arm64Assembler;
+  DISALLOW_COPY_AND_ASSIGN(Arm64Exception);
+};
 
 class Arm64Assembler FINAL : public Assembler {
  public:
@@ -253,7 +271,7 @@ class Arm64Assembler FINAL : public Assembler {
   void AddConstant(XRegister rd, XRegister rn, int32_t value, vixl::Condition cond = vixl::al);
 
   // List of exception blocks to generate at the end of the code cache.
-  ArenaVector<Arm64Exception*> exception_blocks_;
+  ArenaVector<std::unique_ptr<Arm64Exception>> exception_blocks_;
 
  public:
   // Vixl assembler.
@@ -263,26 +281,6 @@ class Arm64Assembler FINAL : public Assembler {
   friend class Arm64ManagedRegister_VixlRegisters_Test;
 };
 
-class Arm64Exception {
- private:
-  Arm64Exception(Arm64ManagedRegister scratch, size_t stack_adjust)
-      : scratch_(scratch), stack_adjust_(stack_adjust) {
-    }
-
-  vixl::Label* Entry() { return &exception_entry_; }
-
-  // Register used for passing Thread::Current()->exception_ .
-  const Arm64ManagedRegister scratch_;
-
-  // Stack adjust for ExceptionPool.
-  const size_t stack_adjust_;
-
-  vixl::Label exception_entry_;
-
-  friend class Arm64Assembler;
-  DISALLOW_COPY_AND_ASSIGN(Arm64Exception);
-};
-
 }  // namespace arm64
 }  // namespace art