Merge "MIPS fix." into dalvik-dev
diff --git a/src/verifier/reg_type_cache.cc b/src/verifier/reg_type_cache.cc
index a8caa94..8e23b74 100644
--- a/src/verifier/reg_type_cache.cc
+++ b/src/verifier/reg_type_cache.cc
@@ -177,20 +177,22 @@
     }
     // Class was not found, must create new type.
 
-    // Create a type if:
-    // 1-The class is instantiable ( not Abstract or Interface ), we should
-    //   abort failing the verification if we get that.
-    // 2- And, the class should be instantiable (Not interface, Abstract or a
-    //    primitive type) OR it is imprecise.
-
-    // Create a precise type if :
-    // 1-The class is final.
-    // 2-OR the precise was passed as true .
+    //To pass the verification, the type should be imprecise,
+    // instantiable or an interface with the precise type set to false.
     CHECK(!precise || klass->IsInstantiable());
+
+    // Create a precise type if:
+    // 1- Class is final and NOT an interface. a precise interface
+    //    is meaningless !!
+    // 2- Precise Flag passed as true.
+
     RegType* entry;
-    // Create an imprecise type if we can'tt tell for a fact that it is precise.
-    if (klass->IsFinal() || precise) {
+    // Create an imprecise type if we can't tell for a fact that it is precise.
+    if ((klass->IsFinal()) || precise) {
+      CHECK(!(klass->IsAbstract()) || klass->IsArrayClass());
+      CHECK(!klass->IsInterface());
       entry = new PreciseReferenceType(klass, descriptor, entries_.size());
+
     } else {
       entry = new ReferenceType(klass, descriptor, entries_.size());
     }
@@ -378,6 +380,7 @@
 }
 const RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
   RegType* entry;
+
   if (uninit_type.IsUnresolvedTypes()) {
     std::string descriptor(uninit_type.GetDescriptor());
     for (size_t i = primitive_count_; i < entries_.size(); i++) {
@@ -390,15 +393,27 @@
     entry = new UnresolvedReferenceType(descriptor, entries_.size());
   } else {
     mirror::Class* klass = uninit_type.GetClass();
-    for (size_t i = primitive_count_; i < entries_.size(); i++) {
-      RegType* cur_entry = entries_[i];
-      if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
-        return *cur_entry;
+    if(uninit_type.IsUninitializedThisReference() && !klass->IsFinal()) {
+      // For uninitialized this reference look for reference types that are not precise.
+      for (size_t i = primitive_count_; i < entries_.size(); i++) {
+        RegType* cur_entry = entries_[i];
+        if (cur_entry->IsReference() && cur_entry->GetClass() == klass) {
+          return *cur_entry;
+        }
       }
+      std::string descriptor = "";
+      entry = new ReferenceType(klass, descriptor, entries_.size());
+    } else {
+      for (size_t i = primitive_count_; i < entries_.size(); i++) {
+        RegType* cur_entry = entries_[i];
+        if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
+          return *cur_entry;
+        }
+      }
+      std::string descriptor = "";
+      entry = new PreciseReferenceType(klass, descriptor, entries_.size());
     }
-    std::string descriptor = "";
-    entry = new PreciseReferenceType(klass, descriptor, entries_.size());
-  }
+ }
   entries_.push_back(entry);
   return *entry;
 }