diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-03-19 10:34:11 +0000 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-03-31 09:44:40 +0100 |
commit | 8ccc3f5d06fd217cdaabd37e743adab2031d3720 (patch) | |
tree | ec8c904baafb4d9b9bfd582245e2d780bcdfaade /compiler/optimizing/code_generator_x86.cc | |
parent | ad174d1b54bf2fa477bec71a0ca93595f54b8fe9 (diff) | |
download | art-8ccc3f5d06fd217cdaabd37e743adab2031d3720.zip art-8ccc3f5d06fd217cdaabd37e743adab2031d3720.tar.gz art-8ccc3f5d06fd217cdaabd37e743adab2031d3720.tar.bz2 |
Add support for invoke-static in optimizing compiler.
Support is limited to calls without parameters and returning
void. For simplicity, we currently follow the Quick ABI.
Change-Id: I54805161141b7eac5959f1cae0dc138dd0b2e8a5
Diffstat (limited to 'compiler/optimizing/code_generator_x86.cc')
-rw-r--r-- | compiler/optimizing/code_generator_x86.cc | 56 |
1 files changed, 51 insertions, 5 deletions
diff --git a/compiler/optimizing/code_generator_x86.cc b/compiler/optimizing/code_generator_x86.cc index c4bda56..54bff0c 100644 --- a/compiler/optimizing/code_generator_x86.cc +++ b/compiler/optimizing/code_generator_x86.cc @@ -18,18 +18,28 @@ #include "utils/assembler.h" #include "utils/x86/assembler_x86.h" +#include "mirror/array.h" +#include "mirror/art_method.h" + #define __ reinterpret_cast<X86Assembler*>(GetAssembler())-> namespace art { namespace x86 { void CodeGeneratorX86::GenerateFrameEntry() { + // Create a fake register to mimic Quick. + static const int kFakeReturnRegister = 8; + core_spill_mask_ |= (1 << kFakeReturnRegister); + // We're currently always using EBP, which is callee-saved in Quick. + core_spill_mask_ |= (1 << EBP); + __ pushl(EBP); __ movl(EBP, ESP); - - if (GetFrameSize() != 0) { - __ subl(ESP, Immediate(GetFrameSize())); - } + // Add the current ART method to the frame size, the return pc, and EBP. + SetFrameSize(RoundUp(GetFrameSize() + 3 * kWordSize, kStackAlignment)); + // The PC and EBP have already been pushed on the stack. + __ subl(ESP, Immediate(GetFrameSize() - 2 * kWordSize)); + __ movl(Address(ESP, 0), EAX); } void CodeGeneratorX86::GenerateFrameExit() { @@ -45,6 +55,10 @@ void CodeGeneratorX86::Push(HInstruction* instruction, Location location) { __ pushl(location.reg<Register>()); } +void InstructionCodeGeneratorX86::LoadCurrentMethod(Register reg) { + __ movl(reg, Address(ESP, 0)); +} + void CodeGeneratorX86::Move(HInstruction* instruction, Location location) { HIntConstant* constant = instruction->AsIntConstant(); if (constant != nullptr) { @@ -110,7 +124,8 @@ void LocationsBuilderX86::VisitLoadLocal(HLoadLocal* local) { static int32_t GetStackSlot(HLocal* local) { // We are currently using EBP to access locals, so the offset must be negative. - return (local->GetRegNumber() + 1) * -kWordSize; + // +1 for going backwards, +1 for the method pointer. + return (local->GetRegNumber() + 2) * -kWordSize; } void InstructionCodeGeneratorX86::VisitLoadLocal(HLoadLocal* load) { @@ -172,5 +187,36 @@ void InstructionCodeGeneratorX86::VisitReturn(HReturn* ret) { __ ret(); } +void LocationsBuilderX86::VisitInvokeStatic(HInvokeStatic* invoke) { + LocationSummary* locations = new (GetGraph()->GetArena()) LocationSummary(invoke); + CHECK_EQ(invoke->InputCount(), 0); + locations->AddTemp(Location(EAX)); + invoke->SetLocations(locations); +} + +void InstructionCodeGeneratorX86::VisitInvokeStatic(HInvokeStatic* invoke) { + Register temp = invoke->GetLocations()->GetTemp(0).reg<Register>(); + size_t index_in_cache = mirror::Array::DataOffset(sizeof(mirror::Object*)).Int32Value() + + invoke->GetIndexInDexCache() * kWordSize; + + // TODO: Implement all kinds of calls: + // 1) boot -> boot + // 2) app -> boot + // 3) app -> app + // + // Currently we implement the app -> app logic, which looks up in the resolve cache. + + // temp = method; + LoadCurrentMethod(temp); + // temp = temp->dex_cache_resolved_methods_; + __ movl(temp, Address(temp, mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value())); + // temp = temp[index_in_cache] + __ movl(temp, Address(temp, index_in_cache)); + // (temp + offset_of_quick_compiled_code)() + __ call(Address(temp, mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value())); + + codegen_->RecordPcInfo(invoke->GetDexPc()); +} + } // namespace x86 } // namespace art |