reg_type_cache.cc revision 2dd0e2cea360bc9206eb88ecc40d259e796c239d
1776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers/*
2776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Copyright (C) 2012 The Android Open Source Project
3776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
4776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Licensed under the Apache License, Version 2.0 (the "License");
5776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * you may not use this file except in compliance with the License.
6776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * You may obtain a copy of the License at
7776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
8776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *      http://www.apache.org/licenses/LICENSE-2.0
9776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers *
10776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * Unless required by applicable law or agreed to in writing, software
11776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * distributed under the License is distributed on an "AS IS" BASIS,
12776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * See the License for the specific language governing permissions and
14776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers * limitations under the License.
15776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers */
16776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
17776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "reg_type_cache.h"
18776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/class-inl.h"
202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers#include "mirror/object-inl.h"
21776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers#include "object_utils.h"
22776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
23776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace art {
24776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersnamespace verifier {
25776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
26776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstatic RegType::Type RegTypeFromPrimitiveType(Primitive::Type prim_type) {
27776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  switch (prim_type) {
28776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimBoolean: return RegType::kRegTypeBoolean;
29776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimByte:    return RegType::kRegTypeByte;
30776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimShort:   return RegType::kRegTypeShort;
31776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimChar:    return RegType::kRegTypeChar;
32776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimInt:     return RegType::kRegTypeInteger;
33776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimLong:    return RegType::kRegTypeLongLo;
34776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimFloat:   return RegType::kRegTypeFloat;
35776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimDouble:  return RegType::kRegTypeDoubleLo;
36776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case Primitive::kPrimVoid:
37ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    default:                      return RegType::kRegTypeConflict;
38776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
39776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
40776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
41776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersstatic RegType::Type RegTypeFromDescriptor(const std::string& descriptor) {
42776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (descriptor.length() == 1) {
43776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    switch (descriptor[0]) {
44776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'Z': return RegType::kRegTypeBoolean;
45776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'B': return RegType::kRegTypeByte;
46776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'S': return RegType::kRegTypeShort;
47776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'C': return RegType::kRegTypeChar;
48776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'I': return RegType::kRegTypeInteger;
49776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'J': return RegType::kRegTypeLongLo;
50776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'F': return RegType::kRegTypeFloat;
51776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'D': return RegType::kRegTypeDoubleLo;
52776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      case 'V':
53ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      default:  return RegType::kRegTypeConflict;
54776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
55776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else if (descriptor[0] == 'L' || descriptor[0] == '[') {
56776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return RegType::kRegTypeReference;
57776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
58ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    return RegType::kRegTypeConflict;
59776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
60776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
61776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
622dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::FromDescriptor(mirror::ClassLoader* loader, const char* descriptor,
63b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers                                            bool precise) {
64b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  return From(RegTypeFromDescriptor(descriptor), loader, descriptor, precise);
65776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
66776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
67b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersstatic bool MatchingPrecisionForClass(RegType* entry, bool precise)
68b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
69b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  return (entry->IsPreciseReference() == precise) || (entry->GetClass()->IsFinal() && !precise);
70b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
71b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
722dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::From(RegType::Type type, mirror::ClassLoader* loader,
732dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers                                  const char* descriptor, bool precise) {
74776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (type <= RegType::kRegTypeLastFixedLocation) {
75776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    // entries should be sized greater than primitive types
76776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    DCHECK_GT(entries_.size(), static_cast<size_t>(type));
77776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType* entry = entries_[type];
78776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    if (entry == NULL) {
792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      mirror::Class* c = NULL;
80776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (strlen(descriptor) != 0) {
8180537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes        c = Runtime::Current()->GetClassLinker()->FindSystemClass(descriptor);
82776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
8380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      entry = new RegType(type, c, 0, type);
84776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      entries_[type] = entry;
85776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
86776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return *entry;
87776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
88b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    DCHECK(type == RegType::kRegTypeReference || type == RegType::kRegTypePreciseReference);
89776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    ClassHelper kh;
90776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
91776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
92776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      // check resolved and unresolved references, ignore uninitialized references
93b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers      if (cur_entry->HasClass()) {
94776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        kh.ChangeClass(cur_entry->GetClass());
95b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers        if (MatchingPrecisionForClass(cur_entry, precise) &&
96b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers            (strcmp(descriptor, kh.GetDescriptor()) == 0)) {
97776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          return *cur_entry;
98776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        }
99776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      } else if (cur_entry->IsUnresolvedReference() &&
10080537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes                 cur_entry->GetDescriptor() == descriptor) {
101776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
102776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
103776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
10480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
1052dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* c;
10680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    if (can_load_classes_) {
10780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      c = class_linker->FindClass(descriptor, loader);
10880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    } else {
10980537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      c = class_linker->LookupClass(descriptor, loader);
11080537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    }
11180537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    if (c != NULL) {
112b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers      // Able to resolve so create resolved register type that is precise if we
113b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers      // know the type is final.
11480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      RegType* entry = new RegType(c->IsFinal() ? RegType::kRegTypePreciseReference
11580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes                                                : RegType::kRegTypeReference,
11680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes                                   c, 0, entries_.size());
117776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      entries_.push_back(entry);
118776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      return *entry;
119776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    } else {
120776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      // TODO: we assume unresolved, but we may be able to do better by validating whether the
121776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      // descriptor string is valid
122776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      // Unable to resolve so create unresolved register type
12380537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      if (can_load_classes_) {
12480537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes        DCHECK(Thread::Current()->IsExceptionPending());
12580537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes        Thread::Current()->ClearException();
12680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      } else {
12780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes        DCHECK(!Thread::Current()->IsExceptionPending());
12880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes      }
129776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (IsValidDescriptor(descriptor)) {
1302dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers        RegType* entry =
1312dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers            new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
132776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        entries_.push_back(entry);
133776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *entry;
134776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      } else {
135776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        // The descriptor is broken return the unknown type as there's nothing sensible that
136776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        // could be done at runtime
137ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers        return Conflict();
138776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
139776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
140776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
141776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
142776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
1432dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::FromClass(mirror::Class* klass, bool precise) {
144776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (klass->IsPrimitive()) {
145776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType::Type type = RegTypeFromPrimitiveType(klass->GetPrimitiveType());
146776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    // entries should be sized greater than primitive types
147776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    DCHECK_GT(entries_.size(), static_cast<size_t>(type));
148776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType* entry = entries_[type];
149776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    if (entry == NULL) {
150776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      entry = new RegType(type, klass, 0, type);
151776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      entries_[type] = entry;
152776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
153776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return *entry;
154776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
155776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
156776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
157b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers      if ((cur_entry->HasClass()) &&
158b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers          MatchingPrecisionForClass(cur_entry, precise) && cur_entry->GetClass() == klass) {
159776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
160776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
161776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
162b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    RegType* entry = new RegType(precise ? RegType::kRegTypePreciseReference
163b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers                                         : RegType::kRegTypeReference,
164b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers                                 klass, 0, entries_.size());
165776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    entries_.push_back(entry);
166776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    return *entry;
167776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
168776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
169776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
170529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedMerge(const RegType& left, const RegType& right) {
171529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  std::set<uint16_t> types;
172529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (left.IsUnresolvedMergedReference()) {
173529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types = left.GetMergedTypes(this);
174529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
175529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(left.GetId());
176529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
177529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  if (right.IsUnresolvedMergedReference()) {
178529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    std::set<uint16_t> right_types = right.GetMergedTypes(this);
179529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right_types.begin(), right_types.end());
180529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  } else {
181529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    types.insert(right.GetId());
182529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
183529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
184529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
185529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    RegType* cur_entry = entries_[i];
186529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    if (cur_entry->IsUnresolvedMergedReference()) {
187529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      std::set<uint16_t> cur_entry_types = cur_entry->GetMergedTypes(this);
188529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      if (cur_entry_types == types) {
189529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers        return *cur_entry;
190529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers      }
191529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers    }
192529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  }
193529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Create entry.
194529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  uint32_t merged_ids = static_cast<uint32_t>(left.GetId()) << 16 |
195529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers                        static_cast<uint32_t>(right.GetId());
196529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  RegType* entry = new RegType(RegType::kRegTypeUnresolvedMergedReference, NULL, merged_ids,
197529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers                               entries_.size());
198529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  entries_.push_back(entry);
199529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers#ifndef DEBUG
200529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  std::set<uint16_t> check_types = entry->GetMergedTypes(this);
201529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  CHECK(check_types == types);
202529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers#endif
203529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  return *entry;
204529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
205529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers
206529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogersconst RegType& RegTypeCache::FromUnresolvedSuperClass(const RegType& child) {
207529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers  // Check if entry already exists.
208529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
209529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers     RegType* cur_entry = entries_[i];
210529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers     if (cur_entry->IsUnresolvedSuperClass()) {
211529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers       uint16_t unresolved_super_child_id = cur_entry->GetUnresolvedSuperClassChildId();
212529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers       if (unresolved_super_child_id == child.GetId()) {
213529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers         return *cur_entry;
214529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers       }
215529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers     }
216529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   }
217529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   // Create entry.
218529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   RegType* entry = new RegType(RegType::kRegTypeUnresolvedSuperClass, NULL, child.GetId(),
219529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers                                entries_.size());
220529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   entries_.push_back(entry);
221529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers   return *entry;
222529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers}
223529781dad1d4bc5685fd9ebbf04c1369246c2403Ian Rogers
224776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::Uninitialized(const RegType& type, uint32_t allocation_pc) {
225776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  RegType* entry;
226776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (type.IsUnresolvedTypes()) {
22780537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    std::string descriptor(type.GetDescriptor());
228776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
229776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
230776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedReference() &&
231776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetAllocationPc() == allocation_pc &&
232776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetDescriptor() == descriptor) {
233776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
234776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
235776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
236776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedReference,
237776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers                        descriptor, allocation_pc, entries_.size());
238776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
2392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
240776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
241776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
242776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUninitializedReference() &&
243776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetAllocationPc() == allocation_pc &&
244776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers          cur_entry->GetClass() == klass) {
245776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
246776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
247776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
248776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    entry = new RegType(RegType::kRegTypeUninitializedReference,
249776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers                        klass, allocation_pc, entries_.size());
250776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
251776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
252776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
253776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
254776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
255776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::FromUninitialized(const RegType& uninit_type) {
256776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  RegType* entry;
257776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (uninit_type.IsUnresolvedTypes()) {
25880537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    std::string descriptor(uninit_type.GetDescriptor());
259776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
260776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
261776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      if (cur_entry->IsUnresolvedReference() && cur_entry->GetDescriptor() == descriptor) {
262776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
263776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
264776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
265776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    entry = new RegType(RegType::kRegTypeUnresolvedReference, descriptor, 0, entries_.size());
266776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
2672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = uninit_type.GetClass();
268776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
269776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      RegType* cur_entry = entries_[i];
270b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers      if (cur_entry->IsPreciseReference() && cur_entry->GetClass() == klass) {
271776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers        return *cur_entry;
272776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      }
273776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
274b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    entry = new RegType(RegType::kRegTypePreciseReference, klass, 0, entries_.size());
275776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
276776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
277776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
278776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
279776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
2802dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::ByteConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2812dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jbyte>::min(), false);
2822dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2832dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2842dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::ShortConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2852dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jshort>::min(), false);
2862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2872dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
2882dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::IntConstant() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
2892dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  return FromCat1Const(std::numeric_limits<jint>::max(), false);
2902dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers}
2912dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers
292ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogersconst RegType& RegTypeCache::UninitializedThisArgument(const RegType& type) {
293ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  // TODO: implement descriptor version.
294ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  RegType* entry;
295ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  if (type.IsUnresolvedTypes()) {
29680537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    std::string descriptor(type.GetDescriptor());
297ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
298ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
299ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      if (cur_entry->IsUnresolvedAndUninitializedThisReference() &&
300ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers          cur_entry->GetDescriptor() == descriptor) {
301ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers        return *cur_entry;
302ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
303ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    }
304ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    entry = new RegType(RegType::kRegTypeUnresolvedAndUninitializedThisReference, descriptor, 0,
305ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers                        entries_.size());
306ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers  } else {
3072dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = type.GetClass();
308ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
309ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      RegType* cur_entry = entries_[i];
310ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      if (cur_entry->IsUninitializedThisReference() && cur_entry->GetClass() == klass) {
311ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers        return *cur_entry;
312ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers      }
313776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
314ad0b3a35857d2cd2db720028ebc51176191e2219Ian Rogers    entry = new RegType(RegType::kRegTypeUninitializedThisReference, klass, 0, entries_.size());
315776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
316776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
317776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
318776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
319776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
320776ac1fa61237db645adb4370a4aab888530caf4Ian Rogersconst RegType& RegTypeCache::FromType(RegType::Type type) {
321776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  CHECK(type < RegType::kRegTypeReference);
322776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  switch (type) {
323b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeBoolean:  return From(type, NULL, "Z", true);
324b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeByte:     return From(type, NULL, "B", true);
325b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeShort:    return From(type, NULL, "S", true);
326b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeChar:     return From(type, NULL, "C", true);
327b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeInteger:  return From(type, NULL, "I", true);
328b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeFloat:    return From(type, NULL, "F", true);
329776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case RegType::kRegTypeLongLo:
330b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeLongHi:   return From(type, NULL, "J", true);
331776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    case RegType::kRegTypeDoubleLo:
332b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    case RegType::kRegTypeDoubleHi: return From(type, NULL, "D", true);
333b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    default:                        return From(type, NULL, "", true);
334776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
335776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
336776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3372bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat1Const(int32_t value, bool precise) {
3382dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  RegType::Type wanted_type =
3392dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      precise ? RegType::kRegTypePreciseConst : RegType::kRegTypeImpreciseConst;
340776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
341776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    RegType* cur_entry = entries_[i];
3422bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValue() == value) {
343776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers      return *cur_entry;
344776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    }
345776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
3462bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
3472bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  entries_.push_back(entry);
3482bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
3492bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
3502bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
3512bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstLo(int32_t value, bool precise) {
3522dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  RegType::Type wanted_type =
3532dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      precise ? RegType::kRegTypePreciseConstLo : RegType::kRegTypeImpreciseConstLo;
3542bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
3552bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
3562bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueLo() == value) {
3572bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      return *cur_entry;
3582bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
3592bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
3602bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
3612bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  entries_.push_back(entry);
3622bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  return *entry;
3632bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers}
3642bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers
3652bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogersconst RegType& RegTypeCache::FromCat2ConstHi(int32_t value, bool precise) {
3662dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers  RegType::Type wanted_type =
3672dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers      precise ? RegType::kRegTypePreciseConstHi : RegType::kRegTypeImpreciseConstHi;
3682bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  for (size_t i = RegType::kRegTypeLastFixedLocation + 1; i < entries_.size(); i++) {
3692bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    RegType* cur_entry = entries_[i];
3702bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    if (cur_entry->GetType() == wanted_type && cur_entry->ConstantValueHi() == value) {
3712bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      return *cur_entry;
3722bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers    }
3732bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  }
3742bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers  RegType* entry = new RegType(wanted_type, NULL, value, entries_.size());
375776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  entries_.push_back(entry);
376776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  return *entry;
377776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
378776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
3792dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogersconst RegType& RegTypeCache::GetComponentType(const RegType& array, mirror::ClassLoader* loader) {
380776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  CHECK(array.IsArrayTypes());
381776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  if (array.IsUnresolvedTypes()) {
38280537bb742dff4ccdf6d04b1c0bb7d2179acc8cbElliott Hughes    std::string descriptor(array.GetDescriptor());
383776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers    std::string component(descriptor.substr(1, descriptor.size() - 1));
384b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    return FromDescriptor(loader, component.c_str(), false);
385776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  } else {
3862dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers    mirror::Class* klass = array.GetClass()->GetComponentType();
387b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    return FromClass(klass, klass->IsFinal());
388b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  }
389b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers}
390b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers
391b49035706fceb2b13e8154668f175af624cf88f4Ian Rogersvoid RegTypeCache::Dump(std::ostream& os) {
392b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers  for (size_t i = 0; i < entries_.size(); i++) {
393b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    RegType* cur_entry = entries_[i];
394b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    if (cur_entry != NULL) {
3952bcb4a496b7aa00d996df3a070524f7568fb35a1Ian Rogers      os << i << ": " << cur_entry->Dump() << "\n";
396b49035706fceb2b13e8154668f175af624cf88f4Ian Rogers    }
397776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers  }
398776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers}
399776ac1fa61237db645adb4370a4aab888530caf4Ian Rogers
400a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace verifier
401a21039c3ae2b20e44ceb2735251c04d0aac89afdElliott Hughes}  // namespace art
402