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_CACHE_INL_H_
18 #define ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_
19 
20 #include "class_linker.h"
21 #include "class_root-inl.h"
22 #include "mirror/class-inl.h"
23 #include "mirror/method_handle_impl.h"
24 #include "mirror/method_type.h"
25 #include "mirror/string.h"
26 #include "mirror/throwable.h"
27 #include "reg_type.h"
28 #include "reg_type_cache.h"
29 
30 namespace art {
31 namespace verifier {
32 
GetFromId(uint16_t id)33 inline const art::verifier::RegType& RegTypeCache::GetFromId(uint16_t id) const {
34   DCHECK_LT(id, entries_.size());
35   const RegType* result = entries_[id];
36   DCHECK(result != nullptr);
37   return *result;
38 }
39 
FromCat1Const(int32_t value,bool precise)40 inline const ConstantType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
41   // We only expect 0 to be a precise constant.
42   DCHECK(value != 0 || precise);
43   if (precise && (value >= kMinSmallConstant) && (value <= kMaxSmallConstant)) {
44     return *small_precise_constants_[value - kMinSmallConstant];
45   }
46   return FromCat1NonSmallConstant(value, precise);
47 }
48 
Boolean()49 inline const BooleanType& RegTypeCache::Boolean() {
50   return *BooleanType::GetInstance();
51 }
Byte()52 inline const ByteType& RegTypeCache::Byte() {
53   return *ByteType::GetInstance();
54 }
Char()55 inline const CharType& RegTypeCache::Char() {
56   return *CharType::GetInstance();
57 }
Short()58 inline const ShortType& RegTypeCache::Short() {
59   return *ShortType::GetInstance();
60 }
Integer()61 inline const IntegerType& RegTypeCache::Integer() {
62   return *IntegerType::GetInstance();
63 }
Float()64 inline const FloatType& RegTypeCache::Float() {
65   return *FloatType::GetInstance();
66 }
LongLo()67 inline const LongLoType& RegTypeCache::LongLo() {
68   return *LongLoType::GetInstance();
69 }
LongHi()70 inline const LongHiType& RegTypeCache::LongHi() {
71   return *LongHiType::GetInstance();
72 }
DoubleLo()73 inline const DoubleLoType& RegTypeCache::DoubleLo() {
74   return *DoubleLoType::GetInstance();
75 }
DoubleHi()76 inline const DoubleHiType& RegTypeCache::DoubleHi() {
77   return *DoubleHiType::GetInstance();
78 }
Undefined()79 inline const UndefinedType& RegTypeCache::Undefined() {
80   return *UndefinedType::GetInstance();
81 }
Conflict()82 inline const ConflictType& RegTypeCache::Conflict() {
83   return *ConflictType::GetInstance();
84 }
Null()85 inline const NullType& RegTypeCache::Null() {
86   return *NullType::GetInstance();
87 }
88 
ByteConstant()89 inline const ImpreciseConstType& RegTypeCache::ByteConstant() {
90   const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::min(), false);
91   DCHECK(result.IsImpreciseConstant());
92   return *down_cast<const ImpreciseConstType*>(&result);
93 }
94 
CharConstant()95 inline const ImpreciseConstType& RegTypeCache::CharConstant() {
96   int32_t jchar_max = static_cast<int32_t>(std::numeric_limits<jchar>::max());
97   const ConstantType& result =  FromCat1Const(jchar_max, false);
98   DCHECK(result.IsImpreciseConstant());
99   return *down_cast<const ImpreciseConstType*>(&result);
100 }
101 
ShortConstant()102 inline const ImpreciseConstType& RegTypeCache::ShortConstant() {
103   const ConstantType& result =  FromCat1Const(std::numeric_limits<jshort>::min(), false);
104   DCHECK(result.IsImpreciseConstant());
105   return *down_cast<const ImpreciseConstType*>(&result);
106 }
107 
IntConstant()108 inline const ImpreciseConstType& RegTypeCache::IntConstant() {
109   const ConstantType& result = FromCat1Const(std::numeric_limits<jint>::max(), false);
110   DCHECK(result.IsImpreciseConstant());
111   return *down_cast<const ImpreciseConstType*>(&result);
112 }
113 
PosByteConstant()114 inline const ImpreciseConstType& RegTypeCache::PosByteConstant() {
115   const ConstantType& result = FromCat1Const(std::numeric_limits<jbyte>::max(), false);
116   DCHECK(result.IsImpreciseConstant());
117   return *down_cast<const ImpreciseConstType*>(&result);
118 }
119 
PosShortConstant()120 inline const ImpreciseConstType& RegTypeCache::PosShortConstant() {
121   const ConstantType& result =  FromCat1Const(std::numeric_limits<jshort>::max(), false);
122   DCHECK(result.IsImpreciseConstant());
123   return *down_cast<const ImpreciseConstType*>(&result);
124 }
125 
JavaLangClass()126 inline const PreciseReferenceType& RegTypeCache::JavaLangClass() {
127   const RegType* result = &FromClass("Ljava/lang/Class;",
128                                      GetClassRoot<mirror::Class>(),
129                                      /* precise= */ true);
130   DCHECK(result->IsPreciseReference());
131   return *down_cast<const PreciseReferenceType*>(result);
132 }
133 
JavaLangString()134 inline const PreciseReferenceType& RegTypeCache::JavaLangString() {
135   // String is final and therefore always precise.
136   const RegType* result = &FromClass("Ljava/lang/String;",
137                                      GetClassRoot<mirror::String>(),
138                                      /* precise= */ true);
139   DCHECK(result->IsPreciseReference());
140   return *down_cast<const PreciseReferenceType*>(result);
141 }
142 
JavaLangInvokeMethodHandle()143 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodHandle() {
144   const RegType* result = &FromClass("Ljava/lang/invoke/MethodHandle;",
145                                      GetClassRoot<mirror::MethodHandle>(),
146                                      /* precise= */ true);
147   DCHECK(result->IsPreciseReference());
148   return *down_cast<const PreciseReferenceType*>(result);
149 }
150 
JavaLangInvokeMethodType()151 inline const PreciseReferenceType& RegTypeCache::JavaLangInvokeMethodType() {
152   const RegType* result = &FromClass("Ljava/lang/invoke/MethodType;",
153                                      GetClassRoot<mirror::MethodType>(),
154                                      /* precise= */ true);
155   DCHECK(result->IsPreciseReference());
156   return *down_cast<const PreciseReferenceType*>(result);
157 }
158 
JavaLangThrowable(bool precise)159 inline const RegType&  RegTypeCache::JavaLangThrowable(bool precise) {
160   const RegType* result = &FromClass("Ljava/lang/Throwable;",
161                                      GetClassRoot<mirror::Throwable>(),
162                                      precise);
163   if (precise) {
164     DCHECK(result->IsPreciseReference());
165     return *down_cast<const PreciseReferenceType*>(result);
166   } else {
167     DCHECK(result->IsReference());
168     return *down_cast<const ReferenceType*>(result);
169   }
170 }
171 
JavaLangObject(bool precise)172 inline const RegType& RegTypeCache::JavaLangObject(bool precise) {
173   const RegType* result = &FromClass("Ljava/lang/Object;", GetClassRoot<mirror::Object>(), precise);
174   if (precise) {
175     DCHECK(result->IsPreciseReference());
176     return *down_cast<const PreciseReferenceType*>(result);
177   } else {
178     DCHECK(result->IsReference());
179     return *down_cast<const ReferenceType*>(result);
180   }
181 }
182 
183 template <class RegTypeType>
AddEntry(RegTypeType * new_entry)184 inline RegTypeType& RegTypeCache::AddEntry(RegTypeType* new_entry) {
185   DCHECK(new_entry != nullptr);
186   entries_.push_back(new_entry);
187   if (new_entry->HasClass()) {
188     ObjPtr<mirror::Class> klass = new_entry->GetClass();
189     DCHECK(!klass->IsPrimitive());
190     klass_entries_.push_back(std::make_pair(GcRoot<mirror::Class>(klass), new_entry));
191   }
192   return *new_entry;
193 }
194 
195 }  // namespace verifier
196 }  // namespace art
197 #endif  // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_
198