Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2016 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 "verifier_deps.h"
     18 
     19 #include <cstring>
     20 
     21 #include "art_field-inl.h"
     22 #include "art_method-inl.h"
     23 #include "base/leb128.h"
     24 #include "base/stl_util.h"
     25 #include "compiler_callbacks.h"
     26 #include "dex/dex_file-inl.h"
     27 #include "indenter.h"
     28 #include "mirror/class-inl.h"
     29 #include "mirror/class_loader.h"
     30 #include "obj_ptr-inl.h"
     31 #include "runtime.h"
     32 
     33 namespace art {
     34 namespace verifier {
     35 
     36 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files, bool output_only)
     37     : output_only_(output_only) {
     38   for (const DexFile* dex_file : dex_files) {
     39     DCHECK(GetDexFileDeps(*dex_file) == nullptr);
     40     std::unique_ptr<DexFileDeps> deps(new DexFileDeps());
     41     dex_deps_.emplace(dex_file, std::move(deps));
     42   }
     43 }
     44 
     45 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files)
     46     : VerifierDeps(dex_files, /*output_only*/ true) {}
     47 
     48 void VerifierDeps::MergeWith(const VerifierDeps& other,
     49                              const std::vector<const DexFile*>& dex_files) {
     50   DCHECK(dex_deps_.size() == other.dex_deps_.size());
     51   for (const DexFile* dex_file : dex_files) {
     52     DexFileDeps* my_deps = GetDexFileDeps(*dex_file);
     53     const DexFileDeps& other_deps = *other.GetDexFileDeps(*dex_file);
     54     // We currently collect extra strings only on the main `VerifierDeps`,
     55     // which should be the one passed as `this` in this method.
     56     DCHECK(other_deps.strings_.empty());
     57     MergeSets(my_deps->assignable_types_, other_deps.assignable_types_);
     58     MergeSets(my_deps->unassignable_types_, other_deps.unassignable_types_);
     59     MergeSets(my_deps->classes_, other_deps.classes_);
     60     MergeSets(my_deps->fields_, other_deps.fields_);
     61     MergeSets(my_deps->methods_, other_deps.methods_);
     62     MergeSets(my_deps->unverified_classes_, other_deps.unverified_classes_);
     63   }
     64 }
     65 
     66 VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) {
     67   auto it = dex_deps_.find(&dex_file);
     68   return (it == dex_deps_.end()) ? nullptr : it->second.get();
     69 }
     70 
     71 const VerifierDeps::DexFileDeps* VerifierDeps::GetDexFileDeps(const DexFile& dex_file) const {
     72   auto it = dex_deps_.find(&dex_file);
     73   return (it == dex_deps_.end()) ? nullptr : it->second.get();
     74 }
     75 
     76 // Access flags that impact vdex verification.
     77 static constexpr uint32_t kAccVdexAccessFlags =
     78     kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccInterface;
     79 
     80 template <typename T>
     81 uint16_t VerifierDeps::GetAccessFlags(T* element) {
     82   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
     83   if (element == nullptr) {
     84     return VerifierDeps::kUnresolvedMarker;
     85   } else {
     86     uint16_t access_flags = Low16Bits(element->GetAccessFlags()) & kAccVdexAccessFlags;
     87     CHECK_NE(access_flags, VerifierDeps::kUnresolvedMarker);
     88     return access_flags;
     89   }
     90 }
     91 
     92 dex::StringIndex VerifierDeps::GetClassDescriptorStringId(const DexFile& dex_file,
     93                                                           ObjPtr<mirror::Class> klass) {
     94   DCHECK(klass != nullptr);
     95   ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
     96   // Array and proxy classes do not have a dex cache.
     97   if (!klass->IsArrayClass() && !klass->IsProxyClass()) {
     98     DCHECK(dex_cache != nullptr) << klass->PrettyClass();
     99     if (dex_cache->GetDexFile() == &dex_file) {
    100       // FindStringId is slow, try to go through the class def if we have one.
    101       const DexFile::ClassDef* class_def = klass->GetClassDef();
    102       DCHECK(class_def != nullptr) << klass->PrettyClass();
    103       const DexFile::TypeId& type_id = dex_file.GetTypeId(class_def->class_idx_);
    104       if (kIsDebugBuild) {
    105         std::string temp;
    106         CHECK_EQ(GetIdFromString(dex_file, klass->GetDescriptor(&temp)), type_id.descriptor_idx_);
    107       }
    108       return type_id.descriptor_idx_;
    109     }
    110   }
    111   std::string temp;
    112   return GetIdFromString(dex_file, klass->GetDescriptor(&temp));
    113 }
    114 
    115 // Try to find the string descriptor of the class. type_idx is a best guess of a matching string id.
    116 static dex::StringIndex TryGetClassDescriptorStringId(const DexFile& dex_file,
    117                                                       dex::TypeIndex type_idx,
    118                                                       ObjPtr<mirror::Class> klass)
    119     REQUIRES_SHARED(Locks::mutator_lock_) {
    120   if (!klass->IsArrayClass()) {
    121     const DexFile::TypeId& type_id = dex_file.GetTypeId(type_idx);
    122     const DexFile& klass_dex = klass->GetDexFile();
    123     const DexFile::TypeId& klass_type_id = klass_dex.GetTypeId(klass->GetClassDef()->class_idx_);
    124     if (strcmp(dex_file.GetTypeDescriptor(type_id),
    125                klass_dex.GetTypeDescriptor(klass_type_id)) == 0) {
    126       return type_id.descriptor_idx_;
    127     }
    128   }
    129   return dex::StringIndex::Invalid();
    130 }
    131 
    132 dex::StringIndex VerifierDeps::GetMethodDeclaringClassStringId(const DexFile& dex_file,
    133                                                                uint32_t dex_method_index,
    134                                                                ArtMethod* method) {
    135   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
    136   if (method == nullptr) {
    137     return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
    138   }
    139   const dex::StringIndex string_id = TryGetClassDescriptorStringId(
    140       dex_file,
    141       dex_file.GetMethodId(dex_method_index).class_idx_,
    142       method->GetDeclaringClass());
    143   if (string_id.IsValid()) {
    144     // Got lucky using the original dex file, return based on the input dex file.
    145     DCHECK_EQ(GetClassDescriptorStringId(dex_file, method->GetDeclaringClass()), string_id);
    146     return string_id;
    147   }
    148   return GetClassDescriptorStringId(dex_file, method->GetDeclaringClass());
    149 }
    150 
    151 dex::StringIndex VerifierDeps::GetFieldDeclaringClassStringId(const DexFile& dex_file,
    152                                                               uint32_t dex_field_idx,
    153                                                               ArtField* field) {
    154   static_assert(kAccJavaFlagsMask == 0xFFFF, "Unexpected value of a constant");
    155   if (field == nullptr) {
    156     return dex::StringIndex(VerifierDeps::kUnresolvedMarker);
    157   }
    158   const dex::StringIndex string_id = TryGetClassDescriptorStringId(
    159       dex_file,
    160       dex_file.GetFieldId(dex_field_idx).class_idx_,
    161       field->GetDeclaringClass());
    162   if (string_id.IsValid()) {
    163     // Got lucky using the original dex file, return based on the input dex file.
    164     DCHECK_EQ(GetClassDescriptorStringId(dex_file, field->GetDeclaringClass()), string_id);
    165     return string_id;
    166   }
    167   return GetClassDescriptorStringId(dex_file, field->GetDeclaringClass());
    168 }
    169 
    170 static inline VerifierDeps* GetMainVerifierDeps() {
    171   // The main VerifierDeps is the one set in the compiler callbacks, which at the
    172   // end of verification will have all the per-thread VerifierDeps merged into it.
    173   CompilerCallbacks* callbacks = Runtime::Current()->GetCompilerCallbacks();
    174   if (callbacks == nullptr) {
    175     return nullptr;
    176   }
    177   return callbacks->GetVerifierDeps();
    178 }
    179 
    180 static inline VerifierDeps* GetThreadLocalVerifierDeps() {
    181   // During AOT, each thread has its own VerifierDeps, to avoid lock contention. At the end
    182   // of full verification, these VerifierDeps will be merged into the main one.
    183   if (!Runtime::Current()->IsAotCompiler()) {
    184     return nullptr;
    185   }
    186   return Thread::Current()->GetVerifierDeps();
    187 }
    188 
    189 static bool FindExistingStringId(const std::vector<std::string>& strings,
    190                                  const std::string& str,
    191                                  uint32_t* found_id) {
    192   uint32_t num_extra_ids = strings.size();
    193   for (size_t i = 0; i < num_extra_ids; ++i) {
    194     if (strings[i] == str) {
    195       *found_id = i;
    196       return true;
    197     }
    198   }
    199   return false;
    200 }
    201 
    202 dex::StringIndex VerifierDeps::GetIdFromString(const DexFile& dex_file, const std::string& str) {
    203   const DexFile::StringId* string_id = dex_file.FindStringId(str.c_str());
    204   if (string_id != nullptr) {
    205     // String is in the DEX file. Return its ID.
    206     return dex_file.GetIndexForStringId(*string_id);
    207   }
    208 
    209   // String is not in the DEX file. Assign a new ID to it which is higher than
    210   // the number of strings in the DEX file.
    211 
    212   // We use the main `VerifierDeps` for adding new strings to simplify
    213   // synchronization/merging of these entries between threads.
    214   VerifierDeps* singleton = GetMainVerifierDeps();
    215   DexFileDeps* deps = singleton->GetDexFileDeps(dex_file);
    216   DCHECK(deps != nullptr);
    217 
    218   uint32_t num_ids_in_dex = dex_file.NumStringIds();
    219   uint32_t found_id;
    220 
    221   {
    222     ReaderMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
    223     if (FindExistingStringId(deps->strings_, str, &found_id)) {
    224       return dex::StringIndex(num_ids_in_dex + found_id);
    225     }
    226   }
    227   {
    228     WriterMutexLock mu(Thread::Current(), *Locks::verifier_deps_lock_);
    229     if (FindExistingStringId(deps->strings_, str, &found_id)) {
    230       return dex::StringIndex(num_ids_in_dex + found_id);
    231     }
    232     deps->strings_.push_back(str);
    233     dex::StringIndex new_id(num_ids_in_dex + deps->strings_.size() - 1);
    234     CHECK_GE(new_id.index_, num_ids_in_dex);  // check for overflows
    235     DCHECK_EQ(str, singleton->GetStringFromId(dex_file, new_id));
    236     return new_id;
    237   }
    238 }
    239 
    240 std::string VerifierDeps::GetStringFromId(const DexFile& dex_file, dex::StringIndex string_id)
    241     const {
    242   uint32_t num_ids_in_dex = dex_file.NumStringIds();
    243   if (string_id.index_ < num_ids_in_dex) {
    244     return std::string(dex_file.StringDataByIdx(string_id));
    245   } else {
    246     const DexFileDeps* deps = GetDexFileDeps(dex_file);
    247     DCHECK(deps != nullptr);
    248     string_id.index_ -= num_ids_in_dex;
    249     CHECK_LT(string_id.index_, deps->strings_.size());
    250     return deps->strings_[string_id.index_];
    251   }
    252 }
    253 
    254 bool VerifierDeps::IsInClassPath(ObjPtr<mirror::Class> klass) const {
    255   DCHECK(klass != nullptr);
    256 
    257   // For array types, we return whether the non-array component type
    258   // is in the classpath.
    259   while (klass->IsArrayClass()) {
    260     klass = klass->GetComponentType();
    261   }
    262 
    263   if (klass->IsPrimitive()) {
    264     return true;
    265   }
    266 
    267   ObjPtr<mirror::DexCache> dex_cache = klass->GetDexCache();
    268   DCHECK(dex_cache != nullptr);
    269   const DexFile* dex_file = dex_cache->GetDexFile();
    270   DCHECK(dex_file != nullptr);
    271 
    272   // Test if the `dex_deps_` contains an entry for `dex_file`. If not, the dex
    273   // file was not registered as being compiled and we assume `klass` is in the
    274   // classpath.
    275   return (GetDexFileDeps(*dex_file) == nullptr);
    276 }
    277 
    278 void VerifierDeps::AddClassResolution(const DexFile& dex_file,
    279                                       dex::TypeIndex type_idx,
    280                                       mirror::Class* klass) {
    281   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    282   if (dex_deps == nullptr) {
    283     // This invocation is from verification of a dex file which is not being compiled.
    284     return;
    285   }
    286 
    287   if (klass != nullptr && !IsInClassPath(klass)) {
    288     // Class resolved into one of the DEX files which are being compiled.
    289     // This is not a classpath dependency.
    290     return;
    291   }
    292 
    293   dex_deps->classes_.emplace(ClassResolution(type_idx, GetAccessFlags(klass)));
    294 }
    295 
    296 void VerifierDeps::AddFieldResolution(const DexFile& dex_file,
    297                                       uint32_t field_idx,
    298                                       ArtField* field) {
    299   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    300   if (dex_deps == nullptr) {
    301     // This invocation is from verification of a dex file which is not being compiled.
    302     return;
    303   }
    304 
    305   if (field != nullptr && !IsInClassPath(field->GetDeclaringClass())) {
    306     // Field resolved into one of the DEX files which are being compiled.
    307     // This is not a classpath dependency.
    308     return;
    309   }
    310 
    311   dex_deps->fields_.emplace(FieldResolution(field_idx,
    312                                             GetAccessFlags(field),
    313                                             GetFieldDeclaringClassStringId(dex_file,
    314                                                                            field_idx,
    315                                                                            field)));
    316 }
    317 
    318 void VerifierDeps::AddMethodResolution(const DexFile& dex_file,
    319                                        uint32_t method_idx,
    320                                        ArtMethod* method) {
    321   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    322   if (dex_deps == nullptr) {
    323     // This invocation is from verification of a dex file which is not being compiled.
    324     return;
    325   }
    326 
    327   if (method != nullptr && !IsInClassPath(method->GetDeclaringClass())) {
    328     // Method resolved into one of the DEX files which are being compiled.
    329     // This is not a classpath dependency.
    330     return;
    331   }
    332 
    333   MethodResolution method_tuple(method_idx,
    334                                 GetAccessFlags(method),
    335                                 GetMethodDeclaringClassStringId(dex_file, method_idx, method));
    336   dex_deps->methods_.insert(method_tuple);
    337 }
    338 
    339 mirror::Class* VerifierDeps::FindOneClassPathBoundaryForInterface(mirror::Class* destination,
    340                                                                   mirror::Class* source) const {
    341   DCHECK(destination->IsInterface());
    342   DCHECK(IsInClassPath(destination));
    343   Thread* thread = Thread::Current();
    344   mirror::Class* current = source;
    345   // Record the classes that are at the boundary between the compiled DEX files and
    346   // the classpath. We will check those classes later to find one class that inherits
    347   // `destination`.
    348   std::vector<ObjPtr<mirror::Class>> boundaries;
    349   // If the destination is a direct interface of a class defined in the DEX files being
    350   // compiled, no need to record it.
    351   while (!IsInClassPath(current)) {
    352     for (size_t i = 0; i < current->NumDirectInterfaces(); ++i) {
    353       ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, current, i);
    354       if (direct == destination) {
    355         return nullptr;
    356       } else if (IsInClassPath(direct)) {
    357         boundaries.push_back(direct);
    358       }
    359     }
    360     current = current->GetSuperClass();
    361   }
    362   DCHECK(current != nullptr);
    363   boundaries.push_back(current);
    364 
    365   // Check if we have an interface defined in the DEX files being compiled, direclty
    366   // inheriting `destination`.
    367   int32_t iftable_count = source->GetIfTableCount();
    368   ObjPtr<mirror::IfTable> iftable = source->GetIfTable();
    369   for (int32_t i = 0; i < iftable_count; ++i) {
    370     mirror::Class* itf = iftable->GetInterface(i);
    371     if (!IsInClassPath(itf)) {
    372       for (size_t j = 0; j < itf->NumDirectInterfaces(); ++j) {
    373         ObjPtr<mirror::Class> direct = mirror::Class::GetDirectInterface(thread, itf, j);
    374         if (direct == destination) {
    375           return nullptr;
    376         } else if (IsInClassPath(direct)) {
    377           boundaries.push_back(direct);
    378         }
    379       }
    380     }
    381   }
    382 
    383   // Find a boundary making `source` inherit from `destination`. We must find one.
    384   for (const ObjPtr<mirror::Class>& boundary : boundaries) {
    385     if (destination->IsAssignableFrom(boundary)) {
    386       return boundary.Ptr();
    387     }
    388   }
    389   LOG(FATAL) << "Should have found a classpath boundary";
    390   UNREACHABLE();
    391 }
    392 
    393 void VerifierDeps::AddAssignability(const DexFile& dex_file,
    394                                     mirror::Class* destination,
    395                                     mirror::Class* source,
    396                                     bool is_strict,
    397                                     bool is_assignable) {
    398   // Test that the method is only called on reference types.
    399   // Note that concurrent verification of `destination` and `source` may have
    400   // set their status to erroneous. However, the tests performed below rely
    401   // merely on no issues with linking (valid access flags, superclass and
    402   // implemented interfaces). If the class at any point reached the IsResolved
    403   // status, the requirement holds. This is guaranteed by RegTypeCache::ResolveClass.
    404   DCHECK(destination != nullptr);
    405   DCHECK(source != nullptr);
    406 
    407   if (destination->IsPrimitive() || source->IsPrimitive()) {
    408     // Primitive types are trivially non-assignable to anything else.
    409     // We do not need to record trivial assignability, as it will
    410     // not change across releases.
    411     return;
    412   }
    413 
    414   if (source->IsObjectClass() && !is_assignable) {
    415     // j.l.Object is trivially non-assignable to other types, don't
    416     // record it.
    417     return;
    418   }
    419 
    420   if (destination == source ||
    421       destination->IsObjectClass() ||
    422       (!is_strict && destination->IsInterface())) {
    423     // Cases when `destination` is trivially assignable from `source`.
    424     DCHECK(is_assignable);
    425     return;
    426   }
    427 
    428   if (destination->IsArrayClass() && source->IsArrayClass()) {
    429     // Both types are arrays. Break down to component types and add recursively.
    430     // This helps filter out destinations from compiled DEX files (see below)
    431     // and deduplicate entries with the same canonical component type.
    432     mirror::Class* destination_component = destination->GetComponentType();
    433     mirror::Class* source_component = source->GetComponentType();
    434 
    435     // Only perform the optimization if both types are resolved which guarantees
    436     // that they linked successfully, as required at the top of this method.
    437     if (destination_component->IsResolved() && source_component->IsResolved()) {
    438       AddAssignability(dex_file,
    439                        destination_component,
    440                        source_component,
    441                        /* is_strict */ true,
    442                        is_assignable);
    443       return;
    444     }
    445   } else {
    446     // We only do this check for non-array types, as arrays might have erroneous
    447     // component types which makes the IsAssignableFrom check unreliable.
    448     DCHECK_EQ(is_assignable, destination->IsAssignableFrom(source));
    449   }
    450 
    451   DexFileDeps* dex_deps = GetDexFileDeps(dex_file);
    452   if (dex_deps == nullptr) {
    453     // This invocation is from verification of a DEX file which is not being compiled.
    454     return;
    455   }
    456 
    457   if (!IsInClassPath(destination) && !IsInClassPath(source)) {
    458     // Both `destination` and `source` are defined in the compiled DEX files.
    459     // No need to record a dependency.
    460     return;
    461   }
    462 
    463   if (!IsInClassPath(source)) {
    464     if (!destination->IsInterface() && !source->IsInterface()) {
    465       // Find the super class at the classpath boundary. Only that class
    466       // can change the assignability.
    467       do {
    468         source = source->GetSuperClass();
    469       } while (!IsInClassPath(source));
    470 
    471       // If that class is the actual destination, no need to record it.
    472       if (source == destination) {
    473         return;
    474       }
    475     } else if (is_assignable) {
    476       source = FindOneClassPathBoundaryForInterface(destination, source);
    477       if (source == nullptr) {
    478         // There was no classpath boundary, no need to record.
    479         return;
    480       }
    481       DCHECK(IsInClassPath(source));
    482     }
    483   }
    484 
    485 
    486   // Get string IDs for both descriptors and store in the appropriate set.
    487   dex::StringIndex destination_id = GetClassDescriptorStringId(dex_file, destination);
    488   dex::StringIndex source_id = GetClassDescriptorStringId(dex_file, source);
    489 
    490   if (is_assignable) {
    491     dex_deps->assignable_types_.emplace(TypeAssignability(destination_id, source_id));
    492   } else {
    493     dex_deps->unassignable_types_.emplace(TypeAssignability(destination_id, source_id));
    494   }
    495 }
    496 
    497 void VerifierDeps::MaybeRecordVerificationStatus(const DexFile& dex_file,
    498                                                  dex::TypeIndex type_idx,
    499                                                  FailureKind failure_kind) {
    500   if (failure_kind == FailureKind::kNoFailure) {
    501     // We only record classes that did not fully verify at compile time.
    502     return;
    503   }
    504 
    505   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    506   if (thread_deps != nullptr) {
    507     DexFileDeps* dex_deps = thread_deps->GetDexFileDeps(dex_file);
    508     dex_deps->unverified_classes_.insert(type_idx);
    509   }
    510 }
    511 
    512 void VerifierDeps::MaybeRecordClassResolution(const DexFile& dex_file,
    513                                               dex::TypeIndex type_idx,
    514                                               mirror::Class* klass) {
    515   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    516   if (thread_deps != nullptr) {
    517     thread_deps->AddClassResolution(dex_file, type_idx, klass);
    518   }
    519 }
    520 
    521 void VerifierDeps::MaybeRecordFieldResolution(const DexFile& dex_file,
    522                                               uint32_t field_idx,
    523                                               ArtField* field) {
    524   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    525   if (thread_deps != nullptr) {
    526     thread_deps->AddFieldResolution(dex_file, field_idx, field);
    527   }
    528 }
    529 
    530 void VerifierDeps::MaybeRecordMethodResolution(const DexFile& dex_file,
    531                                                uint32_t method_idx,
    532                                                ArtMethod* method) {
    533   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    534   if (thread_deps != nullptr) {
    535     thread_deps->AddMethodResolution(dex_file, method_idx, method);
    536   }
    537 }
    538 
    539 void VerifierDeps::MaybeRecordAssignability(const DexFile& dex_file,
    540                                             mirror::Class* destination,
    541                                             mirror::Class* source,
    542                                             bool is_strict,
    543                                             bool is_assignable) {
    544   VerifierDeps* thread_deps = GetThreadLocalVerifierDeps();
    545   if (thread_deps != nullptr) {
    546     thread_deps->AddAssignability(dex_file, destination, source, is_strict, is_assignable);
    547   }
    548 }
    549 
    550 namespace {
    551 
    552 static inline uint32_t DecodeUint32WithOverflowCheck(const uint8_t** in, const uint8_t* end) {
    553   CHECK_LT(*in, end);
    554   return DecodeUnsignedLeb128(in);
    555 }
    556 
    557 template<typename T> inline uint32_t Encode(T in);
    558 
    559 template<> inline uint32_t Encode<uint16_t>(uint16_t in) {
    560   return in;
    561 }
    562 template<> inline uint32_t Encode<uint32_t>(uint32_t in) {
    563   return in;
    564 }
    565 template<> inline uint32_t Encode<dex::TypeIndex>(dex::TypeIndex in) {
    566   return in.index_;
    567 }
    568 template<> inline uint32_t Encode<dex::StringIndex>(dex::StringIndex in) {
    569   return in.index_;
    570 }
    571 
    572 template<typename T> inline T Decode(uint32_t in);
    573 
    574 template<> inline uint16_t Decode<uint16_t>(uint32_t in) {
    575   return dchecked_integral_cast<uint16_t>(in);
    576 }
    577 template<> inline uint32_t Decode<uint32_t>(uint32_t in) {
    578   return in;
    579 }
    580 template<> inline dex::TypeIndex Decode<dex::TypeIndex>(uint32_t in) {
    581   return dex::TypeIndex(in);
    582 }
    583 template<> inline dex::StringIndex Decode<dex::StringIndex>(uint32_t in) {
    584   return dex::StringIndex(in);
    585 }
    586 
    587 // TODO: Clean this up, if we use a template arg here it confuses the compiler.
    588 static inline void EncodeTuple(std::vector<uint8_t>* out, const dex::TypeIndex& t) {
    589   EncodeUnsignedLeb128(out, Encode(t));
    590 }
    591 
    592 // TODO: Clean this up, if we use a template arg here it confuses the compiler.
    593 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, dex::TypeIndex* t) {
    594   *t = Decode<dex::TypeIndex>(DecodeUint32WithOverflowCheck(in, end));
    595 }
    596 
    597 template<typename T1, typename T2>
    598 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2>& t) {
    599   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
    600   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
    601 }
    602 
    603 template<typename T1, typename T2>
    604 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2>* t) {
    605   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
    606   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
    607   *t = std::make_tuple(v1, v2);
    608 }
    609 
    610 template<typename T1, typename T2, typename T3>
    611 static inline void EncodeTuple(std::vector<uint8_t>* out, const std::tuple<T1, T2, T3>& t) {
    612   EncodeUnsignedLeb128(out, Encode(std::get<0>(t)));
    613   EncodeUnsignedLeb128(out, Encode(std::get<1>(t)));
    614   EncodeUnsignedLeb128(out, Encode(std::get<2>(t)));
    615 }
    616 
    617 template<typename T1, typename T2, typename T3>
    618 static inline void DecodeTuple(const uint8_t** in, const uint8_t* end, std::tuple<T1, T2, T3>* t) {
    619   T1 v1 = Decode<T1>(DecodeUint32WithOverflowCheck(in, end));
    620   T2 v2 = Decode<T2>(DecodeUint32WithOverflowCheck(in, end));
    621   T3 v3 = Decode<T3>(DecodeUint32WithOverflowCheck(in, end));
    622   *t = std::make_tuple(v1, v2, v3);
    623 }
    624 
    625 template<typename T>
    626 static inline void EncodeSet(std::vector<uint8_t>* out, const std::set<T>& set) {
    627   EncodeUnsignedLeb128(out, set.size());
    628   for (const T& entry : set) {
    629     EncodeTuple(out, entry);
    630   }
    631 }
    632 
    633 template <typename T>
    634 static inline void EncodeUint16Vector(std::vector<uint8_t>* out,
    635                                       const std::vector<T>& vector) {
    636   EncodeUnsignedLeb128(out, vector.size());
    637   for (const T& entry : vector) {
    638     EncodeUnsignedLeb128(out, Encode(entry));
    639   }
    640 }
    641 
    642 template<typename T>
    643 static inline void DecodeSet(const uint8_t** in, const uint8_t* end, std::set<T>* set) {
    644   DCHECK(set->empty());
    645   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
    646   for (size_t i = 0; i < num_entries; ++i) {
    647     T tuple;
    648     DecodeTuple(in, end, &tuple);
    649     set->emplace(tuple);
    650   }
    651 }
    652 
    653 template<typename T>
    654 static inline void DecodeUint16Vector(const uint8_t** in,
    655                                       const uint8_t* end,
    656                                       std::vector<T>* vector) {
    657   DCHECK(vector->empty());
    658   size_t num_entries = DecodeUint32WithOverflowCheck(in, end);
    659   vector->reserve(num_entries);
    660   for (size_t i = 0; i < num_entries; ++i) {
    661     vector->push_back(
    662         Decode<T>(dchecked_integral_cast<uint16_t>(DecodeUint32WithOverflowCheck(in, end))));
    663   }
    664 }
    665 
    666 static inline void EncodeStringVector(std::vector<uint8_t>* out,
    667                                       const std::vector<std::string>& strings) {
    668   EncodeUnsignedLeb128(out, strings.size());
    669   for (const std::string& str : strings) {
    670     const uint8_t* data = reinterpret_cast<const uint8_t*>(str.c_str());
    671     size_t length = str.length() + 1;
    672     out->insert(out->end(), data, data + length);
    673     DCHECK_EQ(0u, out->back());
    674   }
    675 }
    676 
    677 static inline void DecodeStringVector(const uint8_t** in,
    678                                       const uint8_t* end,
    679                                       std::vector<std::string>* strings) {
    680   DCHECK(strings->empty());
    681   size_t num_strings = DecodeUint32WithOverflowCheck(in, end);
    682   strings->reserve(num_strings);
    683   for (size_t i = 0; i < num_strings; ++i) {
    684     CHECK_LT(*in, end);
    685     const char* string_start = reinterpret_cast<const char*>(*in);
    686     strings->emplace_back(std::string(string_start));
    687     *in += strings->back().length() + 1;
    688   }
    689 }
    690 
    691 }  // namespace
    692 
    693 void VerifierDeps::Encode(const std::vector<const DexFile*>& dex_files,
    694                           std::vector<uint8_t>* buffer) const {
    695   for (const DexFile* dex_file : dex_files) {
    696     const DexFileDeps& deps = *GetDexFileDeps(*dex_file);
    697     EncodeStringVector(buffer, deps.strings_);
    698     EncodeSet(buffer, deps.assignable_types_);
    699     EncodeSet(buffer, deps.unassignable_types_);
    700     EncodeSet(buffer, deps.classes_);
    701     EncodeSet(buffer, deps.fields_);
    702     EncodeSet(buffer, deps.methods_);
    703     EncodeSet(buffer, deps.unverified_classes_);
    704   }
    705 }
    706 
    707 VerifierDeps::VerifierDeps(const std::vector<const DexFile*>& dex_files,
    708                            ArrayRef<const uint8_t> data)
    709     : VerifierDeps(dex_files, /*output_only*/ false) {
    710   if (data.empty()) {
    711     // Return eagerly, as the first thing we expect from VerifierDeps data is
    712     // the number of created strings, even if there is no dependency.
    713     // Currently, only the boot image does not have any VerifierDeps data.
    714     return;
    715   }
    716   const uint8_t* data_start = data.data();
    717   const uint8_t* data_end = data_start + data.size();
    718   for (const DexFile* dex_file : dex_files) {
    719     DexFileDeps* deps = GetDexFileDeps(*dex_file);
    720     DecodeStringVector(&data_start, data_end, &deps->strings_);
    721     DecodeSet(&data_start, data_end, &deps->assignable_types_);
    722     DecodeSet(&data_start, data_end, &deps->unassignable_types_);
    723     DecodeSet(&data_start, data_end, &deps->classes_);
    724     DecodeSet(&data_start, data_end, &deps->fields_);
    725     DecodeSet(&data_start, data_end, &deps->methods_);
    726     DecodeSet(&data_start, data_end, &deps->unverified_classes_);
    727   }
    728   CHECK_LE(data_start, data_end);
    729 }
    730 
    731 bool VerifierDeps::Equals(const VerifierDeps& rhs) const {
    732   if (dex_deps_.size() != rhs.dex_deps_.size()) {
    733     return false;
    734   }
    735 
    736   auto lhs_it = dex_deps_.begin();
    737   auto rhs_it = rhs.dex_deps_.begin();
    738 
    739   for (; (lhs_it != dex_deps_.end()) && (rhs_it != rhs.dex_deps_.end()); lhs_it++, rhs_it++) {
    740     const DexFile* lhs_dex_file = lhs_it->first;
    741     const DexFile* rhs_dex_file = rhs_it->first;
    742     if (lhs_dex_file != rhs_dex_file) {
    743       return false;
    744     }
    745 
    746     DexFileDeps* lhs_deps = lhs_it->second.get();
    747     DexFileDeps* rhs_deps = rhs_it->second.get();
    748     if (!lhs_deps->Equals(*rhs_deps)) {
    749       return false;
    750     }
    751   }
    752 
    753   DCHECK((lhs_it == dex_deps_.end()) && (rhs_it == rhs.dex_deps_.end()));
    754   return true;
    755 }
    756 
    757 bool VerifierDeps::DexFileDeps::Equals(const VerifierDeps::DexFileDeps& rhs) const {
    758   return (strings_ == rhs.strings_) &&
    759          (assignable_types_ == rhs.assignable_types_) &&
    760          (unassignable_types_ == rhs.unassignable_types_) &&
    761          (classes_ == rhs.classes_) &&
    762          (fields_ == rhs.fields_) &&
    763          (methods_ == rhs.methods_) &&
    764          (unverified_classes_ == rhs.unverified_classes_);
    765 }
    766 
    767 void VerifierDeps::Dump(VariableIndentationOutputStream* vios) const {
    768   for (const auto& dep : dex_deps_) {
    769     const DexFile& dex_file = *dep.first;
    770     vios->Stream()
    771         << "Dependencies of "
    772         << dex_file.GetLocation()
    773         << ":\n";
    774 
    775     ScopedIndentation indent(vios);
    776 
    777     for (const std::string& str : dep.second->strings_) {
    778       vios->Stream() << "Extra string: " << str << "\n";
    779     }
    780 
    781     for (const TypeAssignability& entry : dep.second->assignable_types_) {
    782       vios->Stream()
    783         << GetStringFromId(dex_file, entry.GetSource())
    784         << " must be assignable to "
    785         << GetStringFromId(dex_file, entry.GetDestination())
    786         << "\n";
    787     }
    788 
    789     for (const TypeAssignability& entry : dep.second->unassignable_types_) {
    790       vios->Stream()
    791         << GetStringFromId(dex_file, entry.GetSource())
    792         << " must not be assignable to "
    793         << GetStringFromId(dex_file, entry.GetDestination())
    794         << "\n";
    795     }
    796 
    797     for (const ClassResolution& entry : dep.second->classes_) {
    798       vios->Stream()
    799           << dex_file.StringByTypeIdx(entry.GetDexTypeIndex())
    800           << (entry.IsResolved() ? " must be resolved " : "must not be resolved ")
    801           << " with access flags " << std::hex << entry.GetAccessFlags() << std::dec
    802           << "\n";
    803     }
    804 
    805     for (const FieldResolution& entry : dep.second->fields_) {
    806       const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
    807       vios->Stream()
    808           << dex_file.GetFieldDeclaringClassDescriptor(field_id) << "->"
    809           << dex_file.GetFieldName(field_id) << ":"
    810           << dex_file.GetFieldTypeDescriptor(field_id)
    811           << " is expected to be ";
    812       if (!entry.IsResolved()) {
    813         vios->Stream() << "unresolved\n";
    814       } else {
    815         vios->Stream()
    816           << "in class "
    817           << GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
    818           << ", and have the access flags " << std::hex << entry.GetAccessFlags() << std::dec
    819           << "\n";
    820       }
    821     }
    822 
    823     for (const MethodResolution& method : dep.second->methods_) {
    824       const DexFile::MethodId& method_id = dex_file.GetMethodId(method.GetDexMethodIndex());
    825       vios->Stream()
    826           << dex_file.GetMethodDeclaringClassDescriptor(method_id) << "->"
    827           << dex_file.GetMethodName(method_id)
    828           << dex_file.GetMethodSignature(method_id).ToString()
    829           << " is expected to be ";
    830       if (!method.IsResolved()) {
    831         vios->Stream() << "unresolved\n";
    832       } else {
    833         vios->Stream()
    834           << "in class "
    835           << GetStringFromId(dex_file, method.GetDeclaringClassIndex())
    836           << ", have the access flags " << std::hex << method.GetAccessFlags() << std::dec
    837           << "\n";
    838       }
    839     }
    840 
    841     for (dex::TypeIndex type_index : dep.second->unverified_classes_) {
    842       vios->Stream()
    843           << dex_file.StringByTypeIdx(type_index)
    844           << " is expected to be verified at runtime\n";
    845     }
    846   }
    847 }
    848 
    849 bool VerifierDeps::ValidateDependencies(Handle<mirror::ClassLoader> class_loader,
    850                                         Thread* self) const {
    851   for (const auto& entry : dex_deps_) {
    852     if (!VerifyDexFile(class_loader, *entry.first, *entry.second, self)) {
    853       return false;
    854     }
    855   }
    856   return true;
    857 }
    858 
    859 // TODO: share that helper with other parts of the compiler that have
    860 // the same lookup pattern.
    861 static mirror::Class* FindClassAndClearException(ClassLinker* class_linker,
    862                                                  Thread* self,
    863                                                  const char* name,
    864                                                  Handle<mirror::ClassLoader> class_loader)
    865     REQUIRES_SHARED(Locks::mutator_lock_) {
    866   mirror::Class* result = class_linker->FindClass(self, name, class_loader);
    867   if (result == nullptr) {
    868     DCHECK(self->IsExceptionPending());
    869     self->ClearException();
    870   }
    871   return result;
    872 }
    873 
    874 bool VerifierDeps::VerifyAssignability(Handle<mirror::ClassLoader> class_loader,
    875                                        const DexFile& dex_file,
    876                                        const std::set<TypeAssignability>& assignables,
    877                                        bool expected_assignability,
    878                                        Thread* self) const {
    879   StackHandleScope<2> hs(self);
    880   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    881   MutableHandle<mirror::Class> source(hs.NewHandle<mirror::Class>(nullptr));
    882   MutableHandle<mirror::Class> destination(hs.NewHandle<mirror::Class>(nullptr));
    883 
    884   for (const auto& entry : assignables) {
    885     const std::string& destination_desc = GetStringFromId(dex_file, entry.GetDestination());
    886     destination.Assign(
    887         FindClassAndClearException(class_linker, self, destination_desc.c_str(), class_loader));
    888     const std::string& source_desc = GetStringFromId(dex_file, entry.GetSource());
    889     source.Assign(
    890         FindClassAndClearException(class_linker, self, source_desc.c_str(), class_loader));
    891 
    892     if (destination == nullptr) {
    893       LOG(INFO) << "VerifiersDeps: Could not resolve class " << destination_desc;
    894       return false;
    895     }
    896 
    897     if (source == nullptr) {
    898       LOG(INFO) << "VerifierDeps: Could not resolve class " << source_desc;
    899       return false;
    900     }
    901 
    902     DCHECK(destination->IsResolved() && source->IsResolved());
    903     if (destination->IsAssignableFrom(source.Get()) != expected_assignability) {
    904       LOG(INFO) << "VerifierDeps: Class "
    905                 << destination_desc
    906                 << (expected_assignability ? " not " : " ")
    907                 << "assignable from "
    908                 << source_desc;
    909       return false;
    910     }
    911   }
    912   return true;
    913 }
    914 
    915 bool VerifierDeps::VerifyClasses(Handle<mirror::ClassLoader> class_loader,
    916                                  const DexFile& dex_file,
    917                                  const std::set<ClassResolution>& classes,
    918                                  Thread* self) const {
    919   StackHandleScope<1> hs(self);
    920   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    921   MutableHandle<mirror::Class> cls(hs.NewHandle<mirror::Class>(nullptr));
    922   for (const auto& entry : classes) {
    923     const char* descriptor = dex_file.StringByTypeIdx(entry.GetDexTypeIndex());
    924     cls.Assign(FindClassAndClearException(class_linker, self, descriptor, class_loader));
    925 
    926     if (entry.IsResolved()) {
    927       if (cls == nullptr) {
    928         LOG(INFO) << "VerifierDeps: Could not resolve class " << descriptor;
    929         return false;
    930       } else if (entry.GetAccessFlags() != GetAccessFlags(cls.Get())) {
    931         LOG(INFO) << "VerifierDeps: Unexpected access flags on class "
    932                   << descriptor
    933                   << std::hex
    934                   << " (expected="
    935                   << entry.GetAccessFlags()
    936                   << ", actual="
    937                   << GetAccessFlags(cls.Get()) << ")"
    938                   << std::dec;
    939         return false;
    940       }
    941     } else if (cls != nullptr) {
    942       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of class " << descriptor;
    943       return false;
    944     }
    945   }
    946   return true;
    947 }
    948 
    949 static std::string GetFieldDescription(const DexFile& dex_file, uint32_t index) {
    950   const DexFile::FieldId& field_id = dex_file.GetFieldId(index);
    951   return std::string(dex_file.GetFieldDeclaringClassDescriptor(field_id))
    952       + "->"
    953       + dex_file.GetFieldName(field_id)
    954       + ":"
    955       + dex_file.GetFieldTypeDescriptor(field_id);
    956 }
    957 
    958 bool VerifierDeps::VerifyFields(Handle<mirror::ClassLoader> class_loader,
    959                                 const DexFile& dex_file,
    960                                 const std::set<FieldResolution>& fields,
    961                                 Thread* self) const {
    962   // Check recorded fields are resolved the same way, have the same recorded class,
    963   // and have the same recorded flags.
    964   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
    965   for (const auto& entry : fields) {
    966     const DexFile::FieldId& field_id = dex_file.GetFieldId(entry.GetDexFieldIndex());
    967     StringPiece name(dex_file.StringDataByIdx(field_id.name_idx_));
    968     StringPiece type(dex_file.StringDataByIdx(dex_file.GetTypeId(field_id.type_idx_).descriptor_idx_));
    969     // Only use field_id.class_idx_ when the entry is unresolved, which is rare.
    970     // Otherwise, we might end up resolving an application class, which is expensive.
    971     std::string expected_decl_klass = entry.IsResolved()
    972         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
    973         : dex_file.StringByTypeIdx(field_id.class_idx_);
    974     mirror::Class* cls = FindClassAndClearException(
    975         class_linker, self, expected_decl_klass.c_str(), class_loader);
    976     if (cls == nullptr) {
    977       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
    978       return false;
    979     }
    980     DCHECK(cls->IsResolved());
    981 
    982     ArtField* field = mirror::Class::FindField(self, cls, name, type);
    983     if (entry.IsResolved()) {
    984       std::string temp;
    985       if (field == nullptr) {
    986         LOG(INFO) << "VerifierDeps: Could not resolve field "
    987                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
    988         return false;
    989       } else if (expected_decl_klass != field->GetDeclaringClass()->GetDescriptor(&temp)) {
    990         LOG(INFO) << "VerifierDeps: Unexpected declaring class for field resolution "
    991                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
    992                   << " (expected=" << expected_decl_klass
    993                   << ", actual=" << field->GetDeclaringClass()->GetDescriptor(&temp) << ")";
    994         return false;
    995       } else if (entry.GetAccessFlags() != GetAccessFlags(field)) {
    996         LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved field "
    997                   << GetFieldDescription(dex_file, entry.GetDexFieldIndex())
    998                   << std::hex << " (expected=" << entry.GetAccessFlags()
    999                   << ", actual=" << GetAccessFlags(field) << ")" << std::dec;
   1000         return false;
   1001       }
   1002     } else if (field != nullptr) {
   1003       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of field "
   1004                 << GetFieldDescription(dex_file, entry.GetDexFieldIndex());
   1005       return false;
   1006     }
   1007   }
   1008   return true;
   1009 }
   1010 
   1011 static std::string GetMethodDescription(const DexFile& dex_file, uint32_t index) {
   1012   const DexFile::MethodId& method_id = dex_file.GetMethodId(index);
   1013   return std::string(dex_file.GetMethodDeclaringClassDescriptor(method_id))
   1014       + "->"
   1015       + dex_file.GetMethodName(method_id)
   1016       + dex_file.GetMethodSignature(method_id).ToString();
   1017 }
   1018 
   1019 bool VerifierDeps::VerifyMethods(Handle<mirror::ClassLoader> class_loader,
   1020                                  const DexFile& dex_file,
   1021                                  const std::set<MethodResolution>& methods,
   1022                                  Thread* self) const {
   1023   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   1024   PointerSize pointer_size = class_linker->GetImagePointerSize();
   1025 
   1026   for (const auto& entry : methods) {
   1027     const DexFile::MethodId& method_id = dex_file.GetMethodId(entry.GetDexMethodIndex());
   1028 
   1029     const char* name = dex_file.GetMethodName(method_id);
   1030     const Signature signature = dex_file.GetMethodSignature(method_id);
   1031     // Only use method_id.class_idx_ when the entry is unresolved, which is rare.
   1032     // Otherwise, we might end up resolving an application class, which is expensive.
   1033     std::string expected_decl_klass = entry.IsResolved()
   1034         ? GetStringFromId(dex_file, entry.GetDeclaringClassIndex())
   1035         : dex_file.StringByTypeIdx(method_id.class_idx_);
   1036 
   1037     mirror::Class* cls = FindClassAndClearException(
   1038         class_linker, self, expected_decl_klass.c_str(), class_loader);
   1039     if (cls == nullptr) {
   1040       LOG(INFO) << "VerifierDeps: Could not resolve class " << expected_decl_klass;
   1041       return false;
   1042     }
   1043     DCHECK(cls->IsResolved());
   1044     ArtMethod* method = nullptr;
   1045     if (cls->IsInterface()) {
   1046       method = cls->FindInterfaceMethod(name, signature, pointer_size);
   1047     } else {
   1048       method = cls->FindClassMethod(name, signature, pointer_size);
   1049     }
   1050 
   1051     if (entry.IsResolved()) {
   1052       std::string temp;
   1053       if (method == nullptr) {
   1054         LOG(INFO) << "VerifierDeps: Could not resolve method "
   1055                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
   1056         return false;
   1057       } else if (expected_decl_klass != method->GetDeclaringClass()->GetDescriptor(&temp)) {
   1058         LOG(INFO) << "VerifierDeps: Unexpected declaring class for method resolution "
   1059                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
   1060                   << " (expected="
   1061                   << expected_decl_klass
   1062                   << ", actual="
   1063                   << method->GetDeclaringClass()->GetDescriptor(&temp)
   1064                   << ")";
   1065         return false;
   1066       } else if (entry.GetAccessFlags() != GetAccessFlags(method)) {
   1067         LOG(INFO) << "VerifierDeps: Unexpected access flags for resolved method resolution "
   1068                   << GetMethodDescription(dex_file, entry.GetDexMethodIndex())
   1069                   << std::hex
   1070                   << " (expected="
   1071                   << entry.GetAccessFlags()
   1072                   << ", actual="
   1073                   << GetAccessFlags(method) << ")"
   1074                   << std::dec;
   1075         return false;
   1076       }
   1077     } else if (method != nullptr) {
   1078       LOG(INFO) << "VerifierDeps: Unexpected successful resolution of method "
   1079                 << GetMethodDescription(dex_file, entry.GetDexMethodIndex());
   1080       return false;
   1081     }
   1082   }
   1083   return true;
   1084 }
   1085 
   1086 bool VerifierDeps::VerifyDexFile(Handle<mirror::ClassLoader> class_loader,
   1087                                  const DexFile& dex_file,
   1088                                  const DexFileDeps& deps,
   1089                                  Thread* self) const {
   1090   bool result = VerifyAssignability(
   1091       class_loader, dex_file, deps.assignable_types_, /* expected_assignability */ true, self);
   1092   result = result && VerifyAssignability(
   1093       class_loader, dex_file, deps.unassignable_types_, /* expected_assignability */ false, self);
   1094 
   1095   result = result && VerifyClasses(class_loader, dex_file, deps.classes_, self);
   1096   result = result && VerifyFields(class_loader, dex_file, deps.fields_, self);
   1097 
   1098   result = result && VerifyMethods(class_loader, dex_file, deps.methods_, self);
   1099 
   1100   return result;
   1101 }
   1102 
   1103 }  // namespace verifier
   1104 }  // namespace art
   1105