Bring Reference Type Propagation to NewArray
Change-Id: Ieff4f38854e06b0ed4b5689ced94a4289053d80d
diff --git a/compiler/optimizing/bounds_check_elimination_test.cc b/compiler/optimizing/bounds_check_elimination_test.cc
index 163458f..48090a3 100644
--- a/compiler/optimizing/bounds_check_elimination_test.cc
+++ b/compiler/optimizing/bounds_check_elimination_test.cc
@@ -647,7 +647,7 @@
graph->AddBlock(block);
entry->AddSuccessor(block);
HInstruction* new_array = new (allocator)
- HNewArray(constant_10, 0, Primitive::kPrimInt, kQuickAllocArray);
+ HNewArray(constant_10, 0, Primitive::kPrimInt, graph->GetDexFile(), kQuickAllocArray);
block->AddInstruction(new_array);
block->AddInstruction(new (allocator) HGoto());
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 49a0444..c4f033d 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -1027,7 +1027,11 @@
QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
? kQuickAllocArrayWithAccessCheck
: kQuickAllocArray;
- HInstruction* object = new (arena_) HNewArray(length, dex_pc, type_index, entrypoint);
+ HInstruction* object = new (arena_) HNewArray(length,
+ dex_pc,
+ type_index,
+ *dex_compilation_unit_->GetDexFile(),
+ entrypoint);
current_block_->AddInstruction(object);
const char* descriptor = dex_file_->StringByTypeIdx(type_index);
@@ -1993,8 +1997,8 @@
QuickEntrypointEnum entrypoint = NeedsAccessCheck(type_index)
? kQuickAllocArrayWithAccessCheck
: kQuickAllocArray;
- current_block_->AddInstruction(
- new (arena_) HNewArray(length, dex_pc, type_index, entrypoint));
+ current_block_->AddInstruction(new (arena_) HNewArray(
+ length, dex_pc, type_index, *dex_compilation_unit_->GetDexFile(), entrypoint));
UpdateLocal(instruction.VRegA_22c(), current_block_->GetLastInstruction());
break;
}
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 01870c3..a44d745 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2656,16 +2656,19 @@
HNewArray(HInstruction* length,
uint32_t dex_pc,
uint16_t type_index,
+ const DexFile& dex_file,
QuickEntrypointEnum entrypoint)
: HExpression(Primitive::kPrimNot, SideEffects::None()),
dex_pc_(dex_pc),
type_index_(type_index),
+ dex_file_(dex_file),
entrypoint_(entrypoint) {
SetRawInputAt(0, length);
}
uint32_t GetDexPc() const OVERRIDE { return dex_pc_; }
uint16_t GetTypeIndex() const { return type_index_; }
+ const DexFile& GetDexFile() const { return dex_file_; }
// Calls runtime so needs an environment.
bool NeedsEnvironment() const OVERRIDE { return true; }
@@ -2682,6 +2685,7 @@
private:
const uint32_t dex_pc_;
const uint16_t type_index_;
+ const DexFile& dex_file_;
const QuickEntrypointEnum entrypoint_;
DISALLOW_COPY_AND_ASSIGN(HNewArray);
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index 601b48a..91b2e6f 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -35,7 +35,7 @@
void ReferenceTypePropagation::VisitBasicBlock(HBasicBlock* block) {
// TODO: handle other instructions that give type info
- // (NewArray/Call/Field accesses/array accesses)
+ // (Call/Field accesses/array accesses)
// Initialize exact types first for faster convergence.
for (HInstructionIterator it(block->GetInstructions()); !it.Done(); it.Advance()) {
@@ -44,6 +44,8 @@
VisitNewInstance(instr->AsNewInstance());
} else if (instr->IsLoadClass()) {
VisitLoadClass(instr->AsLoadClass());
+ } else if (instr->IsNewArray()) {
+ VisitNewArray(instr->AsNewArray());
}
}
@@ -159,18 +161,29 @@
}
}
-void ReferenceTypePropagation::VisitNewInstance(HNewInstance* instr) {
+void ReferenceTypePropagation::UpdateReferenceTypeInfo(HInstruction* instr,
+ uint16_t type_idx,
+ const DexFile& dex_file) {
+ DCHECK_EQ(instr->GetType(), Primitive::kPrimNot);
+
ScopedObjectAccess soa(Thread::Current());
- mirror::DexCache* dex_cache =
- Runtime::Current()->GetClassLinker()->FindDexCache(instr->GetDexFile());
+ mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file);
// Get type from dex cache assuming it was populated by the verifier.
- mirror::Class* resolved_class = dex_cache->GetResolvedType(instr->GetTypeIndex());
+ mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx);
if (resolved_class != nullptr) {
MutableHandle<mirror::Class> handle = handles_->NewHandle(resolved_class);
instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(handle, true));
}
}
+void ReferenceTypePropagation::VisitNewInstance(HNewInstance* instr) {
+ UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile());
+}
+
+void ReferenceTypePropagation::VisitNewArray(HNewArray* instr) {
+ UpdateReferenceTypeInfo(instr, instr->GetTypeIndex(), instr->GetDexFile());
+}
+
void ReferenceTypePropagation::VisitLoadClass(HLoadClass* instr) {
ScopedObjectAccess soa(Thread::Current());
mirror::DexCache* dex_cache =
diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h
index b68fc67..12c3362 100644
--- a/compiler/optimizing/reference_type_propagation.h
+++ b/compiler/optimizing/reference_type_propagation.h
@@ -42,6 +42,7 @@
private:
void VisitNewInstance(HNewInstance* new_instance);
void VisitLoadClass(HLoadClass* load_class);
+ void VisitNewArray(HNewArray* instr);
void VisitPhi(HPhi* phi);
void VisitBasicBlock(HBasicBlock* block);
@@ -50,6 +51,7 @@
void BoundTypeForIfNotNull(HBasicBlock* block);
void BoundTypeForIfInstanceOf(HBasicBlock* block);
+ void UpdateReferenceTypeInfo(HInstruction* instr, uint16_t type_idx, const DexFile& dex_file);
void ProcessWorklist();
void AddToWorklist(HInstruction* instr);