Set more RTI only if they are valid
Follow-up to aosp/2442280. We haven't seen crashes with these ones,
but we can't guarantee that the RTI will be valid in these code paths.
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: I80da85a6549ba0275a80027016363e0cf9fb8045
diff --git a/compiler/optimizing/bounds_check_elimination.cc b/compiler/optimizing/bounds_check_elimination.cc
index 52f1e9a..210f978 100644
--- a/compiler/optimizing/bounds_check_elimination.cc
+++ b/compiler/optimizing/bounds_check_elimination.cc
@@ -2011,7 +2011,7 @@
phi->SetRawInputAt(0, instruction);
phi->SetRawInputAt(1, zero);
if (type == DataType::Type::kReference) {
- phi->SetReferenceTypeInfo(instruction->GetReferenceTypeInfo());
+ phi->SetReferenceTypeInfoIfValid(instruction->GetReferenceTypeInfo());
}
new_preheader->AddPhi(phi);
return phi;
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 5437d9b..cf49e39 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -181,6 +181,13 @@
} else if (!cond->InputAt(0)->IsNullConstant()) {
return false;
}
+
+ // We can't create a BoundType for an object with an invalid RTI.
+ const ReferenceTypeInfo ti = obj->GetReferenceTypeInfo();
+ if (!ti.IsValid()) {
+ return false;
+ }
+
// Scan all uses of obj and find null check under control dependence.
HBoundType* bound = nullptr;
const HUseList<HInstruction*>& uses = obj->GetUses();
@@ -193,7 +200,6 @@
user_block != throws &&
block->Dominates(user_block)) {
if (bound == nullptr) {
- ReferenceTypeInfo ti = obj->GetReferenceTypeInfo();
bound = new (obj->GetBlock()->GetGraph()->GetAllocator()) HBoundType(obj);
bound->SetUpperBound(ti, /*can_be_null*/ false);
bound->SetReferenceTypeInfo(ti);
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 0e4d587..c24ac84 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1327,7 +1327,7 @@
invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction);
new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
if (invoke_instruction->GetType() == DataType::Type::kReference) {
- new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo());
+ new_invoke->SetReferenceTypeInfoIfValid(invoke_instruction->GetReferenceTypeInfo());
}
*replacement = new_invoke;
@@ -1529,7 +1529,7 @@
invoke_instruction->GetBlock()->InsertInstructionBefore(new_invoke, invoke_instruction);
new_invoke->CopyEnvironmentFrom(invoke_instruction->GetEnvironment());
if (invoke_instruction->GetType() == DataType::Type::kReference) {
- new_invoke->SetReferenceTypeInfo(invoke_instruction->GetReferenceTypeInfo());
+ new_invoke->SetReferenceTypeInfoIfValid(invoke_instruction->GetReferenceTypeInfo());
}
*return_replacement = new_invoke;
return true;
@@ -1854,8 +1854,8 @@
if (!resolved_method->IsStatic() && parameter_index == 0 && receiver_type.IsValid()) {
run_rtp = true;
current->SetReferenceTypeInfo(receiver_type);
- } else if (argument->GetReferenceTypeInfo().IsValid()) {
- current->SetReferenceTypeInfo(argument->GetReferenceTypeInfo());
+ } else {
+ current->SetReferenceTypeInfoIfValid(argument->GetReferenceTypeInfo());
}
current->AsParameterValue()->SetCanBeNull(argument->CanBeNull());
}
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 86b9dba..12ca30f 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -970,7 +970,7 @@
pred_get->GetFieldInfo().GetDexFile(),
pred_get->GetDexPc());
if (pred_get->GetType() == DataType::Type::kReference) {
- replace_with->SetReferenceTypeInfo(pred_get->GetReferenceTypeInfo());
+ replace_with->SetReferenceTypeInfoIfValid(pred_get->GetReferenceTypeInfo());
}
pred_get->GetBlock()->InsertInstructionBefore(replace_with, pred_get);
pred_get->ReplaceWith(replace_with);
@@ -2782,7 +2782,7 @@
ArenaAllocator* allocator = block->GetGraph()->GetAllocator();
HStringBuilderAppend* append = new (allocator) HStringBuilderAppend(
fmt, num_args, has_fp_args, allocator, invoke->GetDexPc());
- append->SetReferenceTypeInfo(invoke->GetReferenceTypeInfo());
+ append->SetReferenceTypeInfoIfValid(invoke->GetReferenceTypeInfo());
for (size_t i = 0; i != num_args; ++i) {
append->SetArgumentAt(i, args[num_args - 1u - i]);
}
diff --git a/compiler/optimizing/load_store_elimination.cc b/compiler/optimizing/load_store_elimination.cc
index cd44082..9cabb12 100644
--- a/compiler/optimizing/load_store_elimination.cc
+++ b/compiler/optimizing/load_store_elimination.cc
@@ -3386,7 +3386,7 @@
ins->GetBlock()->InsertInstructionBefore(new_fget, ins);
if (ins->GetType() == DataType::Type::kReference) {
// Reference info is the same
- new_fget->SetReferenceTypeInfo(ins->GetReferenceTypeInfo());
+ new_fget->SetReferenceTypeInfoIfValid(ins->GetReferenceTypeInfo());
}
// In this phase, substitute instructions are used only for the predicated get
// default values which are used only if the partial singleton did not escape,
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 0876ce0..c99cfab 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -688,7 +688,7 @@
0,
header_phi->GetType());
if (header_phi->GetType() == DataType::Type::kReference) {
- preheader_phi->SetReferenceTypeInfo(header_phi->GetReferenceTypeInfo());
+ preheader_phi->SetReferenceTypeInfoIfValid(header_phi->GetReferenceTypeInfo());
}
preheader->AddPhi(preheader_phi);
@@ -3215,6 +3215,12 @@
SetPackedFlag<kFlagReferenceTypeIsExact>(rti.IsExact());
}
+void HInstruction::SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti) {
+ if (rti.IsValid()) {
+ SetReferenceTypeInfo(rti);
+ }
+}
+
bool HBoundType::InstructionDataEquals(const HInstruction* other) const {
const HBoundType* other_bt = other->AsBoundType();
ScopedObjectAccess soa(Thread::Current());
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 58ce9ce..5854fa2 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2377,7 +2377,10 @@
return GetType() == DataType::Type::kReference;
}
+ // Sets the ReferenceTypeInfo. The RTI must be valid.
void SetReferenceTypeInfo(ReferenceTypeInfo rti);
+ // Same as above, but we only set it if it's valid. Otherwise, we don't change the current RTI.
+ void SetReferenceTypeInfoIfValid(ReferenceTypeInfo rti);
ReferenceTypeInfo GetReferenceTypeInfo() const {
DCHECK_EQ(GetType(), DataType::Type::kReference);
diff --git a/compiler/optimizing/select_generator.cc b/compiler/optimizing/select_generator.cc
index 761e7b5..6a10440 100644
--- a/compiler/optimizing/select_generator.cc
+++ b/compiler/optimizing/select_generator.cc
@@ -160,7 +160,7 @@
ReferenceTypePropagation::FixUpInstructionType(select, graph_->GetHandleCache());
}
} else if (phi->GetType() == DataType::Type::kReference) {
- select->SetReferenceTypeInfo(phi->GetReferenceTypeInfo());
+ select->SetReferenceTypeInfoIfValid(phi->GetReferenceTypeInfo());
}
block->InsertInstructionBefore(select, if_instruction);
diff --git a/compiler/optimizing/superblock_cloner.cc b/compiler/optimizing/superblock_cloner.cc
index ba56eb8..7c0097c 100644
--- a/compiler/optimizing/superblock_cloner.cc
+++ b/compiler/optimizing/superblock_cloner.cc
@@ -633,7 +633,7 @@
HPhi* phi = new (arena_) HPhi(arena_, kNoRegNumber, 0, value->GetType());
if (value->GetType() == DataType::Type::kReference) {
- phi->SetReferenceTypeInfo(value->GetReferenceTypeInfo());
+ phi->SetReferenceTypeInfoIfValid(value->GetReferenceTypeInfo());
}
exit_block->AddPhi(phi);