summaryrefslogtreecommitdiff
path: root/compiler/optimizing/nodes.cc
diff options
context:
space:
mode:
author David Brazdil <dbrazdil@google.com> 2015-12-27 13:36:12 +0000
committer David Brazdil <dbrazdil@google.com> 2016-01-06 10:33:30 +0000
commitf555258861aea7df8af9c2241ab761227fd2f66a (patch)
tree1317545f50f78eb7c9e4dd44ebfb256bdff0af11 /compiler/optimizing/nodes.cc
parentc917d195d8d8d05f90796b1e0842883fc608346d (diff)
ART: Create BoundType for CheckCast early
ReferenceTypePropagation creates a BoundType for each CheckCast and replaces all dominated uses of the casted object with it. This does not include Phi uses on the boundary of the dominated scope, reducing typing precision. This patch creates the BoundType in Builder, causing SsaBuilder to replace uses of the object automatically. Bug: 26081304 Change-Id: I083979155cccb348071ff58cb9060a896ed7d2ac
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r--compiler/optimizing/nodes.cc27
1 files changed, 22 insertions, 5 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index fc12224783..c85e573557 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2060,6 +2060,16 @@ void HGraph::TransformLoopHeaderForBCE(HBasicBlock* header) {
new_pre_header->SetTryCatchInformation(try_catch_info);
}
+static void CheckAgainstUpperBound(ReferenceTypeInfo rti, ReferenceTypeInfo upper_bound_rti)
+ SHARED_REQUIRES(Locks::mutator_lock_) {
+ if (rti.IsValid()) {
+ DCHECK(upper_bound_rti.IsSupertypeOf(rti))
+ << " upper_bound_rti: " << upper_bound_rti
+ << " rti: " << rti;
+ DCHECK(!upper_bound_rti.GetTypeHandle()->CannotBeAssignedFromOtherTypes() || rti.IsExact());
+ }
+}
+
void HInstruction::SetReferenceTypeInfo(ReferenceTypeInfo rti) {
if (kIsDebugBuild) {
DCHECK_EQ(GetType(), Primitive::kPrimNot);
@@ -2068,16 +2078,23 @@ void HInstruction::SetReferenceTypeInfo(ReferenceTypeInfo rti) {
if (IsBoundType()) {
// Having the test here spares us from making the method virtual just for
// the sake of a DCHECK.
- ReferenceTypeInfo upper_bound_rti = AsBoundType()->GetUpperBound();
- DCHECK(upper_bound_rti.IsSupertypeOf(rti))
- << " upper_bound_rti: " << upper_bound_rti
- << " rti: " << rti;
- DCHECK(!upper_bound_rti.GetTypeHandle()->CannotBeAssignedFromOtherTypes() || rti.IsExact());
+ CheckAgainstUpperBound(rti, AsBoundType()->GetUpperBound());
}
}
reference_type_info_ = rti;
}
+void HBoundType::SetUpperBound(const ReferenceTypeInfo& upper_bound, bool can_be_null) {
+ if (kIsDebugBuild) {
+ ScopedObjectAccess soa(Thread::Current());
+ DCHECK(upper_bound.IsValid());
+ DCHECK(!upper_bound_.IsValid()) << "Upper bound should only be set once.";
+ CheckAgainstUpperBound(GetReferenceTypeInfo(), upper_bound);
+ }
+ upper_bound_ = upper_bound;
+ upper_can_be_null_ = can_be_null;
+}
+
ReferenceTypeInfo::ReferenceTypeInfo() : type_handle_(TypeHandle()), is_exact_(false) {}
ReferenceTypeInfo::ReferenceTypeInfo(TypeHandle type_handle, bool is_exact)