summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-03-07 10:18:14 +0000
committerVladimir Marko <vmarko@google.com>2014-03-07 10:54:06 +0000
commita24122dc3aaa74b0385bb0ce30959f8a19c4a300 (patch)
tree4c4bf5d689fa856600a35ae9b14d5b49ebb0ec60 /compiler
parenta9d7be62735e3356cef7e8ed797c519134a17061 (diff)
downloadart-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.cc63
-rw-r--r--compiler/dex/mir_field_info.h4
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