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 HIDDEN {
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_IMPLIES(value == 0, precise);
44 if (precise && (value >= kMinSmallConstant) && (value <= kMaxSmallConstant)) {
45 return *down_cast<const ConstantType*>(entries_[value - kMinSmallConstant]);
46 }
47 return FromCat1NonSmallConstant(value, precise);
48 }
49
Boolean()50 inline const BooleanType& RegTypeCache::Boolean() {
51 return *down_cast<const BooleanType*>(entries_[kBooleanCacheId]);
52 }
Byte()53 inline const ByteType& RegTypeCache::Byte() {
54 return *down_cast<const ByteType*>(entries_[kByteCacheId]);
55 }
Char()56 inline const CharType& RegTypeCache::Char() {
57 return *down_cast<const CharType*>(entries_[kCharCacheId]);
58 }
Short()59 inline const ShortType& RegTypeCache::Short() {
60 return *down_cast<const ShortType*>(entries_[kShortCacheId]);
61 }
Integer()62 inline const IntegerType& RegTypeCache::Integer() {
63 return *down_cast<const IntegerType*>(entries_[kIntCacheId]);
64 }
Float()65 inline const FloatType& RegTypeCache::Float() {
66 return *down_cast<const FloatType*>(entries_[kFloatCacheId]);
67 }
LongLo()68 inline const LongLoType& RegTypeCache::LongLo() {
69 return *down_cast<const LongLoType*>(entries_[kLongLoCacheId]);
70 }
LongHi()71 inline const LongHiType& RegTypeCache::LongHi() {
72 return *down_cast<const LongHiType*>(entries_[kLongHiCacheId]);
73 }
DoubleLo()74 inline const DoubleLoType& RegTypeCache::DoubleLo() {
75 return *down_cast<const DoubleLoType*>(entries_[kDoubleLoCacheId]);
76 }
DoubleHi()77 inline const DoubleHiType& RegTypeCache::DoubleHi() {
78 return *down_cast<const DoubleHiType*>(entries_[kDoubleHiCacheId]);
79 }
Undefined()80 inline const UndefinedType& RegTypeCache::Undefined() {
81 return *down_cast<const UndefinedType*>(entries_[kUndefinedCacheId]);
82 }
Conflict()83 inline const ConflictType& RegTypeCache::Conflict() {
84 return *down_cast<const ConflictType*>(entries_[kConflictCacheId]);
85 }
Null()86 inline const NullType& RegTypeCache::Null() {
87 return *down_cast<const NullType*>(entries_[kNullCacheId]);
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()160 inline const RegType& RegTypeCache::JavaLangThrowable() {
161 const RegType* result = &FromClass("Ljava/lang/Throwable;",
162 GetClassRoot<mirror::Throwable>(),
163 /* precise= */ false);
164 DCHECK(result->IsReference());
165 DCHECK(!result->IsPreciseReference());
166 return *down_cast<const ReferenceType*>(result);
167 }
168
JavaLangObject(bool precise)169 inline const RegType& RegTypeCache::JavaLangObject(bool precise) {
170 const RegType* result = &FromClass("Ljava/lang/Object;", GetClassRoot<mirror::Object>(), precise);
171 if (precise) {
172 DCHECK(result->IsPreciseReference());
173 return *down_cast<const PreciseReferenceType*>(result);
174 } else {
175 DCHECK(result->IsReference());
176 return *down_cast<const ReferenceType*>(result);
177 }
178 }
179
180 template <class RegTypeType>
AddEntry(RegTypeType * new_entry)181 inline RegTypeType& RegTypeCache::AddEntry(RegTypeType* new_entry) {
182 DCHECK(new_entry != nullptr);
183 entries_.push_back(new_entry);
184 if (new_entry->HasClass()) {
185 Handle<mirror::Class> klass = new_entry->GetClassHandle();
186 DCHECK(!klass->IsPrimitive());
187 klass_entries_.push_back(std::make_pair(klass, new_entry));
188 }
189 return *new_entry;
190 }
191
192 } // namespace verifier
193 } // namespace art
194 #endif // ART_RUNTIME_VERIFIER_REG_TYPE_CACHE_INL_H_
195