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