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