diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-04-04 09:07:17 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-04-04 09:07:17 +0000 |
commit | 885e813edc121cd8392eb066981522424480253c (patch) | |
tree | c6baa84fa2586f23d4aa4607cde2f859a8c560f2 /compiler | |
parent | 6f31ce382777d82952d019908866ff28ef3bbc76 (diff) | |
parent | 2e7038ac5848468740d6a419434d3dde8c585a53 (diff) | |
download | art-885e813edc121cd8392eb066981522424480253c.zip art-885e813edc121cd8392eb066981522424480253c.tar.gz art-885e813edc121cd8392eb066981522424480253c.tar.bz2 |
Merge "Add support for new-instance and invoke-direct."
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/optimizing/builder.cc | 15 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 34 | ||||
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 33 | ||||
-rw-r--r-- | compiler/optimizing/nodes.h | 27 |
4 files changed, 100 insertions, 9 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index 0554876..d90405a 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -193,7 +193,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ break; } - case Instruction::INVOKE_STATIC: { + case Instruction::INVOKE_STATIC: + case Instruction::INVOKE_DIRECT: { uint32_t method_idx = instruction.VRegB_35c(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; @@ -204,6 +205,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ return false; } + // Treat invoke-direct like static calls for now. HInvokeStatic* invoke = new (arena_) HInvokeStatic( arena_, number_of_arguments, dex_offset, method_idx); @@ -221,7 +223,8 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ break; } - case Instruction::INVOKE_STATIC_RANGE: { + case Instruction::INVOKE_STATIC_RANGE: + case Instruction::INVOKE_DIRECT_RANGE: { uint32_t method_idx = instruction.VRegB_3rc(); const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx); uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_; @@ -232,6 +235,7 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ return false; } + // Treat invoke-direct like static calls for now. HInvokeStatic* invoke = new (arena_) HInvokeStatic( arena_, number_of_arguments, dex_offset, method_idx); int32_t register_index = instruction.VRegC(); @@ -277,6 +281,13 @@ bool HGraphBuilder::AnalyzeDexInstruction(const Instruction& instruction, int32_ break; } + case Instruction::NEW_INSTANCE: { + current_block_->AddInstruction( + new (arena_) HNewInstance(dex_offset, instruction.VRegB_21c())); + UpdateLocal(instruction.VRegA(), current_block_->GetLastInstruction()); + break; + } + case Instruction::NOP: break; diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 09d6f7b..0aeeef7 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -185,7 +185,7 @@ void InstructionCodeGeneratorARM::VisitReturn(HReturn* ret) { } static constexpr Register kParameterCoreRegisters[] = { R1, R2, R3 }; -static constexpr int kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); +static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); class InvokeStaticCallingConvention : public CallingConvention<Register> { public: @@ -287,5 +287,37 @@ void InstructionCodeGeneratorARM::VisitAdd(HAdd* add) { } } +static constexpr Register kRuntimeParameterCoreRegisters[] = { R0, R1 }; +static constexpr size_t kRuntimeParameterCoreRegistersLength = + arraysize(kRuntimeParameterCoreRegisters); + +class InvokeRuntimeCallingConvention : public CallingConvention<Register> { + public: + InvokeRuntimeCallingConvention() + : CallingConvention(kRuntimeParameterCoreRegisters, + kRuntimeParameterCoreRegistersLength) {} + + private: + DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); +}; + +void LocationsBuilderARM::VisitNewInstance(HNewInstance* instruction) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); + locations->SetOut(Location(R0)); + instruction->SetLocations(locations); +} + +void InstructionCodeGeneratorARM::VisitNewInstance(HNewInstance* instruction) { + InvokeRuntimeCallingConvention calling_convention; + LoadCurrentMethod(calling_convention.GetRegisterAt(1)); + __ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex()); + + int32_t offset = QUICK_ENTRYPOINT_OFFSET(kWordSize, pAllocObjectWithAccessCheck).Int32Value(); + __ ldr(LR, Address(TR, offset)); + __ blx(LR); + + codegen_->RecordPcInfo(instruction->GetDexPc()); +} + } // namespace arm } // namespace art diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index 7b0a087..882541b 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -188,7 +188,7 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { } static constexpr Register kParameterCoreRegisters[] = { ECX, EDX, EBX }; -static constexpr int kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); +static constexpr size_t kParameterCoreRegistersLength = arraysize(kParameterCoreRegisters); class InvokeStaticCallingConvention : public CallingConvention<Register> { public: @@ -199,6 +199,20 @@ class InvokeStaticCallingConvention : public CallingConvention<Register> { DISALLOW_COPY_AND_ASSIGN(InvokeStaticCallingConvention); }; +static constexpr Register kRuntimeParameterCoreRegisters[] = { EAX, ECX, EDX }; +static constexpr size_t kRuntimeParameterCoreRegistersLength = + arraysize(kRuntimeParameterCoreRegisters); + +class InvokeRuntimeCallingConvention : public CallingConvention<Register> { + public: + InvokeRuntimeCallingConvention() + : CallingConvention(kRuntimeParameterCoreRegisters, + kRuntimeParameterCoreRegistersLength) {} + + private: + DISALLOW_COPY_AND_ASSIGN(InvokeRuntimeCallingConvention); +}; + void LocationsBuilderX86::VisitPushArgument(HPushArgument* argument) { LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(argument); InvokeStaticCallingConvention calling_convention; @@ -284,5 +298,22 @@ void InstructionCodeGeneratorX86::VisitAdd(HAdd* add) { } } +void LocationsBuilderX86::VisitNewInstance(HNewInstance* instruction) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(instruction); + locations->SetOut(Location(EAX)); + instruction->SetLocations(locations); +} + +void InstructionCodeGeneratorX86::VisitNewInstance(HNewInstance* instruction) { + InvokeRuntimeCallingConvention calling_convention; + LoadCurrentMethod(calling_convention.GetRegisterAt(1)); + __ movl(calling_convention.GetRegisterAt(0), + Immediate(instruction->GetTypeIndex())); + + __ fs()->call(Address::Absolute(QUICK_ENTRYPOINT_OFFSET(kWordSize, pAllocObjectWithAccessCheck))); + + codegen_->RecordPcInfo(instruction->GetDexPc()); +} + } // namespace x86 } // namespace art diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 2b21905..830d0c7 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -201,6 +201,7 @@ class HBasicBlock : public ArenaObject { M(InvokeStatic) \ M(LoadLocal) \ M(Local) \ + M(NewInstance) \ M(PushArgument) \ M(Return) \ M(ReturnVoid) \ @@ -593,7 +594,7 @@ class HIntConstant : public HTemplateInstruction<0> { class HInvoke : public HInstruction { public: - HInvoke(ArenaAllocator* arena, uint32_t number_of_arguments, int32_t dex_pc) + HInvoke(ArenaAllocator* arena, uint32_t number_of_arguments, uint32_t dex_pc) : inputs_(arena, number_of_arguments), dex_pc_(dex_pc) { inputs_.SetSize(number_of_arguments); @@ -606,11 +607,11 @@ class HInvoke : public HInstruction { inputs_.Put(index, argument); } - int32_t GetDexPc() const { return dex_pc_; } + uint32_t GetDexPc() const { return dex_pc_; } protected: GrowableArray<HInstruction*> inputs_; - const int32_t dex_pc_; + const uint32_t dex_pc_; private: DISALLOW_COPY_AND_ASSIGN(HInvoke); @@ -620,8 +621,8 @@ class HInvokeStatic : public HInvoke { public: HInvokeStatic(ArenaAllocator* arena, uint32_t number_of_arguments, - int32_t dex_pc, - int32_t index_in_dex_cache) + uint32_t dex_pc, + uint32_t index_in_dex_cache) : HInvoke(arena, number_of_arguments, dex_pc), index_in_dex_cache_(index_in_dex_cache) {} uint32_t GetIndexInDexCache() const { return index_in_dex_cache_; } @@ -634,6 +635,22 @@ class HInvokeStatic : public HInvoke { DISALLOW_COPY_AND_ASSIGN(HInvokeStatic); }; +class HNewInstance : public HTemplateInstruction<0> { + public: + HNewInstance(uint32_t dex_pc, uint16_t type_index) : dex_pc_(dex_pc), type_index_(type_index) {} + + uint32_t GetDexPc() const { return dex_pc_; } + uint16_t GetTypeIndex() const { return type_index_; } + + DECLARE_INSTRUCTION(NewInstance) + + private: + const uint32_t dex_pc_; + const uint16_t type_index_; + + DISALLOW_COPY_AND_ASSIGN(HNewInstance); +}; + // HPushArgument nodes are inserted after the evaluation of an argument // of a call. Their mere purpose is to ease the code generator's work. class HPushArgument : public HTemplateInstruction<1> { |