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