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 #ifndef ART_RUNTIME_VERIFIER_REG_TYPE_H_
18 #define ART_RUNTIME_VERIFIER_REG_TYPE_H_
19 
20 #include <stdint.h>
21 #include <limits>
22 #include <set>
23 #include <string>
24 
25 #include "base/arena_object.h"
26 #include "base/bit_vector.h"
27 #include "base/macros.h"
28 #include "base/mutex.h"
29 #include "base/stringpiece.h"
30 #include "dex/primitive.h"
31 #include "gc_root.h"
32 #include "handle_scope.h"
33 #include "obj_ptr.h"
34 
35 namespace art {
36 namespace mirror {
37 class Class;
38 class ClassLoader;
39 }  // namespace mirror
40 
41 class ArenaBitVector;
42 class ScopedArenaAllocator;
43 
44 namespace verifier {
45 
46 class MethodVerifier;
47 class RegTypeCache;
48 
49 /*
50  * RegType holds information about the "type" of data held in a register.
51  */
52 class RegType {
53  public:
IsUndefined()54   virtual bool IsUndefined() const { return false; }
IsConflict()55   virtual bool IsConflict() const { return false; }
IsBoolean()56   virtual bool IsBoolean() const { return false; }
IsByte()57   virtual bool IsByte() const { return false; }
IsChar()58   virtual bool IsChar() const { return false; }
IsShort()59   virtual bool IsShort() const { return false; }
IsInteger()60   virtual bool IsInteger() const { return false; }
IsLongLo()61   virtual bool IsLongLo() const { return false; }
IsLongHi()62   virtual bool IsLongHi() const { return false; }
IsFloat()63   virtual bool IsFloat() const { return false; }
IsDouble()64   virtual bool IsDouble() const { return false; }
IsDoubleLo()65   virtual bool IsDoubleLo() const { return false; }
IsDoubleHi()66   virtual bool IsDoubleHi() const { return false; }
IsUnresolvedReference()67   virtual bool IsUnresolvedReference() const { return false; }
IsUninitializedReference()68   virtual bool IsUninitializedReference() const { return false; }
IsUninitializedThisReference()69   virtual bool IsUninitializedThisReference() const { return false; }
IsUnresolvedAndUninitializedReference()70   virtual bool IsUnresolvedAndUninitializedReference() const { return false; }
IsUnresolvedAndUninitializedThisReference()71   virtual bool IsUnresolvedAndUninitializedThisReference() const {
72     return false;
73   }
IsUnresolvedMergedReference()74   virtual bool IsUnresolvedMergedReference() const { return false; }
IsUnresolvedSuperClass()75   virtual bool IsUnresolvedSuperClass() const { return false; }
IsReference()76   virtual bool IsReference() const { return false; }
IsPreciseReference()77   virtual bool IsPreciseReference() const { return false; }
IsPreciseConstant()78   virtual bool IsPreciseConstant() const { return false; }
IsPreciseConstantLo()79   virtual bool IsPreciseConstantLo() const { return false; }
IsPreciseConstantHi()80   virtual bool IsPreciseConstantHi() const { return false; }
IsImpreciseConstantLo()81   virtual bool IsImpreciseConstantLo() const { return false; }
IsImpreciseConstantHi()82   virtual bool IsImpreciseConstantHi() const { return false; }
IsImpreciseConstant()83   virtual bool IsImpreciseConstant() const { return false; }
IsConstantTypes()84   virtual bool IsConstantTypes() const { return false; }
IsConstant()85   bool IsConstant() const {
86     return IsImpreciseConstant() || IsPreciseConstant();
87   }
IsConstantLo()88   bool IsConstantLo() const {
89     return IsImpreciseConstantLo() || IsPreciseConstantLo();
90   }
IsPrecise()91   bool IsPrecise() const {
92     return IsPreciseConstantLo() || IsPreciseConstant() ||
93            IsPreciseConstantHi();
94   }
IsLongConstant()95   bool IsLongConstant() const { return IsConstantLo(); }
IsConstantHi()96   bool IsConstantHi() const {
97     return (IsPreciseConstantHi() || IsImpreciseConstantHi());
98   }
IsLongConstantHigh()99   bool IsLongConstantHigh() const { return IsConstantHi(); }
IsUninitializedTypes()100   virtual bool IsUninitializedTypes() const { return false; }
IsUnresolvedTypes()101   virtual bool IsUnresolvedTypes() const { return false; }
102 
IsLowHalf()103   bool IsLowHalf() const {
104     return (IsLongLo() || IsDoubleLo() || IsPreciseConstantLo() || IsImpreciseConstantLo());
105   }
IsHighHalf()106   bool IsHighHalf() const {
107     return (IsLongHi() || IsDoubleHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
108   }
IsLongOrDoubleTypes()109   bool IsLongOrDoubleTypes() const { return IsLowHalf(); }
110   // Check this is the low half, and that type_h is its matching high-half.
CheckWidePair(const RegType & type_h)111   inline bool CheckWidePair(const RegType& type_h) const {
112     if (IsLowHalf()) {
113       return ((IsImpreciseConstantLo() && type_h.IsPreciseConstantHi()) ||
114               (IsImpreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
115               (IsPreciseConstantLo() && type_h.IsPreciseConstantHi()) ||
116               (IsPreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
117               (IsDoubleLo() && type_h.IsDoubleHi()) ||
118               (IsLongLo() && type_h.IsLongHi()));
119     }
120     return false;
121   }
122   // The high half that corresponds to this low half
123   const RegType& HighHalf(RegTypeCache* cache) const
124       REQUIRES_SHARED(Locks::mutator_lock_);
125 
126   bool IsConstantBoolean() const;
IsConstantChar()127   virtual bool IsConstantChar() const { return false; }
IsConstantByte()128   virtual bool IsConstantByte() const { return false; }
IsConstantShort()129   virtual bool IsConstantShort() const { return false; }
IsOne()130   virtual bool IsOne() const { return false; }
IsZero()131   virtual bool IsZero() const { return false; }
IsNull()132   virtual bool IsNull() const { return false; }
IsReferenceTypes()133   bool IsReferenceTypes() const {
134     return IsNonZeroReferenceTypes() || IsZero() || IsNull();
135   }
IsZeroOrNull()136   bool IsZeroOrNull() const {
137     return IsZero() || IsNull();
138   }
IsNonZeroReferenceTypes()139   virtual bool IsNonZeroReferenceTypes() const { return false; }
IsCategory1Types()140   bool IsCategory1Types() const {
141     return IsChar() || IsInteger() || IsFloat() || IsConstant() || IsByte() ||
142            IsShort() || IsBoolean();
143   }
IsCategory2Types()144   bool IsCategory2Types() const {
145     return IsLowHalf();  // Don't expect explicit testing of high halves
146   }
IsBooleanTypes()147   bool IsBooleanTypes() const { return IsBoolean() || IsConstantBoolean(); }
IsByteTypes()148   bool IsByteTypes() const {
149     return IsConstantByte() || IsByte() || IsBoolean();
150   }
IsShortTypes()151   bool IsShortTypes() const {
152     return IsShort() || IsByte() || IsBoolean() || IsConstantShort();
153   }
IsCharTypes()154   bool IsCharTypes() const {
155     return IsChar() || IsBooleanTypes() || IsConstantChar();
156   }
IsIntegralTypes()157   bool IsIntegralTypes() const {
158     return IsInteger() || IsConstant() || IsByte() || IsShort() || IsChar() ||
159            IsBoolean();
160   }
161   // Give the constant value encoded, but this shouldn't be called in the
162   // general case.
IsArrayIndexTypes()163   bool IsArrayIndexTypes() const { return IsIntegralTypes(); }
164   // Float type may be derived from any constant type
IsFloatTypes()165   bool IsFloatTypes() const { return IsFloat() || IsConstant(); }
IsLongTypes()166   bool IsLongTypes() const { return IsLongLo() || IsLongConstant(); }
IsLongHighTypes()167   bool IsLongHighTypes() const {
168     return (IsLongHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
169   }
IsDoubleTypes()170   bool IsDoubleTypes() const { return IsDoubleLo() || IsLongConstant(); }
IsDoubleHighTypes()171   bool IsDoubleHighTypes() const {
172     return (IsDoubleHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
173   }
IsLong()174   virtual bool IsLong() const { return false; }
HasClass()175   bool HasClass() const {
176     bool result = !klass_.IsNull();
177     DCHECK_EQ(result, HasClassVirtual());
178     return result;
179   }
HasClassVirtual()180   virtual bool HasClassVirtual() const { return false; }
181   bool IsJavaLangObject() const REQUIRES_SHARED(Locks::mutator_lock_);
182   virtual bool IsArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_);
183   virtual bool IsObjectArrayTypes() const REQUIRES_SHARED(Locks::mutator_lock_);
184   Primitive::Type GetPrimitiveType() const;
185   bool IsJavaLangObjectArray() const
186       REQUIRES_SHARED(Locks::mutator_lock_);
187   bool IsInstantiableTypes() const REQUIRES_SHARED(Locks::mutator_lock_);
GetDescriptor()188   const StringPiece& GetDescriptor() const {
189     DCHECK(HasClass() ||
190            (IsUnresolvedTypes() && !IsUnresolvedMergedReference() &&
191             !IsUnresolvedSuperClass()));
192     return descriptor_;
193   }
GetClass()194   mirror::Class* GetClass() const REQUIRES_SHARED(Locks::mutator_lock_) {
195     DCHECK(!IsUnresolvedReference());
196     DCHECK(!klass_.IsNull()) << Dump();
197     DCHECK(HasClass());
198     return klass_.Read();
199   }
GetId()200   uint16_t GetId() const { return cache_id_; }
201   const RegType& GetSuperClass(RegTypeCache* cache) const
202       REQUIRES_SHARED(Locks::mutator_lock_);
203 
204   virtual std::string Dump() const
205       REQUIRES_SHARED(Locks::mutator_lock_) = 0;
206 
207   // Can this type access other?
208   bool CanAccess(const RegType& other) const
209       REQUIRES_SHARED(Locks::mutator_lock_);
210 
211   // Can this type access a member with the given properties?
212   bool CanAccessMember(ObjPtr<mirror::Class> klass, uint32_t access_flags) const
213       REQUIRES_SHARED(Locks::mutator_lock_);
214 
215   // Can this type be assigned by src?
216   // Note: Object and interface types may always be assigned to one another, see
217   // comment on
218   // ClassJoin.
219   bool IsAssignableFrom(const RegType& src, MethodVerifier* verifier) const
220       REQUIRES_SHARED(Locks::mutator_lock_);
221 
222   // Can this array type potentially be assigned by src.
223   // This function is necessary as array types are valid even if their components types are not,
224   // e.g., when they component type could not be resolved. The function will return true iff the
225   // types are assignable. It will return false otherwise. In case of return=false, soft_error
226   // will be set to true iff the assignment test failure should be treated as a soft-error, i.e.,
227   // when both array types have the same 'depth' and the 'final' component types may be assignable
228   // (both are reference types).
229   bool CanAssignArray(const RegType& src,
230                       RegTypeCache& reg_types,
231                       Handle<mirror::ClassLoader> class_loader,
232                       MethodVerifier* verifier,
233                       bool* soft_error) const
234       REQUIRES_SHARED(Locks::mutator_lock_);
235 
236   // Can this type be assigned by src? Variant of IsAssignableFrom that doesn't
237   // allow assignment to
238   // an interface from an Object.
239   bool IsStrictlyAssignableFrom(const RegType& src, MethodVerifier* verifier) const
240       REQUIRES_SHARED(Locks::mutator_lock_);
241 
242   // Are these RegTypes the same?
Equals(const RegType & other)243   bool Equals(const RegType& other) const { return GetId() == other.GetId(); }
244 
245   // Compute the merge of this register from one edge (path) with incoming_type
246   // from another.
247   const RegType& Merge(const RegType& incoming_type,
248                        RegTypeCache* reg_types,
249                        MethodVerifier* verifier) const
250       REQUIRES_SHARED(Locks::mutator_lock_);
251   // Same as above, but also handles the case where incoming_type == this.
SafeMerge(const RegType & incoming_type,RegTypeCache * reg_types,MethodVerifier * verifier)252   const RegType& SafeMerge(const RegType& incoming_type,
253                            RegTypeCache* reg_types,
254                            MethodVerifier* verifier) const
255       REQUIRES_SHARED(Locks::mutator_lock_) {
256     if (Equals(incoming_type)) {
257       return *this;
258     }
259     return Merge(incoming_type, reg_types, verifier);
260   }
261 
~RegType()262   virtual ~RegType() {}
263 
264   void VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const
265       REQUIRES_SHARED(Locks::mutator_lock_);
266 
new(size_t size)267   static void* operator new(size_t size) noexcept {
268     return ::operator new(size);
269   }
270 
271   static void* operator new(size_t size, ArenaAllocator* allocator) = delete;
272   static void* operator new(size_t size, ScopedArenaAllocator* allocator);
273 
274   enum class AssignmentType {
275     kBoolean,
276     kByte,
277     kShort,
278     kChar,
279     kInteger,
280     kFloat,
281     kLongLo,
282     kDoubleLo,
283     kConflict,
284     kReference,
285     kNotAssignable,
286   };
287 
288   ALWAYS_INLINE
GetAssignmentType()289   inline AssignmentType GetAssignmentType() const {
290     AssignmentType t = GetAssignmentTypeImpl();
291     if (kIsDebugBuild) {
292       if (IsBoolean()) {
293         CHECK(AssignmentType::kBoolean == t);
294       } else if (IsByte()) {
295         CHECK(AssignmentType::kByte == t);
296       } else if (IsShort()) {
297         CHECK(AssignmentType::kShort == t);
298       } else if (IsChar()) {
299         CHECK(AssignmentType::kChar == t);
300       } else if (IsInteger()) {
301         CHECK(AssignmentType::kInteger == t);
302       } else if (IsFloat()) {
303         CHECK(AssignmentType::kFloat == t);
304       } else if (IsLongLo()) {
305         CHECK(AssignmentType::kLongLo == t);
306       } else if (IsDoubleLo()) {
307         CHECK(AssignmentType::kDoubleLo == t);
308       } else if (IsConflict()) {
309         CHECK(AssignmentType::kConflict == t);
310       } else if (IsReferenceTypes()) {
311         CHECK(AssignmentType::kReference == t);
312       } else {
313         LOG(FATAL) << "Unreachable";
314         UNREACHABLE();
315       }
316     }
317     return t;
318   }
319 
320  protected:
RegType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)321   RegType(mirror::Class* klass,
322           const StringPiece& descriptor,
323           uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
324       : descriptor_(descriptor),
325         klass_(klass),
326         cache_id_(cache_id) {}
327 
328   template <typename Class>
CheckConstructorInvariants(Class * this_ ATTRIBUTE_UNUSED)329   void CheckConstructorInvariants(Class* this_ ATTRIBUTE_UNUSED) const
330       REQUIRES_SHARED(Locks::mutator_lock_) {
331     static_assert(std::is_final<Class>::value, "Class must be final.");
332     if (kIsDebugBuild) {
333       CheckInvariants();
334     }
335   }
336 
337   virtual AssignmentType GetAssignmentTypeImpl() const = 0;
338 
339   const StringPiece descriptor_;
340   mutable GcRoot<mirror::Class> klass_;  // Non-const only due to moving classes.
341   const uint16_t cache_id_;
342 
343   friend class RegTypeCache;
344 
345  private:
346   virtual void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_);
347 
348   /*
349    * A basic Join operation on classes. For a pair of types S and T the Join, written S v T = J, is
350    * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is J is the parent of
351    * 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
352    * is the deepest (lowest upper bound) parent of S and T).
353    *
354    * This operation applies for regular classes and arrays, however, for interface types there
355    * needn't be a partial ordering on the types. We could solve the problem of a lack of a partial
356    * order by introducing sets of types, however, the only operation permissible on an interface is
357    * invoke-interface. In the tradition of Java verifiers [1] we defer the verification of interface
358    * types until an invoke-interface call on the interface typed reference at runtime and allow
359    * the perversion of Object being assignable to an interface type (note, however, that we don't
360    * allow assignment of Object or Interface to any concrete class and are therefore type safe).
361    *
362    * Note: This may return null in case of internal errors, e.g., OOME when a new class would have
363    *       to be created but there is no heap space. The exception will stay pending, and it is
364    *       the job of the caller to handle it.
365    *
366    * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
367    */
368   static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
369       REQUIRES_SHARED(Locks::mutator_lock_);
370 
371   static bool AssignableFrom(const RegType& lhs,
372                              const RegType& rhs,
373                              bool strict,
374                              MethodVerifier* verifier)
375       REQUIRES_SHARED(Locks::mutator_lock_);
376 
377   DISALLOW_COPY_AND_ASSIGN(RegType);
378 };
379 
380 // Bottom type.
381 class ConflictType FINAL : public RegType {
382  public:
IsConflict()383   bool IsConflict() const OVERRIDE { return true; }
384 
385   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
386 
387   // Get the singleton Conflict instance.
388   static const ConflictType* GetInstance() PURE;
389 
390   // Create the singleton instance.
391   static const ConflictType* CreateInstance(mirror::Class* klass,
392                                             const StringPiece& descriptor,
393                                             uint16_t cache_id)
394       REQUIRES_SHARED(Locks::mutator_lock_);
395 
396   // Destroy the singleton instance.
397   static void Destroy();
398 
GetAssignmentTypeImpl()399   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
400     return AssignmentType::kConflict;
401   }
402 
403  private:
ConflictType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)404   ConflictType(mirror::Class* klass, const StringPiece& descriptor,
405                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
406       : RegType(klass, descriptor, cache_id) {
407     CheckConstructorInvariants(this);
408   }
409 
410   static const ConflictType* instance_;
411 };
412 
413 // A variant of the bottom type used to specify an undefined value in the
414 // incoming registers.
415 // Merging with UndefinedType yields ConflictType which is the true bottom.
416 class UndefinedType FINAL : public RegType {
417  public:
IsUndefined()418   bool IsUndefined() const OVERRIDE { return true; }
419 
420   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
421 
422   // Get the singleton Undefined instance.
423   static const UndefinedType* GetInstance() PURE;
424 
425   // Create the singleton instance.
426   static const UndefinedType* CreateInstance(mirror::Class* klass,
427                                              const StringPiece& descriptor,
428                                              uint16_t cache_id)
429       REQUIRES_SHARED(Locks::mutator_lock_);
430 
431   // Destroy the singleton instance.
432   static void Destroy();
433 
GetAssignmentTypeImpl()434   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
435     return AssignmentType::kNotAssignable;
436   }
437 
438  private:
UndefinedType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)439   UndefinedType(mirror::Class* klass, const StringPiece& descriptor,
440                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
441       : RegType(klass, descriptor, cache_id) {
442     CheckConstructorInvariants(this);
443   }
444 
445   static const UndefinedType* instance_;
446 };
447 
448 class PrimitiveType : public RegType {
449  public:
450   PrimitiveType(mirror::Class* klass, const StringPiece& descriptor,
451                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
452 
HasClassVirtual()453   bool HasClassVirtual() const OVERRIDE { return true; }
454 };
455 
456 class Cat1Type : public PrimitiveType {
457  public:
458   Cat1Type(mirror::Class* klass, const StringPiece& descriptor,
459            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
460 };
461 
462 class IntegerType FINAL : public Cat1Type {
463  public:
IsInteger()464   bool IsInteger() const OVERRIDE { return true; }
465   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
466   static const IntegerType* CreateInstance(mirror::Class* klass,
467                                            const StringPiece& descriptor,
468                                            uint16_t cache_id)
469       REQUIRES_SHARED(Locks::mutator_lock_);
470   static const IntegerType* GetInstance() PURE;
471   static void Destroy();
472 
GetAssignmentTypeImpl()473   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
474     return AssignmentType::kInteger;
475   }
476 
477  private:
IntegerType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)478   IntegerType(mirror::Class* klass, const StringPiece& descriptor,
479               uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
480       : Cat1Type(klass, descriptor, cache_id) {
481     CheckConstructorInvariants(this);
482   }
483   static const IntegerType* instance_;
484 };
485 
486 class BooleanType FINAL : public Cat1Type {
487  public:
IsBoolean()488   bool IsBoolean() const OVERRIDE { return true; }
489   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
490   static const BooleanType* CreateInstance(mirror::Class* klass,
491                                            const StringPiece& descriptor,
492                                            uint16_t cache_id)
493       REQUIRES_SHARED(Locks::mutator_lock_);
494   static const BooleanType* GetInstance() PURE;
495   static void Destroy();
496 
GetAssignmentTypeImpl()497   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
498     return AssignmentType::kBoolean;
499   }
500 
501  private:
BooleanType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)502   BooleanType(mirror::Class* klass, const StringPiece& descriptor,
503               uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
504       : Cat1Type(klass, descriptor, cache_id) {
505     CheckConstructorInvariants(this);
506   }
507 
508   static const BooleanType* instance_;
509 };
510 
511 class ByteType FINAL : public Cat1Type {
512  public:
IsByte()513   bool IsByte() const OVERRIDE { return true; }
514   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
515   static const ByteType* CreateInstance(mirror::Class* klass,
516                                         const StringPiece& descriptor,
517                                         uint16_t cache_id)
518       REQUIRES_SHARED(Locks::mutator_lock_);
519   static const ByteType* GetInstance() PURE;
520   static void Destroy();
521 
GetAssignmentTypeImpl()522   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
523     return AssignmentType::kByte;
524   }
525 
526  private:
ByteType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)527   ByteType(mirror::Class* klass, const StringPiece& descriptor,
528            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
529       : Cat1Type(klass, descriptor, cache_id) {
530     CheckConstructorInvariants(this);
531   }
532   static const ByteType* instance_;
533 };
534 
535 class ShortType FINAL : public Cat1Type {
536  public:
IsShort()537   bool IsShort() const OVERRIDE { return true; }
538   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
539   static const ShortType* CreateInstance(mirror::Class* klass,
540                                          const StringPiece& descriptor,
541                                          uint16_t cache_id)
542       REQUIRES_SHARED(Locks::mutator_lock_);
543   static const ShortType* GetInstance() PURE;
544   static void Destroy();
545 
GetAssignmentTypeImpl()546   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
547     return AssignmentType::kShort;
548   }
549 
550  private:
ShortType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)551   ShortType(mirror::Class* klass, const StringPiece& descriptor,
552             uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
553       : Cat1Type(klass, descriptor, cache_id) {
554     CheckConstructorInvariants(this);
555   }
556   static const ShortType* instance_;
557 };
558 
559 class CharType FINAL : public Cat1Type {
560  public:
IsChar()561   bool IsChar() const OVERRIDE { return true; }
562   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
563   static const CharType* CreateInstance(mirror::Class* klass,
564                                         const StringPiece& descriptor,
565                                         uint16_t cache_id)
566       REQUIRES_SHARED(Locks::mutator_lock_);
567   static const CharType* GetInstance() PURE;
568   static void Destroy();
569 
GetAssignmentTypeImpl()570   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
571     return AssignmentType::kChar;
572   }
573 
574  private:
CharType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)575   CharType(mirror::Class* klass, const StringPiece& descriptor,
576            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
577       : Cat1Type(klass, descriptor, cache_id) {
578     CheckConstructorInvariants(this);
579   }
580   static const CharType* instance_;
581 };
582 
583 class FloatType FINAL : public Cat1Type {
584  public:
IsFloat()585   bool IsFloat() const OVERRIDE { return true; }
586   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
587   static const FloatType* CreateInstance(mirror::Class* klass,
588                                          const StringPiece& descriptor,
589                                          uint16_t cache_id)
590       REQUIRES_SHARED(Locks::mutator_lock_);
591   static const FloatType* GetInstance() PURE;
592   static void Destroy();
593 
GetAssignmentTypeImpl()594   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
595     return AssignmentType::kFloat;
596   }
597 
598  private:
FloatType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)599   FloatType(mirror::Class* klass, const StringPiece& descriptor,
600             uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
601       : Cat1Type(klass, descriptor, cache_id) {
602     CheckConstructorInvariants(this);
603   }
604   static const FloatType* instance_;
605 };
606 
607 class Cat2Type : public PrimitiveType {
608  public:
609   Cat2Type(mirror::Class* klass, const StringPiece& descriptor,
610            uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_);
611 };
612 
613 class LongLoType FINAL : public Cat2Type {
614  public:
615   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
IsLongLo()616   bool IsLongLo() const OVERRIDE { return true; }
IsLong()617   bool IsLong() const OVERRIDE { return true; }
618   static const LongLoType* CreateInstance(mirror::Class* klass,
619                                           const StringPiece& descriptor,
620                                           uint16_t cache_id)
621       REQUIRES_SHARED(Locks::mutator_lock_);
622   static const LongLoType* GetInstance() PURE;
623   static void Destroy();
624 
GetAssignmentTypeImpl()625   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
626     return AssignmentType::kLongLo;
627   }
628 
629  private:
LongLoType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)630   LongLoType(mirror::Class* klass, const StringPiece& descriptor,
631              uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
632       : Cat2Type(klass, descriptor, cache_id) {
633     CheckConstructorInvariants(this);
634   }
635   static const LongLoType* instance_;
636 };
637 
638 class LongHiType FINAL : public Cat2Type {
639  public:
640   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
IsLongHi()641   bool IsLongHi() const OVERRIDE { return true; }
642   static const LongHiType* CreateInstance(mirror::Class* klass,
643                                           const StringPiece& descriptor,
644                                           uint16_t cache_id)
645       REQUIRES_SHARED(Locks::mutator_lock_);
646   static const LongHiType* GetInstance() PURE;
647   static void Destroy();
648 
GetAssignmentTypeImpl()649   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
650     return AssignmentType::kNotAssignable;
651   }
652 
653  private:
LongHiType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)654   LongHiType(mirror::Class* klass, const StringPiece& descriptor,
655              uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
656       : Cat2Type(klass, descriptor, cache_id) {
657     CheckConstructorInvariants(this);
658   }
659   static const LongHiType* instance_;
660 };
661 
662 class DoubleLoType FINAL : public Cat2Type {
663  public:
664   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
IsDoubleLo()665   bool IsDoubleLo() const OVERRIDE { return true; }
IsDouble()666   bool IsDouble() const OVERRIDE { return true; }
667   static const DoubleLoType* CreateInstance(mirror::Class* klass,
668                                             const StringPiece& descriptor,
669                                             uint16_t cache_id)
670       REQUIRES_SHARED(Locks::mutator_lock_);
671   static const DoubleLoType* GetInstance() PURE;
672   static void Destroy();
673 
GetAssignmentTypeImpl()674   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
675     return AssignmentType::kDoubleLo;
676   }
677 
678  private:
DoubleLoType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)679   DoubleLoType(mirror::Class* klass, const StringPiece& descriptor,
680                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
681       : Cat2Type(klass, descriptor, cache_id) {
682     CheckConstructorInvariants(this);
683   }
684   static const DoubleLoType* instance_;
685 };
686 
687 class DoubleHiType FINAL : public Cat2Type {
688  public:
689   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
IsDoubleHi()690   virtual bool IsDoubleHi() const OVERRIDE { return true; }
691   static const DoubleHiType* CreateInstance(mirror::Class* klass,
692                                       const StringPiece& descriptor,
693                                       uint16_t cache_id)
694       REQUIRES_SHARED(Locks::mutator_lock_);
695   static const DoubleHiType* GetInstance() PURE;
696   static void Destroy();
697 
GetAssignmentTypeImpl()698   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
699     return AssignmentType::kNotAssignable;
700   }
701 
702  private:
DoubleHiType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)703   DoubleHiType(mirror::Class* klass, const StringPiece& descriptor,
704                uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
705       : Cat2Type(klass, descriptor, cache_id) {
706     CheckConstructorInvariants(this);
707   }
708   static const DoubleHiType* instance_;
709 };
710 
711 class ConstantType : public RegType {
712  public:
ConstantType(uint32_t constant,uint16_t cache_id)713   ConstantType(uint32_t constant, uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
714       : RegType(nullptr, "", cache_id), constant_(constant) {
715   }
716 
717 
718   // If this is a 32-bit constant, what is the value? This value may be
719   // imprecise in which case
720   // the value represents part of the integer range of values that may be held
721   // in the register.
ConstantValue()722   int32_t ConstantValue() const {
723     DCHECK(IsConstantTypes());
724     return constant_;
725   }
726 
ConstantValueLo()727   int32_t ConstantValueLo() const {
728     DCHECK(IsConstantLo());
729     return constant_;
730   }
731 
ConstantValueHi()732   int32_t ConstantValueHi() const {
733     if (IsConstantHi() || IsPreciseConstantHi() || IsImpreciseConstantHi()) {
734       return constant_;
735     } else {
736       DCHECK(false);
737       return 0;
738     }
739   }
740 
IsZero()741   bool IsZero() const OVERRIDE {
742     return IsPreciseConstant() && ConstantValue() == 0;
743   }
IsOne()744   bool IsOne() const OVERRIDE {
745     return IsPreciseConstant() && ConstantValue() == 1;
746   }
747 
IsConstantChar()748   bool IsConstantChar() const OVERRIDE {
749     return IsConstant() && ConstantValue() >= 0 &&
750            ConstantValue() <= std::numeric_limits<uint16_t>::max();
751   }
IsConstantByte()752   bool IsConstantByte() const OVERRIDE {
753     return IsConstant() &&
754            ConstantValue() >= std::numeric_limits<int8_t>::min() &&
755            ConstantValue() <= std::numeric_limits<int8_t>::max();
756   }
IsConstantShort()757   bool IsConstantShort() const OVERRIDE {
758     return IsConstant() &&
759            ConstantValue() >= std::numeric_limits<int16_t>::min() &&
760            ConstantValue() <= std::numeric_limits<int16_t>::max();
761   }
IsConstantTypes()762   virtual bool IsConstantTypes() const OVERRIDE { return true; }
763 
GetAssignmentTypeImpl()764   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
765     return AssignmentType::kNotAssignable;
766   }
767 
768  private:
769   const uint32_t constant_;
770 };
771 
772 class PreciseConstType FINAL : public ConstantType {
773  public:
PreciseConstType(uint32_t constant,uint16_t cache_id)774   PreciseConstType(uint32_t constant, uint16_t cache_id)
775       REQUIRES_SHARED(Locks::mutator_lock_)
776       : ConstantType(constant, cache_id) {
777     CheckConstructorInvariants(this);
778   }
779 
IsPreciseConstant()780   bool IsPreciseConstant() const OVERRIDE { return true; }
781 
782   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
783 
GetAssignmentTypeImpl()784   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
785     return AssignmentType::kNotAssignable;
786   }
787 };
788 
789 class PreciseConstLoType FINAL : public ConstantType {
790  public:
PreciseConstLoType(uint32_t constant,uint16_t cache_id)791   PreciseConstLoType(uint32_t constant, uint16_t cache_id)
792       REQUIRES_SHARED(Locks::mutator_lock_)
793       : ConstantType(constant, cache_id) {
794     CheckConstructorInvariants(this);
795   }
IsPreciseConstantLo()796   bool IsPreciseConstantLo() const OVERRIDE { return true; }
797   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
798 
GetAssignmentTypeImpl()799   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
800     return AssignmentType::kNotAssignable;
801   }
802 };
803 
804 class PreciseConstHiType FINAL : public ConstantType {
805  public:
PreciseConstHiType(uint32_t constant,uint16_t cache_id)806   PreciseConstHiType(uint32_t constant, uint16_t cache_id)
807       REQUIRES_SHARED(Locks::mutator_lock_)
808       : ConstantType(constant, cache_id) {
809     CheckConstructorInvariants(this);
810   }
IsPreciseConstantHi()811   bool IsPreciseConstantHi() const OVERRIDE { return true; }
812   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
813 
GetAssignmentTypeImpl()814   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
815     return AssignmentType::kNotAssignable;
816   }
817 };
818 
819 class ImpreciseConstType FINAL : public ConstantType {
820  public:
ImpreciseConstType(uint32_t constat,uint16_t cache_id)821   ImpreciseConstType(uint32_t constat, uint16_t cache_id)
822        REQUIRES_SHARED(Locks::mutator_lock_)
823        : ConstantType(constat, cache_id) {
824     CheckConstructorInvariants(this);
825   }
IsImpreciseConstant()826   bool IsImpreciseConstant() const OVERRIDE { return true; }
827   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
828 
GetAssignmentTypeImpl()829   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
830     return AssignmentType::kNotAssignable;
831   }
832 };
833 
834 class ImpreciseConstLoType FINAL : public ConstantType {
835  public:
ImpreciseConstLoType(uint32_t constant,uint16_t cache_id)836   ImpreciseConstLoType(uint32_t constant, uint16_t cache_id)
837       REQUIRES_SHARED(Locks::mutator_lock_)
838       : ConstantType(constant, cache_id) {
839     CheckConstructorInvariants(this);
840   }
IsImpreciseConstantLo()841   bool IsImpreciseConstantLo() const OVERRIDE { return true; }
842   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
843 
GetAssignmentTypeImpl()844   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
845     return AssignmentType::kNotAssignable;
846   }
847 };
848 
849 class ImpreciseConstHiType FINAL : public ConstantType {
850  public:
ImpreciseConstHiType(uint32_t constant,uint16_t cache_id)851   ImpreciseConstHiType(uint32_t constant, uint16_t cache_id)
852       REQUIRES_SHARED(Locks::mutator_lock_)
853       : ConstantType(constant, cache_id) {
854     CheckConstructorInvariants(this);
855   }
IsImpreciseConstantHi()856   bool IsImpreciseConstantHi() const OVERRIDE { return true; }
857   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
858 
GetAssignmentTypeImpl()859   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
860     return AssignmentType::kNotAssignable;
861   }
862 };
863 
864 // Special "null" type that captures the semantics of null / bottom.
865 class NullType FINAL : public RegType {
866  public:
IsNull()867   bool IsNull() const OVERRIDE {
868     return true;
869   }
870 
871   // Get the singleton Null instance.
872   static const NullType* GetInstance() PURE;
873 
874   // Create the singleton instance.
875   static const NullType* CreateInstance(mirror::Class* klass,
876                                         const StringPiece& descriptor,
877                                         uint16_t cache_id)
878       REQUIRES_SHARED(Locks::mutator_lock_);
879 
880   static void Destroy();
881 
Dump()882   std::string Dump() const OVERRIDE {
883     return "null";
884   }
885 
GetAssignmentTypeImpl()886   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
887     return AssignmentType::kReference;
888   }
889 
IsConstantTypes()890   bool IsConstantTypes() const OVERRIDE {
891     return true;
892   }
893 
894  private:
NullType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)895   NullType(mirror::Class* klass, const StringPiece& descriptor, uint16_t cache_id)
896       REQUIRES_SHARED(Locks::mutator_lock_)
897       : RegType(klass, descriptor, cache_id) {
898     CheckConstructorInvariants(this);
899   }
900 
901   static const NullType* instance_;
902 };
903 
904 // Common parent of all uninitialized types. Uninitialized types are created by
905 // "new" dex
906 // instructions and must be passed to a constructor.
907 class UninitializedType : public RegType {
908  public:
UninitializedType(mirror::Class * klass,const StringPiece & descriptor,uint32_t allocation_pc,uint16_t cache_id)909   UninitializedType(mirror::Class* klass, const StringPiece& descriptor,
910                     uint32_t allocation_pc, uint16_t cache_id)
911       : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {}
912 
913   bool IsUninitializedTypes() const OVERRIDE;
914   bool IsNonZeroReferenceTypes() const OVERRIDE;
915 
GetAllocationPc()916   uint32_t GetAllocationPc() const {
917     DCHECK(IsUninitializedTypes());
918     return allocation_pc_;
919   }
920 
GetAssignmentTypeImpl()921   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
922     return AssignmentType::kReference;
923   }
924 
925  private:
926   const uint32_t allocation_pc_;
927 };
928 
929 // Similar to ReferenceType but not yet having been passed to a constructor.
930 class UninitializedReferenceType FINAL : public UninitializedType {
931  public:
UninitializedReferenceType(mirror::Class * klass,const StringPiece & descriptor,uint32_t allocation_pc,uint16_t cache_id)932   UninitializedReferenceType(mirror::Class* klass,
933                              const StringPiece& descriptor,
934                              uint32_t allocation_pc, uint16_t cache_id)
935       REQUIRES_SHARED(Locks::mutator_lock_)
936       : UninitializedType(klass, descriptor, allocation_pc, cache_id) {
937     CheckConstructorInvariants(this);
938   }
939 
IsUninitializedReference()940   bool IsUninitializedReference() const OVERRIDE { return true; }
941 
HasClassVirtual()942   bool HasClassVirtual() const OVERRIDE { return true; }
943 
944   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
945 };
946 
947 // Similar to UnresolvedReferenceType but not yet having been passed to a
948 // constructor.
949 class UnresolvedUninitializedRefType FINAL : public UninitializedType {
950  public:
UnresolvedUninitializedRefType(const StringPiece & descriptor,uint32_t allocation_pc,uint16_t cache_id)951   UnresolvedUninitializedRefType(const StringPiece& descriptor,
952                                  uint32_t allocation_pc, uint16_t cache_id)
953       REQUIRES_SHARED(Locks::mutator_lock_)
954       : UninitializedType(nullptr, descriptor, allocation_pc, cache_id) {
955     CheckConstructorInvariants(this);
956   }
957 
IsUnresolvedAndUninitializedReference()958   bool IsUnresolvedAndUninitializedReference() const OVERRIDE { return true; }
959 
IsUnresolvedTypes()960   bool IsUnresolvedTypes() const OVERRIDE { return true; }
961 
962   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
963 
964  private:
965   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
966 };
967 
968 // Similar to UninitializedReferenceType but special case for the this argument
969 // of a constructor.
970 class UninitializedThisReferenceType FINAL : public UninitializedType {
971  public:
UninitializedThisReferenceType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)972   UninitializedThisReferenceType(mirror::Class* klass,
973                                  const StringPiece& descriptor,
974                                  uint16_t cache_id)
975       REQUIRES_SHARED(Locks::mutator_lock_)
976       : UninitializedType(klass, descriptor, 0, cache_id) {
977     CheckConstructorInvariants(this);
978   }
979 
IsUninitializedThisReference()980   virtual bool IsUninitializedThisReference() const OVERRIDE { return true; }
981 
HasClassVirtual()982   bool HasClassVirtual() const OVERRIDE { return true; }
983 
984   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
985 
986  private:
987   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
988 };
989 
990 class UnresolvedUninitializedThisRefType FINAL : public UninitializedType {
991  public:
UnresolvedUninitializedThisRefType(const StringPiece & descriptor,uint16_t cache_id)992   UnresolvedUninitializedThisRefType(const StringPiece& descriptor,
993                                      uint16_t cache_id)
994       REQUIRES_SHARED(Locks::mutator_lock_)
995       : UninitializedType(nullptr, descriptor, 0, cache_id) {
996     CheckConstructorInvariants(this);
997   }
998 
IsUnresolvedAndUninitializedThisReference()999   bool IsUnresolvedAndUninitializedThisReference() const OVERRIDE { return true; }
1000 
IsUnresolvedTypes()1001   bool IsUnresolvedTypes() const OVERRIDE { return true; }
1002 
1003   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1004 
1005  private:
1006   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
1007 };
1008 
1009 // A type of register holding a reference to an Object of type GetClass or a
1010 // sub-class.
1011 class ReferenceType FINAL : public RegType {
1012  public:
ReferenceType(mirror::Class * klass,const StringPiece & descriptor,uint16_t cache_id)1013   ReferenceType(mirror::Class* klass, const StringPiece& descriptor,
1014                 uint16_t cache_id) REQUIRES_SHARED(Locks::mutator_lock_)
1015       : RegType(klass, descriptor, cache_id) {
1016     CheckConstructorInvariants(this);
1017   }
1018 
IsReference()1019   bool IsReference() const OVERRIDE { return true; }
1020 
IsNonZeroReferenceTypes()1021   bool IsNonZeroReferenceTypes() const OVERRIDE { return true; }
1022 
HasClassVirtual()1023   bool HasClassVirtual() const OVERRIDE { return true; }
1024 
1025   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1026 
GetAssignmentTypeImpl()1027   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
1028     return AssignmentType::kReference;
1029   }
1030 };
1031 
1032 // A type of register holding a reference to an Object of type GetClass and only
1033 // an object of that
1034 // type.
1035 class PreciseReferenceType FINAL : public RegType {
1036  public:
1037   PreciseReferenceType(mirror::Class* klass, const StringPiece& descriptor,
1038                        uint16_t cache_id)
1039       REQUIRES_SHARED(Locks::mutator_lock_);
1040 
IsPreciseReference()1041   bool IsPreciseReference() const OVERRIDE { return true; }
1042 
IsNonZeroReferenceTypes()1043   bool IsNonZeroReferenceTypes() const OVERRIDE { return true; }
1044 
HasClassVirtual()1045   bool HasClassVirtual() const OVERRIDE { return true; }
1046 
1047   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1048 
GetAssignmentTypeImpl()1049   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
1050     return AssignmentType::kReference;
1051   }
1052 };
1053 
1054 // Common parent of unresolved types.
1055 class UnresolvedType : public RegType {
1056  public:
UnresolvedType(const StringPiece & descriptor,uint16_t cache_id)1057   UnresolvedType(const StringPiece& descriptor, uint16_t cache_id)
1058       REQUIRES_SHARED(Locks::mutator_lock_)
1059       : RegType(nullptr, descriptor, cache_id) {}
1060 
1061   bool IsNonZeroReferenceTypes() const OVERRIDE;
1062 
GetAssignmentTypeImpl()1063   AssignmentType GetAssignmentTypeImpl() const OVERRIDE {
1064     return AssignmentType::kReference;
1065   }
1066 };
1067 
1068 // Similar to ReferenceType except the Class couldn't be loaded. Assignability
1069 // and other tests made
1070 // of this type must be conservative.
1071 class UnresolvedReferenceType FINAL : public UnresolvedType {
1072  public:
UnresolvedReferenceType(const StringPiece & descriptor,uint16_t cache_id)1073   UnresolvedReferenceType(const StringPiece& descriptor, uint16_t cache_id)
1074       REQUIRES_SHARED(Locks::mutator_lock_)
1075       : UnresolvedType(descriptor, cache_id) {
1076     CheckConstructorInvariants(this);
1077   }
1078 
IsUnresolvedReference()1079   bool IsUnresolvedReference() const OVERRIDE { return true; }
1080 
IsUnresolvedTypes()1081   bool IsUnresolvedTypes() const OVERRIDE { return true; }
1082 
1083   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1084 
1085  private:
1086   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
1087 };
1088 
1089 // Type representing the super-class of an unresolved type.
1090 class UnresolvedSuperClass FINAL : public UnresolvedType {
1091  public:
UnresolvedSuperClass(uint16_t child_id,RegTypeCache * reg_type_cache,uint16_t cache_id)1092   UnresolvedSuperClass(uint16_t child_id, RegTypeCache* reg_type_cache,
1093                        uint16_t cache_id)
1094       REQUIRES_SHARED(Locks::mutator_lock_)
1095       : UnresolvedType("", cache_id),
1096         unresolved_child_id_(child_id),
1097         reg_type_cache_(reg_type_cache) {
1098     CheckConstructorInvariants(this);
1099   }
1100 
IsUnresolvedSuperClass()1101   bool IsUnresolvedSuperClass() const OVERRIDE { return true; }
1102 
IsUnresolvedTypes()1103   bool IsUnresolvedTypes() const OVERRIDE { return true; }
1104 
GetUnresolvedSuperClassChildId()1105   uint16_t GetUnresolvedSuperClassChildId() const {
1106     DCHECK(IsUnresolvedSuperClass());
1107     return static_cast<uint16_t>(unresolved_child_id_ & 0xFFFF);
1108   }
1109 
1110   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1111 
1112  private:
1113   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
1114 
1115   const uint16_t unresolved_child_id_;
1116   const RegTypeCache* const reg_type_cache_;
1117 };
1118 
1119 // A merge of unresolved (and resolved) types. If the types were resolved this may be
1120 // Conflict or another known ReferenceType.
1121 class UnresolvedMergedType FINAL : public UnresolvedType {
1122  public:
1123   // Note: the constructor will copy the unresolved BitVector, not use it directly.
1124   UnresolvedMergedType(const RegType& resolved,
1125                        const BitVector& unresolved,
1126                        const RegTypeCache* reg_type_cache,
1127                        uint16_t cache_id)
1128       REQUIRES_SHARED(Locks::mutator_lock_);
1129 
1130   // The resolved part. See description below.
GetResolvedPart()1131   const RegType& GetResolvedPart() const {
1132     return resolved_part_;
1133   }
1134   // The unresolved part.
GetUnresolvedTypes()1135   const BitVector& GetUnresolvedTypes() const {
1136     return unresolved_types_;
1137   }
1138 
IsUnresolvedMergedReference()1139   bool IsUnresolvedMergedReference() const OVERRIDE { return true; }
1140 
IsUnresolvedTypes()1141   bool IsUnresolvedTypes() const OVERRIDE { return true; }
1142 
1143   bool IsArrayTypes() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1144   bool IsObjectArrayTypes() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1145 
1146   std::string Dump() const OVERRIDE REQUIRES_SHARED(Locks::mutator_lock_);
1147 
1148  private:
1149   void CheckInvariants() const REQUIRES_SHARED(Locks::mutator_lock_) OVERRIDE;
1150 
1151   const RegTypeCache* const reg_type_cache_;
1152 
1153   // The original implementation of merged types was a binary tree. Collection of the flattened
1154   // types ("leaves") can be expensive, so we store the expanded list now, as two components:
1155   // 1) A resolved component. We use Zero when there is no resolved component, as that will be
1156   //    an identity merge.
1157   // 2) A bitvector of the unresolved reference types. A bitvector was chosen with the assumption
1158   //    that there should not be too many types in flight in practice. (We also bias the index
1159   //    against the index of Zero, which is one of the later default entries in any cache.)
1160   const RegType& resolved_part_;
1161   const BitVector unresolved_types_;
1162 };
1163 
1164 std::ostream& operator<<(std::ostream& os, const RegType& rhs)
1165     REQUIRES_SHARED(Locks::mutator_lock_);
1166 
1167 }  // namespace verifier
1168 }  // namespace art
1169 
1170 #endif  // ART_RUNTIME_VERIFIER_REG_TYPE_H_
1171