blob: 5db6affcaeb5f1478871cdb88d7edab8e4693380 [file] [log] [blame]
Ian Rogers776ac1f2012-04-13 23:36:36 -07001/*
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.h"
18
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080019
20#include "base/casts.h"
Ian Rogers4f6ad8a2013-03-18 15:27:28 -070021#include "dex_file-inl.h"
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080022#include "mirror/class.h"
23#include "mirror/class-inl.h"
24#include "mirror/object-inl.h"
Ian Rogers693ff612013-02-01 10:56:12 -080025#include "mirror/object_array-inl.h"
Ian Rogers776ac1f2012-04-13 23:36:36 -070026#include "object_utils.h"
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080027#include "reg_type_cache-inl.h"
Ian Rogers776ac1f2012-04-13 23:36:36 -070028
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080029#include <limits>
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080030#include <sstream>
Ian Rogers2dd0e2c2013-01-24 12:42:14 -080031
Ian Rogers776ac1f2012-04-13 23:36:36 -070032namespace art {
33namespace verifier {
34
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080035UndefinedType* UndefinedType::instance_ = NULL;
36ConflictType* ConflictType::instance_ = NULL;
37BooleanType* BooleanType::instance = NULL;
38ByteType* ByteType::instance_ = NULL;
39ShortType* ShortType::instance_ = NULL;
40CharType* CharType::instance_ = NULL;
41FloatType* FloatType::instance_ = NULL;
42LongLoType* LongLoType::instance_ = NULL;
43LongHiType* LongHiType::instance_ = NULL;
44DoubleLoType* DoubleLoType::instance_ = NULL;
45DoubleHiType* DoubleHiType::instance_ = NULL;
46IntegerType* IntegerType::instance_ = NULL;
Ian Rogers776ac1f2012-04-13 23:36:36 -070047
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080048std::string PreciseConstType::Dump() const {
49 std::stringstream result;
50 uint32_t val = ConstantValue();
51 if (val == 0) {
52 CHECK(IsPreciseConstant());
53 result << "Zero/null";
Ian Rogers776ac1f2012-04-13 23:36:36 -070054 } else {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080055 result << "Precise ";
56 if (IsConstantShort()) {
57 result << StringPrintf("Constant: %d", val);
58 } else {
59 result << StringPrintf("Constant: 0x%x", val);
Ian Rogers776ac1f2012-04-13 23:36:36 -070060 }
61 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080062 return result.str();
63}
64
65std::string BooleanType::Dump() const {
66 return "boolean";
67}
68
69std::string ConflictType::Dump() const {
70 return "Conflict";
71}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070072
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080073std::string ByteType::Dump() const {
74 return "Byte";
75}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070076
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080077std::string ShortType::Dump() const {
78 return "short";
79}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070080
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080081std::string CharType::Dump() const {
82 return "Char";
83}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070084
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080085std::string FloatType::Dump() const {
86 return "float";
87}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070088
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080089std::string LongLoType::Dump() const {
90 return "long (Low Half)";
91}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070092
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080093std::string LongHiType::Dump() const {
94 return "long (High Half)";
95}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -070096
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -080097std::string DoubleLoType::Dump() const {
98 return "Double (Low Half)";
99}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700100
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800101std::string DoubleHiType::Dump() const {
102 return "Double (High Half)";
103}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700104
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800105std::string IntegerType::Dump() const {
106 return "Integer";
107}
108
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700109DoubleHiType* DoubleHiType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800110 uint16_t cache_id) {
111 if (instance_ == NULL) {
112 instance_ = new DoubleHiType(klass, descriptor, cache_id);
113 }
114 return instance_;
115}
116
117DoubleHiType* DoubleHiType::GetInstance() {
118 CHECK(instance_ != NULL);
119 return instance_;
120}
121
122void DoubleHiType::Destroy() {
123 if (instance_ != NULL) {
124 delete instance_;
125 instance_ = NULL;
126 }
127}
128
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700129DoubleLoType* DoubleLoType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800130 uint16_t cache_id) {
131 if (instance_ == NULL) {
132 instance_ = new DoubleLoType(klass, descriptor, cache_id);
133 }
134 return instance_;
135}
136
137DoubleLoType* DoubleLoType::GetInstance() {
138 CHECK(instance_ != NULL);
139 return instance_;
140}
141
142void DoubleLoType::Destroy() {
143 if (instance_ != NULL) {
144 delete instance_;
145 instance_ = NULL;
146 }
147}
148
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700149LongLoType* LongLoType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800150 uint16_t cache_id) {
151 if (instance_ == NULL) {
152 instance_ = new LongLoType(klass, descriptor, cache_id);
153 }
154 return instance_;
155}
156
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700157LongHiType* LongHiType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800158 uint16_t cache_id) {
159 if (instance_ == NULL) {
160 instance_ = new LongHiType(klass, descriptor, cache_id);
161 }
162 return instance_;
163}
164
165LongHiType* LongHiType::GetInstance() {
166 CHECK(instance_ != NULL);
167 return instance_;
168}
169
170void LongHiType::Destroy() {
171 if (instance_ != NULL) {
172 delete instance_;
173 instance_ = NULL;
174 }
175}
176
177LongLoType* LongLoType::GetInstance() {
178 CHECK (instance_ != NULL);
179 return instance_;
180}
181
182void LongLoType::Destroy() {
183 if (instance_ != NULL) {
184 delete instance_;
185 instance_ = NULL;
186 }
187}
188
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700189FloatType* FloatType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
190 uint16_t cache_id) {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800191 if (instance_ == NULL) {
192 instance_ = new FloatType(klass, descriptor, cache_id);
193 }
194 return instance_;
195}
196FloatType* FloatType::GetInstance() {
197 CHECK(instance_ != NULL);
198 return instance_;
199}
200
201void FloatType::Destroy() {
202 if (instance_ != NULL) {
203 delete instance_;
204 instance_ = NULL;
205 }
206}
207
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700208CharType* CharType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800209 uint16_t cache_id) {
210 if (instance_ == NULL) {
211 instance_ = new CharType(klass, descriptor, cache_id);
212 }
213 return instance_;
214}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700215
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800216CharType* CharType::GetInstance() {
217 CHECK(instance_ != NULL);
218 return instance_;
219}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700220
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800221void CharType::Destroy() {
222 if (instance_ != NULL) {
223 delete instance_;
224 instance_ = NULL;
225 }
226}
227
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700228ShortType* ShortType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800229 uint16_t cache_id) {
230 if (instance_ == NULL) {
231 instance_ = new ShortType(klass, descriptor, cache_id);
232 }
233 return instance_;
234}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700235
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800236ShortType* ShortType::GetInstance() {
237 CHECK(instance_ != NULL);
238 return instance_;
239}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700240
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800241void ShortType::Destroy() {
242 if (instance_ != NULL) {
243 delete instance_;
244 instance_ = NULL;
245 }
246}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700247
248ByteType* ByteType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
249 uint16_t cache_id) {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800250 if (instance_ == NULL) {
251 instance_ = new ByteType(klass, descriptor, cache_id);
252 }
253 return instance_;
254}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700255
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800256ByteType* ByteType::GetInstance() {
257 CHECK(instance_ != NULL);
258 return instance_;
259}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700260
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800261void ByteType::Destroy() {
262 if (instance_ != NULL) {
263 delete instance_;
264 instance_ = NULL;
265 }
266}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700267
268IntegerType* IntegerType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800269 uint16_t cache_id) {
270 if (instance_ == NULL) {
271 instance_ = new IntegerType(klass, descriptor, cache_id);
272 }
273 return instance_;
274}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700275
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800276IntegerType* IntegerType::GetInstance() {
277 CHECK(instance_ != NULL);
278 return instance_;
279}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700280
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800281void IntegerType::Destroy() {
282 if (instance_ != NULL) {
283 delete instance_;
284 instance_ = NULL;
285 }
286}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700287
288ConflictType* ConflictType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800289 uint16_t cache_id) {
290 if (instance_ == NULL) {
291 instance_ = new ConflictType(klass, descriptor, cache_id);
292 }
293 return instance_;
294}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700295
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800296ConflictType* ConflictType::GetInstance() {
297 CHECK(instance_ != NULL);
298 return instance_;
299}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700300
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800301void ConflictType::Destroy() {
302 if (instance_ != NULL) {
303 delete instance_;
304 instance_ = NULL;
305 }
306}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700307
308BooleanType* BooleanType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800309 uint16_t cache_id) {
310 if (BooleanType::instance == NULL) {
311 instance = new BooleanType(klass, descriptor, cache_id);
312 }
313 return BooleanType::instance;
314}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700315
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800316BooleanType* BooleanType::GetInstance() {
317 CHECK(BooleanType::instance != NULL);
318 return BooleanType::instance;
319}
320
321void BooleanType::Destroy() {
322 if(BooleanType::instance != NULL) {
323 delete instance;
324 instance = NULL;
325 }
326}
327
328std::string UndefinedType::Dump() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
329 return "Undefined";
330}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700331
332UndefinedType* UndefinedType::CreateInstance(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800333 uint16_t cache_id) {
334 if (instance_ == NULL) {
335 instance_ = new UndefinedType(klass, descriptor, cache_id);
336 }
337 return instance_;
338}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700339
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800340UndefinedType* UndefinedType::GetInstance() {
341 CHECK(instance_ != NULL);
342 return instance_;
343}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700344
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800345void UndefinedType::Destroy() {
346 if (instance_ != NULL) {
347 delete instance_;
348 instance_ = NULL;
349 }
350}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700351
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800352std::string UnresolvedMergedType::Dump() const {
353 std::stringstream result;
354 std::set<uint16_t> types = GetMergedTypes();
355 result << "UnresolvedMergedReferences(";
356 typedef std::set<uint16_t>::const_iterator It; // TODO: C++0x auto
357 It it = types.begin();
358 result << reg_type_cache_->GetFromId(*it).Dump();
359 for (++it; it != types.end(); ++it) {
360 result << ", ";
361 result << reg_type_cache_->GetFromId(*it).Dump();
362 }
363 result << ")";
364 return result.str();
365}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700366
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800367std::string UnresolvedSuperClass::Dump() const {
368 std::stringstream result;
369 uint16_t super_type_id = GetUnresolvedSuperClassChildId();
370 result << "UnresolvedSuperClass(" << reg_type_cache_->GetFromId(super_type_id).Dump() << ")";
371 return result.str();
372}
373
374std::string UnresolvedReferenceType::Dump() const {
375 std::stringstream result;
376 result << "Unresolved Reference" << ": " << PrettyDescriptor(GetDescriptor());
377 return result.str();
378}
379
380std::string UnresolvedUninitializedRefType::Dump() const {
381 std::stringstream result;
382 result << "Unresolved And Uninitialized Reference" << ": " << PrettyDescriptor(GetDescriptor());
383 result << " Allocation PC: " << GetAllocationPc();
384 return result.str();
385}
386
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700387std::string UnresolvedUninitializedThisRefType::Dump() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800388 std::stringstream result;
389 result << "Unresolved And Uninitialized This Reference" << PrettyDescriptor(GetDescriptor());
390 return result.str();
391}
392
393std::string ReferenceType::Dump() const {
394 std::stringstream result;
395 result << "Reference" << ": " << PrettyDescriptor(GetClass());
396 return result.str();
397}
398
399std::string PreciseReferenceType::Dump() const {
400 std::stringstream result;
401 result << "Precise Reference" << ": "<< PrettyDescriptor(GetClass());
402 return result.str();
403}
404
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700405std::string UninitializedReferenceType::Dump() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800406 std::stringstream result;
407 result << "Uninitialized Reference" << ": " << PrettyDescriptor(GetClass());
408 result << " Allocation PC: " << GetAllocationPc();
409 return result.str();
410}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700411
412std::string UninitializedThisReferenceType::Dump() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800413 std::stringstream result;
414 result << "Uninitialized This Reference" << ": " << PrettyDescriptor(GetClass());
415 result << "Allocation PC: " << GetAllocationPc();
416 return result.str();
417}
418
419std::string ImpreciseConstType::Dump() const {
420 std::stringstream result;
421 uint32_t val = ConstantValue();
422 if (val == 0) {
423 CHECK(IsPreciseConstant());
424 result << "Zero/null";
425 } else {
426 result << "Imprecise ";
427 if (IsConstantShort()) {
428 result << StringPrintf("Constant: %d", val);
429 } else {
430 result << StringPrintf("Constant: 0x%x", val);
431 }
432 }
433 return result.str();
434}
435std::string PreciseConstLoType::Dump() const {
436 std::stringstream result;
437
438 int32_t val = ConstantValueLo();
439 result << "Precise ";
440 if (val >= std::numeric_limits<jshort>::min() &&
441 val <= std::numeric_limits<jshort>::max()) {
442 result << StringPrintf("Low-half Constant: %d", val);
443 } else {
444 result << StringPrintf("Low-half Constant: 0x%x", val);
445 }
446 return result.str();
447}
448
449std::string ImpreciseConstLoType::Dump() const {
450 std::stringstream result;
451
452 int32_t val = ConstantValueLo();
453 result << "Imprecise ";
454 if (val >= std::numeric_limits<jshort>::min() &&
455 val <= std::numeric_limits<jshort>::max()) {
456 result << StringPrintf("Low-half Constant: %d", val);
457 } else {
458 result << StringPrintf("Low-half Constant: 0x%x", val);
459 }
460 return result.str();
461}
462
463std::string PreciseConstHiType::Dump() const {
464 std::stringstream result;
465 int32_t val = ConstantValueHi();
466 result << "Precise ";
467 if (val >= std::numeric_limits<jshort>::min() &&
468 val <= std::numeric_limits<jshort>::max()) {
469 result << StringPrintf("High-half Constant: %d", val);
470 } else {
471 result << StringPrintf("High-half Constant: 0x%x", val);
472 }
473 return result.str();
474}
475
476std::string ImpreciseConstHiType::Dump() const {
477 std::stringstream result;
478 int32_t val = ConstantValueHi();
479 result << "Imprecise ";
480 if (val >= std::numeric_limits<jshort>::min() &&
481 val <= std::numeric_limits<jshort>::max()) {
482 result << StringPrintf("High-half Constant: %d", val);
483 } else {
484 result << StringPrintf("High-half Constant: 0x%x", val);
485 }
486 return result.str();
487}
488
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700489BooleanType::BooleanType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800490 : RegType(klass, descriptor, cache_id) {
491}
492
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700493ConflictType::ConflictType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800494 : RegType(klass, descriptor, cache_id) {
495}
496
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700497ByteType::ByteType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800498 : RegType(klass, descriptor, cache_id) {
499}
500
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700501ShortType::ShortType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800502 : RegType(klass, descriptor, cache_id) {
503}
504
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700505CharType::CharType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800506 : RegType(klass, descriptor, cache_id) {
507}
508
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700509IntegerType::IntegerType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800510 : RegType(klass, descriptor, cache_id) {
511}
512
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700513ConstantType::ConstantType(uint32_t constant, uint16_t cache_id)
514 : RegType(NULL, "", cache_id), constant_(constant) {
515}
516
517ReferenceType::ReferenceType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
518 : RegType(klass, descriptor, cache_id) {
519}
520
521PreciseReferenceType::PreciseReferenceType(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800522 uint16_t cache_id)
523 : RegType(klass, descriptor, cache_id) {
Sameer Abu Asal02c42232013-04-30 12:09:45 -0700524 DCHECK(klass->IsInstantiable());
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800525}
526
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700527UnresolvedUninitializedThisRefType::UnresolvedUninitializedThisRefType(const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800528 uint16_t cache_id)
529 : UninitializedType(NULL, descriptor, 0, cache_id) {
530}
531
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700532UnresolvedUninitializedRefType::UnresolvedUninitializedRefType(const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800533 uint32_t allocation_pc, uint16_t cache_id)
534 : UninitializedType(NULL, descriptor, allocation_pc, cache_id) {
535}
536
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700537UninitializedReferenceType::UninitializedReferenceType(mirror::Class* klass,
538 const std::string& descriptor,
539 uint32_t allocation_pc, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800540 : UninitializedType(klass, descriptor, allocation_pc, cache_id) {
541}
542
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700543LongHiType::LongHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800544 : RegType(klass, descriptor, cache_id) {
545}
546
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700547FloatType::FloatType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800548 : RegType(klass, descriptor, cache_id) {
549}
550
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700551DoubleLoType::DoubleLoType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800552 : RegType(klass, descriptor, cache_id) {
553}
554
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700555DoubleHiType::DoubleHiType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800556 : RegType(klass, descriptor, cache_id) {
557}
558
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700559LongLoType::LongLoType(mirror::Class* klass, const std::string& descriptor, uint16_t cache_id)
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800560 : RegType(klass, descriptor, cache_id) {
561}
562
563const RegType& UndefinedType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const
564 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
565 if (incoming_type.IsUndefined()) {
566 return *this; // Undefined MERGE Undefined => Undefined
567 }
568 return reg_types->Conflict();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700569}
570
571const RegType& RegType::HighHalf(RegTypeCache* cache) const {
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800572 DCHECK(IsLowHalf());
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800573 if (IsLongLo()) {
574 return cache->LongHi();
575 } else if (IsDoubleLo()) {
576 return cache->DoubleHi();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700577 } else {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800578 DCHECK(IsImpreciseConstantLo());
579 return cache->FromCat2ConstHi(ConstantValue(), false);
Ian Rogers776ac1f2012-04-13 23:36:36 -0700580 }
581}
582
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800583Primitive::Type RegType::GetPrimitiveType() const {
584 if (IsNonZeroReferenceTypes()) {
585 return Primitive::kPrimNot;
586 } else if (IsBooleanTypes()) {
587 return Primitive::kPrimBoolean;
588 } else if (IsByteTypes()) {
589 return Primitive::kPrimByte;
590 } else if (IsShortTypes()) {
591 return Primitive::kPrimShort;
592 } else if (IsCharTypes()) {
593 return Primitive::kPrimChar;
594 } else if (IsFloat()) {
595 return Primitive::kPrimFloat;
596 } else if (IsIntegralTypes()) {
597 return Primitive::kPrimInt;
598 } else if (IsDoubleLo()) {
599 return Primitive::kPrimDouble;
600 } else {
601 DCHECK(IsLongTypes());
602 return Primitive::kPrimLong;
603 }
604}
605
606std::set<uint16_t> UnresolvedMergedType::GetMergedTypes() const {
Ian Rogers529781d2012-07-23 17:24:29 -0700607 std::pair<uint16_t, uint16_t> refs = GetTopMergedTypes();
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800608 const RegType& _left(reg_type_cache_->GetFromId(refs.first));
609 RegType& __left(const_cast<RegType&>(_left));
610 UnresolvedMergedType* left = down_cast<UnresolvedMergedType*>(&__left);
611
612 RegType& _right(
613 const_cast<RegType&>(reg_type_cache_->GetFromId(refs.second)));
614 UnresolvedMergedType* right = down_cast<UnresolvedMergedType*>(&_right);
615
Ian Rogers529781d2012-07-23 17:24:29 -0700616 std::set<uint16_t> types;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800617 if (left->IsUnresolvedMergedReference()) {
618 types = left->GetMergedTypes();
Ian Rogers529781d2012-07-23 17:24:29 -0700619 } else {
620 types.insert(refs.first);
621 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800622 if (right->IsUnresolvedMergedReference()) {
623 std::set<uint16_t> right_types = right->GetMergedTypes();
Ian Rogers529781d2012-07-23 17:24:29 -0700624 types.insert(right_types.begin(), right_types.end());
625 } else {
626 types.insert(refs.second);
627 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800628 if (kIsDebugBuild) {
629 typedef std::set<uint16_t>::const_iterator It; // TODO: C++0x auto
630 for (It it = types.begin(); it != types.end(); ++it) {
631 CHECK(!reg_type_cache_->GetFromId(*it).IsUnresolvedMergedReference());
632 }
Ian Rogers529781d2012-07-23 17:24:29 -0700633 }
Ian Rogers529781d2012-07-23 17:24:29 -0700634 return types;
635}
636
Ian Rogersad0b3a32012-04-16 14:50:24 -0700637const RegType& RegType::GetSuperClass(RegTypeCache* cache) const {
638 if (!IsUnresolvedTypes()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800639 mirror::Class* super_klass = GetClass()->GetSuperClass();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700640 if (super_klass != NULL) {
Sameer Abu Asal02c42232013-04-30 12:09:45 -0700641 // A super class of a precise type isn't precise as a precise type indicates the register
642 // holds exactly that type.
643 return cache->FromClass(super_klass, false);
Ian Rogers0d604842012-04-16 14:50:24 -0700644 } else {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700645 return cache->Zero();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700646 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700647 } else {
Ian Rogers529781d2012-07-23 17:24:29 -0700648 if (!IsUnresolvedMergedReference() && !IsUnresolvedSuperClass() &&
Elliott Hughes80537bb2013-01-04 16:37:26 -0800649 GetDescriptor()[0] == '[') {
Ian Rogers529781d2012-07-23 17:24:29 -0700650 // Super class of all arrays is Object.
Ian Rogersb4903572012-10-11 11:52:56 -0700651 return cache->JavaLangObject(true);
Ian Rogers529781d2012-07-23 17:24:29 -0700652 } else {
653 return cache->FromUnresolvedSuperClass(*this);
654 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700655 }
656}
657
658bool RegType::CanAccess(const RegType& other) const {
659 if (Equals(other)) {
660 return true; // Trivial accessibility.
661 } else {
662 bool this_unresolved = IsUnresolvedTypes();
663 bool other_unresolved = other.IsUnresolvedTypes();
664 if (!this_unresolved && !other_unresolved) {
665 return GetClass()->CanAccess(other.GetClass());
666 } else if (!other_unresolved) {
667 return other.GetClass()->IsPublic(); // Be conservative, only allow if other is public.
668 } else {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800669 return false; // More complicated test not possible on unresolved types, be conservative.
Ian Rogerse1758fe2012-04-19 11:31:15 -0700670 }
Ian Rogersad0b3a32012-04-16 14:50:24 -0700671 }
672}
673
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800674bool RegType::CanAccessMember(mirror::Class* klass, uint32_t access_flags) const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800675 if ((access_flags & kAccPublic) != 0) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700676 return true;
677 }
678 if (!IsUnresolvedTypes()) {
679 return GetClass()->CanAccessMember(klass, access_flags);
680 } else {
681 return false; // More complicated test not possible on unresolved types, be conservative.
Ian Rogers776ac1f2012-04-13 23:36:36 -0700682 }
683}
684
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800685bool RegType::IsObjectArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
686 if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
687 // Primitive arrays will always resolve
688 DCHECK(descriptor_[1] == 'L' || descriptor_[1] == '[');
689 return descriptor_[0] == '[';
690 } else if (HasClass()) {
691 mirror::Class* type = GetClass();
692 return type->IsArrayClass() && !type->GetComponentType()->IsPrimitive();
693 } else {
694 return false;
695 }
696}
697
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800698bool RegType::IsJavaLangObject() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
699 return IsReference() && GetClass()->IsObjectClass();
700}
701
702bool RegType::IsArrayTypes() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
703 if (IsUnresolvedTypes() && !IsUnresolvedMergedReference() && !IsUnresolvedSuperClass()) {
704 return descriptor_[0] == '[';
705 } else if (HasClass()) {
706 return GetClass()->IsArrayClass();
707 } else {
708 return false;
709 }
710}
711
712bool RegType::IsJavaLangObjectArray() const {
713 if (HasClass()) {
714 mirror::Class* type = GetClass();
715 return type->IsArrayClass() && type->GetComponentType()->IsObjectClass();
716 }
717 return false;
718}
719
720bool RegType::IsInstantiableTypes() const {
721 return IsUnresolvedTypes() || (IsNonZeroReferenceTypes() && GetClass()->IsInstantiable());
722}
723
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800724ImpreciseConstType::ImpreciseConstType(uint32_t constat, uint16_t cache_id)
725 : ConstantType(constat, cache_id) {
726}
727
Ian Rogers776ac1f2012-04-13 23:36:36 -0700728bool RegType::IsAssignableFrom(const RegType& src) const {
729 if (Equals(src)) {
730 return true;
731 } else {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800732 if (IsBoolean()) {
733 return src.IsBooleanTypes();
734 } else if (IsByte()) {
735 return src.IsByteTypes();
736 } else if (IsShort()) {
737 return src.IsShortTypes();
738 } else if (IsChar()) {
739 return src.IsCharTypes();
740 } else if (IsInteger()) {
741 return src.IsIntegralTypes();
742 } else if (IsFloat()) {
743 return src.IsFloatTypes();
744 } else if (IsLongLo()) {
745 return src.IsLongTypes();
746 } else if (IsDoubleLo()) {
747 return src.IsDoubleTypes();
748 } else {
749 if (!IsReferenceTypes()) {
750 LOG(FATAL) << "Unexpected register type in 4bleFrom: '" << src << "'";
751 }
752 if (src.IsZero()) {
753 return true; // all reference types can be assigned null
754 } else if (!src.IsReferenceTypes()) {
755 return false; // expect src to be a reference type
756 } else if (IsJavaLangObject()) {
757 return true; // all reference types can be assigned to Object
758 } else if (!IsUnresolvedTypes() && GetClass()->IsInterface()) {
Ian Rogers776ac1f2012-04-13 23:36:36 -0700759 return true; // We allow assignment to any interface, see comment in ClassJoin
760 } else if (IsJavaLangObjectArray()) {
761 return src.IsObjectArrayTypes(); // All reference arrays may be assigned to Object[]
762 } else if (!IsUnresolvedTypes() && !src.IsUnresolvedTypes() &&
763 GetClass()->IsAssignableFrom(src.GetClass())) {
764 // We're assignable from the Class point-of-view
765 return true;
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800766 } else if (IsUnresolvedTypes()) {
767 // Unresolved types are only assignable for null, Object and equality.
768 return (src.IsZero() || src.IsJavaLangObject());
Ian Rogers776ac1f2012-04-13 23:36:36 -0700769 } else {
770 return false;
771 }
772 }
773 }
774}
775
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800776int32_t ConstantType::ConstantValue() const {
777 DCHECK(IsConstantTypes());
778 return constant_;
779}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700780
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800781int32_t ConstantType::ConstantValueLo() const {
782 DCHECK(IsConstantLo());
783 return constant_;
784}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700785
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800786int32_t ConstantType::ConstantValueHi() const {
787 if (IsConstantHi() || IsPreciseConstantHi() || IsImpreciseConstantHi()) {
788 return constant_;
789 } else {
790 DCHECK(false);
791 return 0;
792 }
793}
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700794
Ian Rogers776ac1f2012-04-13 23:36:36 -0700795static const RegType& SelectNonConstant(const RegType& a, const RegType& b) {
796 return a.IsConstant() ? b : a;
797}
798
799const RegType& RegType::Merge(const RegType& incoming_type, RegTypeCache* reg_types) const {
800 DCHECK(!Equals(incoming_type)); // Trivial equality handled by caller
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800801 if (IsConflict()) {
Ian Rogers776ac1f2012-04-13 23:36:36 -0700802 return *this; // Conflict MERGE * => Conflict
803 } else if (incoming_type.IsConflict()) {
804 return incoming_type; // * MERGE Conflict => Conflict
Ian Rogersad0b3a32012-04-16 14:50:24 -0700805 } else if (IsUndefined() || incoming_type.IsUndefined()) {
Ian Rogers776ac1f2012-04-13 23:36:36 -0700806 return reg_types->Conflict(); // Unknown MERGE * => Conflict
807 } else if (IsConstant() && incoming_type.IsConstant()) {
808 int32_t val1 = ConstantValue();
809 int32_t val2 = incoming_type.ConstantValue();
810 if (val1 >= 0 && val2 >= 0) {
811 // +ve1 MERGE +ve2 => MAX(+ve1, +ve2)
812 if (val1 >= val2) {
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800813 if (!IsPreciseConstant()) {
814 return *this;
815 } else {
816 return reg_types->FromCat1Const(val1, false);
817 }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700818 } else {
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800819 if (!incoming_type.IsPreciseConstant()) {
820 return incoming_type;
821 } else {
822 return reg_types->FromCat1Const(val2, false);
823 }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700824 }
825 } else if (val1 < 0 && val2 < 0) {
826 // -ve1 MERGE -ve2 => MIN(-ve1, -ve2)
827 if (val1 <= val2) {
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800828 if (!IsPreciseConstant()) {
829 return *this;
830 } else {
831 return reg_types->FromCat1Const(val1, false);
832 }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700833 } else {
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800834 if (!incoming_type.IsPreciseConstant()) {
835 return incoming_type;
836 } else {
837 return reg_types->FromCat1Const(val2, false);
838 }
Ian Rogers776ac1f2012-04-13 23:36:36 -0700839 }
840 } else {
841 // Values are +ve and -ve, choose smallest signed type in which they both fit
842 if (IsConstantByte()) {
843 if (incoming_type.IsConstantByte()) {
844 return reg_types->ByteConstant();
845 } else if (incoming_type.IsConstantShort()) {
846 return reg_types->ShortConstant();
847 } else {
848 return reg_types->IntConstant();
849 }
850 } else if (IsConstantShort()) {
851 if (incoming_type.IsConstantShort()) {
852 return reg_types->ShortConstant();
853 } else {
854 return reg_types->IntConstant();
855 }
856 } else {
857 return reg_types->IntConstant();
858 }
859 }
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800860 } else if (IsConstantLo() && incoming_type.IsConstantLo()) {
861 int32_t val1 = ConstantValueLo();
862 int32_t val2 = incoming_type.ConstantValueLo();
863 return reg_types->FromCat2ConstLo(val1 | val2, false);
864 } else if (IsConstantHi() && incoming_type.IsConstantHi()) {
865 int32_t val1 = ConstantValueHi();
866 int32_t val2 = incoming_type.ConstantValueHi();
867 return reg_types->FromCat2ConstHi(val1 | val2, false);
Ian Rogers776ac1f2012-04-13 23:36:36 -0700868 } else if (IsIntegralTypes() && incoming_type.IsIntegralTypes()) {
869 if (IsBooleanTypes() && incoming_type.IsBooleanTypes()) {
870 return reg_types->Boolean(); // boolean MERGE boolean => boolean
871 }
872 if (IsByteTypes() && incoming_type.IsByteTypes()) {
873 return reg_types->Byte(); // byte MERGE byte => byte
874 }
875 if (IsShortTypes() && incoming_type.IsShortTypes()) {
876 return reg_types->Short(); // short MERGE short => short
877 }
878 if (IsCharTypes() && incoming_type.IsCharTypes()) {
879 return reg_types->Char(); // char MERGE char => char
880 }
881 return reg_types->Integer(); // int MERGE * => int
882 } else if ((IsFloatTypes() && incoming_type.IsFloatTypes()) ||
883 (IsLongTypes() && incoming_type.IsLongTypes()) ||
884 (IsLongHighTypes() && incoming_type.IsLongHighTypes()) ||
885 (IsDoubleTypes() && incoming_type.IsDoubleTypes()) ||
886 (IsDoubleHighTypes() && incoming_type.IsDoubleHighTypes())) {
887 // check constant case was handled prior to entry
888 DCHECK(!IsConstant() || !incoming_type.IsConstant());
889 // float/long/double MERGE float/long/double_constant => float/long/double
890 return SelectNonConstant(*this, incoming_type);
891 } else if (IsReferenceTypes() && incoming_type.IsReferenceTypes()) {
892 if (IsZero() || incoming_type.IsZero()) {
893 return SelectNonConstant(*this, incoming_type); // 0 MERGE ref => ref
894 } else if (IsJavaLangObject() || incoming_type.IsJavaLangObject()) {
Ian Rogersb4903572012-10-11 11:52:56 -0700895 return reg_types->JavaLangObject(false); // Object MERGE ref => Object
Ian Rogers529781d2012-07-23 17:24:29 -0700896 } else if (IsUnresolvedTypes() || incoming_type.IsUnresolvedTypes()) {
897 // We know how to merge an unresolved type with itself, 0 or Object. In this case we
898 // have two sub-classes and don't know how to merge. Create a new string-based unresolved
899 // type that reflects our lack of knowledge and that allows the rest of the unresolved
900 // mechanics to continue.
901 return reg_types->FromUnresolvedMerge(*this, incoming_type);
902 } else if (IsUninitializedTypes() || incoming_type.IsUninitializedTypes()) {
903 // Something that is uninitialized hasn't had its constructor called. Mark any merge
904 // of this type with something that is initialized as conflicting. The cases of a merge
905 // with itself, 0 or Object are handled above.
Ian Rogers776ac1f2012-04-13 23:36:36 -0700906 return reg_types->Conflict();
907 } else { // Two reference types, compute Join
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800908 mirror::Class* c1 = GetClass();
909 mirror::Class* c2 = incoming_type.GetClass();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700910 DCHECK(c1 != NULL && !c1->IsPrimitive());
911 DCHECK(c2 != NULL && !c2->IsPrimitive());
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800912 mirror::Class* join_class = ClassJoin(c1, c2);
Ian Rogersb4903572012-10-11 11:52:56 -0700913 if (c1 == join_class && !IsPreciseReference()) {
Ian Rogers776ac1f2012-04-13 23:36:36 -0700914 return *this;
Ian Rogersb4903572012-10-11 11:52:56 -0700915 } else if (c2 == join_class && !incoming_type.IsPreciseReference()) {
Ian Rogers776ac1f2012-04-13 23:36:36 -0700916 return incoming_type;
917 } else {
Ian Rogersb4903572012-10-11 11:52:56 -0700918 return reg_types->FromClass(join_class, false);
Ian Rogers776ac1f2012-04-13 23:36:36 -0700919 }
920 }
921 } else {
922 return reg_types->Conflict(); // Unexpected types => Conflict
923 }
924}
925
Ian Rogersad0b3a32012-04-16 14:50:24 -0700926// See comment in reg_type.h
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800927mirror::Class* RegType::ClassJoin(mirror::Class* s, mirror::Class* t) {
Ian Rogersad0b3a32012-04-16 14:50:24 -0700928 DCHECK(!s->IsPrimitive()) << PrettyClass(s);
929 DCHECK(!t->IsPrimitive()) << PrettyClass(t);
930 if (s == t) {
931 return s;
932 } else if (s->IsAssignableFrom(t)) {
933 return s;
934 } else if (t->IsAssignableFrom(s)) {
935 return t;
936 } else if (s->IsArrayClass() && t->IsArrayClass()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800937 mirror::Class* s_ct = s->GetComponentType();
938 mirror::Class* t_ct = t->GetComponentType();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700939 if (s_ct->IsPrimitive() || t_ct->IsPrimitive()) {
940 // Given the types aren't the same, if either array is of primitive types then the only
941 // common parent is java.lang.Object
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800942 mirror::Class* result = s->GetSuperClass(); // short-cut to java.lang.Object
Ian Rogersad0b3a32012-04-16 14:50:24 -0700943 DCHECK(result->IsObjectClass());
944 return result;
945 }
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800946 mirror::Class* common_elem = ClassJoin(s_ct, t_ct);
Ian Rogersad0b3a32012-04-16 14:50:24 -0700947 ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800948 mirror::ClassLoader* class_loader = s->GetClassLoader();
Ian Rogersad0b3a32012-04-16 14:50:24 -0700949 std::string descriptor("[");
950 descriptor += ClassHelper(common_elem).GetDescriptor();
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800951 mirror::Class* array_class = class_linker->FindClass(descriptor.c_str(), class_loader);
Ian Rogersad0b3a32012-04-16 14:50:24 -0700952 DCHECK(array_class != NULL);
953 return array_class;
954 } else {
955 size_t s_depth = s->Depth();
956 size_t t_depth = t->Depth();
957 // Get s and t to the same depth in the hierarchy
958 if (s_depth > t_depth) {
959 while (s_depth > t_depth) {
960 s = s->GetSuperClass();
961 s_depth--;
962 }
963 } else {
964 while (t_depth > s_depth) {
965 t = t->GetSuperClass();
966 t_depth--;
967 }
968 }
969 // Go up the hierarchy until we get to the common parent
970 while (s != t) {
971 s = s->GetSuperClass();
972 t = t->GetSuperClass();
973 }
974 return s;
975 }
976}
977
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800978void RegType::CheckInvariants() const {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800979 if (IsConstant() || IsConstantLo() || IsConstantHi()) {
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800980 CHECK(descriptor_.empty()) << *this;
981 CHECK(klass_ == NULL) << *this;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -0800982 }
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800983}
984
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700985UninitializedType::UninitializedType(mirror::Class* klass, const std::string& descriptor,
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800986 uint32_t allocation_pc, uint16_t cache_id)
987 : RegType(klass, descriptor, cache_id), allocation_pc_(allocation_pc) {
988}
989
990void UninitializedType::CheckInvariants() const {
991 CHECK_EQ(allocation_pc_, 0U) << *this;
992}
993
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700994void UninitializedThisReferenceType::CheckInvariants() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -0800995 UninitializedType::CheckInvariants();
996}
997
Ian Rogers1bf8d4d2013-05-30 00:18:49 -0700998UninitializedThisReferenceType::UninitializedThisReferenceType(mirror::Class* klass,
999 const std::string& descriptor, uint16_t cache_id) : UninitializedType(klass, descriptor, 0, cache_id) {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -08001000}
1001
Ian Rogers1bf8d4d2013-05-30 00:18:49 -07001002void UnresolvedUninitializedThisRefType::CheckInvariants() const {
Sameer Abu Asal51a5fb72013-02-19 14:25:01 -08001003 UninitializedType::CheckInvariants();
1004 CHECK(!descriptor_.empty()) << *this;
1005 CHECK(klass_ == NULL) << *this;
1006}
1007
1008void UnresolvedUninitializedRefType::CheckInvariants() const {
1009 UninitializedType::CheckInvariants();
1010 CHECK(!descriptor_.empty()) << *this;
1011 CHECK(klass_ == NULL) << *this;
1012}
1013
1014void UnresolvedMergedType::CheckInvariants() const {
1015 // Unresolved merged types: merged types should be defined.
1016 CHECK(descriptor_.empty()) << *this;
1017 CHECK(klass_ == NULL) << *this;
1018 CHECK_NE(merged_types_.first, 0U) << *this;
1019 CHECK_NE(merged_types_.second, 0U) << *this;
1020}
1021
1022void UnresolvedReferenceType::CheckInvariants() const {
1023 CHECK(!descriptor_.empty()) << *this;
1024 CHECK(klass_ == NULL) << *this;
1025}
1026
1027void UnresolvedSuperClass::CheckInvariants() const {
1028 // Unresolved merged types: merged types should be defined.
1029 CHECK(descriptor_.empty()) << *this;
1030 CHECK(klass_ == NULL) << *this;
1031 CHECK_NE(unresolved_child_id_, 0U) << *this;
Ian Rogers2dd0e2c2013-01-24 12:42:14 -08001032}
1033
1034std::ostream& operator<<(std::ostream& os, const RegType& rhs) {
Ian Rogers776ac1f2012-04-13 23:36:36 -07001035 os << rhs.Dump();
1036 return os;
1037}
1038
Elliott Hughesa21039c2012-06-21 12:09:25 -07001039} // namespace verifier
1040} // namespace art