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 "base/bit_vector-inl.h"
20 #include "base/casts.h"
21 #include "class_linker-inl.h"
22 #include "dex_file-inl.h"
23 #include "mirror/class.h"
24 #include "mirror/class-inl.h"
25 #include "mirror/object-inl.h"
26 #include "mirror/object_array-inl.h"
27 #include "reg_type_cache-inl.h"
28 #include "scoped_thread_state_change.h"
29
30 #include <limits>
31 #include <sstream>
32
33 namespace art {
34 namespace verifier {
35
36 const UndefinedType* UndefinedType::instance_ = nullptr;
37 const ConflictType* ConflictType::instance_ = nullptr;
38 const BooleanType* BooleanType::instance_ = nullptr;
39 const ByteType* ByteType::instance_ = nullptr;
40 const ShortType* ShortType::instance_ = nullptr;
41 const CharType* CharType::instance_ = nullptr;
42 const FloatType* FloatType::instance_ = nullptr;
43 const LongLoType* LongLoType::instance_ = nullptr;
44 const LongHiType* LongHiType::instance_ = nullptr;
45 const DoubleLoType* DoubleLoType::instance_ = nullptr;
46 const DoubleHiType* DoubleHiType::instance_ = nullptr;
47 const IntegerType* IntegerType::instance_ = nullptr;
48
PrimitiveType(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)49 PrimitiveType::PrimitiveType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
50 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
51 : RegType(klass, descriptor, cache_id) {
52 CHECK(klass != nullptr);
53 CHECK(!descriptor.empty());
54 }
55
Cat1Type(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)56 Cat1Type::Cat1Type(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
57 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
58 : PrimitiveType(klass, descriptor, cache_id) {
59 }
60
Cat2Type(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)61 Cat2Type::Cat2Type(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
62 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
63 : PrimitiveType(klass, descriptor, cache_id) {
64 }
65
Dump() const66 std::string PreciseConstType::Dump() const {
67 std::stringstream result;
68 uint32_t val = ConstantValue();
69 if (val == 0) {
70 CHECK(IsPreciseConstant());
71 result << "Zero/null";
72 } else {
73 result << "Precise ";
74 if (IsConstantShort()) {
75 result << StringPrintf("Constant: %d", val);
76 } else {
77 result << StringPrintf("Constant: 0x%x", val);
78 }
79 }
80 return result.str();
81 }
82
Dump() const83 std::string BooleanType::Dump() const {
84 return "Boolean";
85 }
86
Dump() const87 std::string ConflictType::Dump() const {
88 return "Conflict";
89 }
90
Dump() const91 std::string ByteType::Dump() const {
92 return "Byte";
93 }
94
Dump() const95 std::string ShortType::Dump() const {
96 return "Short";
97 }
98
Dump() const99 std::string CharType::Dump() const {
100 return "Char";
101 }
102
Dump() const103 std::string FloatType::Dump() const {
104 return "Float";
105 }
106
Dump() const107 std::string LongLoType::Dump() const {
108 return "Long (Low Half)";
109 }
110
Dump() const111 std::string LongHiType::Dump() const {
112 return "Long (High Half)";
113 }
114
Dump() const115 std::string DoubleLoType::Dump() const {
116 return "Double (Low Half)";
117 }
118
Dump() const119 std::string DoubleHiType::Dump() const {
120 return "Double (High Half)";
121 }
122
Dump() const123 std::string IntegerType::Dump() const {
124 return "Integer";
125 }
126
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)127 const DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass,
128 const std::string& descriptor,
129 uint16_t cache_id) {
130 CHECK(instance_ == nullptr);
131 instance_ = new DoubleHiType(klass, descriptor, cache_id);
132 return instance_;
133 }
134
Destroy()135 void DoubleHiType::Destroy() {
136 if (instance_ != nullptr) {
137 delete instance_;
138 instance_ = nullptr;
139 }
140 }
141
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)142 const DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass,
143 const std::string& descriptor,
144 uint16_t cache_id) {
145 CHECK(instance_ == nullptr);
146 instance_ = new DoubleLoType(klass, descriptor, cache_id);
147 return instance_;
148 }
149
Destroy()150 void DoubleLoType::Destroy() {
151 if (instance_ != nullptr) {
152 delete instance_;
153 instance_ = nullptr;
154 }
155 }
156
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)157 const LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
158 uint16_t cache_id) {
159 CHECK(instance_ == nullptr);
160 instance_ = new LongLoType(klass, descriptor, cache_id);
161 return instance_;
162 }
163
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)164 const LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
165 uint16_t cache_id) {
166 CHECK(instance_ == nullptr);
167 instance_ = new LongHiType(klass, descriptor, cache_id);
168 return instance_;
169 }
170
Destroy()171 void LongHiType::Destroy() {
172 if (instance_ != nullptr) {
173 delete instance_;
174 instance_ = nullptr;
175 }
176 }
177
Destroy()178 void LongLoType::Destroy() {
179 if (instance_ != nullptr) {
180 delete instance_;
181 instance_ = nullptr;
182 }
183 }
184
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)185 const FloatType* FloatType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
186 uint16_t cache_id) {
187 CHECK(instance_ == nullptr);
188 instance_ = new FloatType(klass, descriptor, cache_id);
189 return instance_;
190 }
191
Destroy()192 void FloatType::Destroy() {
193 if (instance_ != nullptr) {
194 delete instance_;
195 instance_ = nullptr;
196 }
197 }
198
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)199 const CharType* CharType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
200 uint16_t cache_id) {
201 CHECK(instance_ == nullptr);
202 instance_ = new CharType(klass, descriptor, cache_id);
203 return instance_;
204 }
205
Destroy()206 void CharType::Destroy() {
207 if (instance_ != nullptr) {
208 delete instance_;
209 instance_ = nullptr;
210 }
211 }
212
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)213 const ShortType* ShortType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
214 uint16_t cache_id) {
215 CHECK(instance_ == nullptr);
216 instance_ = new ShortType(klass, descriptor, cache_id);
217 return instance_;
218 }
219
Destroy()220 void ShortType::Destroy() {
221 if (instance_ != nullptr) {
222 delete instance_;
223 instance_ = nullptr;
224 }
225 }
226
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)227 const ByteType* ByteType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
228 uint16_t cache_id) {
229 CHECK(instance_ == nullptr);
230 instance_ = new ByteType(klass, descriptor, cache_id);
231 return instance_;
232 }
233
Destroy()234 void ByteType::Destroy() {
235 if (instance_ != nullptr) {
236 delete instance_;
237 instance_ = nullptr;
238 }
239 }
240
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)241 const IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
242 uint16_t cache_id) {
243 CHECK(instance_ == nullptr);
244 instance_ = new IntegerType(klass, descriptor, cache_id);
245 return instance_;
246 }
247
Destroy()248 void IntegerType::Destroy() {
249 if (instance_ != nullptr) {
250 delete instance_;
251 instance_ = nullptr;
252 }
253 }
254
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)255 const ConflictType* ConflictType::CreateInstance(mirror::Class* klass,
256 const std::string& descriptor,
257 uint16_t cache_id) {
258 CHECK(instance_ == nullptr);
259 instance_ = new ConflictType(klass, descriptor, cache_id);
260 return instance_;
261 }
262
Destroy()263 void ConflictType::Destroy() {
264 if (instance_ != nullptr) {
265 delete instance_;
266 instance_ = nullptr;
267 }
268 }
269
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)270 const BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
271 uint16_t cache_id) {
272 CHECK(BooleanType::instance_ == nullptr);
273 instance_ = new BooleanType(klass, descriptor, cache_id);
274 return BooleanType::instance_;
275 }
276
Destroy()277 void BooleanType::Destroy() {
278 if (BooleanType::instance_ != nullptr) {
279 delete instance_;
280 instance_ = nullptr;
281 }
282 }
283
Dump() const284 std::string UndefinedType::Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
285 return "Undefined";
286 }
287
CreateInstance(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)288 const UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass,
289 const std::string& descriptor,
290 uint16_t cache_id) {
291 CHECK(instance_ == nullptr);
292 instance_ = new UndefinedType(klass, descriptor, cache_id);
293 return instance_;
294 }
295
Destroy()296 void UndefinedType::Destroy() {
297 if (instance_ != nullptr) {
298 delete instance_;
299 instance_ = nullptr;
300 }
301 }
302
PreciseReferenceType(mirror::Class * klass,const std::string & descriptor,uint16_t cache_id)303 PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const std::string& descriptor,
304 uint16_t cache_id)
305 : RegType(klass, descriptor, cache_id) {
306 DCHECK(klass->IsInstantiable());
307 }
308
Dump() const309 std::string UnresolvedMergedType::Dump() const {
310 std::stringstream result;
311 result << "UnresolvedMergedReferences(" << GetResolvedPart().Dump() << " | ";
312 const BitVector& types = GetUnresolvedTypes();
313
314 bool first = true;
315 for (uint32_t idx : types.Indexes()) {
316 if (!first) {
317 result << ", ";
318 } else {
319 first = false;
320 }
321 result << reg_type_cache_->GetFromId(idx).Dump();
322 }
323 result << ")";
324 return result.str();
325 }
326
Dump() const327 std::string UnresolvedSuperClass::Dump() const {
328 std::stringstream result;
329 uint16_t super_type_id = GetUnresolvedSuperClassChildId();
330 result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
331 return result.str();
332 }
333
Dump() const334 std::string UnresolvedReferenceType::Dump() const {
335 std::stringstream result;
336 result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor().c_str());
337 return result.str();
338 }
339
Dump() const340 std::string UnresolvedUninitializedRefType::Dump() const {
341 std::stringstream result;
342 result << "Unresolved And Uninitialized Reference" << ": "
343 << PrettyDescriptor(GetDescriptor().c_str())
344 << " Allocation PC: " << GetAllocationPc();
345 return result.str();
346 }
347
Dump() const348 std::string UnresolvedUninitializedThisRefType::Dump() const {
349 std::stringstream result;
350 result << "Unresolved And Uninitialized This Reference"
351 << PrettyDescriptor(GetDescriptor().c_str());
352 return result.str();
353 }
354
Dump() const355 std::string ReferenceType::Dump() const {
356 std::stringstream result;
357 result << "Reference" << ": " << PrettyDescriptor(GetClass());
358 return result.str();
359 }
360
Dump() const361 std::string PreciseReferenceType::Dump() const {
362 std::stringstream result;
363 result << "Precise Reference" << ": "<< PrettyDescriptor(GetClass());
364 return result.str();
365 }
366
Dump() const367 std::string UninitializedReferenceType::Dump() const {
368 std::stringstream result;
369 result << "Uninitialized Reference" << ": " << PrettyDescriptor(GetClass());
370 result << " Allocation PC: " << GetAllocationPc();
371 return result.str();
372 }
373
Dump() const374 std::string UninitializedThisReferenceType::Dump() const {
375 std::stringstream result;
376 result << "Uninitialized This Reference" << ": " << PrettyDescriptor(GetClass());
377 result << "Allocation PC: " << GetAllocationPc();
378 return result.str();
379 }
380
Dump() const381 std::string ImpreciseConstType::Dump() const {
382 std::stringstream result;
383 uint32_t val = ConstantValue();
384 if (val == 0) {
385 result << "Zero/null";
386 } else {
387 result << "Imprecise ";
388 if (IsConstantShort()) {
389 result << StringPrintf("Constant: %d", val);
390 } else {
391 result << StringPrintf("Constant: 0x%x", val);
392 }
393 }
394 return result.str();
395 }
Dump() const396 std::string PreciseConstLoType::Dump() const {
397 std::stringstream result;
398
399 int32_t val = ConstantValueLo();
400 result << "Precise ";
401 if (val >= std::numeric_limits<jshort>::min() &&
402 val <= std::numeric_limits<jshort>::max()) {
403 result << StringPrintf("Low-half Constant: %d", val);
404 } else {
405 result << StringPrintf("Low-half Constant: 0x%x", val);
406 }
407 return result.str();
408 }
409
Dump() const410 std::string ImpreciseConstLoType::Dump() const {
411 std::stringstream result;
412
413 int32_t val = ConstantValueLo();
414 result << "Imprecise ";
415 if (val >= std::numeric_limits<jshort>::min() &&
416 val <= std::numeric_limits<jshort>::max()) {
417 result << StringPrintf("Low-half Constant: %d", val);
418 } else {
419 result << StringPrintf("Low-half Constant: 0x%x", val);
420 }
421 return result.str();
422 }
423
Dump() const424 std::string PreciseConstHiType::Dump() const {
425 std::stringstream result;
426 int32_t val = ConstantValueHi();
427 result << "Precise ";
428 if (val >= std::numeric_limits<jshort>::min() &&
429 val <= std::numeric_limits<jshort>::max()) {
430 result << StringPrintf("High-half Constant: %d", val);
431 } else {
432 result << StringPrintf("High-half Constant: 0x%x", val);
433 }
434 return result.str();
435 }
436
Dump() const437 std::string ImpreciseConstHiType::Dump() const {
438 std::stringstream result;
439 int32_t val = ConstantValueHi();
440 result << "Imprecise ";
441 if (val >= std::numeric_limits<jshort>::min() &&
442 val <= std::numeric_limits<jshort>::max()) {
443 result << StringPrintf("High-half Constant: %d", val);
444 } else {
445 result << StringPrintf("High-half Constant: 0x%x", val);
446 }
447 return result.str();
448 }
449
HighHalf(RegTypeCache * cache) const450 const RegType& RegType::HighHalf(RegTypeCache* cache) const {
451 DCHECK(IsLowHalf());
452 if (IsLongLo()) {
453 return cache->LongHi();
454 } else if (IsDoubleLo()) {
455 return cache->DoubleHi();
456 } else {
457 DCHECK(IsImpreciseConstantLo());
458 const ConstantType* const_val = down_cast<const ConstantType*>(this);
459 return cache->FromCat2ConstHi(const_val->ConstantValue(), false);
460 }
461 }
462
GetPrimitiveType() const463 Primitive::Type RegType::GetPrimitiveType() const {
464 if (IsNonZeroReferenceTypes()) {
465 return Primitive::kPrimNot;
466 } else if (IsBooleanTypes()) {
467 return Primitive::kPrimBoolean;
468 } else if (IsByteTypes()) {
469 return Primitive::kPrimByte;
470 } else if (IsShortTypes()) {
471 return Primitive::kPrimShort;
472 } else if (IsCharTypes()) {
473 return Primitive::kPrimChar;
474 } else if (IsFloat()) {
475 return Primitive::kPrimFloat;
476 } else if (IsIntegralTypes()) {
477 return Primitive::kPrimInt;
478 } else if (IsDoubleLo()) {
479 return Primitive::kPrimDouble;
480 } else {
481 DCHECK(IsLongTypes());
482 return Primitive::kPrimLong;
483 }
484 }
485
IsUninitializedTypes() const486 bool UninitializedType::IsUninitializedTypes() const {
487 return true;
488 }
489
IsNonZeroReferenceTypes() const490 bool UninitializedType::IsNonZeroReferenceTypes() const {
491 return true;
492 }
493
IsNonZeroReferenceTypes() const494 bool UnresolvedType::IsNonZeroReferenceTypes() const {
495 return true;
496 }
497
GetSuperClass(RegTypeCache * cache) const498 const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
499 if (!IsUnresolvedTypes()) {
500 mirror::Class* super_klass = GetClass()->GetSuperClass();
501 if (super_klass != nullptr) {
502 // A super class of a precise type isn't precise as a precise type indicates the register
503 // holds exactly that type.
504 std::string temp;
505 return cache->FromClass(super_klass->GetDescriptor(&temp), super_klass, false);
506 } else {
507 return cache->Zero();
508 }
509 } else {
510 if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
511 GetDescriptor()[0] == '[') {
512 // Super class of all arrays is Object.
513 return cache->JavaLangObject(true);
514 } else {
515 return cache->FromUnresolvedSuperClass(*this);
516 }
517 }
518 }
519
IsObjectArrayTypes() const520 bool RegType::IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
521 if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
522 // Primitive arrays will always resolve
523 DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
524 return descriptor_[0] == '[';
525 } else if (HasClass()) {
526 mirror::Class* type = GetClass();
527 return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
528 } else {
529 return false;
530 }
531 }
532
IsJavaLangObject() const533 bool RegType::IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
534 return IsReference() && GetClass()->IsObjectClass();
535 }
536
IsArrayTypes() const537 bool RegType::IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
538 if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
539 return descriptor_[0] == '[';
540 } else if (HasClass()) {
541 return GetClass()->IsArrayClass();
542 } else {
543 return false;
544 }
545 }
546
IsJavaLangObjectArray() const547 bool RegType::IsJavaLangObjectArray() const {
548 if (HasClass()) {
549 mirror::Class* type = GetClass();
550 return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
551 }
552 return false;
553 }
554
IsInstantiableTypes() const555 bool RegType::IsInstantiableTypes() const {
556 return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
557 }
558
SelectNonConstant(const RegType & a,const RegType & b)559 static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
560 return a.IsConstantTypes() ? b : a;
561 }
562
Merge(const RegType & incoming_type,RegTypeCache * reg_types) const563 const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const {
564 DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller
565 // Perform pointer equality tests for conflict to avoid virtual method dispatch.
566 const ConflictType& conflict = reg_types->Conflict();
567 if (IsUndefined() || incoming_type.IsUndefined()) {
568 // There is a difference between undefined and conflict. Conflicts may be copied around, but
569 // not used. Undefined registers must not be copied. So any merge with undefined should return
570 // undefined.
571 if (IsUndefined()) {
572 return *this;
573 }
574 return incoming_type;
575 } else if (this == &conflict) {
576 DCHECK(IsConflict());
577 return *this; // Conflict MERGE * => Conflict
578 } else if (&incoming_type == &conflict) {
579 DCHECK(incoming_type.IsConflict());
580 return incoming_type; // * MERGE Conflict => Conflict
581 } else if (IsUndefined() || incoming_type.IsUndefined()) {
582 return conflict; // Unknown MERGE * => Conflict
583 } else if (IsConstant() && incoming_type.IsConstant()) {
584 const ConstantType& type1 = *down_cast<const ConstantType*>(this);
585 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
586 int32_t val1 = type1.ConstantValue();
587 int32_t val2 = type2.ConstantValue();
588 if (val1 >= 0 && val2 >= 0) {
589 // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
590 if (val1 >= val2) {
591 if (!type1.IsPreciseConstant()) {
592 return *this;
593 } else {
594 return reg_types->FromCat1Const(val1, false);
595 }
596 } else {
597 if (!type2.IsPreciseConstant()) {
598 return type2;
599 } else {
600 return reg_types->FromCat1Const(val2, false);
601 }
602 }
603 } else if (val1 < 0 && val2 < 0) {
604 // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
605 if (val1 <= val2) {
606 if (!type1.IsPreciseConstant()) {
607 return *this;
608 } else {
609 return reg_types->FromCat1Const(val1, false);
610 }
611 } else {
612 if (!type2.IsPreciseConstant()) {
613 return type2;
614 } else {
615 return reg_types->FromCat1Const(val2, false);
616 }
617 }
618 } else {
619 // Values are +ve and -ve, choose smallest signed type in which they both fit
620 if (type1.IsConstantByte()) {
621 if (type2.IsConstantByte()) {
622 return reg_types->ByteConstant();
623 } else if (type2.IsConstantShort()) {
624 return reg_types->ShortConstant();
625 } else {
626 return reg_types->IntConstant();
627 }
628 } else if (type1.IsConstantShort()) {
629 if (type2.IsConstantShort()) {
630 return reg_types->ShortConstant();
631 } else {
632 return reg_types->IntConstant();
633 }
634 } else {
635 return reg_types->IntConstant();
636 }
637 }
638 } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
639 const ConstantType& type1 = *down_cast<const ConstantType*>(this);
640 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
641 int32_t val1 = type1.ConstantValueLo();
642 int32_t val2 = type2.ConstantValueLo();
643 return reg_types->FromCat2ConstLo(val1 | val2, false);
644 } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
645 const ConstantType& type1 = *down_cast<const ConstantType*>(this);
646 const ConstantType& type2 = *down_cast<const ConstantType*>(&incoming_type);
647 int32_t val1 = type1.ConstantValueHi();
648 int32_t val2 = type2.ConstantValueHi();
649 return reg_types->FromCat2ConstHi(val1 | val2, false);
650 } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
651 if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
652 return reg_types->Boolean(); // boolean MERGE boolean => boolean
653 }
654 if (IsByteTypes() && incoming_type.IsByteTypes()) {
655 return reg_types->Byte(); // byte MERGE byte => byte
656 }
657 if (IsShortTypes() && incoming_type.IsShortTypes()) {
658 return reg_types->Short(); // short MERGE short => short
659 }
660 if (IsCharTypes() && incoming_type.IsCharTypes()) {
661 return reg_types->Char(); // char MERGE char => char
662 }
663 return reg_types->Integer(); // int MERGE * => int
664 } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
665 (IsLongTypes() && incoming_type.IsLongTypes()) ||
666 (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
667 (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
668 (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
669 // check constant case was handled prior to entry
670 DCHECK(!IsConstant() || !incoming_type.IsConstant());
671 // float/long/double MERGE float/long/double_constant => float/long/double
672 return SelectNonConstant(*this, incoming_type);
673 } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
674 if (IsZero() || incoming_type.IsZero()) {
675 return SelectNonConstant(*this, incoming_type); // 0 MERGE ref => ref
676 } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
677 return reg_types->JavaLangObject(false); // Object MERGE ref => Object
678 } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
679 // We know how to merge an unresolved type with itself, 0 or Object. In this case we
680 // have two sub-classes and don't know how to merge. Create a new string-based unresolved
681 // type that reflects our lack of knowledge and that allows the rest of the unresolved
682 // mechanics to continue.
683 return reg_types->FromUnresolvedMerge(*this, incoming_type);
684 } else if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
685 // Something that is uninitialized hasn't had its constructor called. Mark any merge
686 // of this type with something that is initialized as conflicting. The cases of a merge
687 // with itself, 0 or Object are handled above.
688 return conflict;
689 } else { // Two reference types, compute Join
690 mirror::Class* c1 = GetClass();
691 mirror::Class* c2 = incoming_type.GetClass();
692 DCHECK(c1 != nullptr && !c1->IsPrimitive());
693 DCHECK(c2 != nullptr && !c2->IsPrimitive());
694 mirror::Class* join_class = ClassJoin(c1, c2);
695 if (c1 == join_class && !IsPreciseReference()) {
696 return *this;
697 } else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
698 return incoming_type;
699 } else {
700 std::string temp;
701 return reg_types->FromClass(join_class->GetDescriptor(&temp), join_class, false);
702 }
703 }
704 } else {
705 return conflict; // Unexpected types => Conflict
706 }
707 }
708
709 // See comment in reg_type.h
ClassJoin(mirror::Class * s,mirror::Class * t)710 mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
711 DCHECK(!s->IsPrimitive()) << PrettyClass(s);
712 DCHECK(!t->IsPrimitive()) << PrettyClass(t);
713 if (s == t) {
714 return s;
715 } else if (s->IsAssignableFrom(t)) {
716 return s;
717 } else if (t->IsAssignableFrom(s)) {
718 return t;
719 } else if (s->IsArrayClass() && t->IsArrayClass()) {
720 mirror::Class* s_ct = s->GetComponentType();
721 mirror::Class* t_ct = t->GetComponentType();
722 if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
723 // Given the types aren't the same, if either array is of primitive types then the only
724 // common parent is java.lang.Object
725 mirror::Class* result = s->GetSuperClass(); // short-cut to java.lang.Object
726 DCHECK(result->IsObjectClass());
727 return result;
728 }
729 mirror::Class* common_elem = ClassJoin(s_ct, t_ct);
730 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
731 mirror::Class* array_class = class_linker->FindArrayClass(Thread::Current(), &common_elem);
732 DCHECK(array_class != nullptr);
733 return array_class;
734 } else {
735 size_t s_depth = s->Depth();
736 size_t t_depth = t->Depth();
737 // Get s and t to the same depth in the hierarchy
738 if (s_depth > t_depth) {
739 while (s_depth > t_depth) {
740 s = s->GetSuperClass();
741 s_depth--;
742 }
743 } else {
744 while (t_depth > s_depth) {
745 t = t->GetSuperClass();
746 t_depth--;
747 }
748 }
749 // Go up the hierarchy until we get to the common parent
750 while (s != t) {
751 s = s->GetSuperClass();
752 t = t->GetSuperClass();
753 }
754 return s;
755 }
756 }
757
CheckInvariants() const758 void RegType::CheckInvariants() const {
759 if (IsConstant() || IsConstantLo() || IsConstantHi()) {
760 CHECK(descriptor_.empty()) << *this;
761 CHECK(klass_.IsNull()) << *this;
762 }
763 if (!klass_.IsNull()) {
764 CHECK(!descriptor_.empty()) << *this;
765 }
766 }
767
VisitRoots(RootVisitor * visitor,const RootInfo & root_info) const768 void RegType::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) const {
769 klass_.VisitRootIfNonNull(visitor, root_info);
770 }
771
CheckInvariants() const772 void UninitializedThisReferenceType::CheckInvariants() const {
773 CHECK_EQ(GetAllocationPc(), 0U) << *this;
774 }
775
CheckInvariants() const776 void UnresolvedUninitializedThisRefType::CheckInvariants() const {
777 CHECK_EQ(GetAllocationPc(), 0U) << *this;
778 CHECK(!descriptor_.empty()) << *this;
779 CHECK(klass_.IsNull()) << *this;
780 }
781
CheckInvariants() const782 void UnresolvedUninitializedRefType::CheckInvariants() const {
783 CHECK(!descriptor_.empty()) << *this;
784 CHECK(klass_.IsNull()) << *this;
785 }
786
UnresolvedMergedType(const RegType & resolved,const BitVector & unresolved,const RegTypeCache * reg_type_cache,uint16_t cache_id)787 UnresolvedMergedType::UnresolvedMergedType(const RegType& resolved,
788 const BitVector& unresolved,
789 const RegTypeCache* reg_type_cache,
790 uint16_t cache_id)
791 : UnresolvedType("", cache_id),
792 reg_type_cache_(reg_type_cache),
793 resolved_part_(resolved),
794 unresolved_types_(unresolved, false, unresolved.GetAllocator()) {
795 if (kIsDebugBuild) {
796 CheckInvariants();
797 }
798 }
CheckInvariants() const799 void UnresolvedMergedType::CheckInvariants() const {
800 // Unresolved merged types: merged types should be defined.
801 CHECK(descriptor_.empty()) << *this;
802 CHECK(klass_.IsNull()) << *this;
803 CHECK(resolved_part_.IsReferenceTypes());
804 CHECK(!resolved_part_.IsUnresolvedTypes());
805 }
806
CheckInvariants() const807 void UnresolvedReferenceType::CheckInvariants() const {
808 CHECK(!descriptor_.empty()) << *this;
809 CHECK(klass_.IsNull()) << *this;
810 }
811
CheckInvariants() const812 void UnresolvedSuperClass::CheckInvariants() const {
813 // Unresolved merged types: merged types should be defined.
814 CHECK(descriptor_.empty()) << *this;
815 CHECK(klass_.IsNull()) << *this;
816 CHECK_NE(unresolved_child_id_, 0U) << *this;
817 }
818
operator <<(std::ostream & os,const RegType & rhs)819 std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
820 os << rhs.Dump();
821 return os;
822 }
823
CanAssignArray(const RegType & src,RegTypeCache & reg_types,Handle<mirror::ClassLoader> class_loader,bool * soft_error) const824 bool RegType::CanAssignArray(const RegType& src, RegTypeCache& reg_types,
825 Handle<mirror::ClassLoader> class_loader, bool* soft_error) const {
826 if (!IsArrayTypes() || !src.IsArrayTypes()) {
827 *soft_error = false;
828 return false;
829 }
830
831 const RegType& cmp1 = reg_types.GetComponentType(*this, class_loader.Get());
832 const RegType& cmp2 = reg_types.GetComponentType(src, class_loader.Get());
833
834 if (cmp1.IsAssignableFrom(cmp2)) {
835 return true;
836 }
837 if (cmp1.IsUnresolvedTypes()) {
838 if (cmp2.IsIntegralTypes() || cmp2.IsFloatTypes() || cmp2.IsArrayTypes()) {
839 *soft_error = false;
840 return false;
841 }
842 *soft_error = true;
843 return false;
844 }
845 if (cmp2.IsUnresolvedTypes()) {
846 if (cmp1.IsIntegralTypes() || cmp1.IsFloatTypes() || cmp1.IsArrayTypes()) {
847 *soft_error = false;
848 return false;
849 }
850 *soft_error = true;
851 return false;
852 }
853 if (!cmp1.IsArrayTypes() || !cmp2.IsArrayTypes()) {
854 *soft_error = false;
855 return false;
856 }
857 return cmp1.CanAssignArray(cmp2, reg_types, class_loader, soft_error);
858 }
859
860
861 } // namespace verifier
862 } // namespace art
863