Optimizing: Create fewer handles in inliner. am: 5a62af5dc9
Change-Id: I05eed8cab6fa1c976db7c3b2c6b782a5a839ba39
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 05a0afa..126bf25 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -2167,7 +2167,8 @@
inliner.Run();
}
-static bool IsReferenceTypeRefinement(ReferenceTypeInfo declared_rti,
+static bool IsReferenceTypeRefinement(ObjPtr<mirror::Class> declared_class,
+ bool declared_is_exact,
bool declared_can_be_null,
HInstruction* actual_obj)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -2176,22 +2177,29 @@
}
ReferenceTypeInfo actual_rti = actual_obj->GetReferenceTypeInfo();
- return (actual_rti.IsExact() && !declared_rti.IsExact()) ||
- declared_rti.IsStrictSupertypeOf(actual_rti);
+ ObjPtr<mirror::Class> actual_class = actual_rti.GetTypeHandle().Get();
+ return (actual_rti.IsExact() && !declared_is_exact) ||
+ (declared_class != actual_class && declared_class->IsAssignableFrom(actual_class));
}
-ReferenceTypeInfo HInliner::GetClassRTI(ObjPtr<mirror::Class> klass) {
- return ReferenceTypePropagation::IsAdmissible(klass)
- ? ReferenceTypeInfo::Create(handles_->NewHandle(klass))
- : graph_->GetInexactObjectRti();
+static bool IsReferenceTypeRefinement(ObjPtr<mirror::Class> declared_class,
+ bool declared_can_be_null,
+ HInstruction* actual_obj)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ bool admissible = ReferenceTypePropagation::IsAdmissible(declared_class);
+ return IsReferenceTypeRefinement(
+ admissible ? declared_class : GetClassRoot<mirror::Class>(),
+ /*declared_is_exact=*/ admissible && declared_class->CannotBeAssignedFromOtherTypes(),
+ declared_can_be_null,
+ actual_obj);
}
bool HInliner::ArgumentTypesMoreSpecific(HInvoke* invoke_instruction, ArtMethod* resolved_method) {
// If this is an instance call, test whether the type of the `this` argument
// is more specific than the class which declares the method.
if (!resolved_method->IsStatic()) {
- if (IsReferenceTypeRefinement(GetClassRTI(resolved_method->GetDeclaringClass()),
- /* declared_can_be_null= */ false,
+ if (IsReferenceTypeRefinement(resolved_method->GetDeclaringClass(),
+ /*declared_can_be_null=*/ false,
invoke_instruction->InputAt(0u))) {
return true;
}
@@ -2210,9 +2218,7 @@
if (input->GetType() == DataType::Type::kReference) {
ObjPtr<mirror::Class> param_cls = resolved_method->LookupResolvedClassFromTypeIndex(
param_list->GetTypeItem(param_idx).type_idx_);
- if (IsReferenceTypeRefinement(GetClassRTI(param_cls),
- /* declared_can_be_null= */ true,
- input)) {
+ if (IsReferenceTypeRefinement(param_cls, /*declared_can_be_null=*/ true, input)) {
return true;
}
}
@@ -2227,8 +2233,10 @@
if (return_replacement != nullptr) {
if (return_replacement->GetType() == DataType::Type::kReference) {
// Test if the return type is a refinement of the declared return type.
- if (IsReferenceTypeRefinement(invoke_instruction->GetReferenceTypeInfo(),
- /* declared_can_be_null= */ true,
+ ReferenceTypeInfo invoke_rti = invoke_instruction->GetReferenceTypeInfo();
+ if (IsReferenceTypeRefinement(invoke_rti.GetTypeHandle().Get(),
+ invoke_rti.IsExact(),
+ /*declared_can_be_null=*/ true,
return_replacement)) {
return true;
} else if (return_replacement->IsInstanceFieldGet()) {
@@ -2258,7 +2266,10 @@
// some functionality from the reference type propagation.
DCHECK(return_replacement->IsPhi());
ObjPtr<mirror::Class> cls = resolved_method->LookupResolvedReturnType();
- return_replacement->SetReferenceTypeInfo(GetClassRTI(cls));
+ ReferenceTypeInfo rti = ReferenceTypePropagation::IsAdmissible(cls)
+ ? ReferenceTypeInfo::Create(handles_->NewHandle(cls))
+ : graph_->GetInexactObjectRti();
+ return_replacement->SetReferenceTypeInfo(rti);
}
}
}
diff --git a/compiler/optimizing/inliner.h b/compiler/optimizing/inliner.h
index 882ba4e..786b768 100644
--- a/compiler/optimizing/inliner.h
+++ b/compiler/optimizing/inliner.h
@@ -250,11 +250,6 @@
void FixUpReturnReferenceType(ArtMethod* resolved_method, HInstruction* return_replacement)
REQUIRES_SHARED(Locks::mutator_lock_);
- // Creates an instance of ReferenceTypeInfo from `klass` if `klass` is
- // admissible (see ReferenceTypePropagation::IsAdmissible for details).
- // Otherwise returns inexact Object RTI.
- ReferenceTypeInfo GetClassRTI(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_);
-
bool ArgumentTypesMoreSpecific(HInvoke* invoke_instruction, ArtMethod* resolved_method)
REQUIRES_SHARED(Locks::mutator_lock_);
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index e02a393..7aeab72 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -272,13 +272,6 @@
return GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get());
}
- bool IsStrictSupertypeOf(ReferenceTypeInfo rti) const REQUIRES_SHARED(Locks::mutator_lock_) {
- DCHECK(IsValid());
- DCHECK(rti.IsValid());
- return GetTypeHandle().Get() != rti.GetTypeHandle().Get() &&
- GetTypeHandle()->IsAssignableFrom(rti.GetTypeHandle().Get());
- }
-
// Returns true if the type information provide the same amount of details.
// Note that it does not mean that the instructions have the same actual type
// (because the type can be the result of a merge).
diff --git a/compiler/optimizing/reference_type_propagation.h b/compiler/optimizing/reference_type_propagation.h
index 7c6a048..8a41d65 100644
--- a/compiler/optimizing/reference_type_propagation.h
+++ b/compiler/optimizing/reference_type_propagation.h
@@ -45,9 +45,11 @@
// Returns true if klass is admissible to the propagation: non-null and resolved.
// For an array type, we also check if the component type is admissible.
static bool IsAdmissible(ObjPtr<mirror::Class> klass) REQUIRES_SHARED(Locks::mutator_lock_) {
- return klass != nullptr &&
- klass->IsResolved() &&
- (!klass->IsArrayClass() || IsAdmissible(klass->GetComponentType()));
+ while (klass != nullptr && klass->IsArrayClass()) {
+ DCHECK(klass->IsResolved());
+ klass = klass->GetComponentType();
+ }
+ return klass != nullptr && klass->IsResolved();
}
static constexpr const char* kReferenceTypePropagationPassName = "reference_type_propagation";