Add support for unresolved classes in optimizing.

Change-Id: I0e299a81e560eb9cb0737ec46125dffc99333b54
diff --git a/compiler/optimizing/reference_type_propagation.cc b/compiler/optimizing/reference_type_propagation.cc
index d22f254..f7a7e42 100644
--- a/compiler/optimizing/reference_type_propagation.cc
+++ b/compiler/optimizing/reference_type_propagation.cc
@@ -121,8 +121,9 @@
           if (instr->IsBoundType()) {
             DCHECK(instr->AsBoundType()->GetUpperBound().IsValid());
           } else if (instr->IsLoadClass()) {
-            DCHECK(instr->AsLoadClass()->GetReferenceTypeInfo().IsExact());
-            DCHECK(instr->AsLoadClass()->GetLoadedClassRTI().IsValid());
+            HLoadClass* cls = instr->AsLoadClass();
+            DCHECK(cls->GetReferenceTypeInfo().IsExact());
+            DCHECK(!cls->GetLoadedClassRTI().IsValid() || cls->GetLoadedClassRTI().IsExact());
           } else if (instr->IsNullCheck()) {
             DCHECK(instr->GetReferenceTypeInfo().IsEqual(instr->InputAt(0)->GetReferenceTypeInfo()))
                 << "NullCheck " << instr->GetReferenceTypeInfo()
@@ -168,6 +169,7 @@
       SHARED_REQUIRES(Locks::mutator_lock_) {
   ReferenceTypeInfo obj_rti = obj->GetReferenceTypeInfo();
   ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
+  DCHECK(class_rti.IsValid());
   HBoundType* bound_type = new (arena) HBoundType(obj, class_rti, upper_can_be_null);
   // Narrow the type as much as possible.
   if (class_rti.GetTypeHandle()->CannotBeAssignedFromOtherTypes()) {
@@ -316,6 +318,15 @@
     return;
   }
 
+  HLoadClass* load_class = instanceOf->InputAt(1)->AsLoadClass();
+  ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    if (!class_rti.IsValid()) {
+      // He have loaded an unresolved class. Don't bother bounding the type.
+      return;
+    }
+  }
   // We only need to bound the type if we have uses in the relevant block.
   // So start with null and create the HBoundType lazily, only if it's needed.
   HBoundType* bound_type = nullptr;
@@ -336,8 +347,6 @@
     if (instanceOfTrueBlock->Dominates(user->GetBlock())) {
       if (bound_type == nullptr) {
         ScopedObjectAccess soa(Thread::Current());
-        HLoadClass* load_class = instanceOf->InputAt(1)->AsLoadClass();
-        ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
         HInstruction* insert_point = instanceOfTrueBlock->GetFirstInstruction();
         if (ShouldCreateBoundType(insert_point, obj, class_rti, nullptr, instanceOfTrueBlock)) {
           bound_type = CreateBoundType(
@@ -475,10 +484,10 @@
   // Get type from dex cache assuming it was populated by the verifier.
   mirror::Class* resolved_class = dex_cache->GetResolvedType(instr->GetTypeIndex());
   // TODO: investigating why we are still getting unresolved classes: b/22821472.
-  ReferenceTypeInfo::TypeHandle handle = (resolved_class != nullptr)
-    ? handles_->NewHandle(resolved_class)
-    : object_class_handle_;
-  instr->SetLoadedClassRTI(ReferenceTypeInfo::Create(handle, /* is_exact */ true));
+  if (resolved_class != nullptr) {
+    instr->SetLoadedClassRTI(ReferenceTypeInfo::Create(
+        handles_->NewHandle(resolved_class), /* is_exact */ true));
+  }
   instr->SetReferenceTypeInfo(ReferenceTypeInfo::Create(class_class_handle_, /* is_exact */ true));
 }
 
@@ -517,6 +526,15 @@
 }
 
 void RTPVisitor::VisitCheckCast(HCheckCast* check_cast) {
+  HLoadClass* load_class = check_cast->InputAt(1)->AsLoadClass();
+  ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
+  {
+    ScopedObjectAccess soa(Thread::Current());
+    if (!class_rti.IsValid()) {
+      // He have loaded an unresolved class. Don't bother bounding the type.
+      return;
+    }
+  }
   HInstruction* obj = check_cast->InputAt(0);
   HBoundType* bound_type = nullptr;
   for (HUseIterator<HInstruction*> it(obj->GetUses()); !it.Done(); it.Advance()) {
@@ -524,8 +542,6 @@
     if (check_cast->StrictlyDominates(user)) {
       if (bound_type == nullptr) {
         ScopedObjectAccess soa(Thread::Current());
-        HLoadClass* load_class = check_cast->InputAt(1)->AsLoadClass();
-        ReferenceTypeInfo class_rti = load_class->GetLoadedClassRTI();
         if (ShouldCreateBoundType(check_cast->GetNext(), obj, class_rti, check_cast, nullptr)) {
           bound_type = CreateBoundType(
               GetGraph()->GetArena(),