diff options
author | Nicolas Geoffray <ngeoffray@google.com> | 2014-09-02 15:17:15 +0100 |
---|---|---|
committer | Nicolas Geoffray <ngeoffray@google.com> | 2014-09-08 12:15:07 +0100 |
commit | 3946844c34ad965515f677084b07d663d70ad1b8 (patch) | |
tree | 0d85bfba2ff69c34a2897351d1e50a1464509305 /compiler/optimizing/code_generator.cc | |
parent | e2c23739c6395a83b30ece38f8a2e9e1bf7cf3ce (diff) | |
download | android_art-3946844c34ad965515f677084b07d663d70ad1b8.tar.gz android_art-3946844c34ad965515f677084b07d663d70ad1b8.tar.bz2 android_art-3946844c34ad965515f677084b07d663d70ad1b8.zip |
Runtime support for the new stack maps for the opt compiler.
Now most of the methods supported by the compiler can be optimized,
instead of using the baseline.
Change-Id: I80ab36a34913fa4e7dd576c7bf55af63594dc1fa
Diffstat (limited to 'compiler/optimizing/code_generator.cc')
-rw-r--r-- | compiler/optimizing/code_generator.cc | 104 |
1 files changed, 98 insertions, 6 deletions
diff --git a/compiler/optimizing/code_generator.cc b/compiler/optimizing/code_generator.cc index 7269fff62c..7731e6e982 100644 --- a/compiler/optimizing/code_generator.cc +++ b/compiler/optimizing/code_generator.cc @@ -41,10 +41,11 @@ void CodeGenerator::CompileBaseline(CodeAllocator* allocator, bool is_leaf) { if (!is_leaf) { MarkNotLeaf(); } - ComputeFrameSize(GetGraph()->GetMaximumNumberOfOutVRegs() - + GetGraph()->GetNumberOfLocalVRegs() - + GetGraph()->GetNumberOfTemporaries() - + 1 /* filler */); + ComputeFrameSize(GetGraph()->GetNumberOfLocalVRegs() + + GetGraph()->GetNumberOfTemporaries() + + 1 /* filler */, + GetGraph()->GetMaximumNumberOfOutVRegs() + + 1 /* current method */); GenerateFrameEntry(); for (size_t i = 0, e = blocks.Size(); i < e; ++i) { @@ -110,10 +111,10 @@ size_t CodeGenerator::AllocateFreeRegisterInternal( return -1; } -void CodeGenerator::ComputeFrameSize(size_t number_of_spill_slots) { +void CodeGenerator::ComputeFrameSize(size_t number_of_spill_slots, size_t number_of_out_slots) { SetFrameSize(RoundUp( number_of_spill_slots * kVRegSize - + kVRegSize // Art method + + number_of_out_slots * kVRegSize + FrameEntrySpillSize(), kStackAlignment)); } @@ -376,4 +377,95 @@ void CodeGenerator::BuildVMapTable(std::vector<uint8_t>* data) const { *data = vmap_encoder.GetData(); } +void CodeGenerator::BuildStackMaps(std::vector<uint8_t>* data) { + uint32_t size = stack_map_stream_.ComputeNeededSize(); + data->resize(size); + MemoryRegion region(data->data(), size); + stack_map_stream_.FillIn(region); +} + +void CodeGenerator::RecordPcInfo(HInstruction* instruction, uint32_t dex_pc) { + // Collect PC infos for the mapping table. + struct PcInfo pc_info; + pc_info.dex_pc = dex_pc; + pc_info.native_pc = GetAssembler()->CodeSize(); + pc_infos_.Add(pc_info); + + // Populate stack map information. + + if (instruction == nullptr) { + // For stack overflow checks. + stack_map_stream_.AddStackMapEntry(dex_pc, pc_info.native_pc, 0, 0, 0, 0); + return; + } + + LocationSummary* locations = instruction->GetLocations(); + HEnvironment* environment = instruction->GetEnvironment(); + + size_t environment_size = instruction->EnvironmentSize(); + + size_t register_mask = 0; + size_t inlining_depth = 0; + stack_map_stream_.AddStackMapEntry( + dex_pc, pc_info.native_pc, register_mask, + locations->GetStackMask(), environment_size, inlining_depth); + + // Walk over the environment, and record the location of dex registers. + for (size_t i = 0; i < environment_size; ++i) { + HInstruction* current = environment->GetInstructionAt(i); + if (current == nullptr) { + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kNone, 0); + continue; + } + + Location location = locations->GetEnvironmentAt(i); + switch (location.GetKind()) { + case Location::kConstant: { + DCHECK(current == location.GetConstant()); + if (current->IsLongConstant()) { + int64_t value = current->AsLongConstant()->GetValue(); + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kConstant, Low32Bits(value)); + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kConstant, High32Bits(value)); + ++i; + DCHECK_LT(i, environment_size); + } else { + DCHECK(current->IsIntConstant()); + int32_t value = current->AsIntConstant()->GetValue(); + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kConstant, value); + } + break; + } + + case Location::kStackSlot: { + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kInStack, location.GetStackIndex()); + break; + } + + case Location::kDoubleStackSlot: { + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kInStack, location.GetStackIndex()); + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kInStack, + location.GetHighStackIndex(kVRegSize)); + ++i; + DCHECK_LT(i, environment_size); + break; + } + + case Location::kRegister : { + int id = location.reg().RegId(); + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kInRegister, id); + if (current->GetType() == Primitive::kPrimDouble + || current->GetType() == Primitive::kPrimLong) { + stack_map_stream_.AddDexRegisterEntry(DexRegisterMap::kInRegister, id); + ++i; + DCHECK_LT(i, environment_size); + } + break; + } + + default: + LOG(FATAL) << "Unexpected kind " << location.GetKind(); + } + } +} + } // namespace art |