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 #include "reg_type-inl.h"
18
19 #include "android-base/stringprintf.h"
20
21 #include "base/arena_bit_vector.h"
22 #include "base/bit_vector-inl.h"
23 #include "base/casts.h"
24 #include "class_linker-inl.h"
25 #include "dex/descriptors_names.h"
26 #include "dex/dex_file-inl.h"
27 #include "method_verifier.h"
28 #include "mirror/class-inl.h"
29 #include "mirror/class.h"
30 #include "mirror/object-inl.h"
31 #include "mirror/object_array-inl.h"
32 #include "reg_type_cache-inl.h"
33 #include "scoped_thread_state_change-inl.h"
34
35 #include <limits>
36 #include <sstream>
37
38 namespace art HIDDEN {
39 namespace verifier {
40
41 using android::base::StringPrintf;
42
operator <<(std::ostream & os,RegType::Kind kind)43 std::ostream& operator<<(std::ostream& os, RegType::Kind kind) {
44 const char* kind_name;
45 switch (kind) {
46 #define DEFINE_REG_TYPE_CASE(name) \
47 case RegType::Kind::k##name: \
48 kind_name = #name; \
49 break;
50 FOR_EACH_CONCRETE_REG_TYPE(DEFINE_REG_TYPE_CASE)
51 #undef DEFINE_REG_TYPE_CASE
52 default:
53 return os << "Corrupted RegType::Kind: " << static_cast<uint32_t>(kind);
54 }
55 return os << kind_name;
56 }
57
operator <<(std::ostream & os,RegType::Assignability assignability)58 std::ostream& operator<<(std::ostream& os, RegType::Assignability assignability) {
59 const char* assignability_name;
60 switch (assignability) {
61 case RegType::Assignability::kAssignable:
62 assignability_name = "Assignable";
63 break;
64 case RegType::Assignability::kNotAssignable:
65 assignability_name = "NotAssignable";
66 break;
67 case RegType::Assignability::kNarrowingConversion:
68 assignability_name = "NarrowingConversion";
69 break;
70 case RegType::Assignability::kReference:
71 assignability_name = "Reference";
72 break;
73 case RegType::Assignability::kInvalid:
74 assignability_name = "Invalid";
75 break;
76 default:
77 return os << "Corrupted RegType::Assignability: " << static_cast<uint32_t>(assignability);
78 }
79 return os << assignability_name;
80 }
81
Dump() const82 std::string RegType::Dump() const {
83 std::string_view reference_tag;
84 switch (GetKind()) {
85 case Kind::kUndefined: return "Undefined";
86 case Kind::kConflict: return "Conflict";
87 case Kind::kBoolean: return "Boolean";
88 case Kind::kByte: return "Byte";
89 case Kind::kShort: return "Short";
90 case Kind::kChar: return "Char";
91 case Kind::kInteger: return "Integer";
92 case Kind::kLongLo: return "Long (Low Half)";
93 case Kind::kLongHi: return "Long (High Half)";
94 case Kind::kFloat: return "Float";
95 case Kind::kDoubleLo: return "Double (Low Half)";
96 case Kind::kDoubleHi: return "Double (High Half)";
97 case Kind::kZero: return "Zero/null";
98 case Kind::kBooleanConstant: return "BooleanConstant";
99 case Kind::kPositiveByteConstant: return "PositiveByteConstant";
100 case Kind::kPositiveShortConstant: return "PositiveShortConstant";
101 case Kind::kCharConstant: return "CharConstant";
102 case Kind::kByteConstant: return "ByteConstant";
103 case Kind::kShortConstant: return "ShortConstant";
104 case Kind::kIntegerConstant: return "IntegerConstant";
105 case Kind::kConstantLo: return "Low-half Constant";
106 case Kind::kConstantHi: return "High-half Constant";
107 case Kind::kNull: return "null";
108 case Kind::kJavaLangObject: return "Reference java.lang.Object";
109
110 case Kind::kUnresolvedReference:
111 reference_tag = "Unresolved Reference: ";
112 break;
113 case Kind::kUninitializedReference:
114 reference_tag = "Uninitialized Reference: ";
115 break;
116 case Kind::kUninitializedThisReference:
117 reference_tag = "Uninitialized This Reference: ";
118 break;
119 case Kind::kUnresolvedUninitializedReference:
120 reference_tag = "Unresolved And Uninitialized Reference: ";
121 break;
122 case Kind::kUnresolvedUninitializedThisReference:
123 reference_tag = "Unresolved And Uninitialized This Reference: ";
124 break;
125 case Kind::kReference:
126 reference_tag = "Reference: ";
127 break;
128
129 case Kind::kUnresolvedMergedReference:
130 return down_cast<const UnresolvedMergedReferenceType&>(*this).DumpImpl();
131 }
132 DCHECK(!reference_tag.empty());
133 std::string result(reference_tag);
134 AppendPrettyDescriptor(std::string(GetDescriptor()).c_str(), &result);
135 return result;
136 }
137
DumpImpl() const138 std::string UnresolvedMergedReferenceType::DumpImpl() const {
139 std::stringstream result;
140 result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
141 const BitVector& types = GetUnresolvedTypes();
142
143 bool first = true;
144 for (uint32_t idx : types.Indexes()) {
145 if (!first) {
146 result << ", ";
147 } else {
148 first = false;
149 }
150 result << reg_type_cache_->GetFromId(idx).Dump();
151 }
152 result << ")";
153 return result.str();
154 }
155
HighHalf(RegTypeCache * cache) const156 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
157 DCHECK(IsLowHalf());
158 if (IsLongLo()) {
159 return cache->LongHi();
160 } else if (IsDoubleLo()) {
161 return cache->DoubleHi();
162 } else {
163 DCHECK(IsConstantLo());
164 return cache->ConstantHi();
165 }
166 }
167
GetPrimitiveType() const168 Primitive::Type RegType::GetPrimitiveType() const {
169 if (IsNonZeroReferenceTypes()) {
170 return Primitive::kPrimNot;
171 } else if (IsBooleanTypes()) {
172 return Primitive::kPrimBoolean;
173 } else if (IsByteTypes()) {
174 return Primitive::kPrimByte;
175 } else if (IsShortTypes()) {
176 return Primitive::kPrimShort;
177 } else if (IsCharTypes()) {
178 return Primitive::kPrimChar;
179 } else if (IsFloat()) {
180 return Primitive::kPrimFloat;
181 } else if (IsIntegralTypes()) {
182 return Primitive::kPrimInt;
183 } else if (IsDoubleLo()) {
184 return Primitive::kPrimDouble;
185 } else {
186 DCHECK(IsLongTypes());
187 return Primitive::kPrimLong;
188 }
189 }
190
IsObjectArrayTypes() const191 bool RegType::IsObjectArrayTypes() const {
192 if (IsUnresolvedMergedReference()) {
193 return down_cast<const UnresolvedMergedReferenceType&>(*this).IsObjectArrayTypesImpl();
194 } else if (IsUnresolvedTypes()) {
195 // Primitive arrays will always resolve.
196 DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
197 return descriptor_[0] == '[';
198 } else if (HasClass()) {
199 ObjPtr<mirror::Class> type = GetClass();
200 return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
201 } else {
202 return false;
203 }
204 }
205
IsArrayTypes() const206 bool RegType::IsArrayTypes() const {
207 if (IsUnresolvedMergedReference()) {
208 return down_cast<const UnresolvedMergedReferenceType&>(*this).IsArrayTypesImpl();
209 } else if (IsUnresolvedTypes()) {
210 return descriptor_[0] == '[';
211 } else if (HasClass()) {
212 return GetClass()->IsArrayClass();
213 } else {
214 return false;
215 }
216 }
217
IsJavaLangObjectArray() const218 bool RegType::IsJavaLangObjectArray() const {
219 if (HasClass()) {
220 ObjPtr<mirror::Class> type = GetClass();
221 return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
222 }
223 return false;
224 }
225
IsInstantiableTypes() const226 bool RegType::IsInstantiableTypes() const {
227 DCHECK(IsJavaLangObject() || IsReference() || IsUnresolvedReference()) << *this;
228 return !IsReference() || GetClass()->IsInstantiable();
229 }
230
SelectNonConstant(const RegType & a,const RegType & b)231 static constexpr const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
232 return a.IsConstantTypes() ? b : a;
233 }
234
SelectNonConstant2(const RegType & a,const RegType & b)235 static const RegType& SelectNonConstant2(const RegType& a, const RegType& b) {
236 return a.IsConstantTypes() ? (b.IsZero() ? a : b) : a;
237 }
238
239 namespace {
240
241 ObjPtr<mirror::Class> ArrayClassJoin(ObjPtr<mirror::Class> s,
242 ObjPtr<mirror::Class> t,
243 ClassLinker* class_linker)
244 REQUIRES_SHARED(Locks::mutator_lock_);
245
246 ObjPtr<mirror::Class> InterfaceClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t)
247 REQUIRES_SHARED(Locks::mutator_lock_);
248
249 /*
250 * A basic Join operation on classes. For a pair of types S and T the Join, written S v T = J, is
251 * S <: J, T <: J and for-all U such that S <: U, T <: U then J <: U. That is J is the parent of
252 * S and T such that there isn't a parent of both S and T that isn't also the parent of J (ie J
253 * is the deepest (lowest upper bound) parent of S and T).
254 *
255 * This operation applies for regular classes and arrays, however, for interface types there
256 * needn't be a partial ordering on the types. We could solve the problem of a lack of a partial
257 * order by introducing sets of types, however, the only operation permissible on an interface is
258 * invoke-interface. In the tradition of Java verifiers [1] we defer the verification of interface
259 * types until an invoke-interface call on the interface typed reference at runtime and allow
260 * the perversion of Object being assignable to an interface type (note, however, that we don't
261 * allow assignment of Object or Interface to any concrete class and are therefore type safe).
262 *
263 * Note: This may return null in case of internal errors, e.g., OOME when a new class would have
264 * to be created but there is no heap space. The exception will stay pending, and it is
265 * the job of the caller to handle it.
266 *
267 * [1] Java bytecode verification: algorithms and formalizations, Xavier Leroy
268 */
ClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t,ClassLinker * class_linker)269 ObjPtr<mirror::Class> ClassJoin(ObjPtr<mirror::Class> s,
270 ObjPtr<mirror::Class> t,
271 ClassLinker* class_linker)
272 REQUIRES_SHARED(Locks::mutator_lock_) {
273 DCHECK(!s->IsPrimitive()) << s->PrettyClass();
274 DCHECK(!t->IsPrimitive()) << t->PrettyClass();
275 if (s == t) {
276 return s;
277 } else if (s->IsAssignableFrom(t)) {
278 return s;
279 } else if (t->IsAssignableFrom(s)) {
280 return t;
281 } else if (s->IsArrayClass() && t->IsArrayClass()) {
282 return ArrayClassJoin(s, t, class_linker);
283 } else if (s->IsInterface() || t->IsInterface()) {
284 return InterfaceClassJoin(s, t);
285 } else {
286 size_t s_depth = s->Depth();
287 size_t t_depth = t->Depth();
288 // Get s and t to the same depth in the hierarchy
289 if (s_depth > t_depth) {
290 while (s_depth > t_depth) {
291 s = s->GetSuperClass();
292 s_depth--;
293 }
294 } else {
295 while (t_depth > s_depth) {
296 t = t->GetSuperClass();
297 t_depth--;
298 }
299 }
300 // Go up the hierarchy until we get to the common parent
301 while (s != t) {
302 s = s->GetSuperClass();
303 t = t->GetSuperClass();
304 }
305 return s;
306 }
307 }
308
ArrayClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t,ClassLinker * class_linker)309 ObjPtr<mirror::Class> ArrayClassJoin(ObjPtr<mirror::Class> s,
310 ObjPtr<mirror::Class> t,
311 ClassLinker* class_linker) {
312 ObjPtr<mirror::Class> s_ct = s->GetComponentType();
313 ObjPtr<mirror::Class> t_ct = t->GetComponentType();
314 if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
315 // Given the types aren't the same, if either array is of primitive types then the only
316 // common parent is java.lang.Object
317 ObjPtr<mirror::Class> result = s->GetSuperClass(); // short-cut to java.lang.Object
318 DCHECK(result->IsObjectClass());
319 return result;
320 }
321 Thread* self = Thread::Current();
322 ObjPtr<mirror::Class> common_elem = ClassJoin(s_ct, t_ct, class_linker);
323 if (UNLIKELY(common_elem == nullptr)) {
324 self->AssertPendingException();
325 return nullptr;
326 }
327 // Note: The following lookup invalidates existing ObjPtr<>s.
328 ObjPtr<mirror::Class> array_class = class_linker->FindArrayClass(self, common_elem);
329 if (UNLIKELY(array_class == nullptr)) {
330 self->AssertPendingException();
331 return nullptr;
332 }
333 return array_class;
334 }
335
InterfaceClassJoin(ObjPtr<mirror::Class> s,ObjPtr<mirror::Class> t)336 ObjPtr<mirror::Class> InterfaceClassJoin(ObjPtr<mirror::Class> s, ObjPtr<mirror::Class> t) {
337 // This is expensive, as we do not have good data structures to do this even halfway
338 // efficiently.
339 //
340 // We're not following JVMS for interface verification (not everything is assignable to an
341 // interface, we trade this for IMT dispatch). We also don't have set types to make up for
342 // it. So we choose one arbitrary common ancestor interface by walking the interface tables
343 // backwards.
344 //
345 // For comparison, runtimes following the JVMS will punt all interface type checking to
346 // runtime.
347 ObjPtr<mirror::IfTable> s_if = s->GetIfTable();
348 int32_t s_if_count = s->GetIfTableCount();
349 ObjPtr<mirror::IfTable> t_if = t->GetIfTable();
350 int32_t t_if_count = t->GetIfTableCount();
351
352 // Note: we'll be using index == count to stand for the argument itself.
353 for (int32_t s_it = s_if_count; s_it >= 0; --s_it) {
354 ObjPtr<mirror::Class> s_cl = s_it == s_if_count ? s : s_if->GetInterface(s_it);
355 if (!s_cl->IsInterface()) {
356 continue;
357 }
358
359 for (int32_t t_it = t_if_count; t_it >= 0; --t_it) {
360 ObjPtr<mirror::Class> t_cl = t_it == t_if_count ? t : t_if->GetInterface(t_it);
361 if (!t_cl->IsInterface()) {
362 continue;
363 }
364
365 if (s_cl == t_cl) {
366 // Found something arbitrary in common.
367 return s_cl;
368 }
369 }
370 }
371
372 // Return java.lang.Object.
373 ObjPtr<mirror::Class> obj_class = s->IsInterface() ? s->GetSuperClass() : t->GetSuperClass();
374 DCHECK(obj_class->IsObjectClass());
375 return obj_class;
376 }
377
378 class RegTypeMergeImpl final : public RegType {
379 public:
RegTypeMergeImpl(RegType::Kind kind)380 explicit constexpr RegTypeMergeImpl(RegType::Kind kind)
381 : RegType("", /* unused cache id */ 0, kind) {}
382
383 constexpr RegType::Kind MergeKind(RegType::Kind incoming_kind) const;
384 };
385
MergeKind(RegType::Kind incoming_kind) const386 constexpr RegType::Kind RegTypeMergeImpl::MergeKind(RegType::Kind incoming_kind) const {
387 const RegTypeMergeImpl incoming_type(incoming_kind);
388 if (IsUndefined() || incoming_type.IsUndefined()) {
389 // There is a difference between undefined and conflict. Conflicts may be copied around, but
390 // not used. Undefined registers must not be copied. So any merge with undefined should return
391 // undefined.
392 return Kind::kUndefined;
393 } else if (IsConflict() || incoming_type.IsConflict()) {
394 return Kind::kConflict; // (Conflict MERGE *) or (* MERGE Conflict) => Conflict
395 } else if (IsConstant() && incoming_type.IsConstant()) {
396 // Kind enumerator values within the non-negative and can-be-negative constant groups are
397 // ordered by increasing range, so the type with the higher kind can be used within these
398 // groups as the merged kind and merging across the groups is also quite simple.
399 static_assert(Kind::kZero < Kind::kBooleanConstant);
400 static_assert(Kind::kBooleanConstant < Kind::kPositiveByteConstant);
401 static_assert(Kind::kPositiveByteConstant < Kind::kPositiveShortConstant);
402 static_assert(Kind::kPositiveShortConstant < Kind::kCharConstant);
403 static_assert(Kind::kByteConstant < Kind::kShortConstant);
404 static_assert(Kind::kShortConstant < Kind::kIntegerConstant);
405
406 auto is_non_negative = [](const RegType& reg_type) constexpr {
407 bool result = reg_type.IsZero() ||
408 reg_type.IsBooleanConstant() ||
409 reg_type.IsPositiveByteConstant() ||
410 reg_type.IsPositiveShortConstant() ||
411 reg_type.IsCharConstant();
412 DCHECK_NE(
413 result,
414 reg_type.IsByteConstant() || reg_type.IsShortConstant() || reg_type.IsIntegerConstant());
415 return result;
416 };
417
418 bool is_non_negative_this = is_non_negative(*this);
419 if (is_non_negative_this == is_non_negative(incoming_type)) {
420 return GetKind() >= incoming_type.GetKind() ? GetKind() : incoming_type.GetKind();
421 }
422 Kind non_negative_kind = is_non_negative_this ? GetKind() : incoming_type.GetKind();
423 Kind can_be_negative_kind = is_non_negative_this ? incoming_type.GetKind() : GetKind();
424 if (can_be_negative_kind == Kind::kByteConstant &&
425 non_negative_kind <= Kind::kPositiveByteConstant) {
426 return Kind::kByteConstant;
427 } else if (can_be_negative_kind <= Kind::kShortConstant &&
428 non_negative_kind <= Kind::kPositiveShortConstant) {
429 return Kind::kShortConstant;
430 } else {
431 return Kind::kIntegerConstant;
432 }
433 } else if ((IsConstantLo() && incoming_type.IsConstantLo()) ||
434 (IsConstantHi() && incoming_type.IsConstantHi())) {
435 return GetKind();
436 } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
437 if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
438 return Kind::kBoolean; // boolean MERGE boolean => boolean
439 }
440 if (IsByteTypes() && incoming_type.IsByteTypes()) {
441 return Kind::kByte; // byte MERGE byte => byte
442 }
443 if (IsShortTypes() && incoming_type.IsShortTypes()) {
444 return Kind::kShort; // short MERGE short => short
445 }
446 if (IsCharTypes() && incoming_type.IsCharTypes()) {
447 return Kind::kChar; // char MERGE char => char
448 }
449 return Kind::kInteger; // int MERGE * => int
450 } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
451 (IsLongTypes() && incoming_type.IsLongTypes()) ||
452 (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
453 (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
454 (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
455 // check constant case was handled prior to entry
456 DCHECK_IMPLIES(IsConstant(), !incoming_type.IsConstant());
457 // float/long/double MERGE float/long/double_constant => float/long/double
458 return SelectNonConstant(*this, incoming_type).GetKind();
459 } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
460 if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
461 // Something that is uninitialized hasn't had its constructor called. Unitialized types are
462 // special. They may only ever be merged with themselves (must be taken care of by the
463 // caller of Merge(), see the DCHECK on entry). So mark any other merge as conflicting here.
464 return Kind::kConflict;
465 } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
466 return Kind::kJavaLangObject;
467 } else {
468 // Use `UnresolvedMergedReference` to tell the caller to process a reference merge.
469 // This does not mean that the actual merged kind must be `UnresolvedMergedReference`.
470 return Kind::kUnresolvedMergedReference;
471 }
472 } else {
473 return Kind::kConflict; // Unexpected types => Conflict
474 }
475 }
476
477 } // namespace
478
Merge(const RegType & incoming_type,RegTypeCache * reg_types,MethodVerifier * verifier) const479 const RegType& RegType::Merge(const RegType& incoming_type,
480 RegTypeCache* reg_types,
481 MethodVerifier* verifier) const {
482 DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller
483
484 static constexpr size_t kNumKinds = NumberOfKinds();
485 using MergeTable = std::array<std::array<Kind, kNumKinds>, kNumKinds>;
486 static constexpr MergeTable kMergeTable = []() constexpr {
487 MergeTable result;
488 for (size_t lhs = 0u; lhs != kNumKinds; ++lhs) {
489 for (size_t rhs = 0u; rhs != kNumKinds; ++rhs) {
490 RegTypeMergeImpl lhs_impl(enum_cast<RegType::Kind>(lhs));
491 result[lhs][rhs] = lhs_impl.MergeKind(enum_cast<RegType::Kind>(rhs));
492 }
493 }
494 return result;
495 }();
496
497 Kind merge_kind = kMergeTable[GetKind()][incoming_type.GetKind()];
498 if (merge_kind != Kind::kUnresolvedMergedReference) {
499 return reg_types->GetFromRegKind(merge_kind);
500 } else {
501 // The `UnresolvedMergedReference` tells us to do non-trivial reference merging which
502 // requires more information than the two kinds used for the lookup in `kMergeTable`.
503 DCHECK(IsReferenceTypes()) << *this;
504 DCHECK(incoming_type.IsReferenceTypes()) << incoming_type;
505 DCHECK(!IsUninitializedTypes()) << *this;
506 DCHECK(!incoming_type.IsUninitializedTypes());
507 DCHECK(!IsJavaLangObject());
508 DCHECK(!incoming_type.IsJavaLangObject());
509 if (IsZeroOrNull() || incoming_type.IsZeroOrNull()) {
510 return SelectNonConstant2(*this, incoming_type); // 0 MERGE ref => ref
511 } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
512 // We know how to merge an unresolved type with itself, 0 or Object. In this case we
513 // have two sub-classes and don't know how to merge. Create a new string-based unresolved
514 // type that reflects our lack of knowledge and that allows the rest of the unresolved
515 // mechanics to continue.
516 return reg_types->FromUnresolvedMerge(*this, incoming_type, verifier);
517 } else { // Two reference types, compute Join
518 // Do not cache the classes as ClassJoin() can suspend and invalidate ObjPtr<>s.
519 DCHECK(GetClass() != nullptr && !GetClass()->IsPrimitive());
520 DCHECK(incoming_type.GetClass() != nullptr && !incoming_type.GetClass()->IsPrimitive());
521 ObjPtr<mirror::Class> join_class = ClassJoin(GetClass(),
522 incoming_type.GetClass(),
523 reg_types->GetClassLinker());
524 if (UNLIKELY(join_class == nullptr)) {
525 // Internal error joining the classes (e.g., OOME). Report an unresolved reference type.
526 // We cannot report an unresolved merge type, as that will attempt to merge the resolved
527 // components, leaving us in an infinite loop.
528 // We do not want to report the originating exception, as that would require a fast path
529 // out all the way to VerifyClass. Instead attempt to continue on without a detailed type.
530 Thread* self = Thread::Current();
531 self->AssertPendingException();
532 self->ClearException();
533
534 // When compiling on the host, we rather want to abort to ensure determinism for preopting.
535 // (In that case, it is likely a misconfiguration of dex2oat.)
536 if (!kIsTargetBuild && (verifier != nullptr && verifier->IsAotMode())) {
537 LOG(FATAL) << "Could not create class join of "
538 << GetClass()->PrettyClass()
539 << " & "
540 << incoming_type.GetClass()->PrettyClass();
541 UNREACHABLE();
542 }
543
544 return reg_types->MakeUnresolvedReference();
545 }
546
547 // Record the dependency that both `GetClass()` and `incoming_type.GetClass()`
548 // are assignable to `join_class`. The `verifier` is null during unit tests.
549 if (verifier != nullptr) {
550 VerifierDeps::MaybeRecordAssignability(verifier->GetVerifierDeps(),
551 verifier->GetDexFile(),
552 verifier->GetClassDef(),
553 join_class,
554 GetClass());
555 VerifierDeps::MaybeRecordAssignability(verifier->GetVerifierDeps(),
556 verifier->GetDexFile(),
557 verifier->GetClassDef(),
558 join_class,
559 incoming_type.GetClass());
560 }
561 if (GetClass() == join_class) {
562 return *this;
563 } else if (incoming_type.GetClass() == join_class) {
564 return incoming_type;
565 } else {
566 return reg_types->FromClass(join_class);
567 }
568 }
569 }
570 }
571
CheckClassDescriptor() const572 void ReferenceType::CheckClassDescriptor() const {
573 CHECK(IsReference());
574 CHECK(!klass_.IsNull());
575 CHECK(!descriptor_.empty()) << *this;
576 std::string temp;
577 CHECK_EQ(descriptor_, klass_->GetDescriptor(&temp)) << *this;
578 }
579
UnresolvedMergedReferenceType(const RegType & resolved,const BitVector & unresolved,const RegTypeCache * reg_type_cache,uint16_t cache_id)580 UnresolvedMergedReferenceType::UnresolvedMergedReferenceType(const RegType& resolved,
581 const BitVector& unresolved,
582 const RegTypeCache* reg_type_cache,
583 uint16_t cache_id)
584 : UnresolvedType("", cache_id, Kind::kUnresolvedMergedReference),
585 reg_type_cache_(reg_type_cache),
586 resolved_part_(resolved),
587 unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
588 CheckConstructorInvariants(this);
589 if (kIsDebugBuild) {
590 CheckInvariants();
591 }
592 }
593
CheckInvariants() const594 void UnresolvedMergedReferenceType::CheckInvariants() const {
595 CHECK(reg_type_cache_ != nullptr);
596
597 // Unresolved merged types: merged types should be defined.
598 CHECK(descriptor_.empty()) << *this;
599 CHECK(!HasClass()) << *this;
600
601 CHECK(!resolved_part_.IsConflict());
602 CHECK(resolved_part_.IsReferenceTypes());
603 CHECK(!resolved_part_.IsUnresolvedTypes());
604
605 CHECK(resolved_part_.IsZero() ||
606 !(resolved_part_.IsArrayTypes() && !resolved_part_.IsObjectArrayTypes()));
607
608 CHECK_GT(unresolved_types_.NumSetBits(), 0U);
609 bool unresolved_is_array =
610 reg_type_cache_->GetFromId(unresolved_types_.GetHighestBitSet()).IsArrayTypes();
611 for (uint32_t idx : unresolved_types_.Indexes()) {
612 const RegType& t = reg_type_cache_->GetFromId(idx);
613 CHECK_EQ(unresolved_is_array, t.IsArrayTypes());
614 }
615
616 if (!resolved_part_.IsZero()) {
617 CHECK_EQ(resolved_part_.IsArrayTypes(), unresolved_is_array);
618 }
619 }
620
IsArrayTypesImpl() const621 bool UnresolvedMergedReferenceType::IsArrayTypesImpl() const {
622 // For a merge to be an array, both the resolved and the unresolved part need to be object
623 // arrays.
624 // (Note: we encode a missing resolved part [which doesn't need to be an array] as zero.)
625
626 if (!resolved_part_.IsZero() && !resolved_part_.IsArrayTypes()) {
627 return false;
628 }
629
630 // It is enough to check just one of the merged types. Otherwise the merge should have been
631 // collapsed (checked in CheckInvariants on construction).
632 uint32_t idx = unresolved_types_.GetHighestBitSet();
633 const RegType& unresolved = reg_type_cache_->GetFromId(idx);
634 return unresolved.IsArrayTypes();
635 }
IsObjectArrayTypesImpl() const636 bool UnresolvedMergedReferenceType::IsObjectArrayTypesImpl() const {
637 // Same as IsArrayTypes, as primitive arrays are always resolved.
638 return IsArrayTypes();
639 }
640
operator <<(std::ostream & os,const RegType & rhs)641 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
642 os << rhs.Dump();
643 return os;
644 }
645
646 } // namespace verifier
647 } // namespace art
648