summaryrefslogtreecommitdiff
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc105
1 files changed, 39 insertions, 66 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 6831e9b6aa..3012346a95 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -342,7 +342,10 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item)
ArenaBitVector can_block_throw(arena_, graph_->GetBlocks().size(), /* expandable */ true);
// Scan blocks and mark those which contain throwing instructions.
- for (HBasicBlock* block : graph_->GetBlocks()) {
+ // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators
+ // can be invalidated. We remember the initial size to avoid iterating over the new blocks.
+ for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) {
+ HBasicBlock* block = graph_->GetBlocks()[block_id];
bool can_throw = false;
for (HInstructionIterator insn(block->GetInstructions()); !insn.Done(); insn.Advance()) {
if (insn.Current()->CanThrow()) {
@@ -380,7 +383,10 @@ void HGraphBuilder::InsertTryBoundaryBlocks(const DexFile::CodeItem& code_item)
// (c) link the new blocks to corresponding exception handlers.
// We cannot iterate only over blocks in `branch_targets_` because switch-case
// blocks share the same dex_pc.
- for (HBasicBlock* try_block : graph_->GetBlocks()) {
+ // NOTE: We're appending new blocks inside the loop, so we need to use index because iterators
+ // can be invalidated. We remember the initial size to avoid iterating over the new blocks.
+ for (size_t block_id = 0u, end = graph_->GetBlocks().size(); block_id != end; ++block_id) {
+ HBasicBlock* try_block = graph_->GetBlocks()[block_id];
// TryBoundary blocks are added at the end of the list and not iterated over.
DCHECK(!try_block->IsSingleTryBoundary());
@@ -1225,12 +1231,6 @@ void HGraphBuilder::PotentiallySimplifyFakeString(uint16_t original_dex_register
}
}
-static Primitive::Type GetFieldAccessType(const DexFile& dex_file, uint16_t field_index) {
- const DexFile::FieldId& field_id = dex_file.GetFieldId(field_index);
- const char* type = dex_file.GetFieldTypeDescriptor(field_id);
- return Primitive::GetType(type[0]);
-}
-
bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
uint32_t dex_pc,
bool is_put) {
@@ -1250,61 +1250,44 @@ bool HGraphBuilder::BuildInstanceFieldAccess(const Instruction& instruction,
ArtField* resolved_field =
compiler_driver_->ComputeInstanceFieldInfo(field_index, dex_compilation_unit_, is_put, soa);
+ if (resolved_field == nullptr) {
+ MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
+ return false;
+ }
- HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot, dex_pc);
- HInstruction* null_check = new (arena_) HNullCheck(object, dex_pc);
- current_block_->AddInstruction(null_check);
+ Primitive::Type field_type = resolved_field->GetTypeAsPrimitiveType();
- Primitive::Type field_type = (resolved_field == nullptr)
- ? GetFieldAccessType(*dex_file_, field_index)
- : resolved_field->GetTypeAsPrimitiveType();
+ HInstruction* object = LoadLocal(obj_reg, Primitive::kPrimNot, dex_pc);
+ current_block_->AddInstruction(new (arena_) HNullCheck(object, dex_pc));
if (is_put) {
Temporaries temps(graph_);
+ HInstruction* null_check = current_block_->GetLastInstruction();
// We need one temporary for the null check.
temps.Add(null_check);
HInstruction* value = LoadLocal(source_or_dest_reg, field_type, dex_pc);
- HInstruction* field_set = nullptr;
- if (resolved_field == nullptr) {
- MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
- field_set = new (arena_) HUnresolvedInstanceFieldSet(null_check,
- value,
- field_type,
- field_index,
- dex_pc);
- } else {
- field_set = new (arena_) HInstanceFieldSet(null_check,
- value,
- field_type,
- resolved_field->GetOffset(),
- resolved_field->IsVolatile(),
- field_index,
- *dex_file_,
- dex_compilation_unit_->GetDexCache(),
- dex_pc);
- }
- current_block_->AddInstruction(field_set);
+ current_block_->AddInstruction(new (arena_) HInstanceFieldSet(
+ null_check,
+ value,
+ field_type,
+ resolved_field->GetOffset(),
+ resolved_field->IsVolatile(),
+ field_index,
+ *dex_file_,
+ dex_compilation_unit_->GetDexCache(),
+ dex_pc));
} else {
- HInstruction* field_get = nullptr;
- if (resolved_field == nullptr) {
- MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
- field_get = new (arena_) HUnresolvedInstanceFieldGet(null_check,
- field_type,
- field_index,
- dex_pc);
- } else {
- field_get = new (arena_) HInstanceFieldGet(null_check,
- field_type,
- resolved_field->GetOffset(),
- resolved_field->IsVolatile(),
- field_index,
- *dex_file_,
- dex_compilation_unit_->GetDexCache(),
- dex_pc);
- }
- current_block_->AddInstruction(field_get);
- UpdateLocal(source_or_dest_reg, field_get, dex_pc);
- }
+ current_block_->AddInstruction(new (arena_) HInstanceFieldGet(
+ current_block_->GetLastInstruction(),
+ field_type,
+ resolved_field->GetOffset(),
+ resolved_field->IsVolatile(),
+ field_index,
+ *dex_file_,
+ dex_compilation_unit_->GetDexCache(),
+ dex_pc));
+ UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction(), dex_pc);
+ }
return true;
}
@@ -1361,18 +1344,8 @@ bool HGraphBuilder::BuildStaticFieldAccess(const Instruction& instruction,
soa, dex_cache, class_loader, dex_compilation_unit_, field_index, true);
if (resolved_field == nullptr) {
- MaybeRecordStat(MethodCompilationStat::kUnresolvedField);
- Primitive::Type field_type = GetFieldAccessType(*dex_file_, field_index);
- if (is_put) {
- HInstruction* value = LoadLocal(source_or_dest_reg, field_type, dex_pc);
- current_block_->AddInstruction(
- new (arena_) HUnresolvedStaticFieldSet(value, field_type, field_index, dex_pc));
- } else {
- current_block_->AddInstruction(
- new (arena_) HUnresolvedStaticFieldGet(field_type, field_index, dex_pc));
- UpdateLocal(source_or_dest_reg, current_block_->GetLastInstruction(), dex_pc);
- }
- return true;
+ MaybeRecordStat(MethodCompilationStat::kNotCompiledUnresolvedField);
+ return false;
}
const DexFile& outer_dex_file = *outer_compilation_unit_->GetDexFile();