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 {
39 namespace verifier {
40 
41 using android::base::StringPrintf;
42 
43 const UndefinedType* UndefinedType::instance_ = nullptr;
44 const ConflictType* ConflictType::instance_ = nullptr;
45 const BooleanType* BooleanType::instance_ = nullptr;
46 const ByteType* ByteType::instance_ = nullptr;
47 const ShortType* ShortType::instance_ = nullptr;
48 const CharType* CharType::instance_ = nullptr;
49 const FloatType* FloatType::instance_ = nullptr;
50 const LongLoType* LongLoType::instance_ = nullptr;
51 const LongHiType* LongHiType::instance_ = nullptr;
52 const DoubleLoType* DoubleLoType::instance_ = nullptr;
53 const DoubleHiType* DoubleHiType::instance_ = nullptr;
54 const IntegerType* IntegerType::instance_ = nullptr;
55 const NullType* NullType::instance_ = nullptr;
56 
PrimitiveType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)57 PrimitiveType::PrimitiveType(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
58     : RegType(klass, descriptor, cache_id) {
59   CHECK(klass != nullptr);
60   CHECK(!descriptor.empty());
61 }
62 
Cat1Type(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)63 Cat1Type::Cat1Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
64     : PrimitiveType(klass, descriptor, cache_id) {
65 }
66 
Cat2Type(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)67 Cat2Type::Cat2Type(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
68     : PrimitiveType(klass, descriptor, cache_id) {
69 }
70 
Dump() const71 std::string PreciseConstType::Dump() const {
72   std::stringstream result;
73   uint32_t val = ConstantValue();
74   if (val == 0) {
75     CHECK(IsPreciseConstant());
76     result << "Zero/null";
77   } else {
78     result << "Precise ";
79     if (IsConstantShort()) {
80       result << StringPrintf("Constant: %d", val);
81     } else {
82       result << StringPrintf("Constant: 0x%x", val);
83     }
84   }
85   return result.str();
86 }
87 
Dump() const88 std::string BooleanType::Dump() const {
89   return "Boolean";
90 }
91 
Dump() const92 std::string ConflictType::Dump() const {
93     return "Conflict";
94 }
95 
Dump() const96 std::string ByteType::Dump() const {
97   return "Byte";
98 }
99 
Dump() const100 std::string ShortType::Dump() const {
101   return "Short";
102 }
103 
Dump() const104 std::string CharType::Dump() const {
105   return "Char";
106 }
107 
Dump() const108 std::string FloatType::Dump() const {
109   return "Float";
110 }
111 
Dump() const112 std::string LongLoType::Dump() const {
113   return "Long (Low Half)";
114 }
115 
Dump() const116 std::string LongHiType::Dump() const {
117   return "Long (High Half)";
118 }
119 
Dump() const120 std::string DoubleLoType::Dump() const {
121   return "Double (Low Half)";
122 }
123 
Dump() const124 std::string DoubleHiType::Dump() const {
125   return "Double (High Half)";
126 }
127 
Dump() const128 std::string IntegerType::Dump() const {
129   return "Integer";
130 }
131 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)132 const DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass,
133                                                  const StringPiece& descriptor,
134                                                  uint16_t cache_id) {
135   CHECK(instance_ == nullptr);
136   instance_ = new DoubleHiType(klass, descriptor, cache_id);
137   return instance_;
138 }
139 
Destroy()140 void DoubleHiType::Destroy() {
141   if (instance_ != nullptr) {
142     delete instance_;
143     instance_ = nullptr;
144   }
145 }
146 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)147 const DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass,
148                                                  const StringPiece& descriptor,
149                                                  uint16_t cache_id) {
150   CHECK(instance_ == nullptr);
151   instance_ = new DoubleLoType(klass, descriptor, cache_id);
152   return instance_;
153 }
154 
Destroy()155 void DoubleLoType::Destroy() {
156   if (instance_ != nullptr) {
157     delete instance_;
158     instance_ = nullptr;
159   }
160 }
161 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)162 const LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
163                                              uint16_t cache_id) {
164   CHECK(instance_ == nullptr);
165   instance_ = new LongLoType(klass, descriptor, cache_id);
166   return instance_;
167 }
168 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)169 const LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
170                                              uint16_t cache_id) {
171   CHECK(instance_ == nullptr);
172   instance_ = new LongHiType(klass, descriptor, cache_id);
173   return instance_;
174 }
175 
Destroy()176 void LongHiType::Destroy() {
177   if (instance_ != nullptr) {
178     delete instance_;
179     instance_ = nullptr;
180   }
181 }
182 
Destroy()183 void LongLoType::Destroy() {
184   if (instance_ != nullptr) {
185     delete instance_;
186     instance_ = nullptr;
187   }
188 }
189 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)190 const FloatType* FloatType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
191                                            uint16_t cache_id) {
192   CHECK(instance_ == nullptr);
193   instance_ = new FloatType(klass, descriptor, cache_id);
194   return instance_;
195 }
196 
Destroy()197 void FloatType::Destroy() {
198   if (instance_ != nullptr) {
199     delete instance_;
200     instance_ = nullptr;
201   }
202 }
203 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)204 const CharType* CharType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
205                                          uint16_t cache_id) {
206   CHECK(instance_ == nullptr);
207   instance_ = new CharType(klass, descriptor, cache_id);
208   return instance_;
209 }
210 
Destroy()211 void CharType::Destroy() {
212   if (instance_ != nullptr) {
213     delete instance_;
214     instance_ = nullptr;
215   }
216 }
217 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)218 const ShortType* ShortType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
219                                            uint16_t cache_id) {
220   CHECK(instance_ == nullptr);
221   instance_ = new ShortType(klass, descriptor, cache_id);
222   return instance_;
223 }
224 
Destroy()225 void ShortType::Destroy() {
226   if (instance_ != nullptr) {
227     delete instance_;
228     instance_ = nullptr;
229   }
230 }
231 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)232 const ByteType* ByteType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
233                                          uint16_t cache_id) {
234   CHECK(instance_ == nullptr);
235   instance_ = new ByteType(klass, descriptor, cache_id);
236   return instance_;
237 }
238 
Destroy()239 void ByteType::Destroy() {
240   if (instance_ != nullptr) {
241     delete instance_;
242     instance_ = nullptr;
243   }
244 }
245 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)246 const IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
247                                                uint16_t cache_id) {
248   CHECK(instance_ == nullptr);
249   instance_ = new IntegerType(klass, descriptor, cache_id);
250   return instance_;
251 }
252 
Destroy()253 void IntegerType::Destroy() {
254   if (instance_ != nullptr) {
255     delete instance_;
256     instance_ = nullptr;
257   }
258 }
259 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)260 const ConflictType* ConflictType::CreateInstance(mirror::Class* klass,
261                                                  const StringPiece& descriptor,
262                                                  uint16_t cache_id) {
263   CHECK(instance_ == nullptr);
264   instance_ = new ConflictType(klass, descriptor, cache_id);
265   return instance_;
266 }
267 
Destroy()268 void ConflictType::Destroy() {
269   if (instance_ != nullptr) {
270     delete instance_;
271     instance_ = nullptr;
272   }
273 }
274 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)275 const BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const StringPiece& descriptor,
276                                          uint16_t cache_id) {
277   CHECK(BooleanType::instance_ == nullptr);
278   instance_ = new BooleanType(klass, descriptor, cache_id);
279   return BooleanType::instance_;
280 }
281 
Destroy()282 void BooleanType::Destroy() {
283   if (BooleanType::instance_ != nullptr) {
284     delete instance_;
285     instance_ = nullptr;
286   }
287 }
288 
Dump() const289 std::string UndefinedType::Dump() const REQUIRES_SHARED(Locks::mutator_lock_) {
290   return "Undefined";
291 }
292 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)293 const UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass,
294                                                    const StringPiece& descriptor,
295                                                    uint16_t cache_id) {
296   CHECK(instance_ == nullptr);
297   instance_ = new UndefinedType(klass, descriptor, cache_id);
298   return instance_;
299 }
300 
Destroy()301 void UndefinedType::Destroy() {
302   if (instance_ != nullptr) {
303     delete instance_;
304     instance_ = nullptr;
305   }
306 }
307 
PreciseReferenceType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)308 PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const StringPiece& descriptor,
309                                            uint16_t cache_id)
310     : RegType(klass, descriptor, cache_id) {
311   // Note: no check for IsInstantiable() here. We may produce this in case an InstantiationError
312   //       would be thrown at runtime, but we need to continue verification and *not* create a
313   //       hard failure or abort.
314   CheckConstructorInvariants(this);
315 }
316 
Dump() const317 std::string UnresolvedMergedType::Dump() const {
318   std::stringstream result;
319   result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
320   const BitVector& types = GetUnresolvedTypes();
321 
322   bool first = true;
323   for (uint32_t idx : types.Indexes()) {
324     if (!first) {
325       result << ", ";
326     } else {
327       first = false;
328     }
329     result << reg_type_cache_->GetFromId(idx).Dump();
330   }
331   result << ")";
332   return result.str();
333 }
334 
Dump() const335 std::string UnresolvedSuperClass::Dump() const {
336   std::stringstream result;
337   uint16_t super_type_id = GetUnresolvedSuperClassChildId();
338   result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
339   return result.str();
340 }
341 
Dump() const342 std::string UnresolvedReferenceType::Dump() const {
343   std::stringstream result;
344   result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor().as_string().c_str());
345   return result.str();
346 }
347 
Dump() const348 std::string UnresolvedUninitializedRefType::Dump() const {
349   std::stringstream result;
350   result << "Unresolved And Uninitialized Reference" << ": "
351       << PrettyDescriptor(GetDescriptor().as_string().c_str())
352       << " Allocation PC: " << GetAllocationPc();
353   return result.str();
354 }
355 
Dump() const356 std::string UnresolvedUninitializedThisRefType::Dump() const {
357   std::stringstream result;
358   result << "Unresolved And Uninitialized This Reference"
359       << PrettyDescriptor(GetDescriptor().as_string().c_str());
360   return result.str();
361 }
362 
Dump() const363 std::string ReferenceType::Dump() const {
364   std::stringstream result;
365   result << "Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
366   return result.str();
367 }
368 
Dump() const369 std::string PreciseReferenceType::Dump() const {
370   std::stringstream result;
371   result << "Precise Reference" << ": "<< mirror::Class::PrettyDescriptor(GetClass());
372   return result.str();
373 }
374 
Dump() const375 std::string UninitializedReferenceType::Dump() const {
376   std::stringstream result;
377   result << "Uninitialized Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
378   result << " Allocation PC: " << GetAllocationPc();
379   return result.str();
380 }
381 
Dump() const382 std::string UninitializedThisReferenceType::Dump() const {
383   std::stringstream result;
384   result << "Uninitialized This Reference" << ": " << mirror::Class::PrettyDescriptor(GetClass());
385   result << "Allocation PC: " << GetAllocationPc();
386   return result.str();
387 }
388 
Dump() const389 std::string ImpreciseConstType::Dump() const {
390   std::stringstream result;
391   uint32_t val = ConstantValue();
392   if (val == 0) {
393     result << "Zero/null";
394   } else {
395     result << "Imprecise ";
396     if (IsConstantShort()) {
397       result << StringPrintf("Constant: %d", val);
398     } else {
399       result << StringPrintf("Constant: 0x%x", val);
400     }
401   }
402   return result.str();
403 }
Dump() const404 std::string PreciseConstLoType::Dump() const {
405   std::stringstream result;
406 
407   int32_t val = ConstantValueLo();
408   result << "Precise ";
409   if (val >= std::numeric_limits<jshort>::min() &&
410       val <= std::numeric_limits<jshort>::max()) {
411     result << StringPrintf("Low-half Constant: %d", val);
412   } else {
413     result << StringPrintf("Low-half Constant: 0x%x", val);
414   }
415   return result.str();
416 }
417 
Dump() const418 std::string ImpreciseConstLoType::Dump() const {
419   std::stringstream result;
420 
421   int32_t val = ConstantValueLo();
422   result << "Imprecise ";
423   if (val >= std::numeric_limits<jshort>::min() &&
424       val <= std::numeric_limits<jshort>::max()) {
425     result << StringPrintf("Low-half Constant: %d", val);
426   } else {
427     result << StringPrintf("Low-half Constant: 0x%x", val);
428   }
429   return result.str();
430 }
431 
Dump() const432 std::string PreciseConstHiType::Dump() const {
433   std::stringstream result;
434   int32_t val = ConstantValueHi();
435   result << "Precise ";
436   if (val >= std::numeric_limits<jshort>::min() &&
437       val <= std::numeric_limits<jshort>::max()) {
438     result << StringPrintf("High-half Constant: %d", val);
439   } else {
440     result << StringPrintf("High-half Constant: 0x%x", val);
441   }
442   return result.str();
443 }
444 
Dump() const445 std::string ImpreciseConstHiType::Dump() const {
446   std::stringstream result;
447   int32_t val = ConstantValueHi();
448   result << "Imprecise ";
449   if (val >= std::numeric_limits<jshort>::min() &&
450       val <= std::numeric_limits<jshort>::max()) {
451     result << StringPrintf("High-half Constant: %d", val);
452   } else {
453     result << StringPrintf("High-half Constant: 0x%x", val);
454   }
455   return result.str();
456 }
457 
HighHalf(RegTypeCache * cache) const458 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
459   DCHECK(IsLowHalf());
460   if (IsLongLo()) {
461     return cache->LongHi();
462   } else if (IsDoubleLo()) {
463     return cache->DoubleHi();
464   } else {
465     DCHECK(IsImpreciseConstantLo());
466     const ConstantType* const_val = down_cast<const ConstantType*>(this);
467     return cache->FromCat2ConstHi(const_val->ConstantValue(), false);
468   }
469 }
470 
GetPrimitiveType() const471 Primitive::Type RegType::GetPrimitiveType() const {
472   if (IsNonZeroReferenceTypes()) {
473     return Primitive::kPrimNot;
474   } else if (IsBooleanTypes()) {
475     return Primitive::kPrimBoolean;
476   } else if (IsByteTypes()) {
477     return Primitive::kPrimByte;
478   } else if (IsShortTypes()) {
479     return Primitive::kPrimShort;
480   } else if (IsCharTypes()) {
481     return Primitive::kPrimChar;
482   } else if (IsFloat()) {
483     return Primitive::kPrimFloat;
484   } else if (IsIntegralTypes()) {
485     return Primitive::kPrimInt;
486   } else if (IsDoubleLo()) {
487     return Primitive::kPrimDouble;
488   } else {
489     DCHECK(IsLongTypes());
490     return Primitive::kPrimLong;
491   }
492 }
493 
IsUninitializedTypes() const494 bool UninitializedType::IsUninitializedTypes() const {
495   return true;
496 }
497 
IsNonZeroReferenceTypes() const498 bool UninitializedType::IsNonZeroReferenceTypes() const {
499   return true;
500 }
501 
IsNonZeroReferenceTypes() const502 bool UnresolvedType::IsNonZeroReferenceTypes() const {
503   return true;
504 }
505 
GetSuperClass(RegTypeCache * cache) const506 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
507   if (!IsUnresolvedTypes()) {
508     mirror::Class* super_klass = GetClass()->GetSuperClass();
509     if (super_klass != nullptr) {
510       // A super class of a precise type isn't precise as a precise type indicates the register
511       // holds exactly that type.
512       std::string temp;
513       return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false);
514     } else {
515       return cache->Zero();
516     }
517   } else {
518     if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
519         GetDescriptor()[0] == '[') {
520       // Super class of all arrays is Object.
521       return cache->JavaLangObject(true);
522     } else {
523       return cache->FromUnresolvedSuperClass(*this);
524     }
525   }
526 }
527 
IsJavaLangObject() const528 bool RegType::IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_) {
529   return IsReference() && GetClass()->IsObjectClass();
530 }
531 
IsObjectArrayTypes() const532 bool RegType::IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
533   if (IsUnresolvedTypes()) {
534     DCHECK(!IsUnresolvedMergedReference());
535 
536     if (IsUnresolvedSuperClass()) {
537       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
538       // unresolved).
539       return false;
540     }
541 
542     // Primitive arrays will always resolve.
543     DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
544     return descriptor_[0] == '[';
545   } else if (HasClass()) {
546     mirror::Class* type = GetClass();
547     return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
548   } else {
549     return false;
550   }
551 }
552 
IsArrayTypes() const553 bool RegType::IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_) {
554   if (IsUnresolvedTypes()) {
555     DCHECK(!IsUnresolvedMergedReference());
556 
557     if (IsUnresolvedSuperClass()) {
558       // Cannot be an array, as the superclass of arrays is java.lang.Object (which cannot be
559       // unresolved).
560       return false;
561     }
562     return descriptor_[0] == '[';
563   } else if (HasClass()) {
564     return GetClass()->IsArrayClass();
565   } else {
566     return false;
567   }
568 }
569 
IsJavaLangObjectArray() const570 bool RegType::IsJavaLangObjectArray() const {
571   if (HasClass()) {
572     mirror::Class* type = GetClass();
573     return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
574   }
575   return false;
576 }
577 
IsInstantiableTypes() const578 bool RegType::IsInstantiableTypes() const {
579   return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
580 }
581 
SelectNonConstant(const RegType & a,const RegType & b)582 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
583   return a.IsConstantTypes() ? b : a;
584 }
585 
SelectNonConstant2(const RegType & a,const RegType & b)586 static const RegType& SelectNonConstant2(const RegType& a, const RegType& b) {
587   return a.IsConstantTypes() ? (b.IsZero() ? a : b) : a;
588 }
589 
Merge(const RegType & incoming_type,RegTypeCache * reg_types,MethodVerifier * verifier) const590 const RegType& RegType::Merge(const RegType& incoming_type,
591                               RegTypeCache* reg_types,
592                               MethodVerifier* verifier) const {
593   DCHECK(!Equals(incoming_type));  // Trivial equality handled by caller
594   // Perform pointer equality tests for undefined and conflict to avoid virtual method dispatch.
595   const UndefinedType& undefined = reg_types->Undefined();
596   const ConflictType& conflict = reg_types->Conflict();
597   DCHECK_EQ(this == &undefined, IsUndefined());
598   DCHECK_EQ(&incoming_type == &undefined, incoming_type.IsUndefined());
599   DCHECK_EQ(this == &conflict, IsConflict());
600   DCHECK_EQ(&incoming_type == &conflict, incoming_type.IsConflict());
601   if (this == &undefined || &incoming_type == &undefined) {
602     // There is a difference between undefined and conflict. Conflicts may be copied around, but
603     // not used. Undefined registers must not be copied. So any merge with undefined should return
604     // undefined.
605     return undefined;
606   } else if (this == &conflict || &incoming_type == &conflict) {
607     return conflict;  // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
608   } else if (IsConstant() && incoming_type.IsConstant()) {
609     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
610     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
611     int32_t val1 = type1.ConstantValue();
612     int32_t val2 = type2.ConstantValue();
613     if (val1 >= 0 && val2 >= 0) {
614       // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
615       if (val1 >= val2) {
616         if (!type1.IsPreciseConstant()) {
617           return *this;
618         } else {
619           return reg_types->FromCat1Const(val1, false);
620         }
621       } else {
622         if (!type2.IsPreciseConstant()) {
623           return type2;
624         } else {
625           return reg_types->FromCat1Const(val2, false);
626         }
627       }
628     } else if (val1 < 0 && val2 < 0) {
629       // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
630       if (val1 <= val2) {
631         if (!type1.IsPreciseConstant()) {
632           return *this;
633         } else {
634           return reg_types->FromCat1Const(val1, false);
635         }
636       } else {
637         if (!type2.IsPreciseConstant()) {
638           return type2;
639         } else {
640           return reg_types->FromCat1Const(val2, false);
641         }
642       }
643     } else {
644       // Values are +ve and -ve, choose smallest signed type in which they both fit
645       if (type1.IsConstantByte()) {
646         if (type2.IsConstantByte()) {
647           return reg_types->ByteConstant();
648         } else if (type2.IsConstantShort()) {
649           return reg_types->ShortConstant();
650         } else {
651           return reg_types->IntConstant();
652         }
653       } else if (type1.IsConstantShort()) {
654         if (type2.IsConstantShort()) {
655           return reg_types->ShortConstant();
656         } else {
657           return reg_types->IntConstant();
658         }
659       } else {
660         return reg_types->IntConstant();
661       }
662     }
663   } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
664     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
665     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
666     int32_t val1 = type1.ConstantValueLo();
667     int32_t val2 = type2.ConstantValueLo();
668     return reg_types->FromCat2ConstLo(val1 | val2, false);
669   } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
670     const ConstantType& type1 = *down_cast<const ConstantType*>(this);
671     const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
672     int32_t val1 = type1.ConstantValueHi();
673     int32_t val2 = type2.ConstantValueHi();
674     return reg_types->FromCat2ConstHi(val1 | val2, false);
675   } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
676     if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
677       return reg_types->Boolean();  // boolean MERGE boolean => boolean
678     }
679     if (IsByteTypes() && incoming_type.IsByteTypes()) {
680       return reg_types->Byte();  // byte MERGE byte => byte
681     }
682     if (IsShortTypes() && incoming_type.IsShortTypes()) {
683       return reg_types->Short();  // short MERGE short => short
684     }
685     if (IsCharTypes() && incoming_type.IsCharTypes()) {
686       return reg_types->Char();  // char MERGE char => char
687     }
688     return reg_types->Integer();  // int MERGE * => int
689   } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
690              (IsLongTypes() && incoming_type.IsLongTypes()) ||
691              (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
692              (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
693              (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
694     // check constant case was handled prior to entry
695     DCHECK(!IsConstant() || !incoming_type.IsConstant());
696     // float/long/double MERGE float/long/double_constant => float/long/double
697     return SelectNonConstant(*this, incoming_type);
698   } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
699     if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
700       // Something that is uninitialized hasn't had its constructor called. Unitialized types are
701       // special. They may only ever be merged with themselves (must be taken care of by the
702       // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here.
703       return conflict;
704     } else if (IsZeroOrNull() || incoming_type.IsZeroOrNull()) {
705       return SelectNonConstant2(*this, incoming_type);  // 0 MERGE ref => ref
706     } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
707       return reg_types->JavaLangObject(false);  // Object MERGE ref => Object
708     } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
709       // We know how to merge an unresolved type with itself, 0 or Object. In this case we
710       // have two sub-classes and don't know how to merge. Create a new string-based unresolved
711       // type that reflects our lack of knowledge and that allows the rest of the unresolved
712       // mechanics to continue.
713       return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
714     } else {  // Two reference types, compute Join
715       mirror::Class* c1 = GetClass();
716       mirror::Class* c2 = incoming_type.GetClass();
717       DCHECK(c1 != nullptr && !c1->IsPrimitive());
718       DCHECK(c2 != nullptr && !c2->IsPrimitive());
719       mirror::Class* join_class = ClassJoin(c1, c2);
720       if (UNLIKELY(join_class == nullptr)) {
721         // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
722         // We cannot report an unresolved merge type, as that will attempt to merge the resolved
723         // components, leaving us in an infinite loop.
724         // We do not want to report the originating exception, as that would require a fast path
725         // out all the way to VerifyClass. Instead attempt to continue on without a detailed type.
726         Thread* self = Thread::Current();
727         self->AssertPendingException();
728         self->ClearException();
729 
730         // When compiling on the host, we rather want to abort to ensure determinism for preopting.
731         // (In that case, it is likely a misconfiguration of dex2oat.)
732         if (!kIsTargetBuild && Runtime::Current()->IsAotCompiler()) {
733           LOG(FATAL) << "Could not create class join of "
734                      << c1->PrettyClass()
735                      << " & "
736                      << c2->PrettyClass();
737           UNREACHABLE();
738         }
739 
740         return reg_types->MakeUnresolvedReference();
741       }
742 
743       // Record the dependency that both `c1` and `c2` are assignable to `join_class`.
744       // The `verifier` is null during unit tests.
745       if (verifier != nullptr) {
746         VerifierDeps::MaybeRecordAssignability(
747             verifier->GetDexFile(), join_class, c1, true /* strict */, true /* is_assignable */);
748         VerifierDeps::MaybeRecordAssignability(
749             verifier->GetDexFile(), join_class, c2, true /* strict */, true /* is_assignable */);
750       }
751       if (c1 == join_class && !IsPreciseReference()) {
752         return *this;
753       } else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
754         return incoming_type;
755       } else {
756         std::string temp;
757         return reg_types->FromClass(join_class->GetDescriptor(&temp), join_class, false);
758       }
759     }
760   } else {
761     return conflict;  // Unexpected types => Conflict
762   }
763 }
764 
765 // See comment in reg_type.h
ClassJoin(mirror::Class * s,mirror::Class * t)766 mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
767   DCHECK(!s->IsPrimitive()) << s->PrettyClass();
768   DCHECK(!t->IsPrimitive()) << t->PrettyClass();
769   if (s == t) {
770     return s;
771   } else if (s->IsAssignableFrom(t)) {
772     return s;
773   } else if (t->IsAssignableFrom(s)) {
774     return t;
775   } else if (s->IsArrayClass() && t->IsArrayClass()) {
776     mirror::Class* s_ct = s->GetComponentType();
777     mirror::Class* t_ct = t->GetComponentType();
778     if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
779       // Given the types aren't the same, if either array is of primitive types then the only
780       // common parent is java.lang.Object
781       mirror::Class* result = s->GetSuperClass();  // short-cut to java.lang.Object
782       DCHECK(result->IsObjectClass());
783       return result;
784     }
785     Thread* self = Thread::Current();
786     ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct);
787     if (UNLIKELY(common_elem == nullptr)) {
788       self->AssertPendingException();
789       return nullptr;
790     }
791     ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
792     mirror::Class* array_class = class_linker->FindArrayClass(self, &common_elem);
793     if (UNLIKELY(array_class == nullptr)) {
794       self->AssertPendingException();
795       return nullptr;
796     }
797     return array_class;
798   } else {
799     size_t s_depth = s->Depth();
800     size_t t_depth = t->Depth();
801     // Get s and t to the same depth in the hierarchy
802     if (s_depth > t_depth) {
803       while (s_depth > t_depth) {
804         s = s->GetSuperClass();
805         s_depth--;
806       }
807     } else {
808       while (t_depth > s_depth) {
809         t = t->GetSuperClass();
810         t_depth--;
811       }
812     }
813     // Go up the hierarchy until we get to the common parent
814     while (s != t) {
815       s = s->GetSuperClass();
816       t = t->GetSuperClass();
817     }
818     return s;
819   }
820 }
821 
CheckInvariants() const822 void RegType::CheckInvariants() const {
823   if (IsConstant() || IsConstantLo() || IsConstantHi()) {
824     CHECK(descriptor_.empty()) << *this;
825     CHECK(klass_.IsNull()) << *this;
826   }
827   if (!klass_.IsNull()) {
828     CHECK(!descriptor_.empty()) << *this;
829     std::string temp;
830     CHECK_EQ(descriptor_, klass_.Read()->GetDescriptor(&temp)) << *this;
831   }
832 }
833 
VisitRoots(RootVisitor * visitor,const RootInfo & root_info) const834 void RegType::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const {
835   klass_.VisitRootIfNonNull(visitor, root_info);
836 }
837 
CheckInvariants() const838 void UninitializedThisReferenceType::CheckInvariants() const {
839   CHECK_EQ(GetAllocationPc(), 0U) << *this;
840 }
841 
CheckInvariants() const842 void UnresolvedUninitializedThisRefType::CheckInvariants() const {
843   CHECK_EQ(GetAllocationPc(), 0U) << *this;
844   CHECK(!descriptor_.empty()) << *this;
845   CHECK(klass_.IsNull()) << *this;
846 }
847 
CheckInvariants() const848 void UnresolvedUninitializedRefType::CheckInvariants() const {
849   CHECK(!descriptor_.empty()) << *this;
850   CHECK(klass_.IsNull()) << *this;
851 }
852 
UnresolvedMergedType(const RegType & resolved,const BitVector & unresolved,const RegTypeCache * reg_type_cache,uint16_t cache_id)853 UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved,
854                                            const BitVector& unresolved,
855                                            const RegTypeCache* reg_type_cache,
856                                            uint16_t cache_id)
857     : UnresolvedType("", cache_id),
858       reg_type_cache_(reg_type_cache),
859       resolved_part_(resolved),
860       unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
861   CheckConstructorInvariants(this);
862 }
CheckInvariants() const863 void UnresolvedMergedType::CheckInvariants() const {
864   CHECK(reg_type_cache_ != nullptr);
865 
866   // Unresolved merged types: merged types should be defined.
867   CHECK(descriptor_.empty()) << *this;
868   CHECK(klass_.IsNull()) << *this;
869 
870   CHECK(!resolved_part_.IsConflict());
871   CHECK(resolved_part_.IsReferenceTypes());
872   CHECK(!resolved_part_.IsUnresolvedTypes());
873 
874   CHECK(resolved_part_.IsZero() ||
875         !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes()));
876 
877   CHECK_GT(unresolved_types_.NumSetBits(), 0U);
878   bool unresolved_is_array =
879       reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes();
880   for (uint32_t idx : unresolved_types_.Indexes()) {
881     const RegType& t = reg_type_cache_->GetFromId(idx);
882     CHECK_EQ(unresolved_is_array, t.IsArrayTypes());
883   }
884 
885   if (!resolved_part_.IsZero()) {
886     CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array);
887   }
888 }
889 
IsArrayTypes() const890 bool UnresolvedMergedType::IsArrayTypes() const {
891   // For a merge to be an array, both the resolved and the unresolved part need to be object
892   // arrays.
893   // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.)
894 
895   if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) {
896     return false;
897   }
898 
899   // It is enough to check just one of the merged types. Otherwise the merge should have been
900   // collapsed (checked in CheckInvariants on construction).
901   uint32_t idx = unresolved_types_.GetHighestBitSet();
902   const RegType& unresolved = reg_type_cache_->GetFromId(idx);
903   return unresolved.IsArrayTypes();
904 }
IsObjectArrayTypes() const905 bool UnresolvedMergedType::IsObjectArrayTypes() const {
906   // Same as IsArrayTypes, as primitive arrays are always resolved.
907   return IsArrayTypes();
908 }
909 
CheckInvariants() const910 void UnresolvedReferenceType::CheckInvariants() const {
911   CHECK(!descriptor_.empty()) << *this;
912   CHECK(klass_.IsNull()) << *this;
913 }
914 
CheckInvariants() const915 void UnresolvedSuperClass::CheckInvariants() const {
916   // Unresolved merged types: merged types should be defined.
917   CHECK(descriptor_.empty()) << *this;
918   CHECK(klass_.IsNull()) << *this;
919   CHECK_NE(unresolved_child_id_, 0U) << *this;
920 }
921 
operator <<(std::ostream & os,const RegType & rhs)922 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
923   os << rhs.Dump();
924   return os;
925 }
926 
CanAssignArray(const RegType & src,RegTypeCache & reg_types,Handle<mirror::ClassLoader> class_loader,MethodVerifier * verifier,bool * soft_error) const927 bool RegType::CanAssignArray(const RegType& src,
928                              RegTypeCache& reg_types,
929                              Handle<mirror::ClassLoader> class_loader,
930                              MethodVerifier* verifier,
931                              bool* soft_error) const {
932   if (!IsArrayTypes() || !src.IsArrayTypes()) {
933     *soft_error = false;
934     return false;
935   }
936 
937   if (IsUnresolvedMergedReference() || src.IsUnresolvedMergedReference()) {
938     // An unresolved array type means that it's an array of some reference type. Reference arrays
939     // can never be assigned to primitive-type arrays, and vice versa. So it is a soft error if
940     // both arrays are reference arrays, otherwise a hard error.
941     *soft_error = IsObjectArrayTypes() && src.IsObjectArrayTypes();
942     return false;
943   }
944 
945   const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get());
946   const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get());
947 
948   if (cmp1.IsAssignableFrom(cmp2, verifier)) {
949     return true;
950   }
951   if (cmp1.IsUnresolvedTypes()) {
952     if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) {
953       *soft_error = false;
954       return false;
955     }
956     *soft_error = true;
957     return false;
958   }
959   if (cmp2.IsUnresolvedTypes()) {
960     if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) {
961       *soft_error = false;
962       return false;
963     }
964     *soft_error = true;
965     return false;
966   }
967   if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) {
968     *soft_error = false;
969     return false;
970   }
971   return cmp1.CanAssignArray(cmp2, reg_types, class_loader, verifier, soft_error);
972 }
973 
CreateInstance(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)974 const NullType* NullType::CreateInstance(mirror::Class* klass,
975                                          const StringPiece& descriptor,
976                                          uint16_t cache_id) {
977   CHECK(instance_ == nullptr);
978   instance_ = new NullType(klass, descriptor, cache_id);
979   return instance_;
980 }
981 
Destroy()982 void NullType::Destroy() {
983   if (NullType::instance_ != nullptr) {
984     delete instance_;
985     instance_ = nullptr;
986   }
987 }
988 
989 
990 }  // namespace verifier
991 }  // namespace art
992