blob: 73e131eff5c508fc5380a81a3eeac5910480a23d [file] [log] [blame]
Ian Rogers776ac1f2012-04-13 23:36:36 -07001/*
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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_VERIFIER_REG_TYPE_H_
18#define ART_RUNTIME_VERIFIER_REG_TYPE_H_
Ian Rogers776ac1f2012-04-13 23:36:36 -070019
Ian Rogers776ac1f2012-04-13 23:36:36 -070020#include <stdint.h>
Ian Rogers8e1f4f82014-11-05 11:07:30 -080021#include <limits>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include <set>
23#include <string>
Ian Rogers776ac1f2012-04-13 23:36:36 -070024
Ian Rogers576ca0c2014-06-06 15:58:22 -070025#include "base/macros.h"
Ian Rogers68d8b422014-07-17 11:09:10 -070026#include "base/mutex.h"
Ian Rogers54410912014-09-10 15:33:05 -070027#include "gc_root.h"
Ian Rogers576ca0c2014-06-06 15:58:22 -070028#include "object_callbacks.h"
29#include "primitive.h"
30
Ian Rogers776ac1f2012-04-13 23:36:36 -070031namespace art {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080032namespace mirror {
33class Class;
34} // namespace mirror
Ian Rogers8e1f4f82014-11-05 11:07:30 -080035
Ian Rogers776ac1f2012-04-13 23:36:36 -070036namespace verifier {
37
38class RegTypeCache;
Ian Rogers776ac1f2012-04-13 23:36:36 -070039/*
40 * RegType holds information about the "type" of data held in a register.
41 */
42class RegType {
43 public:
Ian Rogers637c65b2013-05-31 11:46:00 -070044 virtual bool IsUndefined() const { return false; }
45 virtual bool IsConflict() const { return false; }
46 virtual bool IsBoolean() const { return false; }
47 virtual bool IsByte() const { return false; }
48 virtual bool IsChar() const { return false; }
49 virtual bool IsShort() const { return false; }
50 virtual bool IsInteger() const { return false; }
51 virtual bool IsLongLo() const { return false; }
52 virtual bool IsLongHi() const { return false; }
53 virtual bool IsFloat() const { return false; }
54 virtual bool IsDouble() const { return false; }
55 virtual bool IsDoubleLo() const { return false; }
56 virtual bool IsDoubleHi() const { return false; }
57 virtual bool IsUnresolvedReference() const { return false; }
58 virtual bool IsUninitializedReference() const { return false; }
59 virtual bool IsUninitializedThisReference() const { return false; }
60 virtual bool IsUnresolvedAndUninitializedReference() const { return false; }
Ian Rogers7b078e82014-09-10 14:44:24 -070061 virtual bool IsUnresolvedAndUninitializedThisReference() const {
62 return false;
63 }
Ian Rogers637c65b2013-05-31 11:46:00 -070064 virtual bool IsUnresolvedMergedReference() const { return false; }
65 virtual bool IsUnresolvedSuperClass() const { return false; }
66 virtual bool IsReference() const { return false; }
67 virtual bool IsPreciseReference() const { return false; }
68 virtual bool IsPreciseConstant() const { return false; }
69 virtual bool IsPreciseConstantLo() const { return false; }
70 virtual bool IsPreciseConstantHi() const { return false; }
71 virtual bool IsImpreciseConstantLo() const { return false; }
72 virtual bool IsImpreciseConstantHi() const { return false; }
73 virtual bool IsImpreciseConstant() const { return false; }
74 virtual bool IsConstantTypes() const { return false; }
Ian Rogers2bcb4a42012-11-08 10:39:18 -080075 bool IsConstant() const {
Ian Rogers7b078e82014-09-10 14:44:24 -070076 return IsImpreciseConstant() || IsPreciseConstant();
Ian Rogers2bcb4a42012-11-08 10:39:18 -080077 }
Ian Rogers2bcb4a42012-11-08 10:39:18 -080078 bool IsConstantLo() const {
Ian Rogers7b078e82014-09-10 14:44:24 -070079 return IsImpreciseConstantLo() || IsPreciseConstantLo();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080080 }
81 bool IsPrecise() const {
Ian Rogers7b078e82014-09-10 14:44:24 -070082 return IsPreciseConstantLo() || IsPreciseConstant() ||
83 IsPreciseConstantHi();
Ian Rogers2bcb4a42012-11-08 10:39:18 -080084 }
Ian Rogers7b078e82014-09-10 14:44:24 -070085 bool IsLongConstant() const { return IsConstantLo(); }
Ian Rogers2bcb4a42012-11-08 10:39:18 -080086 bool IsConstantHi() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080087 return (IsPreciseConstantHi() || IsImpreciseConstantHi());
Ian Rogers2bcb4a42012-11-08 10:39:18 -080088 }
Ian Rogers7b078e82014-09-10 14:44:24 -070089 bool IsLongConstantHigh() const { return IsConstantHi(); }
Ian Rogers637c65b2013-05-31 11:46:00 -070090 virtual bool IsUninitializedTypes() const { return false; }
Ian Rogers7b078e82014-09-10 14:44:24 -070091 virtual bool IsUnresolvedTypes() const { return false; }
Ian Rogers776ac1f2012-04-13 23:36:36 -070092
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080093 bool IsLowHalf() const {
Ian Rogers7b078e82014-09-10 14:44:24 -070094 return (IsLongLo() || IsDoubleLo() || IsPreciseConstantLo() || IsImpreciseConstantLo());
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080095 }
96 bool IsHighHalf() const {
Ian Rogers7b078e82014-09-10 14:44:24 -070097 return (IsLongHi() || IsDoubleHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080098 }
Ian Rogers7b078e82014-09-10 14:44:24 -070099 bool IsLongOrDoubleTypes() const { return IsLowHalf(); }
Ian Rogers637c65b2013-05-31 11:46:00 -0700100 // Check this is the low half, and that type_h is its matching high-half.
Ian Rogersd8f69b02014-09-10 21:43:52 +0000101 inline bool CheckWidePair(const RegType& type_h) const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800102 if (IsLowHalf()) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700103 return ((IsImpreciseConstantLo() && type_h.IsPreciseConstantHi()) ||
Sameer Abu Asal998be612013-03-31 18:40:48 -0700104 (IsImpreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
Ian Rogers7b078e82014-09-10 14:44:24 -0700105 (IsPreciseConstantLo() && type_h.IsPreciseConstantHi()) ||
106 (IsPreciseConstantLo() && type_h.IsImpreciseConstantHi()) ||
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800107 (IsDoubleLo() && type_h.IsDoubleHi()) ||
108 (IsLongLo() && type_h.IsLongHi()));
109 }
110 return false;
111 }
Ian Rogers637c65b2013-05-31 11:46:00 -0700112 // The high half that corresponds to this low half
Ian Rogers7b078e82014-09-10 14:44:24 -0700113 const RegType& HighHalf(RegTypeCache* cache) const
114 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700115
Ian Rogers7b078e82014-09-10 14:44:24 -0700116 bool IsConstantBoolean() const;
117 virtual bool IsConstantChar() const { return false; }
118 virtual bool IsConstantByte() const { return false; }
119 virtual bool IsConstantShort() const { return false; }
120 virtual bool IsOne() const { return false; }
121 virtual bool IsZero() const { return false; }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700122 bool IsReferenceTypes() const {
jeffhao182e90b2012-05-01 18:27:09 -0700123 return IsNonZeroReferenceTypes() || IsZero();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700124 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700125 virtual bool IsNonZeroReferenceTypes() const { return false; }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700126 bool IsCategory1Types() const {
Ian Rogers7b078e82014-09-10 14:44:24 -0700127 return IsChar() || IsInteger() || IsFloat() || IsConstant() || IsByte() ||
128 IsShort() || IsBoolean();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700129 }
130 bool IsCategory2Types() const {
131 return IsLowHalf(); // Don't expect explicit testing of high halves
132 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700133 bool IsBooleanTypes() const { return IsBoolean() || IsConstantBoolean(); }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800134 bool IsByteTypes() const {
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700135 return IsConstantByte() || IsByte() || IsBoolean();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800136 }
137 bool IsShortTypes() const {
138 return IsShort() || IsByte() || IsBoolean() || IsConstantShort();
139 }
140 bool IsCharTypes() const {
141 return IsChar() || IsBooleanTypes() || IsConstantChar();
142 }
143 bool IsIntegralTypes() const {
Ian Rogers7b078e82014-09-10 14:44:24 -0700144 return IsInteger() || IsConstant() || IsByte() || IsShort() || IsChar() ||
145 IsBoolean();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800146 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700147 // Give the constant value encoded, but this shouldn't be called in the
148 // general case.
149 bool IsArrayIndexTypes() const { return IsIntegralTypes(); }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700150 // Float type may be derived from any constant type
Ian Rogers7b078e82014-09-10 14:44:24 -0700151 bool IsFloatTypes() const { return IsFloat() || IsConstant(); }
152 bool IsLongTypes() const { return IsLongLo() || IsLongConstant(); }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700153 bool IsLongHighTypes() const {
Ian Rogers7b078e82014-09-10 14:44:24 -0700154 return (IsLongHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
Ian Rogers776ac1f2012-04-13 23:36:36 -0700155 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700156 bool IsDoubleTypes() const { return IsDoubleLo() || IsLongConstant(); }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700157 bool IsDoubleHighTypes() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800158 return (IsDoubleHi() || IsPreciseConstantHi() || IsImpreciseConstantHi());
Ian Rogers776ac1f2012-04-13 23:36:36 -0700159 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700160 virtual bool IsLong() const { return false; }
161 bool HasClass() const {
162 bool result = !klass_.IsNull();
163 DCHECK_EQ(result, HasClassVirtual());
164 return result;
Ian Rogers776ac1f2012-04-13 23:36:36 -0700165 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700166 virtual bool HasClassVirtual() const { return false; }
Ian Rogersd8f69b02014-09-10 21:43:52 +0000167 bool IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
168 bool IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
169 bool IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstrom02c8cc62013-07-18 15:54:44 -0700170 Primitive::Type GetPrimitiveType() const;
Ian Rogers7b078e82014-09-10 14:44:24 -0700171 bool IsJavaLangObjectArray() const
172 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogersd8f69b02014-09-10 21:43:52 +0000173 bool IsInstantiableTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700174 const std::string& GetDescriptor() const {
Ian Rogers7b078e82014-09-10 14:44:24 -0700175 DCHECK(HasClass() ||
176 (IsUnresolvedTypes() && !IsUnresolvedMergedReference() &&
177 !IsUnresolvedSuperClass()));
Elliott Hughes80537bb2013-01-04 16:37:26 -0800178 return descriptor_;
Ian Rogers776ac1f2012-04-13 23:36:36 -0700179 }
Ian Rogersd8f69b02014-09-10 21:43:52 +0000180 mirror::Class* GetClass() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800181 DCHECK(!IsUnresolvedReference());
Ian Rogers54410912014-09-10 15:33:05 -0700182 DCHECK(!klass_.IsNull()) << Dump();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800183 DCHECK(HasClass());
Ian Rogers54410912014-09-10 15:33:05 -0700184 return klass_.Read();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800185 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700186 uint16_t GetId() const { return cache_id_; }
Ian Rogersd8f69b02014-09-10 21:43:52 +0000187 const RegType& GetSuperClass(RegTypeCache* cache) const
Ian Rogers637c65b2013-05-31 11:46:00 -0700188 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
189
Ian Rogers7b078e82014-09-10 14:44:24 -0700190 virtual std::string Dump() const
191 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0;
Ian Rogers637c65b2013-05-31 11:46:00 -0700192
193 // Can this type access other?
Ian Rogers7b078e82014-09-10 14:44:24 -0700194 bool CanAccess(const RegType& other) const
195 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700196
197 // Can this type access a member with the given properties?
Ian Rogersd8f69b02014-09-10 21:43:52 +0000198 bool CanAccessMember(mirror::Class* klass, uint32_t access_flags) const
Ian Rogers7b078e82014-09-10 14:44:24 -0700199 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700200
201 // Can this type be assigned by src?
Ian Rogers7b078e82014-09-10 14:44:24 -0700202 // Note: Object and interface types may always be assigned to one another, see
203 // comment on
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700204 // ClassJoin.
Ian Rogers7b078e82014-09-10 14:44:24 -0700205 bool IsAssignableFrom(const RegType& src) const
206 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700207
Ian Rogers7b078e82014-09-10 14:44:24 -0700208 // Can this type be assigned by src? Variant of IsAssignableFrom that doesn't
209 // allow assignment to
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700210 // an interface from an Object.
Ian Rogersd8f69b02014-09-10 21:43:52 +0000211 bool IsStrictlyAssignableFrom(const RegType& src) const
212 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700213
214 // Are these RegTypes the same?
Ian Rogers7b078e82014-09-10 14:44:24 -0700215 bool Equals(const RegType& other) const { return GetId() == other.GetId(); }
Ian Rogers637c65b2013-05-31 11:46:00 -0700216
Ian Rogers7b078e82014-09-10 14:44:24 -0700217 // Compute the merge of this register from one edge (path) with incoming_type
218 // from another.
219 const RegType& Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
Ian Rogers637c65b2013-05-31 11:46:00 -0700220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
221
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700222 /*
Ian Rogers7b078e82014-09-10 14:44:24 -0700223 * A basic Join operation on classes. For a pair of types S and T the Join,
224 *written S v T = J, is
225 * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is
226 *J is the parent of
227 * S and T such that there isn't a parent of both S and T that isn't also the
228 *parent of J (ie J
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700229 * is the deepest (lowest upper bound) parent of S and T).
230 *
Ian Rogers7b078e82014-09-10 14:44:24 -0700231 * This operation applies for regular classes and arrays, however, for
232 *interface types there
233 * needn't be a partial ordering on the types. We could solve the problem of a
234 *lack of a partial
235 * order by introducing sets of types, however, the only operation permissible
236 *on an interface is
237 * invoke-interface. In the tradition of Java verifiers [1] we defer the
238 *verification of interface
239 * types until an invoke-interface call on the interface typed reference at
240 *runtime and allow
241 * the perversion of Object being assignable to an interface type (note,
242 *however, that we don't
243 * allow assignment of Object or Interface to any concrete class and are
244 *therefore type safe).
Ian Rogers16e3d2c2013-06-07 12:57:00 -0700245 *
246 * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
247 */
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800248 static mirror::Class* ClassJoin(mirror::Class* s, mirror::Class* t)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700249 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700250
251 virtual ~RegType() {}
252
Mathieu Chartier12d625f2015-03-13 11:33:37 -0700253 void VisitRoots(RootCallback* callback, void* arg, const RootInfo& root_info) const
Ian Rogers7b078e82014-09-10 14:44:24 -0700254 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800255
Ian Rogers637c65b2013-05-31 11:46:00 -0700256 protected:
Ian Rogers7b078e82014-09-10 14:44:24 -0700257 RegType(mirror::Class* klass, const std::string& descriptor,
258 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogersd8f69b02014-09-10 21:43:52 +0000259 : descriptor_(descriptor), klass_(klass), cache_id_(cache_id) {
Ian Rogers637c65b2013-05-31 11:46:00 -0700260 if (kIsDebugBuild) {
261 CheckInvariants();
262 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800263 }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700264
Ian Rogers637c65b2013-05-31 11:46:00 -0700265 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
266
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800267 const std::string descriptor_;
Ian Rogers7b078e82014-09-10 14:44:24 -0700268 mutable GcRoot<mirror::Class>
269 klass_; // Non-const only due to moving classes.
Ian Rogers776ac1f2012-04-13 23:36:36 -0700270 const uint16_t cache_id_;
271
Ian Rogers637c65b2013-05-31 11:46:00 -0700272 friend class RegTypeCache;
273
Mathieu Chartier02e25112013-08-14 16:14:24 -0700274 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700275 static bool AssignableFrom(const RegType& lhs, const RegType& rhs, bool strict)
276 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
277
Ian Rogers776ac1f2012-04-13 23:36:36 -0700278 DISALLOW_COPY_AND_ASSIGN(RegType);
279};
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800280
Ian Rogers637c65b2013-05-31 11:46:00 -0700281// Bottom type.
Ian Rogers7b078e82014-09-10 14:44:24 -0700282class ConflictType FINAL : public RegType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800283 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700284 bool IsConflict() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700285
Ian Rogers7b078e82014-09-10 14:44:24 -0700286 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700287
288 // Get the singleton Conflict instance.
Ian Rogers7b078e82014-09-10 14:44:24 -0700289 static const ConflictType* GetInstance() PURE;
Ian Rogers637c65b2013-05-31 11:46:00 -0700290
291 // Create the singleton instance.
Ian Rogers7b078e82014-09-10 14:44:24 -0700292 static const ConflictType* CreateInstance(mirror::Class* klass,
293 const std::string& descriptor,
294 uint16_t cache_id)
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700295 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700296
297 // Destroy the singleton instance.
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800298 static void Destroy();
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -0700299
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800300 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700301 ConflictType(mirror::Class* klass, const std::string& descriptor,
302 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
303 : RegType(klass, descriptor, cache_id) {}
Ian Rogers637c65b2013-05-31 11:46:00 -0700304
Ian Rogers7b078e82014-09-10 14:44:24 -0700305 static const ConflictType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800306};
307
Ian Rogers7b078e82014-09-10 14:44:24 -0700308// A variant of the bottom type used to specify an undefined value in the
309// incoming registers.
Ian Rogers637c65b2013-05-31 11:46:00 -0700310// Merging with UndefinedType yields ConflictType which is the true bottom.
Ian Rogers7b078e82014-09-10 14:44:24 -0700311class UndefinedType FINAL : public RegType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800312 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700313 bool IsUndefined() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700314
Ian Rogers7b078e82014-09-10 14:44:24 -0700315 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700316
317 // Get the singleton Undefined instance.
Ian Rogers7b078e82014-09-10 14:44:24 -0700318 static const UndefinedType* GetInstance() PURE;
Ian Rogers637c65b2013-05-31 11:46:00 -0700319
320 // Create the singleton instance.
Ian Rogers7b078e82014-09-10 14:44:24 -0700321 static const UndefinedType* CreateInstance(mirror::Class* klass,
322 const std::string& descriptor,
323 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800324 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700325
326 // Destroy the singleton instance.
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800327 static void Destroy();
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -0700328
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800329 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700330 UndefinedType(mirror::Class* klass, const std::string& descriptor,
331 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
332 : RegType(klass, descriptor, cache_id) {}
Ian Rogers637c65b2013-05-31 11:46:00 -0700333
Ian Rogers7b078e82014-09-10 14:44:24 -0700334 static const UndefinedType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800335};
336
Ian Rogers637c65b2013-05-31 11:46:00 -0700337class PrimitiveType : public RegType {
338 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700339 PrimitiveType(mirror::Class* klass, const std::string& descriptor,
340 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Logan Chien10f0ca22014-09-23 23:01:47 +0800341
342 bool HasClassVirtual() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700343};
344
345class Cat1Type : public PrimitiveType {
346 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700347 Cat1Type(mirror::Class* klass, const std::string& descriptor,
348 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700349};
350
351class IntegerType : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800352 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700353 bool IsInteger() const OVERRIDE { return true; }
354 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
355 static const IntegerType* CreateInstance(mirror::Class* klass,
356 const std::string& descriptor,
357 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800358 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700359 static const IntegerType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800360 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700361
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800362 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700363 IntegerType(mirror::Class* klass, const std::string& descriptor,
364 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
365 : Cat1Type(klass, descriptor, cache_id) {}
366 static const IntegerType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800367};
368
Ian Rogers7b078e82014-09-10 14:44:24 -0700369class BooleanType FINAL : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800370 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700371 bool IsBoolean() const OVERRIDE { return true; }
372 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
373 static const BooleanType* CreateInstance(mirror::Class* klass,
374 const std::string& descriptor,
375 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800376 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700377 static const BooleanType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800378 static void Destroy();
Ian Rogers637c65b2013-05-31 11:46:00 -0700379
Ian Rogers7b078e82014-09-10 14:44:24 -0700380 private:
381 BooleanType(mirror::Class* klass, const std::string& descriptor,
382 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
383 : Cat1Type(klass, descriptor, cache_id) {}
384
385 static const BooleanType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800386};
387
Ian Rogers7b078e82014-09-10 14:44:24 -0700388class ByteType FINAL : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800389 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700390 bool IsByte() const OVERRIDE { return true; }
391 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
392 static const ByteType* CreateInstance(mirror::Class* klass,
393 const std::string& descriptor,
394 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800395 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700396 static const ByteType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800397 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700398
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800399 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700400 ByteType(mirror::Class* klass, const std::string& descriptor,
401 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
402 : Cat1Type(klass, descriptor, cache_id) {}
403 static const ByteType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800404};
405
Ian Rogers7b078e82014-09-10 14:44:24 -0700406class ShortType FINAL : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800407 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700408 bool IsShort() const OVERRIDE { return true; }
409 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
410 static const ShortType* CreateInstance(mirror::Class* klass,
411 const std::string& descriptor,
412 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800413 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700414 static const ShortType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800415 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700416
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800417 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700418 ShortType(mirror::Class* klass, const std::string& descriptor,
419 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
420 : Cat1Type(klass, descriptor, cache_id) {}
421 static const ShortType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800422};
423
Ian Rogers7b078e82014-09-10 14:44:24 -0700424class CharType FINAL : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800425 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700426 bool IsChar() const OVERRIDE { return true; }
427 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
428 static const CharType* CreateInstance(mirror::Class* klass,
429 const std::string& descriptor,
430 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800431 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700432 static const CharType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800433 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700434
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800435 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700436 CharType(mirror::Class* klass, const std::string& descriptor,
437 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
438 : Cat1Type(klass, descriptor, cache_id) {}
439 static const CharType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800440};
441
Ian Rogers7b078e82014-09-10 14:44:24 -0700442class FloatType FINAL : public Cat1Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800443 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700444 bool IsFloat() const OVERRIDE { return true; }
445 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
446 static const FloatType* CreateInstance(mirror::Class* klass,
447 const std::string& descriptor,
448 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800449 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700450 static const FloatType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800451 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700452
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800453 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700454 FloatType(mirror::Class* klass, const std::string& descriptor,
455 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
456 : Cat1Type(klass, descriptor, cache_id) {}
457 static const FloatType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800458};
459
Ian Rogers637c65b2013-05-31 11:46:00 -0700460class Cat2Type : public PrimitiveType {
461 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700462 Cat2Type(mirror::Class* klass, const std::string& descriptor,
463 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700464};
465
Ian Rogers7b078e82014-09-10 14:44:24 -0700466class LongLoType FINAL : public Cat2Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800467 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700468 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
469 bool IsLongLo() const OVERRIDE { return true; }
470 bool IsLong() const OVERRIDE { return true; }
471 static const LongLoType* CreateInstance(mirror::Class* klass,
472 const std::string& descriptor,
473 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800474 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700475 static const LongLoType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800476 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700477
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800478 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700479 LongLoType(mirror::Class* klass, const std::string& descriptor,
480 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
481 : Cat2Type(klass, descriptor, cache_id) {}
482 static const LongLoType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800483};
484
Ian Rogers7b078e82014-09-10 14:44:24 -0700485class LongHiType FINAL : public Cat2Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800486 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700487 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
488 bool IsLongHi() const OVERRIDE { return true; }
489 static const LongHiType* CreateInstance(mirror::Class* klass,
490 const std::string& descriptor,
491 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800492 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700493 static const LongHiType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800494 static void Destroy();
Ian Rogers7b078e82014-09-10 14:44:24 -0700495
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800496 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700497 LongHiType(mirror::Class* klass, const std::string& descriptor,
498 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
499 : Cat2Type(klass, descriptor, cache_id) {}
500 static const LongHiType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800501};
502
Ian Rogers7b078e82014-09-10 14:44:24 -0700503class DoubleLoType FINAL : public Cat2Type {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800504 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700505 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
506 bool IsDoubleLo() const OVERRIDE { return true; }
507 bool IsDouble() const OVERRIDE { return true; }
508 static const DoubleLoType* CreateInstance(mirror::Class* klass,
509 const std::string& descriptor,
510 uint16_t cache_id)
511 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
512 static const DoubleLoType* GetInstance() PURE;
513 static void Destroy();
514
515 private:
516 DoubleLoType(mirror::Class* klass, const std::string& descriptor,
517 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
518 : Cat2Type(klass, descriptor, cache_id) {}
519 static const DoubleLoType* instance_;
520};
521
522class DoubleHiType FINAL : public Cat2Type {
523 public:
524 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
525 virtual bool IsDoubleHi() const OVERRIDE { return true; }
526 static const DoubleHiType* CreateInstance(mirror::Class* klass,
527 const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800528 uint16_t cache_id)
529 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers7b078e82014-09-10 14:44:24 -0700530 static const DoubleHiType* GetInstance() PURE;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800531 static void Destroy();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800532
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800533 private:
Ian Rogers7b078e82014-09-10 14:44:24 -0700534 DoubleHiType(mirror::Class* klass, const std::string& descriptor,
535 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
536 : Cat2Type(klass, descriptor, cache_id) {}
537 static const DoubleHiType* instance_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800538};
539
540class ConstantType : public RegType {
541 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700542 ConstantType(uint32_t constant, uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
543 : RegType(nullptr, "", cache_id), constant_(constant) {
544 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800545
Ian Rogers7b078e82014-09-10 14:44:24 -0700546
547 // If this is a 32-bit constant, what is the value? This value may be
548 // imprecise in which case
549 // the value represents part of the integer range of values that may be held
550 // in the register.
Ian Rogersfc0e94b2013-09-23 23:51:32 -0700551 int32_t ConstantValue() const {
552 DCHECK(IsConstantTypes());
553 return constant_;
554 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800555
Ian Rogers7b078e82014-09-10 14:44:24 -0700556 int32_t ConstantValueLo() const {
557 DCHECK(IsConstantLo());
558 return constant_;
559 }
560
561 int32_t ConstantValueHi() const {
562 if (IsConstantHi() || IsPreciseConstantHi() || IsImpreciseConstantHi()) {
563 return constant_;
564 } else {
565 DCHECK(false);
566 return 0;
567 }
568 }
569
570 bool IsZero() const OVERRIDE {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800571 return IsPreciseConstant() && ConstantValue() == 0;
572 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700573 bool IsOne() const OVERRIDE {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800574 return IsPreciseConstant() && ConstantValue() == 1;
575 }
576
Ian Rogers7b078e82014-09-10 14:44:24 -0700577 bool IsConstantChar() const OVERRIDE {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800578 return IsConstant() && ConstantValue() >= 0 &&
Ian Rogers8e1f4f82014-11-05 11:07:30 -0800579 ConstantValue() <= std::numeric_limits<uint16_t>::max();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800580 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700581 bool IsConstantByte() const OVERRIDE {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800582 return IsConstant() &&
Ian Rogers8e1f4f82014-11-05 11:07:30 -0800583 ConstantValue() >= std::numeric_limits<int8_t>::min() &&
584 ConstantValue() <= std::numeric_limits<int8_t>::max();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800585 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700586 bool IsConstantShort() const OVERRIDE {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800587 return IsConstant() &&
Ian Rogers8e1f4f82014-11-05 11:07:30 -0800588 ConstantValue() >= std::numeric_limits<int16_t>::min() &&
589 ConstantValue() <= std::numeric_limits<int16_t>::max();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800590 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700591 virtual bool IsConstantTypes() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700592
593 private:
594 const uint32_t constant_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800595};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700596
Ian Rogers7b078e82014-09-10 14:44:24 -0700597class PreciseConstType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800598 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700599 PreciseConstType(uint32_t constant, uint16_t cache_id)
600 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
601 : ConstantType(constant, cache_id) {}
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800602
Ian Rogers7b078e82014-09-10 14:44:24 -0700603 bool IsPreciseConstant() const OVERRIDE { return true; }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800604
Ian Rogers7b078e82014-09-10 14:44:24 -0700605 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800606};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700607
Ian Rogers7b078e82014-09-10 14:44:24 -0700608class PreciseConstLoType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800609 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700610 PreciseConstLoType(uint32_t constant, uint16_t cache_id)
611 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
612 : ConstantType(constant, cache_id) {}
613 bool IsPreciseConstantLo() const OVERRIDE { return true; }
614 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800615};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700616
Ian Rogers7b078e82014-09-10 14:44:24 -0700617class PreciseConstHiType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800618 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700619 PreciseConstHiType(uint32_t constant, uint16_t cache_id)
620 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
621 : ConstantType(constant, cache_id) {}
622 bool IsPreciseConstantHi() const OVERRIDE { return true; }
623 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800624};
625
Ian Rogers7b078e82014-09-10 14:44:24 -0700626class ImpreciseConstType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800627 public:
628 ImpreciseConstType(uint32_t constat, uint16_t cache_id)
Ian Rogers7b078e82014-09-10 14:44:24 -0700629 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
630 : ConstantType(constat, cache_id) {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800631 }
Ian Rogers7b078e82014-09-10 14:44:24 -0700632 bool IsImpreciseConstant() const OVERRIDE { return true; }
633 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800634};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700635
Ian Rogers7b078e82014-09-10 14:44:24 -0700636class ImpreciseConstLoType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800637 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700638 ImpreciseConstLoType(uint32_t constant, uint16_t cache_id)
639 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
640 : ConstantType(constant, cache_id) {}
641 bool IsImpreciseConstantLo() const OVERRIDE { return true; }
642 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800643};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700644
Ian Rogers7b078e82014-09-10 14:44:24 -0700645class ImpreciseConstHiType FINAL : public ConstantType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800646 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700647 ImpreciseConstHiType(uint32_t constant, uint16_t cache_id)
648 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
649 : ConstantType(constant, cache_id) {}
650 bool IsImpreciseConstantHi() const OVERRIDE { return true; }
651 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800652};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700653
Ian Rogers7b078e82014-09-10 14:44:24 -0700654// Common parent of all uninitialized types. Uninitialized types are created by
655// "new" dex
Ian Rogers637c65b2013-05-31 11:46:00 -0700656// instructions and must be passed to a constructor.
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800657class UninitializedType : public RegType {
658 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700659 UninitializedType(mirror::Class* klass, const std::string& descriptor,
660 uint32_t allocation_pc, uint16_t cache_id)
661 : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {}
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800662
Ian Rogers7b078e82014-09-10 14:44:24 -0700663 bool IsUninitializedTypes() const OVERRIDE;
664 bool IsNonZeroReferenceTypes() const OVERRIDE;
Ian Rogers637c65b2013-05-31 11:46:00 -0700665
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800666 uint32_t GetAllocationPc() const {
667 DCHECK(IsUninitializedTypes());
668 return allocation_pc_;
669 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800670
671 private:
672 const uint32_t allocation_pc_;
673};
674
Ian Rogers637c65b2013-05-31 11:46:00 -0700675// Similar to ReferenceType but not yet having been passed to a constructor.
Ian Rogers7b078e82014-09-10 14:44:24 -0700676class UninitializedReferenceType FINAL : public UninitializedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800677 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700678 UninitializedReferenceType(mirror::Class* klass,
679 const std::string& descriptor,
Ian Rogers637c65b2013-05-31 11:46:00 -0700680 uint32_t allocation_pc, uint16_t cache_id)
681 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers7b078e82014-09-10 14:44:24 -0700682 : UninitializedType(klass, descriptor, allocation_pc, cache_id) {}
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800683
Ian Rogers7b078e82014-09-10 14:44:24 -0700684 bool IsUninitializedReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700685
Ian Rogers7b078e82014-09-10 14:44:24 -0700686 bool HasClassVirtual() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700687
Ian Rogers7b078e82014-09-10 14:44:24 -0700688 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800689};
690
Ian Rogers7b078e82014-09-10 14:44:24 -0700691// Similar to UnresolvedReferenceType but not yet having been passed to a
692// constructor.
693class UnresolvedUninitializedRefType FINAL : public UninitializedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800694 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700695 UnresolvedUninitializedRefType(const std::string& descriptor,
696 uint32_t allocation_pc, uint16_t cache_id)
Ian Rogers637c65b2013-05-31 11:46:00 -0700697 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
698 : UninitializedType(NULL, descriptor, allocation_pc, cache_id) {
699 if (kIsDebugBuild) {
700 CheckInvariants();
701 }
702 }
703
Ian Rogers7b078e82014-09-10 14:44:24 -0700704 bool IsUnresolvedAndUninitializedReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700705
Ian Rogers7b078e82014-09-10 14:44:24 -0700706 bool IsUnresolvedTypes() const OVERRIDE { return true; }
707
708 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
709
Ian Rogers637c65b2013-05-31 11:46:00 -0700710 private:
711 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800712};
713
Ian Rogers7b078e82014-09-10 14:44:24 -0700714// Similar to UninitializedReferenceType but special case for the this argument
715// of a constructor.
716class UninitializedThisReferenceType FINAL : public UninitializedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800717 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700718 UninitializedThisReferenceType(mirror::Class* klass,
719 const std::string& descriptor,
Ian Rogers637c65b2013-05-31 11:46:00 -0700720 uint16_t cache_id)
721 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
722 : UninitializedType(klass, descriptor, 0, cache_id) {
723 if (kIsDebugBuild) {
724 CheckInvariants();
725 }
726 }
727
Ian Rogers7b078e82014-09-10 14:44:24 -0700728 virtual bool IsUninitializedThisReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700729
Ian Rogers7b078e82014-09-10 14:44:24 -0700730 bool HasClassVirtual() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700731
Ian Rogers7b078e82014-09-10 14:44:24 -0700732 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700733
734 private:
735 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800736};
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700737
Ian Rogers7b078e82014-09-10 14:44:24 -0700738class UnresolvedUninitializedThisRefType FINAL : public UninitializedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800739 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700740 UnresolvedUninitializedThisRefType(const std::string& descriptor,
741 uint16_t cache_id)
Ian Rogers637c65b2013-05-31 11:46:00 -0700742 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
743 : UninitializedType(NULL, descriptor, 0, cache_id) {
744 if (kIsDebugBuild) {
745 CheckInvariants();
746 }
747 }
748
Ian Rogers7b078e82014-09-10 14:44:24 -0700749 bool IsUnresolvedAndUninitializedThisReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700750
Ian Rogers7b078e82014-09-10 14:44:24 -0700751 bool IsUnresolvedTypes() const OVERRIDE { return true; }
752
753 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
754
Ian Rogers637c65b2013-05-31 11:46:00 -0700755 private:
756 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800757};
758
Ian Rogers7b078e82014-09-10 14:44:24 -0700759// A type of register holding a reference to an Object of type GetClass or a
760// sub-class.
761class ReferenceType FINAL : public RegType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800762 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700763 ReferenceType(mirror::Class* klass, const std::string& descriptor,
764 uint16_t cache_id) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
765 : RegType(klass, descriptor, cache_id) {}
Ian Rogers637c65b2013-05-31 11:46:00 -0700766
Ian Rogers7b078e82014-09-10 14:44:24 -0700767 bool IsReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700768
Ian Rogers7b078e82014-09-10 14:44:24 -0700769 bool IsNonZeroReferenceTypes() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700770
Ian Rogers7b078e82014-09-10 14:44:24 -0700771 bool HasClassVirtual() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700772
Ian Rogers7b078e82014-09-10 14:44:24 -0700773 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800774};
775
Ian Rogers7b078e82014-09-10 14:44:24 -0700776// A type of register holding a reference to an Object of type GetClass and only
777// an object of that
Ian Rogers637c65b2013-05-31 11:46:00 -0700778// type.
Ian Rogers7b078e82014-09-10 14:44:24 -0700779class PreciseReferenceType FINAL : public RegType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800780 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700781 PreciseReferenceType(mirror::Class* klass, const std::string& descriptor,
782 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800783 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700784
Ian Rogers7b078e82014-09-10 14:44:24 -0700785 bool IsPreciseReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700786
Ian Rogers7b078e82014-09-10 14:44:24 -0700787 bool IsNonZeroReferenceTypes() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700788
Ian Rogers7b078e82014-09-10 14:44:24 -0700789 bool HasClassVirtual() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700790
Ian Rogers7b078e82014-09-10 14:44:24 -0700791 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800792};
793
Ian Rogers637c65b2013-05-31 11:46:00 -0700794// Common parent of unresolved types.
795class UnresolvedType : public RegType {
796 public:
797 UnresolvedType(const std::string& descriptor, uint16_t cache_id)
Ian Rogers7b078e82014-09-10 14:44:24 -0700798 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
799 : RegType(NULL, descriptor, cache_id) {}
Ian Rogers637c65b2013-05-31 11:46:00 -0700800
Ian Rogers7b078e82014-09-10 14:44:24 -0700801 bool IsNonZeroReferenceTypes() const OVERRIDE;
Ian Rogers637c65b2013-05-31 11:46:00 -0700802};
803
Ian Rogers7b078e82014-09-10 14:44:24 -0700804// Similar to ReferenceType except the Class couldn't be loaded. Assignability
805// and other tests made
Ian Rogers637c65b2013-05-31 11:46:00 -0700806// of this type must be conservative.
Ian Rogers7b078e82014-09-10 14:44:24 -0700807class UnresolvedReferenceType FINAL : public UnresolvedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800808 public:
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700809 UnresolvedReferenceType(const std::string& descriptor, uint16_t cache_id)
Ian Rogers7b078e82014-09-10 14:44:24 -0700810 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
811 : UnresolvedType(descriptor, cache_id) {
Ian Rogers637c65b2013-05-31 11:46:00 -0700812 if (kIsDebugBuild) {
813 CheckInvariants();
814 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800815 }
Ian Rogers637c65b2013-05-31 11:46:00 -0700816
Ian Rogers7b078e82014-09-10 14:44:24 -0700817 bool IsUnresolvedReference() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700818
Ian Rogers7b078e82014-09-10 14:44:24 -0700819 bool IsUnresolvedTypes() const OVERRIDE { return true; }
820
821 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
822
Ian Rogers637c65b2013-05-31 11:46:00 -0700823 private:
824 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800825};
826
Ian Rogers637c65b2013-05-31 11:46:00 -0700827// Type representing the super-class of an unresolved type.
Ian Rogers7b078e82014-09-10 14:44:24 -0700828class UnresolvedSuperClass FINAL : public UnresolvedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800829 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700830 UnresolvedSuperClass(uint16_t child_id, RegTypeCache* reg_type_cache,
831 uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800832 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers7b078e82014-09-10 14:44:24 -0700833 : UnresolvedType("", cache_id),
834 unresolved_child_id_(child_id),
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800835 reg_type_cache_(reg_type_cache) {
Ian Rogers637c65b2013-05-31 11:46:00 -0700836 if (kIsDebugBuild) {
837 CheckInvariants();
838 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800839 }
Ian Rogers637c65b2013-05-31 11:46:00 -0700840
Ian Rogers7b078e82014-09-10 14:44:24 -0700841 bool IsUnresolvedSuperClass() const OVERRIDE { return true; }
842
843 bool IsUnresolvedTypes() const OVERRIDE { return true; }
Ian Rogers637c65b2013-05-31 11:46:00 -0700844
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800845 uint16_t GetUnresolvedSuperClassChildId() const {
846 DCHECK(IsUnresolvedSuperClass());
847 return static_cast<uint16_t>(unresolved_child_id_ & 0xFFFF);
848 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800849
Ian Rogers7b078e82014-09-10 14:44:24 -0700850 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -0700851
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800852 private:
Ian Rogers637c65b2013-05-31 11:46:00 -0700853 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
854
Sameer Abu Asal2c6de222013-05-02 17:38:59 -0700855 const uint16_t unresolved_child_id_;
856 const RegTypeCache* const reg_type_cache_;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800857};
858
Ian Rogers7b078e82014-09-10 14:44:24 -0700859// A merge of two unresolved types. If the types were resolved this may be
860// Conflict or another
Ian Rogers637c65b2013-05-31 11:46:00 -0700861// known ReferenceType.
Ian Rogers7b078e82014-09-10 14:44:24 -0700862class UnresolvedMergedType FINAL : public UnresolvedType {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800863 public:
Ian Rogers7b078e82014-09-10 14:44:24 -0700864 UnresolvedMergedType(uint16_t left_id, uint16_t right_id,
865 const RegTypeCache* reg_type_cache, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800866 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
Ian Rogers7b078e82014-09-10 14:44:24 -0700867 : UnresolvedType("", cache_id),
868 reg_type_cache_(reg_type_cache),
869 merged_types_(left_id, right_id) {
Ian Rogers637c65b2013-05-31 11:46:00 -0700870 if (kIsDebugBuild) {
871 CheckInvariants();
872 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800873 }
Ian Rogers637c65b2013-05-31 11:46:00 -0700874
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800875 // The top of a tree of merged types.
876 std::pair<uint16_t, uint16_t> GetTopMergedTypes() const {
877 DCHECK(IsUnresolvedMergedReference());
878 return merged_types_;
879 }
Ian Rogers637c65b2013-05-31 11:46:00 -0700880
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800881 // The complete set of merged types.
882 std::set<uint16_t> GetMergedTypes() const;
Ian Rogers637c65b2013-05-31 11:46:00 -0700883
Ian Rogers7b078e82014-09-10 14:44:24 -0700884 bool IsUnresolvedMergedReference() const OVERRIDE { return true; }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800885
Ian Rogers7b078e82014-09-10 14:44:24 -0700886 bool IsUnresolvedTypes() const OVERRIDE { return true; }
887
888 std::string Dump() const OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Brian Carlstrom0cd7ec22013-07-17 23:40:20 -0700889
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800890 private:
Ian Rogers637c65b2013-05-31 11:46:00 -0700891 void CheckInvariants() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
892
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800893 const RegTypeCache* const reg_type_cache_;
894 const std::pair<uint16_t, uint16_t> merged_types_;
895};
896
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800897std::ostream& operator<<(std::ostream& os, const RegType& rhs)
898 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers637c65b2013-05-31 11:46:00 -0700899
Ian Rogers776ac1f2012-04-13 23:36:36 -0700900} // namespace verifier
901} // namespace art
902
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700903#endif // ART_RUNTIME_VERIFIER_REG_TYPE_H_