diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-07-15 12:55:21 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-07-15 12:58:29 +0100 |
commit | ab032bc1ff57831106fdac6a91a136293609401f (patch) | |
tree | 5891daefe635283443a255a811ab6a3f3b8a62cd | |
parent | 635561b86ac03f5562bdb779baa6db12f31b3cae (diff) | |
download | art-ab032bc1ff57831106fdac6a91a136293609401f.zip art-ab032bc1ff57831106fdac6a91a136293609401f.tar.gz art-ab032bc1ff57831106fdac6a91a136293609401f.tar.bz2 |
Fix a braino in the stack layout.
Also do some refactoring to have this code be just in CodeGenerator.
Change-Id: I88de109889138af8d60027973c12a64bee813cb7
-rw-r--r-- | compiler/optimizing/code_generator.cc | 35 | ||||
-rw-r--r-- | compiler/optimizing/code_generator.h | 6 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 39 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 36 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.cc | 41 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86_64.h | 5 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 4 | ||||
-rw-r--r-- | test/401-optimizing-compiler/expected.txt | 1 | ||||
-rw-r--r-- | test/401-optimizing-compiler/src/Main.java | 10 |
11 files changed, 69 insertions, 118 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index b0e6a75..e0db0f1 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -38,7 +38,7 @@ void CodeGenerator::CompileBaseline(CodeAllocator* allocator) { DCHECK_EQ(frame_size_, kUninitializedFrameSize); ComputeFrameSize(GetGraph()->GetMaximumNumberOfOutVRegs() - + GetGraph()->GetNumberOfVRegs() + + GetGraph()->GetNumberOfLocalVRegs() + GetGraph()->GetNumberOfTemporaries() + 1 /* filler */); GenerateFrameEntry(); @@ -106,6 +106,39 @@ size_t CodeGenerator::AllocateFreeRegisterInternal( return -1; } +void CodeGenerator::ComputeFrameSize(size_t number_of_spill_slots) { + SetFrameSize(RoundUp( + number_of_spill_slots * kVRegSize + + kVRegSize // Art method + + FrameEntrySpillSize(), + kStackAlignment)); +} + +Location CodeGenerator::GetTemporaryLocation(HTemporary* temp) const { + uint16_t number_of_locals = GetGraph()->GetNumberOfLocalVRegs(); + // Use the temporary region (right below the dex registers). + int32_t slot = GetFrameSize() - FrameEntrySpillSize() + - kVRegSize // filler + - (number_of_locals * kVRegSize) + - ((1 + temp->GetIndex()) * kVRegSize); + return Location::StackSlot(slot); +} + +int32_t CodeGenerator::GetStackSlot(HLocal* local) const { + uint16_t reg_number = local->GetRegNumber(); + uint16_t number_of_locals = GetGraph()->GetNumberOfLocalVRegs(); + if (reg_number >= number_of_locals) { + // Local is a parameter of the method. It is stored in the caller's frame. + return GetFrameSize() + kVRegSize // ART method + + (reg_number - number_of_locals) * kVRegSize; + } else { + // Local is a temporary in this method. It is stored in this method's frame. + return GetFrameSize() - FrameEntrySpillSize() + - kVRegSize // filler. + - (number_of_locals * kVRegSize) + + (reg_number * kVRegSize); + } +} void CodeGenerator::AllocateRegistersLocally(HInstruction* instruction) const { LocationSummary* locations = instruction->GetLocations(); diff --git a/compiler/optimizing/code_generator.h b/compiler/optimizing/code_generator.h index abfb790..18e3e5a 100644 --- a/compiler/optimizing/code_generator.h +++ b/compiler/optimizing/code_generator.h @@ -96,7 +96,10 @@ class CodeGenerator : public ArenaObject { virtual HGraphVisitor* GetInstructionVisitor() = 0; virtual Assembler* GetAssembler() = 0; virtual size_t GetWordSize() const = 0; - virtual void ComputeFrameSize(size_t number_of_spill_slots) = 0; + void ComputeFrameSize(size_t number_of_spill_slots); + virtual size_t FrameEntrySpillSize() const = 0; + int32_t GetStackSlot(HLocal* local) const; + Location GetTemporaryLocation(HTemporary* temp) const; uint32_t GetFrameSize() const { return frame_size_; } void SetFrameSize(uint32_t size) { frame_size_ = size; } @@ -150,7 +153,6 @@ class CodeGenerator : public ArenaObject { size_t AllocateFreeRegisterInternal(bool* blocked_registers, size_t number_of_registers) const; virtual Location GetStackLocation(HLoadLocal* load) const = 0; - virtual Location GetTemporaryLocation(HTemporary* temp) const = 0; // Frame size required for this method. uint32_t frame_size_; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index e702407..73c2d48 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -99,6 +99,10 @@ CodeGeneratorARM::CodeGeneratorARM(HGraph* graph) instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this) {} +size_t CodeGeneratorARM::FrameEntrySpillSize() const { + return kNumberOfPushedRegistersAtEntry * kArmWordSize; +} + static bool* GetBlockedRegisterPairs(bool* blocked_registers) { return blocked_registers + kNumberOfAllocIds; } @@ -200,14 +204,6 @@ InstructionCodeGeneratorARM::InstructionCodeGeneratorARM(HGraph* graph, CodeGene assembler_(codegen->GetAssembler()), codegen_(codegen) {} -void CodeGeneratorARM::ComputeFrameSize(size_t number_of_spill_slots) { - SetFrameSize(RoundUp( - number_of_spill_slots * kVRegSize - + kVRegSize // Art method - + kNumberOfPushedRegistersAtEntry * kArmWordSize, - kStackAlignment)); -} - void CodeGeneratorARM::GenerateFrameEntry() { core_spill_mask_ |= (1 << LR | 1 << R6 | 1 << R7); __ PushList(1 << LR | 1 << R6 | 1 << R7); @@ -226,33 +222,6 @@ void CodeGeneratorARM::Bind(Label* label) { __ Bind(label); } -Location CodeGeneratorARM::GetTemporaryLocation(HTemporary* temp) const { - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - // Use the temporary region (right below the dex registers). - int32_t slot = GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kArmWordSize) - - kVRegSize // filler - - (number_of_vregs * kVRegSize) - - ((1 + temp->GetIndex()) * kVRegSize); - return Location::StackSlot(slot); -} - -int32_t CodeGeneratorARM::GetStackSlot(HLocal* local) const { - uint16_t reg_number = local->GetRegNumber(); - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - uint16_t number_of_in_vregs = GetGraph()->GetNumberOfInVRegs(); - if (reg_number >= number_of_vregs - number_of_in_vregs) { - // Local is a parameter of the method. It is stored in the caller's frame. - return GetFrameSize() + kVRegSize // ART method - + (reg_number - number_of_vregs + number_of_in_vregs) * kVRegSize; - } else { - // Local is a temporary in this method. It is stored in this method's frame. - return GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kArmWordSize) - - kVRegSize // filler. - - (number_of_vregs * kVRegSize) - + (reg_number * kVRegSize); - } -} - Location CodeGeneratorARM::GetStackLocation(HLoadLocal* load) const { switch (load->GetType()) { case Primitive::kPrimLong: diff --git a/compiler/optimizing/code_generator_arm.h b/compiler/optimizing/code_generator_arm.h index b7322b2..1b5974f 100644 --- a/compiler/optimizing/code_generator_arm.h +++ b/compiler/optimizing/code_generator_arm.h @@ -126,7 +126,6 @@ class CodeGeneratorARM : public CodeGenerator { explicit CodeGeneratorARM(HGraph* graph); virtual ~CodeGeneratorARM() { } - virtual void ComputeFrameSize(size_t number_of_spill_slots) OVERRIDE; virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; virtual void Bind(Label* label) OVERRIDE; @@ -136,6 +135,8 @@ class CodeGeneratorARM : public CodeGenerator { return kArmWordSize; } + virtual size_t FrameEntrySpillSize() const OVERRIDE; + virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } @@ -153,9 +154,7 @@ class CodeGeneratorARM : public CodeGenerator { Primitive::Type type, bool* blocked_registers) const OVERRIDE; virtual size_t GetNumberOfRegisters() const OVERRIDE; - int32_t GetStackSlot(HLocal* local) const; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual Location GetTemporaryLocation(HTemporary* temp) const OVERRIDE; virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { return kNumberOfCoreRegisters; diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 52cb39d..4e69a0c 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -83,12 +83,8 @@ CodeGeneratorX86::CodeGeneratorX86(HGraph* graph) instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this) {} -void CodeGeneratorX86::ComputeFrameSize(size_t number_of_spill_slots) { - SetFrameSize(RoundUp( - number_of_spill_slots * kVRegSize - + kVRegSize // Art method - + kNumberOfPushedRegistersAtEntry * kX86WordSize, - kStackAlignment)); +size_t CodeGeneratorX86::FrameEntrySpillSize() const { + return kNumberOfPushedRegistersAtEntry * kX86WordSize; } static bool* GetBlockedRegisterPairs(bool* blocked_registers) { @@ -204,34 +200,6 @@ void InstructionCodeGeneratorX86::LoadCurrentMethod(Register reg) { __ movl(reg, Address(ESP, kCurrentMethodStackOffset)); } -Location CodeGeneratorX86::GetTemporaryLocation(HTemporary* temp) const { - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - // Use the temporary region (right below the dex registers). - int32_t slot = GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kX86WordSize) - - kVRegSize // filler - - (number_of_vregs * kVRegSize) - - ((1 + temp->GetIndex()) * kVRegSize); - return Location::StackSlot(slot); -} - -int32_t CodeGeneratorX86::GetStackSlot(HLocal* local) const { - uint16_t reg_number = local->GetRegNumber(); - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - uint16_t number_of_in_vregs = GetGraph()->GetNumberOfInVRegs(); - if (reg_number >= number_of_vregs - number_of_in_vregs) { - // Local is a parameter of the method. It is stored in the caller's frame. - return GetFrameSize() + kVRegSize // ART method - + (reg_number - number_of_vregs + number_of_in_vregs) * kVRegSize; - } else { - // Local is a temporary in this method. It is stored in this method's frame. - return GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kX86WordSize) - - kVRegSize // filler. - - (number_of_vregs * kVRegSize) - + (reg_number * kVRegSize); - } -} - - Location CodeGeneratorX86::GetStackLocation(HLoadLocal* load) const { switch (load->GetType()) { case Primitive::kPrimLong: diff --git a/compiler/optimizing/code_generator_x86.h b/compiler/optimizing/code_generator_x86.h index 2a45954..d622d2a 100644 --- a/compiler/optimizing/code_generator_x86.h +++ b/compiler/optimizing/code_generator_x86.h @@ -128,7 +128,6 @@ class CodeGeneratorX86 : public CodeGenerator { explicit CodeGeneratorX86(HGraph* graph); virtual ~CodeGeneratorX86() { } - virtual void ComputeFrameSize(size_t number_of_spill_slots) OVERRIDE; virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; virtual void Bind(Label* label) OVERRIDE; @@ -138,6 +137,8 @@ class CodeGeneratorX86 : public CodeGenerator { return kX86WordSize; } + virtual size_t FrameEntrySpillSize() const OVERRIDE; + virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } @@ -155,9 +156,7 @@ class CodeGeneratorX86 : public CodeGenerator { virtual ManagedRegister AllocateFreeRegister( Primitive::Type type, bool* blocked_registers) const OVERRIDE; - int32_t GetStackSlot(HLocal* local) const; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual Location GetTemporaryLocation(HTemporary* temp) const OVERRIDE; virtual size_t GetNumberOfCoreRegisters() const OVERRIDE { return kNumberOfCpuRegisters; diff --git a/compiler/optimizing/code_generator_x86_64.cc b/compiler/optimizing/code_generator_x86_64.cc index 93d74ee..e3ce5ce 100644 --- a/compiler/optimizing/code_generator_x86_64.cc +++ b/compiler/optimizing/code_generator_x86_64.cc @@ -91,6 +91,10 @@ CodeGeneratorX86_64::CodeGeneratorX86_64(HGraph* graph) instruction_visitor_(graph, this), move_resolver_(graph->GetArena(), this) {} +size_t CodeGeneratorX86_64::FrameEntrySpillSize() const { + return kNumberOfPushedRegistersAtEntry * kX86_64WordSize; +} + InstructionCodeGeneratorX86_64::InstructionCodeGeneratorX86_64(HGraph* graph, CodeGeneratorX86_64* codegen) : HGraphVisitor(graph), assembler_(codegen->GetAssembler()), @@ -137,16 +141,6 @@ void CodeGeneratorX86_64::SetupBlockedRegisters(bool* blocked_registers) const { blocked_registers[R15] = true; } -void CodeGeneratorX86_64::ComputeFrameSize(size_t number_of_spill_slots) { - // Add the current ART method to the frame size, the return PC, and the filler. - SetFrameSize(RoundUp( - number_of_spill_slots * kVRegSize - + kVRegSize // filler - + kVRegSize // Art method - + kNumberOfPushedRegistersAtEntry * kX86_64WordSize, - kStackAlignment)); -} - void CodeGeneratorX86_64::GenerateFrameEntry() { // Create a fake register to mimic Quick. static const int kFakeReturnRegister = 16; @@ -170,33 +164,6 @@ void InstructionCodeGeneratorX86_64::LoadCurrentMethod(CpuRegister reg) { __ movl(reg, Address(CpuRegister(RSP), kCurrentMethodStackOffset)); } -Location CodeGeneratorX86_64::GetTemporaryLocation(HTemporary* temp) const { - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - // Use the temporary region (right below the dex registers). - int32_t slot = GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kX86_64WordSize) - - kVRegSize // filler - - (number_of_vregs * kVRegSize) - - ((1 + temp->GetIndex()) * kVRegSize); - return Location::StackSlot(slot); -} - -int32_t CodeGeneratorX86_64::GetStackSlot(HLocal* local) const { - uint16_t reg_number = local->GetRegNumber(); - uint16_t number_of_vregs = GetGraph()->GetNumberOfVRegs(); - uint16_t number_of_in_vregs = GetGraph()->GetNumberOfInVRegs(); - if (reg_number >= number_of_vregs - number_of_in_vregs) { - // Local is a parameter of the method. It is stored in the caller's frame. - return GetFrameSize() + kVRegSize // ART method - + (reg_number - number_of_vregs + number_of_in_vregs) * kVRegSize; - } else { - // Local is a temporary in this method. It is stored in this method's frame. - return GetFrameSize() - (kNumberOfPushedRegistersAtEntry * kX86_64WordSize) - - kVRegSize // filler - - (number_of_vregs * kVRegSize) - + (reg_number * kVRegSize); - } -} - Location CodeGeneratorX86_64::GetStackLocation(HLoadLocal* load) const { switch (load->GetType()) { case Primitive::kPrimLong: diff --git a/compiler/optimizing/code_generator_x86_64.h b/compiler/optimizing/code_generator_x86_64.h index 97a0b2e..8283dda 100644 --- a/compiler/optimizing/code_generator_x86_64.h +++ b/compiler/optimizing/code_generator_x86_64.h @@ -125,7 +125,6 @@ class CodeGeneratorX86_64 : public CodeGenerator { explicit CodeGeneratorX86_64(HGraph* graph); virtual ~CodeGeneratorX86_64() {} - virtual void ComputeFrameSize(size_t number_of_spill_slots) OVERRIDE; virtual void GenerateFrameEntry() OVERRIDE; virtual void GenerateFrameExit() OVERRIDE; virtual void Bind(Label* label) OVERRIDE; @@ -135,6 +134,8 @@ class CodeGeneratorX86_64 : public CodeGenerator { return kX86_64WordSize; } + virtual size_t FrameEntrySpillSize() const OVERRIDE; + virtual HGraphVisitor* GetLocationBuilder() OVERRIDE { return &location_builder_; } @@ -151,9 +152,7 @@ class CodeGeneratorX86_64 : public CodeGenerator { return &move_resolver_; } - int32_t GetStackSlot(HLocal* local) const; virtual Location GetStackLocation(HLoadLocal* load) const OVERRIDE; - virtual Location GetTemporaryLocation(HTemporary* temp) const OVERRIDE; virtual size_t GetNumberOfRegisters() const OVERRIDE { return kNumberOfRegIds; diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 689aab0..ca846b3 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -138,6 +138,10 @@ class HGraph : public ArenaObject { return number_of_in_vregs_; } + uint16_t GetNumberOfLocalVRegs() const { + return number_of_vregs_ - number_of_in_vregs_; + } + const GrowableArray<HBasicBlock*>& GetReversePostOrder() const { return reverse_post_order_; } diff --git a/test/401-optimizing-compiler/expected.txt b/test/401-optimizing-compiler/expected.txt index 97492a4..d6ef64b 100644 --- a/test/401-optimizing-compiler/expected.txt +++ b/test/401-optimizing-compiler/expected.txt @@ -11,3 +11,4 @@ Forced GC Forced GC Forced GC Forced GC +Forced GC diff --git a/test/401-optimizing-compiler/src/Main.java b/test/401-optimizing-compiler/src/Main.java index e5706a5..a5192e1 100644 --- a/test/401-optimizing-compiler/src/Main.java +++ b/test/401-optimizing-compiler/src/Main.java @@ -71,6 +71,10 @@ public class Main { if (m.$opt$TestOtherParameter(new Main()) == m) { throw new Error("Unexpected value returned"); } + + if (m.$opt$TestReturnNewObject(m) == m) { + throw new Error("Unexpected value returned"); + } } static int $opt$TestInvokeIntParameter(int param) { @@ -108,6 +112,12 @@ public class Main { return other; } + Object $opt$TestReturnNewObject(Object other) { + Object o = new Object(); + forceGCStaticMethod(); + return o; + } + public static void $opt$TestInvokeStatic() { printStaticMethod(); printStaticMethodWith2Args(1, 2); |