diff options
author | Vladimir Marko <vmarko@google.com> | 2014-03-07 10:18:14 +0000 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2014-03-07 10:54:06 +0000 |
commit | a24122dc3aaa74b0385bb0ce30959f8a19c4a300 (patch) | |
tree | 4c4bf5d689fa856600a35ae9b14d5b49ebb0ec60 /compiler | |
parent | a9d7be62735e3356cef7e8ed797c519134a17061 (diff) | |
download | art-a24122dc3aaa74b0385bb0ce30959f8a19c4a300.zip art-a24122dc3aaa74b0385bb0ce30959f8a19c4a300.tar.gz art-a24122dc3aaa74b0385bb0ce30959f8a19c4a300.tar.bz2 |
Use ScopedArenaAllocator for CacheFieldLoweringInfo pass.
Change-Id: Idcc2edeb865e29b1bc42b108fc58a1f964295317
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/dex/mir_analysis.cc | 63 | ||||
-rw-r--r-- | compiler/dex/mir_field_info.h | 4 |
2 files changed, 19 insertions, 48 deletions
diff --git a/compiler/dex/mir_analysis.cc b/compiler/dex/mir_analysis.cc index d159f49..667ee26 100644 --- a/compiler/dex/mir_analysis.cc +++ b/compiler/dex/mir_analysis.cc @@ -1095,16 +1095,15 @@ bool MIRGraph::SkipCompilation() { } void MIRGraph::DoCacheFieldLoweringInfo() { - // Try to use stack-allocated array, resort to heap if we exceed the initial size. - static constexpr size_t kInitialSize = 32; - uint16_t stack_idxs[kInitialSize]; - UniquePtr<uint16_t[]> allocated_idxs; - uint16_t* field_idxs = stack_idxs; - size_t size = kInitialSize; + // All IGET/IPUT/SGET/SPUT instructions take 2 code units and there must also be a RETURN. + const uint32_t max_refs = (current_code_item_->insns_size_in_code_units_ - 1u) / 2u; + ScopedArenaAllocator allocator(&cu_->arena_stack); + uint16_t* field_idxs = + reinterpret_cast<uint16_t*>(allocator.Alloc(max_refs * sizeof(uint16_t), kArenaAllocMisc)); // Find IGET/IPUT/SGET/SPUT insns, store IGET/IPUT fields at the beginning, SGET/SPUT at the end. size_t ifield_pos = 0u; - size_t sfield_pos = size; + size_t sfield_pos = max_refs; AllNodesIterator iter(this); for (BasicBlock* bb = iter.Next(); bb != nullptr; bb = iter.Next()) { if (bb->block_type != kDalvikByteCode) { @@ -1113,14 +1112,12 @@ void MIRGraph::DoCacheFieldLoweringInfo() { for (MIR* mir = bb->first_mir_insn; mir != nullptr; mir = mir->next) { if (mir->dalvikInsn.opcode >= Instruction::IGET && mir->dalvikInsn.opcode <= Instruction::SPUT_SHORT) { - bool need_alloc = false; const Instruction* insn = Instruction::At(current_code_item_->insns_ + mir->offset); - uint16_t field_idx; // Get field index and try to find it among existing indexes. If found, it's usually among // the last few added, so we'll start the search from ifield_pos/sfield_pos. Though this // is a linear search, it actually performs much better than map based approach. if (mir->dalvikInsn.opcode <= Instruction::IPUT_SHORT) { - field_idx = insn->VRegC_22c(); + uint16_t field_idx = insn->VRegC_22c(); size_t i = ifield_pos; while (i != 0u && field_idxs[i - 1] != field_idx) { --i; @@ -1129,44 +1126,18 @@ void MIRGraph::DoCacheFieldLoweringInfo() { mir->meta.ifield_lowering_info = i - 1; } else { mir->meta.ifield_lowering_info = ifield_pos; - if (UNLIKELY(ifield_pos == sfield_pos)) { - need_alloc = true; - } else { - field_idxs[ifield_pos++] = field_idx; - } + field_idxs[ifield_pos++] = field_idx; } } else { - field_idx = insn->VRegB_21c(); + uint16_t field_idx = insn->VRegB_21c(); size_t i = sfield_pos; - while (i != size && field_idxs[i] != field_idx) { + while (i != max_refs && field_idxs[i] != field_idx) { ++i; } - if (i != size) { - mir->meta.sfield_lowering_info = size - i - 1u; - } else { - mir->meta.sfield_lowering_info = size - sfield_pos; - if (UNLIKELY(ifield_pos == sfield_pos)) { - need_alloc = true; - } else { - field_idxs[--sfield_pos] = field_idx; - } - } - } - if (UNLIKELY(need_alloc)) { - DCHECK(field_idxs == stack_idxs); - // All IGET/IPUT/SGET/SPUT instructions take 2 code units and there must also be a RETURN. - uint32_t max_refs = (current_code_item_->insns_size_in_code_units_ - 1u) / 2u; - allocated_idxs.reset(new uint16_t[max_refs]); - field_idxs = allocated_idxs.get(); - size_t sfield_count = size - sfield_pos; - sfield_pos = max_refs - sfield_count; - size = max_refs; - memcpy(field_idxs, stack_idxs, ifield_pos * sizeof(field_idxs[0])); - memcpy(field_idxs + sfield_pos, stack_idxs + ifield_pos, - sfield_count * sizeof(field_idxs[0])); - if (mir->dalvikInsn.opcode <= Instruction::IPUT_SHORT) { - field_idxs[ifield_pos++] = field_idx; + if (i != max_refs) { + mir->meta.sfield_lowering_info = max_refs - i - 1u; } else { + mir->meta.sfield_lowering_info = max_refs - sfield_pos; field_idxs[--sfield_pos] = field_idx; } } @@ -1186,16 +1157,16 @@ void MIRGraph::DoCacheFieldLoweringInfo() { ifield_lowering_infos_.GetRawStorage(), ifield_pos); } - if (sfield_pos != size) { + if (sfield_pos != max_refs) { // Resolve static field infos. DCHECK_EQ(sfield_lowering_infos_.Size(), 0u); - sfield_lowering_infos_.Resize(size - sfield_pos); - for (size_t pos = size; pos != sfield_pos;) { + sfield_lowering_infos_.Resize(max_refs - sfield_pos); + for (size_t pos = max_refs; pos != sfield_pos;) { --pos; sfield_lowering_infos_.Insert(MirSFieldLoweringInfo(field_idxs[pos])); } MirSFieldLoweringInfo::Resolve(cu_->compiler_driver, GetCurrentDexCompilationUnit(), - sfield_lowering_infos_.GetRawStorage(), size - sfield_pos); + sfield_lowering_infos_.GetRawStorage(), max_refs - sfield_pos); } } diff --git a/compiler/dex/mir_field_info.h b/compiler/dex/mir_field_info.h index 41cb4ce..e64e9fc 100644 --- a/compiler/dex/mir_field_info.h +++ b/compiler/dex/mir_field_info.h @@ -100,7 +100,7 @@ class MirFieldInfo { class MirIFieldLoweringInfo : public MirFieldInfo { public: // For each requested instance field retrieve the field's declaring location (dex file, class - // index and field index) and volatility and compute the whether we can fast path the access + // index and field index) and volatility and compute whether we can fast path the access // with IGET/IPUT. For fast path fields, retrieve the field offset. static void Resolve(CompilerDriver* compiler_driver, const DexCompilationUnit* mUnit, MirIFieldLoweringInfo* field_infos, size_t count) @@ -143,7 +143,7 @@ class MirIFieldLoweringInfo : public MirFieldInfo { class MirSFieldLoweringInfo : public MirFieldInfo { public: // For each requested static field retrieve the field's declaring location (dex file, class - // index and field index) and volatility and compute the whether we can fast path the access with + // index and field index) and volatility and compute whether we can fast path the access with // IGET/IPUT. For fast path fields (at least for IGET), retrieve the information needed for // the field access, i.e. the field offset, whether the field is in the same class as the // method being compiled, whether the declaring class can be safely assumed to be initialized |