1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "reg_type-inl.h"
18 
19 #include "android-base/stringprintf.h"
20 
21 #include "base/arena_bit_vector.h"
22 #include "base/bit_vector-inl.h"
23 #include "base/casts.h"
24 #include "class_linker-inl.h"
25 #include "dex/descriptors_names.h"
26 #include "dex/dex_file-inl.h"
27 #include "method_verifier.h"
28 #include "mirror/class-inl.h"
29 #include "mirror/class.h"
30 #include "mirror/object-inl.h"
31 #include "mirror/object_array-inl.h"
32 #include "reg_type_cache-inl.h"
33 #include "scoped_thread_state_change-inl.h"
34 
35 #include <limits>
36 #include <sstream>
37 
38 namespace art HIDDEN {
39 namespace verifier {
40 
41 using android::base::StringPrintf;
42 
PrimitiveType(Handle<mirror::Class> klass,const std::string_view & descriptor,uint16_t cache_id)43 PrimitiveType::PrimitiveType(Handle<mirror::Class> klass,
44                              const std::string_view& descriptor,
45                              uint16_t cache_id)
46     : RegType(klass, descriptor, cache_id) {
47   CHECK(klass != nullptr);
48   CHECK(!descriptor.empty());
49 }
50 
Cat1Type(Handle<mirror::Class> klass,const std::string_view & descriptor,uint16_t cache_id)51 Cat1Type::Cat1Type(Handle<mirror::Class> klass,
52                    const std::string_view& descriptor,
53                    uint16_t cache_id)
54     : PrimitiveType(klass, descriptor, cache_id) {
55 }
56 
Cat2Type(Handle<mirror::Class> klass,const std::string_view & descriptor,uint16_t cache_id)57 Cat2Type::Cat2Type(Handle<mirror::Class> klass,
58                    const std::string_view& descriptor,
59                    uint16_t cache_id)
60     : PrimitiveType(klass, descriptor, cache_id) {
61 }
62 
Dump() const63 std::string PreciseConstType::Dump() const {
64   std::stringstream result;
65   uint32_t val = ConstantValue();
66   if (val == 0) {
67     CHECK(IsPreciseConstant());
68     result << "Zero/null";
69   } else {
70     result << "Precise ";
71     if (IsConstantShort()) {
72       result << StringPrintf("Constant: %d", val);
73     } else {
74       result << StringPrintf("Constant: 0x%x", val);
75     }
76   }
77   return result.str();
78 }
79 
Dump() const80 std::string BooleanType::Dump() const {
81   return "Boolean";
82 }
83 
Dump() const84 std::string ConflictType::Dump() const {
85     return "Conflict";
86 }
87 
Dump() const88 std::string ByteType::Dump() const {
89   return "Byte";
90 }
91 
Dump() const92 std::string ShortType::Dump() const {
93   return "Short";
94 }
95 
Dump() const96 std::string CharType::Dump() const {
97   return "Char";
98 }
99 
Dump() const100 std::string FloatType::Dump() const {
101   return "Float";
102 }
103 
Dump() const104 std::string LongLoType::Dump() const {
105   return "Long (Low Half)";
106 }
107 
Dump() const108 std::string LongHiType::Dump() const {
109   return "Long (High Half)";
110 }
111 
Dump() const112 std::string DoubleLoType::Dump() const {
113   return "Double (Low Half)";
114 }
115 
Dump() const116 std::string DoubleHiType::Dump() const {
117   return "Double (High Half)";
118 }
119 
Dump() const120 std::string IntegerType::Dump() const {
121   return "Integer";
122 }
123 
Dump() const124 std::string UndefinedType::Dump() const REQUIRES_SHARED(Locks::mutator_lock_) {
125   return "Undefined";
126 }
127 
PreciseReferenceType(Handle<mirror::Class> klass,const std::string_view & descriptor,uint16_t cache_id)128 PreciseReferenceType::PreciseReferenceType(Handle<mirror::Class> klass,
129                                            const std::string_view& descriptor,
130                                            uint16_t cache_id)
131     : RegType(klass, descriptor, cache_id) {
132   // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError
133   //       would be thrown at runtime, but we need to continue verification and *not* create a
134   //       hard failure or abort.
135   CheckConstructorInvariants(this);
136 }
137 
Dump() const138 std::string UnresolvedMergedType::Dump() const {
139   std::stringstream result;
140   result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
141   const BitVector& types = GetUnresolvedTypes();
142 
143   bool first = true;
144   for (uint32_t idx : types.Indexes()) {
145     if (!first) {
146       result << ", ";
147     } else {
148       first = false;
149     }
150     result << reg_type_cache_->GetFromId(idx).Dump();
151   }
152   result << ")";
153   return result.str();
154 }
155 
Dump() const156 std::string UnresolvedSuperClass::Dump() const {
157   std::stringstream result;
158   uint16_t super_type_id = GetUnresolvedSuperClassChildId();
159   result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
160   return result.str();
161 }
162 
Dump() const163 std::string UnresolvedReferenceType::Dump() const {
164   std::stringstream result;
165   result << "Unresolved Reference: " << PrettyDescriptor(std::string(GetDescriptor()).c_str());
166   return result.str();
167 }
168 
Dump() const169 std::string UnresolvedUninitializedRefType::Dump() const {
170   std::stringstream result;
171   result << "Unresolved And Uninitialized Reference: "
172       << PrettyDescriptor(std::string(GetDescriptor()).c_str())
173       << " Allocation PC: " << GetAllocationPc();
174   return result.str();
175 }
176 
Dump() const177 std::string UnresolvedUninitializedThisRefType::Dump() const {
178   std::stringstream result;
179   result << "Unresolved And Uninitialized This Reference: "
180       << PrettyDescriptor(std::string(GetDescriptor()).c_str());
181   return result.str();
182 }
183 
Dump() const184 std::string ReferenceType::Dump() const {
185   std::stringstream result;
186   result << "Reference: " << mirror::Class::PrettyDescriptor(GetClass());
187   return result.str();
188 }
189 
Dump() const190 std::string PreciseReferenceType::Dump() const {
191   std::stringstream result;
192   result << "Precise Reference: " << mirror::Class::PrettyDescriptor(GetClass());
193   return result.str();
194 }
195 
Dump() const196 std::string UninitializedReferenceType::Dump() const {
197   std::stringstream result;
198   result << "Uninitialized Reference: " << mirror::Class::PrettyDescriptor(GetClass());
199   result << " Allocation PC: " << GetAllocationPc();
200   return result.str();
201 }
202 
Dump() const203 std::string UninitializedThisReferenceType::Dump() const {
204   std::stringstream result;
205   result << "Uninitialized This Reference: " << mirror::Class::PrettyDescriptor(GetClass());
206   result << "Allocation PC: " << GetAllocationPc();
207   return result.str();
208 }
209 
Dump() const210 std::string ImpreciseConstType::Dump() const {
211   std::stringstream result;
212   uint32_t val = ConstantValue();
213   if (val == 0) {
214     result << "Zero/null";
215   } else {
216     result << "Imprecise ";
217     if (IsConstantShort()) {
218       result << StringPrintf("Constant: %d", val);
219     } else {
220       result << StringPrintf("Constant: 0x%x", val);
221     }
222   }
223   return result.str();
224 }
Dump() const225 std::string PreciseConstLoType::Dump() const {
226   std::stringstream result;
227 
228   int32_t val = ConstantValueLo();
229   result << "Precise ";
230   if (val >= std::numeric_limits<jshort>::min() &&
231       val <= std::numeric_limits<jshort>::max()) {
232     result << StringPrintf("Low-half Constant: %d", val);
233   } else {
234     result << StringPrintf("Low-half Constant: 0x%x", val);
235   }
236   return result.str();
237 }
238 
Dump() const239 std::string ImpreciseConstLoType::Dump() const {
240   std::stringstream result;
241 
242   int32_t val = ConstantValueLo();
243   result << "Imprecise ";
244   if (val >= std::numeric_limits<jshort>::min() &&
245       val <= std::numeric_limits<jshort>::max()) {
246     result << StringPrintf("Low-half Constant: %d", val);
247   } else {
248     result << StringPrintf("Low-half Constant: 0x%x", val);
249   }
250   return result.str();
251 }
252 
Dump() const253 std::string PreciseConstHiType::Dump() const {
254   std::stringstream result;
255   int32_t val = ConstantValueHi();
256   result << "Precise ";
257   if (val >= std::numeric_limits<jshort>::min() &&
258       val <= std::numeric_limits<jshort>::max()) {
259     result << StringPrintf("High-half Constant: %d", val);
260   } else {
261     result << StringPrintf("High-half Constant: 0x%x", val);
262   }
263   return result.str();
264 }
265 
Dump() const266 std::string ImpreciseConstHiType::Dump() const {
267   std::stringstream result;
268   int32_t val = ConstantValueHi();
269   result << "Imprecise ";
270   if (val >= std::numeric_limits<jshort>::min() &&
271       val <= std::numeric_limits<jshort>::max()) {
272     result << StringPrintf("High-half Constant: %d", val);
273   } else {
274     result << StringPrintf("High-half Constant: 0x%x", val);
275   }
276   return result.str();
277 }
278 
HighHalf(RegTypeCache * cache) const279 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
280   DCHECK(IsLowHalf());
281   if (IsLongLo()) {
282     return cache->LongHi();
283   } else if (IsDoubleLo()) {
284     return cache->DoubleHi();
285   } else {
286     DCHECK(IsImpreciseConstantLo());
287     const ConstantType* const_val = down_cast<const ConstantType*>(this);
288     return cache->FromCat2ConstHi(const_val->ConstantValue(), false);
289   }
290 }
291 
GetPrimitiveType() const292 Primitive::Type RegType::GetPrimitiveType() const {
293   if (IsNonZeroReferenceTypes()) {
294     return Primitive::kPrimNot;
295   } else if (IsBooleanTypes()) {
296     return Primitive::kPrimBoolean;
297   } else if (IsByteTypes()) {
298     return Primitive::kPrimByte;
299   } else if (IsShortTypes()) {
300     return Primitive::kPrimShort;
301   } else if (IsCharTypes()) {
302     return Primitive::kPrimChar;
303   } else if (IsFloat()) {
304     return Primitive::kPrimFloat;
305   } else if (IsIntegralTypes()) {
306     return Primitive::kPrimInt;
307   } else if (IsDoubleLo()) {
308     return Primitive::kPrimDouble;
309   } else {
310     DCHECK(IsLongTypes());
311     return Primitive::kPrimLong;
312   }
313 }
314 
IsUninitializedTypes() const315 bool UninitializedType::IsUninitializedTypes() const {
316   return true;
317 }
318 
IsNonZeroReferenceTypes() const319 bool UninitializedType::IsNonZeroReferenceTypes() const {
320   return true;
321 }
322 
IsNonZeroReferenceTypes() const323 bool UnresolvedType::IsNonZeroReferenceTypes() const {
324   return true;
325 }
326 
GetSuperClass(RegTypeCache * cache) const327 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
328   if (!IsUnresolvedTypes()) {
329     ObjPtr<mirror::Class> super_klass = GetClass()->GetSuperClass();
330     if (super_klass != nullptr) {
331       // A super class of a precise type isn't precise as a precise type indicates the register
332       // holds exactly that type.
333       std::string temp;
334       return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false);
335     } else {
336       return cache->Zero();
337     }
338   } else {
339     if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
340         GetDescriptor()[0] == '[') {
341       // Super class of all arrays is Object.
342       return cache->JavaLangObject(true);
343     } else {
344       return cache->FromUnresolvedSuperClass(*this);
345     }
346   }
347 }
348 
IsJavaLangObject() const349 bool RegType::IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
350   return IsReference() && GetClass()->IsObjectClass();
351 }
352 
IsObjectArrayTypes() const353 bool RegType::IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
354   if (IsUnresolvedTypes()) {
355     DCHECK(!IsUnresolvedMergedReference());
356 
357     if (IsUnresolvedSuperClass()) {
358       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
359       // unresolved).
360       return false;
361     }
362 
363     // Primitive arrays will always resolve.
364     DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
365     return descriptor_[0] == '[';
366   } else if (HasClass()) {
367     ObjPtr<mirror::Class> type = GetClass();
368     return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
369   } else {
370     return false;
371   }
372 }
373 
IsArrayTypes() const374 bool RegType::IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
375   if (IsUnresolvedTypes()) {
376     DCHECK(!IsUnresolvedMergedReference());
377 
378     if (IsUnresolvedSuperClass()) {
379       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
380       // unresolved).
381       return false;
382     }
383     return descriptor_[0] == '[';
384   } else if (HasClass()) {
385     return GetClass()->IsArrayClass();
386   } else {
387     return false;
388   }
389 }
390 
IsJavaLangObjectArray() const391 bool RegType::IsJavaLangObjectArray() const {
392   if (HasClass()) {
393     ObjPtr<mirror::Class> type = GetClass();
394     return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
395   }
396   return false;
397 }
398 
IsInstantiableTypes() const399 bool RegType::IsInstantiableTypes() const {
400   return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
401 }
402 
SelectNonConstant(const RegType & a,const RegType & b)403 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
404   return a.IsConstantTypes() ? b : a;
405 }
406 
SelectNonConstant2(const RegType & a,const RegType & b)407 static const RegType& SelectNonConstant2(const RegType& a, const RegType& b) {
408   return a.IsConstantTypes() ? (b.IsZero() ? a : b) : a;
409 }
410 
411 
412 namespace {
413 
414 ObjPtr<mirror::Class> ArrayClassJoin(ObjPtr<mirror::Class> s,
415                                      ObjPtr<mirror::Class> t,
416                                      ClassLinker* class_linker)
417     REQUIRES_SHARED(Locks::mutator_lock_);
418 
419 ObjPtr<mirror::Class> InterfaceClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t)
420     REQUIRES_SHARED(Locks::mutator_lock_);
421 
422 /*
423  * A basic Join operation on classes. For a pair of types S and T the Join, written S v T = J, is
424  * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is J is the parent of
425  * S and T such that there isn't a parent of both S and T that isn't also the parent of J (ie J
426  * is the deepest (lowest upper bound) parent of S and T).
427  *
428  * This operation applies for regular classes and arrays, however, for interface types there
429  * needn't be a partial ordering on the types. We could solve the problem of a lack of a partial
430  * order by introducing sets of types, however, the only operation permissible on an interface is
431  * invoke-interface. In the tradition of Java verifiers [1] we defer the verification of interface
432  * types until an invoke-interface call on the interface typed reference at runtime and allow
433  * the perversion of Object being assignable to an interface type (note, however, that we don't
434  * allow assignment of Object or Interface to any concrete class and are therefore type safe).
435  *
436  * Note: This may return null in case of internal errors, e.g., OOME when a new class would have
437  *       to be created but there is no heap space. The exception will stay pending, and it is
438  *       the job of the caller to handle it.
439  *
440  * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
441  */
ClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t,ClassLinker * class_linker)442 ObjPtr<mirror::Class> ClassJoin(ObjPtr<mirror::Class> s,
443                                 ObjPtr<mirror::Class> t,
444                                 ClassLinker* class_linker)
445     REQUIRES_SHARED(Locks::mutator_lock_) {
446   DCHECK(!s->IsPrimitive()) << s->PrettyClass();
447   DCHECK(!t->IsPrimitive()) << t->PrettyClass();
448   if (s == t) {
449     return s;
450   } else if (s->IsAssignableFrom(t)) {
451     return s;
452   } else if (t->IsAssignableFrom(s)) {
453     return t;
454   } else if (s->IsArrayClass() && t->IsArrayClass()) {
455     return ArrayClassJoin(s, t, class_linker);
456   } else if (s->IsInterface() || t->IsInterface()) {
457     return InterfaceClassJoin(s, t);
458   } else {
459     size_t s_depth = s->Depth();
460     size_t t_depth = t->Depth();
461     // Get s and t to the same depth in the hierarchy
462     if (s_depth > t_depth) {
463       while (s_depth > t_depth) {
464         s = s->GetSuperClass();
465         s_depth--;
466       }
467     } else {
468       while (t_depth > s_depth) {
469         t = t->GetSuperClass();
470         t_depth--;
471       }
472     }
473     // Go up the hierarchy until we get to the common parent
474     while (s != t) {
475       s = s->GetSuperClass();
476       t = t->GetSuperClass();
477     }
478     return s;
479   }
480 }
481 
ArrayClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t,ClassLinker * class_linker)482 ObjPtr<mirror::Class> ArrayClassJoin(ObjPtr<mirror::Class> s,
483                                      ObjPtr<mirror::Class> t,
484                                      ClassLinker* class_linker) {
485   ObjPtr<mirror::Class> s_ct = s->GetComponentType();
486   ObjPtr<mirror::Class> t_ct = t->GetComponentType();
487   if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
488     // Given the types aren't the same, if either array is of primitive types then the only
489     // common parent is java.lang.Object
490     ObjPtr<mirror::Class> result = s->GetSuperClass();  // short-cut to java.lang.Object
491     DCHECK(result->IsObjectClass());
492     return result;
493   }
494   Thread* self = Thread::Current();
495   ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct, class_linker);
496   if (UNLIKELY(common_elem == nullptr)) {
497     self->AssertPendingException();
498     return nullptr;
499   }
500   // Note: The following lookup invalidates existing ObjPtr<>s.
501   ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, common_elem);
502   if (UNLIKELY(array_class == nullptr)) {
503     self->AssertPendingException();
504     return nullptr;
505   }
506   return array_class;
507 }
508 
InterfaceClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t)509 ObjPtr<mirror::Class> InterfaceClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t) {
510   // This is expensive, as we do not have good data structures to do this even halfway
511   // efficiently.
512   //
513   // We're not following JVMS for interface verification (not everything is assignable to an
514   // interface, we trade this for IMT dispatch). We also don't have set types to make up for
515   // it. So we choose one arbitrary common ancestor interface by walking the interface tables
516   // backwards.
517   //
518   // For comparison, runtimes following the JVMS will punt all interface type checking to
519   // runtime.
520   ObjPtr<mirror::IfTable> s_if = s->GetIfTable();
521   int32_t s_if_count = s->GetIfTableCount();
522   ObjPtr<mirror::IfTable> t_if = t->GetIfTable();
523   int32_t t_if_count = t->GetIfTableCount();
524 
525   // Note: we'll be using index == count to stand for the argument itself.
526   for (int32_t s_it = s_if_count; s_it >= 0; --s_it) {
527     ObjPtr<mirror::Class> s_cl = s_it == s_if_count ? s : s_if->GetInterface(s_it);
528     if (!s_cl->IsInterface()) {
529       continue;
530     }
531 
532     for (int32_t t_it = t_if_count; t_it >= 0; --t_it) {
533       ObjPtr<mirror::Class> t_cl = t_it == t_if_count ? t : t_if->GetInterface(t_it);
534       if (!t_cl->IsInterface()) {
535         continue;
536       }
537 
538       if (s_cl == t_cl) {
539         // Found something arbitrary in common.
540         return s_cl;
541       }
542     }
543   }
544 
545   // Return java.lang.Object.
546   ObjPtr<mirror::Class> obj_class = s->IsInterface() ? s->GetSuperClass() : t->GetSuperClass();
547   DCHECK(obj_class->IsObjectClass());
548   return obj_class;
549 }
550 
551 }  // namespace
552 
Merge(const RegType & incoming_type,RegTypeCache * reg_types,MethodVerifier * verifier) const553 const RegType& RegType::Merge(const RegType& incoming_type,
554                               RegTypeCache* reg_types,
555                               MethodVerifier* verifier) const {
556   DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
557   // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
558   const UndefinedType& undefined = reg_types->Undefined();
559   const ConflictType& conflict = reg_types->Conflict();
560   DCHECK_EQ(this == &undefined, IsUndefined());
561   DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
562   DCHECK_EQ(this == &conflict, IsConflict());
563   DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
564   if (this == &undefined || &incoming_type == &undefined) {
565     // There is a difference between undefined and conflict. Conflicts may be copied around, but
566     // not used. Undefined registers must not be copied. So any merge with undefined should return
567     // undefined.
568     return undefined;
569   } else if (this == &conflict || &incoming_type == &conflict) {
570     return conflict;  // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
571   } else if (IsConstant() && incoming_type.IsConstant()) {
572     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
573     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
574     int32_t val1 = type1.ConstantValue();
575     int32_t val2 = type2.ConstantValue();
576     if (val1 >= 0 && val2 >= 0) {
577       // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
578       if (val1 >= val2) {
579         if (!type1.IsPreciseConstant()) {
580           return *this;
581         } else {
582           return reg_types->FromCat1Const(val1, false);
583         }
584       } else {
585         if (!type2.IsPreciseConstant()) {
586           return type2;
587         } else {
588           return reg_types->FromCat1Const(val2, false);
589         }
590       }
591     } else if (val1 < 0 && val2 < 0) {
592       // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
593       if (val1 <= val2) {
594         if (!type1.IsPreciseConstant()) {
595           return *this;
596         } else {
597           return reg_types->FromCat1Const(val1, false);
598         }
599       } else {
600         if (!type2.IsPreciseConstant()) {
601           return type2;
602         } else {
603           return reg_types->FromCat1Const(val2, false);
604         }
605       }
606     } else {
607       // Values are +ve and -ve, choose smallest signed type in which they both fit
608       if (type1.IsConstantByte()) {
609         if (type2.IsConstantByte()) {
610           return reg_types->ByteConstant();
611         } else if (type2.IsConstantShort()) {
612           return reg_types->ShortConstant();
613         } else {
614           return reg_types->IntConstant();
615         }
616       } else if (type1.IsConstantShort()) {
617         if (type2.IsConstantShort()) {
618           return reg_types->ShortConstant();
619         } else {
620           return reg_types->IntConstant();
621         }
622       } else {
623         return reg_types->IntConstant();
624       }
625     }
626   } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
627     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
628     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
629     int32_t val1 = type1.ConstantValueLo();
630     int32_t val2 = type2.ConstantValueLo();
631     return reg_types->FromCat2ConstLo(val1 | val2, false);
632   } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
633     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
634     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
635     int32_t val1 = type1.ConstantValueHi();
636     int32_t val2 = type2.ConstantValueHi();
637     return reg_types->FromCat2ConstHi(val1 | val2, false);
638   } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
639     if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
640       return reg_types->Boolean();  // boolean MERGE boolean => boolean
641     }
642     if (IsByteTypes() && incoming_type.IsByteTypes()) {
643       return reg_types->Byte();  // byte MERGE byte => byte
644     }
645     if (IsShortTypes() && incoming_type.IsShortTypes()) {
646       return reg_types->Short();  // short MERGE short => short
647     }
648     if (IsCharTypes() && incoming_type.IsCharTypes()) {
649       return reg_types->Char();  // char MERGE char => char
650     }
651     return reg_types->Integer();  // int MERGE * => int
652   } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
653              (IsLongTypes() && incoming_type.IsLongTypes()) ||
654              (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
655              (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
656              (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
657     // check constant case was handled prior to entry
658     DCHECK_IMPLIES(IsConstant(), !incoming_type.IsConstant());
659     // float/long/double MERGE float/long/double_constant => float/long/double
660     return SelectNonConstant(*this, incoming_type);
661   } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
662     if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
663       // Something that is uninitialized hasn't had its constructor called. Unitialized types are
664       // special. They may only ever be merged with themselves (must be taken care of by the
665       // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here.
666       return conflict;
667     } else if (IsZeroOrNull() || incoming_type.IsZeroOrNull()) {
668       return SelectNonConstant2(*this, incoming_type);  // 0 MERGE ref => ref
669     } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
670       return reg_types->JavaLangObject(false);  // Object MERGE ref => Object
671     } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
672       // We know how to merge an unresolved type with itself, 0 or Object. In this case we
673       // have two sub-classes and don't know how to merge. Create a new string-based unresolved
674       // type that reflects our lack of knowledge and that allows the rest of the unresolved
675       // mechanics to continue.
676       return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
677     } else {  // Two reference types, compute Join
678       // Do not cache the classes as ClassJoin() can suspend and invalidate ObjPtr<>s.
679       DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive());
680       DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive());
681       ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(),
682                                                    incoming_type.GetClass(),
683                                                    reg_types->GetClassLinker());
684       if (UNLIKELY(join_class == nullptr)) {
685         // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
686         // We cannot report an unresolved merge type, as that will attempt to merge the resolved
687         // components, leaving us in an infinite loop.
688         // We do not want to report the originating exception, as that would require a fast path
689         // out all the way to VerifyClass. Instead attempt to continue on without a detailed type.
690         Thread* self = Thread::Current();
691         self->AssertPendingException();
692         self->ClearException();
693 
694         // When compiling on the host, we rather want to abort to ensure determinism for preopting.
695         // (In that case, it is likely a misconfiguration of dex2oat.)
696         if (!kIsTargetBuild && (verifier != nullptr && verifier->IsAotMode())) {
697           LOG(FATAL) << "Could not create class join of "
698                      << GetClass()->PrettyClass()
699                      << " & "
700                      << incoming_type.GetClass()->PrettyClass();
701           UNREACHABLE();
702         }
703 
704         return reg_types->MakeUnresolvedReference();
705       }
706 
707       // Record the dependency that both `GetClass()` and `incoming_type.GetClass()`
708       // are assignable to `join_class`. The `verifier` is null during unit tests.
709       if (verifier != nullptr) {
710         VerifierDeps::MaybeRecordAssignability(verifier->GetVerifierDeps(),
711                                                verifier->GetDexFile(),
712                                                verifier->GetClassDef(),
713                                                join_class,
714                                                GetClass());
715         VerifierDeps::MaybeRecordAssignability(verifier->GetVerifierDeps(),
716                                                verifier->GetDexFile(),
717                                                verifier->GetClassDef(),
718                                                join_class,
719                                                incoming_type.GetClass());
720       }
721       if (GetClass() == join_class && !IsPreciseReference()) {
722         return *this;
723       } else if (incoming_type.GetClass() == join_class && !incoming_type.IsPreciseReference()) {
724         return incoming_type;
725       } else {
726         std::string temp;
727         const char* descriptor = join_class->GetDescriptor(&temp);
728         return reg_types->FromClass(descriptor, join_class, /* precise= */ false);
729       }
730     }
731   } else {
732     return conflict;  // Unexpected types => Conflict
733   }
734 }
735 
CheckInvariants() const736 void RegType::CheckInvariants() const {
737   if (IsConstant() || IsConstantLo() || IsConstantHi()) {
738     CHECK(descriptor_.empty()) << *this;
739     CHECK(klass_.IsNull()) << *this;
740   }
741   if (!klass_.IsNull()) {
742     CHECK(!descriptor_.empty()) << *this;
743     std::string temp;
744     CHECK_EQ(descriptor_, klass_->GetDescriptor(&temp)) << *this;
745   }
746 }
747 
CheckInvariants() const748 void UninitializedThisReferenceType::CheckInvariants() const {
749   CHECK_EQ(GetAllocationPc(), 0U) << *this;
750 }
751 
CheckInvariants() const752 void UnresolvedUninitializedThisRefType::CheckInvariants() const {
753   CHECK_EQ(GetAllocationPc(), 0U) << *this;
754   CHECK(!descriptor_.empty()) << *this;
755   CHECK(!HasClass()) << *this;
756 }
757 
CheckInvariants() const758 void UnresolvedUninitializedRefType::CheckInvariants() const {
759   CHECK(!descriptor_.empty()) << *this;
760   CHECK(!HasClass()) << *this;
761 }
762 
UnresolvedMergedType(const RegType & resolved,const BitVector & unresolved,const RegTypeCache * reg_type_cache,uint16_t cache_id)763 UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved,
764                                            const BitVector& unresolved,
765                                            const RegTypeCache* reg_type_cache,
766                                            uint16_t cache_id)
767     : UnresolvedType(reg_type_cache->GetNullHandle(), "", cache_id),
768       reg_type_cache_(reg_type_cache),
769       resolved_part_(resolved),
770       unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
771   CheckConstructorInvariants(this);
772 }
CheckInvariants() const773 void UnresolvedMergedType::CheckInvariants() const {
774   CHECK(reg_type_cache_ != nullptr);
775 
776   // Unresolved merged types: merged types should be defined.
777   CHECK(descriptor_.empty()) << *this;
778   CHECK(!HasClass()) << *this;
779 
780   CHECK(!resolved_part_.IsConflict());
781   CHECK(resolved_part_.IsReferenceTypes());
782   CHECK(!resolved_part_.IsUnresolvedTypes());
783 
784   CHECK(resolved_part_.IsZero() ||
785         !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes()));
786 
787   CHECK_GT(unresolved_types_.NumSetBits(), 0U);
788   bool unresolved_is_array =
789       reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes();
790   for (uint32_t idx : unresolved_types_.Indexes()) {
791     const RegType& t = reg_type_cache_->GetFromId(idx);
792     CHECK_EQ(unresolved_is_array, t.IsArrayTypes());
793   }
794 
795   if (!resolved_part_.IsZero()) {
796     CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array);
797   }
798 }
799 
IsArrayTypes() const800 bool UnresolvedMergedType::IsArrayTypes() const {
801   // For a merge to be an array, both the resolved and the unresolved part need to be object
802   // arrays.
803   // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.)
804 
805   if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) {
806     return false;
807   }
808 
809   // It is enough to check just one of the merged types. Otherwise the merge should have been
810   // collapsed (checked in CheckInvariants on construction).
811   uint32_t idx = unresolved_types_.GetHighestBitSet();
812   const RegType& unresolved = reg_type_cache_->GetFromId(idx);
813   return unresolved.IsArrayTypes();
814 }
IsObjectArrayTypes() const815 bool UnresolvedMergedType::IsObjectArrayTypes() const {
816   // Same as IsArrayTypes, as primitive arrays are always resolved.
817   return IsArrayTypes();
818 }
819 
CheckInvariants() const820 void UnresolvedReferenceType::CheckInvariants() const {
821   CHECK(!descriptor_.empty()) << *this;
822   CHECK(!HasClass()) << *this;
823 }
824 
CheckInvariants() const825 void UnresolvedSuperClass::CheckInvariants() const {
826   // Unresolved merged types: merged types should be defined.
827   CHECK(descriptor_.empty()) << *this;
828   CHECK(!HasClass()) << *this;
829   CHECK_NE(unresolved_child_id_, 0U) << *this;
830 }
831 
operator <<(std::ostream & os,const RegType & rhs)832 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
833   os << rhs.Dump();
834   return os;
835 }
836 
837 }  // namespace verifier
838 }  // namespace art
839