diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-10-31 14:24:05 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-10-31 14:24:06 +0000 |
commit | a9014f977ae90373f5bad4cf812c2bda810b10f8 (patch) | |
tree | 40f4bc76cb5e7cf9c95fced70b1ad5c2c2d39f4e /compiler/optimizing/code_generator_arm.cc | |
parent | 8b557af85871e5086589afd2b3a17089d0f67df8 (diff) | |
parent | b5f62b3dc5ac2731ba8ad53cdf3d9bdb14fbf86b (diff) |
Merge "Support for CONST_STRING in optimizing compiler."
Diffstat (limited to 'compiler/optimizing/code_generator_arm.cc')
-rw-r--r-- | compiler/optimizing/code_generator_arm.cc | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc index 9ed19695a3..c812f6b416 100644 --- a/compiler/optimizing/code_generator_arm.cc +++ b/compiler/optimizing/code_generator_arm.cc @@ -196,6 +196,37 @@ class ClinitCheckSlowPathARM : public SlowPathCodeARM { DISALLOW_COPY_AND_ASSIGN(ClinitCheckSlowPathARM); }; +class LoadStringSlowPathARM : public SlowPathCodeARM { + public: + explicit LoadStringSlowPathARM(HLoadString* instruction) : instruction_(instruction) {} + + virtual void EmitNativeCode(CodeGenerator* codegen) OVERRIDE { + LocationSummary* locations = instruction_->GetLocations(); + DCHECK(!locations->GetLiveRegisters()->ContainsCoreRegister(locations->Out().reg())); + + CodeGeneratorARM* arm_codegen = down_cast<CodeGeneratorARM*>(codegen); + __ Bind(GetEntryLabel()); + codegen->SaveLiveRegisters(locations); + + InvokeRuntimeCallingConvention calling_convention; + arm_codegen->LoadCurrentMethod(calling_convention.GetRegisterAt(0)); + __ LoadImmediate(calling_convention.GetRegisterAt(1), instruction_->GetStringIndex()); + arm_codegen->InvokeRuntime( + QUICK_ENTRY_POINT(pResolveString), instruction_, instruction_->GetDexPc()); + arm_codegen->Move32(locations->Out(), Location::RegisterLocation(R0)); + + codegen->RestoreLiveRegisters(locations); + __ b(GetExitLabel()); + } + + private: + HLoadString* const instruction_; + + DISALLOW_COPY_AND_ASSIGN(LoadStringSlowPathARM); +}; + +#undef __ + #undef __ #define __ reinterpret_cast<ArmAssembler*>(GetAssembler())-> @@ -2270,5 +2301,25 @@ void InstructionCodeGeneratorARM::VisitStaticFieldSet(HStaticFieldSet* instructi } } +void LocationsBuilderARM::VisitLoadString(HLoadString* load) { + LocationSummary* locations = + new (GetGraph()->GetArena()) LocationSummary(load, LocationSummary::kCallOnSlowPath); + locations->SetOut(Location::RequiresRegister()); +} + +void InstructionCodeGeneratorARM::VisitLoadString(HLoadString* load) { + SlowPathCodeARM* slow_path = new (GetGraph()->GetArena()) LoadStringSlowPathARM(load); + codegen_->AddSlowPath(slow_path); + + Register out = load->GetLocations()->Out().As<Register>(); + codegen_->LoadCurrentMethod(out); + __ LoadFromOffset( + kLoadWord, out, out, mirror::ArtMethod::DexCacheStringsOffset().Int32Value()); + __ LoadFromOffset(kLoadWord, out, out, CodeGenerator::GetCacheOffset(load->GetStringIndex())); + __ cmp(out, ShifterOperand(0)); + __ b(slow_path->GetEntryLabel(), EQ); + __ Bind(slow_path->GetExitLabel()); +} + } // namespace arm } // namespace art |