Home | History | Annotate | Download | only in verifier
      1 /*
      2  * Copyright (C) 2011 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 "method_verifier-inl.h"
     18 
     19 #include <iostream>
     20 
     21 #include "android-base/stringprintf.h"
     22 
     23 #include "art_field-inl.h"
     24 #include "art_method-inl.h"
     25 #include "base/enums.h"
     26 #include "base/logging.h"
     27 #include "base/mutex-inl.h"
     28 #include "base/stl_util.h"
     29 #include "base/systrace.h"
     30 #include "base/time_utils.h"
     31 #include "class_linker.h"
     32 #include "compiler_callbacks.h"
     33 #include "dex_file-inl.h"
     34 #include "dex_instruction-inl.h"
     35 #include "dex_instruction_utils.h"
     36 #include "dex_instruction_visitor.h"
     37 #include "experimental_flags.h"
     38 #include "gc/accounting/card_table-inl.h"
     39 #include "handle_scope-inl.h"
     40 #include "indenter.h"
     41 #include "intern_table.h"
     42 #include "leb128.h"
     43 #include "method_resolution_kind.h"
     44 #include "mirror/class.h"
     45 #include "mirror/class-inl.h"
     46 #include "mirror/dex_cache-inl.h"
     47 #include "mirror/method_handle_impl.h"
     48 #include "mirror/object-inl.h"
     49 #include "mirror/object_array-inl.h"
     50 #include "reg_type-inl.h"
     51 #include "register_line-inl.h"
     52 #include "runtime.h"
     53 #include "scoped_thread_state_change-inl.h"
     54 #include "utils.h"
     55 #include "verifier_deps.h"
     56 #include "verifier_compiler_binding.h"
     57 
     58 namespace art {
     59 namespace verifier {
     60 
     61 using android::base::StringPrintf;
     62 
     63 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
     64 static constexpr bool kDebugVerify = false;
     65 // TODO: Add a constant to method_verifier to turn on verbose logging?
     66 
     67 // On VLOG(verifier), should we dump the whole state when we run into a hard failure?
     68 static constexpr bool kDumpRegLinesOnHardFailureIfVLOG = true;
     69 
     70 // We print a warning blurb about "dx --no-optimize" when we find monitor-locking issues. Make
     71 // sure we only print this once.
     72 static bool gPrintedDxMonitorText = false;
     73 
     74 PcToRegisterLineTable::PcToRegisterLineTable(ScopedArenaAllocator& arena)
     75     : register_lines_(arena.Adapter(kArenaAllocVerifier)) {}
     76 
     77 void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* flags,
     78                                  uint32_t insns_size, uint16_t registers_size,
     79                                  MethodVerifier* verifier) {
     80   DCHECK_GT(insns_size, 0U);
     81   register_lines_.resize(insns_size);
     82   for (uint32_t i = 0; i < insns_size; i++) {
     83     bool interesting = false;
     84     switch (mode) {
     85       case kTrackRegsAll:
     86         interesting = flags[i].IsOpcode();
     87         break;
     88       case kTrackCompilerInterestPoints:
     89         interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget();
     90         break;
     91       case kTrackRegsBranches:
     92         interesting = flags[i].IsBranchTarget();
     93         break;
     94       default:
     95         break;
     96     }
     97     if (interesting) {
     98       register_lines_[i].reset(RegisterLine::Create(registers_size, verifier));
     99     }
    100   }
    101 }
    102 
    103 PcToRegisterLineTable::~PcToRegisterLineTable() {}
    104 
    105 // Note: returns true on failure.
    106 ALWAYS_INLINE static inline bool FailOrAbort(MethodVerifier* verifier, bool condition,
    107                                              const char* error_msg, uint32_t work_insn_idx) {
    108   if (kIsDebugBuild) {
    109     // In a debug build, abort if the error condition is wrong. Only warn if
    110     // we are already aborting (as this verification is likely run to print
    111     // lock information).
    112     if (LIKELY(gAborting == 0)) {
    113       DCHECK(condition) << error_msg << work_insn_idx;
    114     } else {
    115       if (!condition) {
    116         LOG(ERROR) << error_msg << work_insn_idx;
    117         verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
    118         return true;
    119       }
    120     }
    121   } else {
    122     // In a non-debug build, just fail the class.
    123     if (!condition) {
    124       verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
    125       return true;
    126     }
    127   }
    128 
    129   return false;
    130 }
    131 
    132 static void SafelyMarkAllRegistersAsConflicts(MethodVerifier* verifier, RegisterLine* reg_line) {
    133   if (verifier->IsInstanceConstructor()) {
    134     // Before we mark all regs as conflicts, check that we don't have an uninitialized this.
    135     reg_line->CheckConstructorReturn(verifier);
    136   }
    137   reg_line->MarkAllRegistersAsConflicts(verifier);
    138 }
    139 
    140 FailureKind MethodVerifier::VerifyClass(Thread* self,
    141                                         mirror::Class* klass,
    142                                         CompilerCallbacks* callbacks,
    143                                         bool allow_soft_failures,
    144                                         HardFailLogMode log_level,
    145                                         std::string* error) {
    146   if (klass->IsVerified()) {
    147     return FailureKind::kNoFailure;
    148   }
    149   bool early_failure = false;
    150   std::string failure_message;
    151   const DexFile& dex_file = klass->GetDexFile();
    152   const DexFile::ClassDef* class_def = klass->GetClassDef();
    153   mirror::Class* super = klass->GetSuperClass();
    154   std::string temp;
    155   if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
    156     early_failure = true;
    157     failure_message = " that has no super class";
    158   } else if (super != nullptr && super->IsFinal()) {
    159     early_failure = true;
    160     failure_message = " that attempts to sub-class final class " + super->PrettyDescriptor();
    161   } else if (class_def == nullptr) {
    162     early_failure = true;
    163     failure_message = " that isn't present in dex file " + dex_file.GetLocation();
    164   }
    165   if (early_failure) {
    166     *error = "Verifier rejected class " + klass->PrettyDescriptor() + failure_message;
    167     if (callbacks != nullptr) {
    168       ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
    169       callbacks->ClassRejected(ref);
    170     }
    171     return FailureKind::kHardFailure;
    172   }
    173   StackHandleScope<2> hs(self);
    174   Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
    175   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
    176   return VerifyClass(self,
    177                      &dex_file,
    178                      dex_cache,
    179                      class_loader,
    180                      *class_def,
    181                      callbacks,
    182                      allow_soft_failures,
    183                      log_level,
    184                      error);
    185 }
    186 
    187 template <bool kDirect>
    188 static bool HasNextMethod(ClassDataItemIterator* it) {
    189   return kDirect ? it->HasNextDirectMethod() : it->HasNextVirtualMethod();
    190 }
    191 
    192 static FailureKind FailureKindMax(FailureKind fk1, FailureKind fk2) {
    193   static_assert(FailureKind::kNoFailure < FailureKind::kSoftFailure
    194                     && FailureKind::kSoftFailure < FailureKind::kHardFailure,
    195                 "Unexpected FailureKind order");
    196   return std::max(fk1, fk2);
    197 }
    198 
    199 void MethodVerifier::FailureData::Merge(const MethodVerifier::FailureData& fd) {
    200   kind = FailureKindMax(kind, fd.kind);
    201   types |= fd.types;
    202 }
    203 
    204 template <bool kDirect>
    205 MethodVerifier::FailureData MethodVerifier::VerifyMethods(Thread* self,
    206                                                           ClassLinker* linker,
    207                                                           const DexFile* dex_file,
    208                                                           const DexFile::ClassDef& class_def,
    209                                                           ClassDataItemIterator* it,
    210                                                           Handle<mirror::DexCache> dex_cache,
    211                                                           Handle<mirror::ClassLoader> class_loader,
    212                                                           CompilerCallbacks* callbacks,
    213                                                           bool allow_soft_failures,
    214                                                           HardFailLogMode log_level,
    215                                                           bool need_precise_constants,
    216                                                           std::string* error_string) {
    217   DCHECK(it != nullptr);
    218 
    219   MethodVerifier::FailureData failure_data;
    220 
    221   int64_t previous_method_idx = -1;
    222   while (HasNextMethod<kDirect>(it)) {
    223     self->AllowThreadSuspension();
    224     uint32_t method_idx = it->GetMemberIndex();
    225     if (method_idx == previous_method_idx) {
    226       // smali can create dex files with two encoded_methods sharing the same method_idx
    227       // http://code.google.com/p/smali/issues/detail?id=119
    228       it->Next();
    229       continue;
    230     }
    231     previous_method_idx = method_idx;
    232     InvokeType type = it->GetMethodInvokeType(class_def);
    233     ArtMethod* method = linker->ResolveMethod<ClassLinker::kNoICCECheckForCache>(
    234         *dex_file, method_idx, dex_cache, class_loader, nullptr, type);
    235     if (method == nullptr) {
    236       DCHECK(self->IsExceptionPending());
    237       // We couldn't resolve the method, but continue regardless.
    238       self->ClearException();
    239     } else {
    240       DCHECK(method->GetDeclaringClassUnchecked() != nullptr) << type;
    241     }
    242     StackHandleScope<1> hs(self);
    243     std::string hard_failure_msg;
    244     MethodVerifier::FailureData result = VerifyMethod(self,
    245                                                       method_idx,
    246                                                       dex_file,
    247                                                       dex_cache,
    248                                                       class_loader,
    249                                                       class_def,
    250                                                       it->GetMethodCodeItem(),
    251                                                       method,
    252                                                       it->GetMethodAccessFlags(),
    253                                                       callbacks,
    254                                                       allow_soft_failures,
    255                                                       log_level,
    256                                                       need_precise_constants,
    257                                                       &hard_failure_msg);
    258     if (result.kind == FailureKind::kHardFailure) {
    259       if (failure_data.kind == FailureKind::kHardFailure) {
    260         // If we logged an error before, we need a newline.
    261         *error_string += "\n";
    262       } else {
    263         // If we didn't log a hard failure before, print the header of the message.
    264         *error_string += "Verifier rejected class ";
    265         *error_string += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
    266         *error_string += ":";
    267       }
    268       *error_string += " ";
    269       *error_string += hard_failure_msg;
    270     }
    271     failure_data.Merge(result);
    272     it->Next();
    273   }
    274 
    275   return failure_data;
    276 }
    277 
    278 FailureKind MethodVerifier::VerifyClass(Thread* self,
    279                                         const DexFile* dex_file,
    280                                         Handle<mirror::DexCache> dex_cache,
    281                                         Handle<mirror::ClassLoader> class_loader,
    282                                         const DexFile::ClassDef& class_def,
    283                                         CompilerCallbacks* callbacks,
    284                                         bool allow_soft_failures,
    285                                         HardFailLogMode log_level,
    286                                         std::string* error) {
    287   ScopedTrace trace(__FUNCTION__);
    288 
    289   // A class must not be abstract and final.
    290   if ((class_def.access_flags_ & (kAccAbstract | kAccFinal)) == (kAccAbstract | kAccFinal)) {
    291     *error = "Verifier rejected class ";
    292     *error += PrettyDescriptor(dex_file->GetClassDescriptor(class_def));
    293     *error += ": class is abstract and final.";
    294     return FailureKind::kHardFailure;
    295   }
    296 
    297   const uint8_t* class_data = dex_file->GetClassData(class_def);
    298   if (class_data == nullptr) {
    299     // empty class, probably a marker interface
    300     return FailureKind::kNoFailure;
    301   }
    302   ClassDataItemIterator it(*dex_file, class_data);
    303   while (it.HasNextStaticField() || it.HasNextInstanceField()) {
    304     it.Next();
    305   }
    306   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    307   // Direct methods.
    308   MethodVerifier::FailureData data1 = VerifyMethods<true>(self,
    309                                                           linker,
    310                                                           dex_file,
    311                                                           class_def,
    312                                                           &it,
    313                                                           dex_cache,
    314                                                           class_loader,
    315                                                           callbacks,
    316                                                           allow_soft_failures,
    317                                                           log_level,
    318                                                           false /* need precise constants */,
    319                                                           error);
    320   // Virtual methods.
    321   MethodVerifier::FailureData data2 = VerifyMethods<false>(self,
    322                                                            linker,
    323                                                            dex_file,
    324                                                            class_def,
    325                                                            &it,
    326                                                            dex_cache,
    327                                                            class_loader,
    328                                                            callbacks,
    329                                                            allow_soft_failures,
    330                                                            log_level,
    331                                                            false /* need precise constants */,
    332                                                            error);
    333 
    334   data1.Merge(data2);
    335 
    336   if (data1.kind == FailureKind::kNoFailure) {
    337     return FailureKind::kNoFailure;
    338   } else {
    339     if ((data1.types & VERIFY_ERROR_LOCKING) != 0) {
    340       // Print a warning about expected slow-down. Use a string temporary to print one contiguous
    341       // warning.
    342       std::string tmp =
    343           StringPrintf("Class %s failed lock verification and will run slower.",
    344                        PrettyDescriptor(dex_file->GetClassDescriptor(class_def)).c_str());
    345       if (!gPrintedDxMonitorText) {
    346         tmp = tmp + "\nCommon causes for lock verification issues are non-optimized dex code\n"
    347                     "and incorrect proguard optimizations.";
    348         gPrintedDxMonitorText = true;
    349       }
    350       LOG(WARNING) << tmp;
    351     }
    352     return data1.kind;
    353   }
    354 }
    355 
    356 static bool IsLargeMethod(const DexFile::CodeItem* const code_item) {
    357   if (code_item == nullptr) {
    358     return false;
    359   }
    360 
    361   uint16_t registers_size = code_item->registers_size_;
    362   uint32_t insns_size = code_item->insns_size_in_code_units_;
    363 
    364   return registers_size * insns_size > 4*1024*1024;
    365 }
    366 
    367 MethodVerifier::FailureData MethodVerifier::VerifyMethod(Thread* self,
    368                                                          uint32_t method_idx,
    369                                                          const DexFile* dex_file,
    370                                                          Handle<mirror::DexCache> dex_cache,
    371                                                          Handle<mirror::ClassLoader> class_loader,
    372                                                          const DexFile::ClassDef& class_def,
    373                                                          const DexFile::CodeItem* code_item,
    374                                                          ArtMethod* method,
    375                                                          uint32_t method_access_flags,
    376                                                          CompilerCallbacks* callbacks,
    377                                                          bool allow_soft_failures,
    378                                                          HardFailLogMode log_level,
    379                                                          bool need_precise_constants,
    380                                                          std::string* hard_failure_msg) {
    381   MethodVerifier::FailureData result;
    382   uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
    383 
    384   MethodVerifier verifier(self,
    385                           dex_file,
    386                           dex_cache,
    387                           class_loader,
    388                           class_def,
    389                           code_item,
    390                           method_idx,
    391                           method,
    392                           method_access_flags,
    393                           true /* can_load_classes */,
    394                           allow_soft_failures,
    395                           need_precise_constants,
    396                           false /* verify to dump */,
    397                           true /* allow_thread_suspension */);
    398   if (verifier.Verify()) {
    399     // Verification completed, however failures may be pending that didn't cause the verification
    400     // to hard fail.
    401     CHECK(!verifier.have_pending_hard_failure_);
    402 
    403     if (code_item != nullptr && callbacks != nullptr) {
    404       // Let the interested party know that the method was verified.
    405       callbacks->MethodVerified(&verifier);
    406     }
    407 
    408     if (verifier.failures_.size() != 0) {
    409       if (VLOG_IS_ON(verifier)) {
    410         verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in "
    411                                                     << dex_file->PrettyMethod(method_idx) << "\n");
    412       }
    413       result.kind = FailureKind::kSoftFailure;
    414       if (method != nullptr &&
    415           !CanCompilerHandleVerificationFailure(verifier.encountered_failure_types_)) {
    416         method->SetDontCompile();
    417       }
    418     }
    419     if (method != nullptr) {
    420       if (verifier.HasInstructionThatWillThrow()) {
    421         method->SetDontCompile();
    422         if (Runtime::Current()->IsAotCompiler() &&
    423             (callbacks != nullptr) && !callbacks->IsBootImage()) {
    424           // When compiling apps, make HasInstructionThatWillThrow a soft error to trigger
    425           // re-verification at runtime.
    426           // The dead code after the throw is not verified and might be invalid. This may cause
    427           // the JIT compiler to crash since it assumes that all the code is valid.
    428           //
    429           // There's a strong assumption that the entire boot image is verified and all its dex
    430           // code is valid (even the dead and unverified one). As such this is done only for apps.
    431           // (CompilerDriver DCHECKs in VerifyClassVisitor that methods from boot image are
    432           // fully verified).
    433           result.kind = FailureKind::kSoftFailure;
    434         }
    435       }
    436       if ((verifier.encountered_failure_types_ & VerifyError::VERIFY_ERROR_LOCKING) != 0) {
    437         method->AddAccessFlags(kAccMustCountLocks);
    438       }
    439     }
    440   } else {
    441     // Bad method data.
    442     CHECK_NE(verifier.failures_.size(), 0U);
    443 
    444     if (UNLIKELY(verifier.have_pending_experimental_failure_)) {
    445       // Failed due to being forced into interpreter. This is ok because
    446       // we just want to skip verification.
    447       result.kind = FailureKind::kSoftFailure;
    448     } else {
    449       CHECK(verifier.have_pending_hard_failure_);
    450       if (VLOG_IS_ON(verifier)) {
    451         log_level = std::max(HardFailLogMode::kLogVerbose, log_level);
    452       }
    453       if (log_level >= HardFailLogMode::kLogVerbose) {
    454         LogSeverity severity;
    455         switch (log_level) {
    456           case HardFailLogMode::kLogVerbose:
    457             severity = LogSeverity::VERBOSE;
    458             break;
    459           case HardFailLogMode::kLogWarning:
    460             severity = LogSeverity::WARNING;
    461             break;
    462           case HardFailLogMode::kLogInternalFatal:
    463             severity = LogSeverity::FATAL_WITHOUT_ABORT;
    464             break;
    465           default:
    466             LOG(FATAL) << "Unsupported log-level " << static_cast<uint32_t>(log_level);
    467             UNREACHABLE();
    468         }
    469         verifier.DumpFailures(LOG_STREAM(severity) << "Verification error in "
    470                                                    << dex_file->PrettyMethod(method_idx)
    471                                                    << "\n");
    472       }
    473       if (hard_failure_msg != nullptr) {
    474         CHECK(!verifier.failure_messages_.empty());
    475         *hard_failure_msg =
    476             verifier.failure_messages_[verifier.failure_messages_.size() - 1]->str();
    477       }
    478       result.kind = FailureKind::kHardFailure;
    479 
    480       if (callbacks != nullptr) {
    481         // Let the interested party know that we failed the class.
    482         ClassReference ref(dex_file, dex_file->GetIndexForClassDef(class_def));
    483         callbacks->ClassRejected(ref);
    484       }
    485     }
    486     if (VLOG_IS_ON(verifier)) {
    487       std::cout << "\n" << verifier.info_messages_.str();
    488       verifier.Dump(std::cout);
    489     }
    490   }
    491   if (kTimeVerifyMethod) {
    492     uint64_t duration_ns = NanoTime() - start_ns;
    493     if (duration_ns > MsToNs(100)) {
    494       LOG(WARNING) << "Verification of " << dex_file->PrettyMethod(method_idx)
    495                    << " took " << PrettyDuration(duration_ns)
    496                    << (IsLargeMethod(code_item) ? " (large method)" : "");
    497     }
    498   }
    499   result.types = verifier.encountered_failure_types_;
    500   return result;
    501 }
    502 
    503 MethodVerifier* MethodVerifier::VerifyMethodAndDump(Thread* self,
    504                                                     VariableIndentationOutputStream* vios,
    505                                                     uint32_t dex_method_idx,
    506                                                     const DexFile* dex_file,
    507                                                     Handle<mirror::DexCache> dex_cache,
    508                                                     Handle<mirror::ClassLoader> class_loader,
    509                                                     const DexFile::ClassDef& class_def,
    510                                                     const DexFile::CodeItem* code_item,
    511                                                     ArtMethod* method,
    512                                                     uint32_t method_access_flags) {
    513   MethodVerifier* verifier = new MethodVerifier(self,
    514                                                 dex_file,
    515                                                 dex_cache,
    516                                                 class_loader,
    517                                                 class_def,
    518                                                 code_item,
    519                                                 dex_method_idx,
    520                                                 method,
    521                                                 method_access_flags,
    522                                                 true /* can_load_classes */,
    523                                                 true /* allow_soft_failures */,
    524                                                 true /* need_precise_constants */,
    525                                                 true /* verify_to_dump */,
    526                                                 true /* allow_thread_suspension */);
    527   verifier->Verify();
    528   verifier->DumpFailures(vios->Stream());
    529   vios->Stream() << verifier->info_messages_.str();
    530   // Only dump and return if no hard failures. Otherwise the verifier may be not fully initialized
    531   // and querying any info is dangerous/can abort.
    532   if (verifier->have_pending_hard_failure_) {
    533     delete verifier;
    534     return nullptr;
    535   } else {
    536     verifier->Dump(vios);
    537     return verifier;
    538   }
    539 }
    540 
    541 MethodVerifier::MethodVerifier(Thread* self,
    542                                const DexFile* dex_file,
    543                                Handle<mirror::DexCache> dex_cache,
    544                                Handle<mirror::ClassLoader> class_loader,
    545                                const DexFile::ClassDef& class_def,
    546                                const DexFile::CodeItem* code_item,
    547                                uint32_t dex_method_idx,
    548                                ArtMethod* method,
    549                                uint32_t method_access_flags,
    550                                bool can_load_classes,
    551                                bool allow_soft_failures,
    552                                bool need_precise_constants,
    553                                bool verify_to_dump,
    554                                bool allow_thread_suspension)
    555     : self_(self),
    556       arena_stack_(Runtime::Current()->GetArenaPool()),
    557       arena_(&arena_stack_),
    558       reg_types_(can_load_classes, arena_),
    559       reg_table_(arena_),
    560       work_insn_idx_(DexFile::kDexNoIndex),
    561       dex_method_idx_(dex_method_idx),
    562       mirror_method_(method),
    563       method_access_flags_(method_access_flags),
    564       return_type_(nullptr),
    565       dex_file_(dex_file),
    566       dex_cache_(dex_cache),
    567       class_loader_(class_loader),
    568       class_def_(class_def),
    569       code_item_(code_item),
    570       declaring_class_(nullptr),
    571       interesting_dex_pc_(-1),
    572       monitor_enter_dex_pcs_(nullptr),
    573       have_pending_hard_failure_(false),
    574       have_pending_runtime_throw_failure_(false),
    575       have_pending_experimental_failure_(false),
    576       have_any_pending_runtime_throw_failure_(false),
    577       new_instance_count_(0),
    578       monitor_enter_count_(0),
    579       encountered_failure_types_(0),
    580       can_load_classes_(can_load_classes),
    581       allow_soft_failures_(allow_soft_failures),
    582       need_precise_constants_(need_precise_constants),
    583       has_check_casts_(false),
    584       has_virtual_or_interface_invokes_(false),
    585       verify_to_dump_(verify_to_dump),
    586       allow_thread_suspension_(allow_thread_suspension),
    587       is_constructor_(false),
    588       link_(nullptr) {
    589   self->PushVerifier(this);
    590 }
    591 
    592 MethodVerifier::~MethodVerifier() {
    593   Thread::Current()->PopVerifier(this);
    594   STLDeleteElements(&failure_messages_);
    595 }
    596 
    597 void MethodVerifier::FindLocksAtDexPc(ArtMethod* m, uint32_t dex_pc,
    598                                       std::vector<uint32_t>* monitor_enter_dex_pcs) {
    599   StackHandleScope<2> hs(Thread::Current());
    600   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    601   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    602   MethodVerifier verifier(hs.Self(),
    603                           m->GetDexFile(),
    604                           dex_cache,
    605                           class_loader,
    606                           m->GetClassDef(),
    607                           m->GetCodeItem(),
    608                           m->GetDexMethodIndex(),
    609                           m,
    610                           m->GetAccessFlags(),
    611                           false /* can_load_classes */,
    612                           true  /* allow_soft_failures */,
    613                           false /* need_precise_constants */,
    614                           false /* verify_to_dump */,
    615                           false /* allow_thread_suspension */);
    616   verifier.interesting_dex_pc_ = dex_pc;
    617   verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
    618   verifier.FindLocksAtDexPc();
    619 }
    620 
    621 static bool HasMonitorEnterInstructions(const DexFile::CodeItem* const code_item) {
    622   const Instruction* inst = Instruction::At(code_item->insns_);
    623 
    624   uint32_t insns_size = code_item->insns_size_in_code_units_;
    625   for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
    626     if (inst->Opcode() == Instruction::MONITOR_ENTER) {
    627       return true;
    628     }
    629 
    630     dex_pc += inst->SizeInCodeUnits();
    631     inst = inst->Next();
    632   }
    633 
    634   return false;
    635 }
    636 
    637 void MethodVerifier::FindLocksAtDexPc() {
    638   CHECK(monitor_enter_dex_pcs_ != nullptr);
    639   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    640 
    641   // Quick check whether there are any monitor_enter instructions at all.
    642   if (!HasMonitorEnterInstructions(code_item_)) {
    643     return;
    644   }
    645 
    646   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    647   // verification. In practice, the phase we want relies on data structures set up by all the
    648   // earlier passes, so we just run the full method verification and bail out early when we've
    649   // got what we wanted.
    650   Verify();
    651 }
    652 
    653 ArtField* MethodVerifier::FindAccessedFieldAtDexPc(ArtMethod* m, uint32_t dex_pc) {
    654   StackHandleScope<2> hs(Thread::Current());
    655   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    656   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    657   MethodVerifier verifier(hs.Self(),
    658                           m->GetDexFile(),
    659                           dex_cache,
    660                           class_loader,
    661                           m->GetClassDef(),
    662                           m->GetCodeItem(),
    663                           m->GetDexMethodIndex(),
    664                           m,
    665                           m->GetAccessFlags(),
    666                           true  /* can_load_classes */,
    667                           true  /* allow_soft_failures */,
    668                           false /* need_precise_constants */,
    669                           false /* verify_to_dump */,
    670                           true  /* allow_thread_suspension */);
    671   return verifier.FindAccessedFieldAtDexPc(dex_pc);
    672 }
    673 
    674 ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
    675   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    676 
    677   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    678   // verification. In practice, the phase we want relies on data structures set up by all the
    679   // earlier passes, so we just run the full method verification and bail out early when we've
    680   // got what we wanted.
    681   bool success = Verify();
    682   if (!success) {
    683     return nullptr;
    684   }
    685   RegisterLine* register_line = reg_table_.GetLine(dex_pc);
    686   if (register_line == nullptr) {
    687     return nullptr;
    688   }
    689   const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
    690   return GetQuickFieldAccess(inst, register_line);
    691 }
    692 
    693 ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(ArtMethod* m, uint32_t dex_pc) {
    694   StackHandleScope<2> hs(Thread::Current());
    695   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    696   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    697   MethodVerifier verifier(hs.Self(),
    698                           m->GetDexFile(),
    699                           dex_cache,
    700                           class_loader,
    701                           m->GetClassDef(),
    702                           m->GetCodeItem(),
    703                           m->GetDexMethodIndex(),
    704                           m,
    705                           m->GetAccessFlags(),
    706                           true  /* can_load_classes */,
    707                           true  /* allow_soft_failures */,
    708                           false /* need_precise_constants */,
    709                           false /* verify_to_dump */,
    710                           true  /* allow_thread_suspension */);
    711   return verifier.FindInvokedMethodAtDexPc(dex_pc);
    712 }
    713 
    714 ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(uint32_t dex_pc) {
    715   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    716 
    717   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    718   // verification. In practice, the phase we want relies on data structures set up by all the
    719   // earlier passes, so we just run the full method verification and bail out early when we've
    720   // got what we wanted.
    721   bool success = Verify();
    722   if (!success) {
    723     return nullptr;
    724   }
    725   RegisterLine* register_line = reg_table_.GetLine(dex_pc);
    726   if (register_line == nullptr) {
    727     return nullptr;
    728   }
    729   const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
    730   const bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
    731   return GetQuickInvokedMethod(inst, register_line, is_range, false);
    732 }
    733 
    734 bool MethodVerifier::Verify() {
    735   // Some older code doesn't correctly mark constructors as such. Test for this case by looking at
    736   // the name.
    737   const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
    738   const char* method_name = dex_file_->StringDataByIdx(method_id.name_idx_);
    739   bool instance_constructor_by_name = strcmp("<init>", method_name) == 0;
    740   bool static_constructor_by_name = strcmp("<clinit>", method_name) == 0;
    741   bool constructor_by_name = instance_constructor_by_name || static_constructor_by_name;
    742   // Check that only constructors are tagged, and check for bad code that doesn't tag constructors.
    743   if ((method_access_flags_ & kAccConstructor) != 0) {
    744     if (!constructor_by_name) {
    745       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    746             << "method is marked as constructor, but not named accordingly";
    747       return false;
    748     }
    749     is_constructor_ = true;
    750   } else if (constructor_by_name) {
    751     LOG(WARNING) << "Method " << dex_file_->PrettyMethod(dex_method_idx_)
    752                  << " not marked as constructor.";
    753     is_constructor_ = true;
    754   }
    755   // If it's a constructor, check whether IsStatic() matches the name.
    756   // This should have been rejected by the dex file verifier. Only do in debug build.
    757   if (kIsDebugBuild) {
    758     if (IsConstructor()) {
    759       if (IsStatic() ^ static_constructor_by_name) {
    760         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    761               << "constructor name doesn't match static flag";
    762         return false;
    763       }
    764     }
    765   }
    766 
    767   // Methods may only have one of public/protected/private.
    768   // This should have been rejected by the dex file verifier. Only do in debug build.
    769   if (kIsDebugBuild) {
    770     size_t access_mod_count =
    771         (((method_access_flags_ & kAccPublic) == 0) ? 0 : 1) +
    772         (((method_access_flags_ & kAccProtected) == 0) ? 0 : 1) +
    773         (((method_access_flags_ & kAccPrivate) == 0) ? 0 : 1);
    774     if (access_mod_count > 1) {
    775       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "method has more than one of public/protected/private";
    776       return false;
    777     }
    778   }
    779 
    780   // If there aren't any instructions, make sure that's expected, then exit successfully.
    781   if (code_item_ == nullptr) {
    782     // Only native or abstract methods may not have code.
    783     if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) {
    784       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method";
    785       return false;
    786     }
    787 
    788     // This should have been rejected by the dex file verifier. Only do in debug build.
    789     // Note: the above will also be rejected in the dex file verifier, starting in dex version 37.
    790     if (kIsDebugBuild) {
    791       if ((method_access_flags_ & kAccAbstract) != 0) {
    792         // Abstract methods are not allowed to have the following flags.
    793         static constexpr uint32_t kForbidden =
    794             kAccPrivate |
    795             kAccStatic |
    796             kAccFinal |
    797             kAccNative |
    798             kAccStrict |
    799             kAccSynchronized;
    800         if ((method_access_flags_ & kForbidden) != 0) {
    801           Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    802                 << "method can't be abstract and private/static/final/native/strict/synchronized";
    803           return false;
    804         }
    805       }
    806       if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
    807         // Interface methods must be public and abstract (if default methods are disabled).
    808         uint32_t kRequired = kAccPublic;
    809         if ((method_access_flags_ & kRequired) != kRequired) {
    810           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods must be public";
    811           return false;
    812         }
    813         // In addition to the above, interface methods must not be protected.
    814         static constexpr uint32_t kForbidden = kAccProtected;
    815         if ((method_access_flags_ & kForbidden) != 0) {
    816           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface methods can't be protected";
    817           return false;
    818         }
    819       }
    820       // We also don't allow constructors to be abstract or native.
    821       if (IsConstructor()) {
    822         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be abstract or native";
    823         return false;
    824       }
    825     }
    826     return true;
    827   }
    828 
    829   // This should have been rejected by the dex file verifier. Only do in debug build.
    830   if (kIsDebugBuild) {
    831     // When there's code, the method must not be native or abstract.
    832     if ((method_access_flags_ & (kAccNative | kAccAbstract)) != 0) {
    833       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "non-zero-length code in abstract or native method";
    834       return false;
    835     }
    836 
    837     if ((class_def_.GetJavaAccessFlags() & kAccInterface) != 0) {
    838       // Interfaces may always have static initializers for their fields. If we are running with
    839       // default methods enabled we also allow other public, static, non-final methods to have code.
    840       // Otherwise that is the only type of method allowed.
    841       if (!(IsConstructor() && IsStatic())) {
    842         if (IsInstanceConstructor()) {
    843           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have non-static constructor";
    844           return false;
    845         } else if (method_access_flags_ & kAccFinal) {
    846           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interfaces may not have final methods";
    847           return false;
    848         } else {
    849           uint32_t access_flag_options = kAccPublic;
    850           if (dex_file_->GetVersion() >= DexFile::kDefaultMethodsVersion) {
    851             access_flag_options |= kAccPrivate;
    852           }
    853           if (!(method_access_flags_ & access_flag_options)) {
    854             Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    855                 << "interfaces may not have protected or package-private members";
    856             return false;
    857           }
    858         }
    859       }
    860     }
    861 
    862     // Instance constructors must not be synchronized.
    863     if (IsInstanceConstructor()) {
    864       static constexpr uint32_t kForbidden = kAccSynchronized;
    865       if ((method_access_flags_ & kForbidden) != 0) {
    866         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "constructors can't be synchronized";
    867         return false;
    868       }
    869     }
    870   }
    871 
    872   // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers.
    873   if (code_item_->ins_size_ > code_item_->registers_size_) {
    874     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins=" << code_item_->ins_size_
    875                                       << " regs=" << code_item_->registers_size_;
    876     return false;
    877   }
    878 
    879   // Allocate and initialize an array to hold instruction data.
    880   insn_flags_.reset(arena_.AllocArray<InstructionFlags>(code_item_->insns_size_in_code_units_));
    881   DCHECK(insn_flags_ != nullptr);
    882   std::uninitialized_fill_n(insn_flags_.get(),
    883                             code_item_->insns_size_in_code_units_,
    884                             InstructionFlags());
    885   // Run through the instructions and see if the width checks out.
    886   bool result = ComputeWidthsAndCountOps();
    887   // Flag instructions guarded by a "try" block and check exception handlers.
    888   result = result && ScanTryCatchBlocks();
    889   // Perform static instruction verification.
    890   result = result && VerifyInstructions();
    891   // Perform code-flow analysis and return.
    892   result = result && VerifyCodeFlow();
    893 
    894   return result;
    895 }
    896 
    897 std::ostream& MethodVerifier::Fail(VerifyError error) {
    898   // Mark the error type as encountered.
    899   encountered_failure_types_ |= static_cast<uint32_t>(error);
    900 
    901   switch (error) {
    902     case VERIFY_ERROR_NO_CLASS:
    903     case VERIFY_ERROR_NO_FIELD:
    904     case VERIFY_ERROR_NO_METHOD:
    905     case VERIFY_ERROR_ACCESS_CLASS:
    906     case VERIFY_ERROR_ACCESS_FIELD:
    907     case VERIFY_ERROR_ACCESS_METHOD:
    908     case VERIFY_ERROR_INSTANTIATION:
    909     case VERIFY_ERROR_CLASS_CHANGE:
    910     case VERIFY_ERROR_FORCE_INTERPRETER:
    911     case VERIFY_ERROR_LOCKING:
    912       if (Runtime::Current()->IsAotCompiler() || !can_load_classes_) {
    913         // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
    914         // class change and instantiation errors into soft verification errors so that we re-verify
    915         // at runtime. We may fail to find or to agree on access because of not yet available class
    916         // loaders, or class loaders that will differ at runtime. In these cases, we don't want to
    917         // affect the soundness of the code being compiled. Instead, the generated code runs "slow
    918         // paths" that dynamically perform the verification and cause the behavior to be that akin
    919         // to an interpreter.
    920         error = VERIFY_ERROR_BAD_CLASS_SOFT;
    921       } else {
    922         // If we fail again at runtime, mark that this instruction would throw and force this
    923         // method to be executed using the interpreter with checks.
    924         have_pending_runtime_throw_failure_ = true;
    925 
    926         // We need to save the work_line if the instruction wasn't throwing before. Otherwise we'll
    927         // try to merge garbage.
    928         // Note: this assumes that Fail is called before we do any work_line modifications.
    929         // Note: this can fail before we touch any instruction, for the signature of a method. So
    930         //       add a check.
    931         if (work_insn_idx_ < DexFile::kDexNoIndex) {
    932           const uint16_t* insns = code_item_->insns_ + work_insn_idx_;
    933           const Instruction* inst = Instruction::At(insns);
    934           int opcode_flags = Instruction::FlagsOf(inst->Opcode());
    935 
    936           if ((opcode_flags & Instruction::kThrow) == 0 && CurrentInsnFlags()->IsInTry()) {
    937             saved_line_->CopyFromLine(work_line_.get());
    938           }
    939         }
    940       }
    941       break;
    942 
    943       // Indication that verification should be retried at runtime.
    944     case VERIFY_ERROR_BAD_CLASS_SOFT:
    945       if (!allow_soft_failures_) {
    946         have_pending_hard_failure_ = true;
    947       }
    948       break;
    949 
    950       // Hard verification failures at compile time will still fail at runtime, so the class is
    951       // marked as rejected to prevent it from being compiled.
    952     case VERIFY_ERROR_BAD_CLASS_HARD: {
    953       have_pending_hard_failure_ = true;
    954       if (VLOG_IS_ON(verifier) && kDumpRegLinesOnHardFailureIfVLOG) {
    955         ScopedObjectAccess soa(Thread::Current());
    956         std::ostringstream oss;
    957         Dump(oss);
    958         LOG(ERROR) << oss.str();
    959       }
    960       break;
    961     }
    962   }
    963   failures_.push_back(error);
    964   std::string location(StringPrintf("%s: [0x%X] ", dex_file_->PrettyMethod(dex_method_idx_).c_str(),
    965                                     work_insn_idx_));
    966   std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate);
    967   failure_messages_.push_back(failure_message);
    968   return *failure_message;
    969 }
    970 
    971 std::ostream& MethodVerifier::LogVerifyInfo() {
    972   return info_messages_ << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_)
    973                         << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
    974 }
    975 
    976 void MethodVerifier::PrependToLastFailMessage(std::string prepend) {
    977   size_t failure_num = failure_messages_.size();
    978   DCHECK_NE(failure_num, 0U);
    979   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    980   prepend += last_fail_message->str();
    981   failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate);
    982   delete last_fail_message;
    983 }
    984 
    985 void MethodVerifier::AppendToLastFailMessage(const std::string& append) {
    986   size_t failure_num = failure_messages_.size();
    987   DCHECK_NE(failure_num, 0U);
    988   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    989   (*last_fail_message) << append;
    990 }
    991 
    992 bool MethodVerifier::ComputeWidthsAndCountOps() {
    993   const uint16_t* insns = code_item_->insns_;
    994   size_t insns_size = code_item_->insns_size_in_code_units_;
    995   const Instruction* inst = Instruction::At(insns);
    996   size_t new_instance_count = 0;
    997   size_t monitor_enter_count = 0;
    998   size_t dex_pc = 0;
    999 
   1000   while (dex_pc < insns_size) {
   1001     Instruction::Code opcode = inst->Opcode();
   1002     switch (opcode) {
   1003       case Instruction::APUT_OBJECT:
   1004       case Instruction::CHECK_CAST:
   1005         has_check_casts_ = true;
   1006         break;
   1007       case Instruction::INVOKE_VIRTUAL:
   1008       case Instruction::INVOKE_VIRTUAL_RANGE:
   1009       case Instruction::INVOKE_INTERFACE:
   1010       case Instruction::INVOKE_INTERFACE_RANGE:
   1011         has_virtual_or_interface_invokes_ = true;
   1012         break;
   1013       case Instruction::MONITOR_ENTER:
   1014         monitor_enter_count++;
   1015         break;
   1016       case Instruction::NEW_INSTANCE:
   1017         new_instance_count++;
   1018         break;
   1019       default:
   1020         break;
   1021     }
   1022     size_t inst_size = inst->SizeInCodeUnits();
   1023     GetInstructionFlags(dex_pc).SetIsOpcode();
   1024     dex_pc += inst_size;
   1025     inst = inst->RelativeAt(inst_size);
   1026   }
   1027 
   1028   if (dex_pc != insns_size) {
   1029     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected ("
   1030                                       << dex_pc << " vs. " << insns_size << ")";
   1031     return false;
   1032   }
   1033 
   1034   new_instance_count_ = new_instance_count;
   1035   monitor_enter_count_ = monitor_enter_count;
   1036   return true;
   1037 }
   1038 
   1039 bool MethodVerifier::ScanTryCatchBlocks() {
   1040   uint32_t tries_size = code_item_->tries_size_;
   1041   if (tries_size == 0) {
   1042     return true;
   1043   }
   1044   uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1045   const DexFile::TryItem* tries = DexFile::GetTryItems(*code_item_, 0);
   1046 
   1047   for (uint32_t idx = 0; idx < tries_size; idx++) {
   1048     const DexFile::TryItem* try_item = &tries[idx];
   1049     uint32_t start = try_item->start_addr_;
   1050     uint32_t end = start + try_item->insn_count_;
   1051     if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
   1052       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start
   1053                                         << " endAddr=" << end << " (size=" << insns_size << ")";
   1054       return false;
   1055     }
   1056     if (!GetInstructionFlags(start).IsOpcode()) {
   1057       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1058           << "'try' block starts inside an instruction (" << start << ")";
   1059       return false;
   1060     }
   1061     uint32_t dex_pc = start;
   1062     const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
   1063     while (dex_pc < end) {
   1064       GetInstructionFlags(dex_pc).SetInTry();
   1065       size_t insn_size = inst->SizeInCodeUnits();
   1066       dex_pc += insn_size;
   1067       inst = inst->RelativeAt(insn_size);
   1068     }
   1069   }
   1070   // Iterate over each of the handlers to verify target addresses.
   1071   const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
   1072   uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
   1073   ClassLinker* linker = Runtime::Current()->GetClassLinker();
   1074   for (uint32_t idx = 0; idx < handlers_size; idx++) {
   1075     CatchHandlerIterator iterator(handlers_ptr);
   1076     for (; iterator.HasNext(); iterator.Next()) {
   1077       uint32_t dex_pc= iterator.GetHandlerAddress();
   1078       if (!GetInstructionFlags(dex_pc).IsOpcode()) {
   1079         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1080             << "exception handler starts at bad address (" << dex_pc << ")";
   1081         return false;
   1082       }
   1083       if (!CheckNotMoveResult(code_item_->insns_, dex_pc)) {
   1084         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1085             << "exception handler begins with move-result* (" << dex_pc << ")";
   1086         return false;
   1087       }
   1088       GetInstructionFlags(dex_pc).SetBranchTarget();
   1089       // Ensure exception types are resolved so that they don't need resolution to be delivered,
   1090       // unresolved exception types will be ignored by exception delivery
   1091       if (iterator.GetHandlerTypeIndex().IsValid()) {
   1092         mirror::Class* exception_type = linker->ResolveType(*dex_file_,
   1093                                                             iterator.GetHandlerTypeIndex(),
   1094                                                             dex_cache_, class_loader_);
   1095         if (exception_type == nullptr) {
   1096           DCHECK(self_->IsExceptionPending());
   1097           self_->ClearException();
   1098         }
   1099       }
   1100     }
   1101     handlers_ptr = iterator.EndDataPointer();
   1102   }
   1103   return true;
   1104 }
   1105 
   1106 bool MethodVerifier::VerifyInstructions() {
   1107   const Instruction* inst = Instruction::At(code_item_->insns_);
   1108 
   1109   /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */
   1110   GetInstructionFlags(0).SetBranchTarget();
   1111   GetInstructionFlags(0).SetCompileTimeInfoPoint();
   1112 
   1113   uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1114   for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
   1115     if (!VerifyInstruction(inst, dex_pc)) {
   1116       DCHECK_NE(failures_.size(), 0U);
   1117       return false;
   1118     }
   1119     /* Flag instructions that are garbage collection points */
   1120     // All invoke points are marked as "Throw" points already.
   1121     // We are relying on this to also count all the invokes as interesting.
   1122     if (inst->IsBranch()) {
   1123       GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint();
   1124       // The compiler also needs safepoints for fall-through to loop heads.
   1125       // Such a loop head must be a target of a branch.
   1126       int32_t offset = 0;
   1127       bool cond, self_ok;
   1128       bool target_ok = GetBranchOffset(dex_pc, &offset, &cond, &self_ok);
   1129       DCHECK(target_ok);
   1130       GetInstructionFlags(dex_pc + offset).SetCompileTimeInfoPoint();
   1131     } else if (inst->IsSwitch() || inst->IsThrow()) {
   1132       GetInstructionFlags(dex_pc).SetCompileTimeInfoPoint();
   1133     } else if (inst->IsReturn()) {
   1134       GetInstructionFlags(dex_pc).SetCompileTimeInfoPointAndReturn();
   1135     }
   1136     dex_pc += inst->SizeInCodeUnits();
   1137     inst = inst->Next();
   1138   }
   1139   return true;
   1140 }
   1141 
   1142 bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_offset) {
   1143   if (UNLIKELY(inst->IsExperimental())) {
   1144     // Experimental instructions don't yet have verifier support implementation.
   1145     // While it is possible to use them by themselves, when we try to use stable instructions
   1146     // with a virtual register that was created by an experimental instruction,
   1147     // the data flow analysis will fail.
   1148     Fail(VERIFY_ERROR_FORCE_INTERPRETER)
   1149         << "experimental instruction is not supported by verifier; skipping verification";
   1150     have_pending_experimental_failure_ = true;
   1151     return false;
   1152   }
   1153 
   1154   bool result = true;
   1155   switch (inst->GetVerifyTypeArgumentA()) {
   1156     case Instruction::kVerifyRegA:
   1157       result = result && CheckRegisterIndex(inst->VRegA());
   1158       break;
   1159     case Instruction::kVerifyRegAWide:
   1160       result = result && CheckWideRegisterIndex(inst->VRegA());
   1161       break;
   1162   }
   1163   switch (inst->GetVerifyTypeArgumentB()) {
   1164     case Instruction::kVerifyRegB:
   1165       result = result && CheckRegisterIndex(inst->VRegB());
   1166       break;
   1167     case Instruction::kVerifyRegBField:
   1168       result = result && CheckFieldIndex(inst->VRegB());
   1169       break;
   1170     case Instruction::kVerifyRegBMethod:
   1171       result = result && CheckMethodIndex(inst->VRegB());
   1172       break;
   1173     case Instruction::kVerifyRegBNewInstance:
   1174       result = result && CheckNewInstance(dex::TypeIndex(inst->VRegB()));
   1175       break;
   1176     case Instruction::kVerifyRegBString:
   1177       result = result && CheckStringIndex(inst->VRegB());
   1178       break;
   1179     case Instruction::kVerifyRegBType:
   1180       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegB()));
   1181       break;
   1182     case Instruction::kVerifyRegBWide:
   1183       result = result && CheckWideRegisterIndex(inst->VRegB());
   1184       break;
   1185   }
   1186   switch (inst->GetVerifyTypeArgumentC()) {
   1187     case Instruction::kVerifyRegC:
   1188       result = result && CheckRegisterIndex(inst->VRegC());
   1189       break;
   1190     case Instruction::kVerifyRegCField:
   1191       result = result && CheckFieldIndex(inst->VRegC());
   1192       break;
   1193     case Instruction::kVerifyRegCNewArray:
   1194       result = result && CheckNewArray(dex::TypeIndex(inst->VRegC()));
   1195       break;
   1196     case Instruction::kVerifyRegCType:
   1197       result = result && CheckTypeIndex(dex::TypeIndex(inst->VRegC()));
   1198       break;
   1199     case Instruction::kVerifyRegCWide:
   1200       result = result && CheckWideRegisterIndex(inst->VRegC());
   1201       break;
   1202   }
   1203   switch (inst->GetVerifyTypeArgumentH()) {
   1204     case Instruction::kVerifyRegHPrototype:
   1205       result = result && CheckPrototypeIndex(inst->VRegH());
   1206       break;
   1207   }
   1208   switch (inst->GetVerifyExtraFlags()) {
   1209     case Instruction::kVerifyArrayData:
   1210       result = result && CheckArrayData(code_offset);
   1211       break;
   1212     case Instruction::kVerifyBranchTarget:
   1213       result = result && CheckBranchTarget(code_offset);
   1214       break;
   1215     case Instruction::kVerifySwitchTargets:
   1216       result = result && CheckSwitchTargets(code_offset);
   1217       break;
   1218     case Instruction::kVerifyVarArgNonZero:
   1219       // Fall-through.
   1220     case Instruction::kVerifyVarArg: {
   1221       // Instructions that can actually return a negative value shouldn't have this flag.
   1222       uint32_t v_a = dchecked_integral_cast<uint32_t>(inst->VRegA());
   1223       if ((inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && v_a == 0) ||
   1224           v_a > Instruction::kMaxVarArgRegs) {
   1225         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << v_a << ") in "
   1226                                              "non-range invoke";
   1227         return false;
   1228       }
   1229 
   1230       uint32_t args[Instruction::kMaxVarArgRegs];
   1231       inst->GetVarArgs(args);
   1232       result = result && CheckVarArgRegs(v_a, args);
   1233       break;
   1234     }
   1235     case Instruction::kVerifyVarArgRangeNonZero:
   1236       // Fall-through.
   1237     case Instruction::kVerifyVarArgRange:
   1238       if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero &&
   1239           inst->VRegA() <= 0) {
   1240         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
   1241                                              "range invoke";
   1242         return false;
   1243       }
   1244       result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC());
   1245       break;
   1246     case Instruction::kVerifyError:
   1247       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name();
   1248       result = false;
   1249       break;
   1250   }
   1251   if (inst->GetVerifyIsRuntimeOnly() && Runtime::Current()->IsAotCompiler() && !verify_to_dump_) {
   1252     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name();
   1253     result = false;
   1254   }
   1255   return result;
   1256 }
   1257 
   1258 inline bool MethodVerifier::CheckRegisterIndex(uint32_t idx) {
   1259   if (idx >= code_item_->registers_size_) {
   1260     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= "
   1261                                       << code_item_->registers_size_ << ")";
   1262     return false;
   1263   }
   1264   return true;
   1265 }
   1266 
   1267 inline bool MethodVerifier::CheckWideRegisterIndex(uint32_t idx) {
   1268   if (idx + 1 >= code_item_->registers_size_) {
   1269     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx
   1270                                       << "+1 >= " << code_item_->registers_size_ << ")";
   1271     return false;
   1272   }
   1273   return true;
   1274 }
   1275 
   1276 inline bool MethodVerifier::CheckFieldIndex(uint32_t idx) {
   1277   if (idx >= dex_file_->GetHeader().field_ids_size_) {
   1278     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max "
   1279                                       << dex_file_->GetHeader().field_ids_size_ << ")";
   1280     return false;
   1281   }
   1282   return true;
   1283 }
   1284 
   1285 inline bool MethodVerifier::CheckMethodIndex(uint32_t idx) {
   1286   if (idx >= dex_file_->GetHeader().method_ids_size_) {
   1287     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max "
   1288                                       << dex_file_->GetHeader().method_ids_size_ << ")";
   1289     return false;
   1290   }
   1291   return true;
   1292 }
   1293 
   1294 inline bool MethodVerifier::CheckNewInstance(dex::TypeIndex idx) {
   1295   if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) {
   1296     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1297                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1298     return false;
   1299   }
   1300   // We don't need the actual class, just a pointer to the class name.
   1301   const char* descriptor = dex_file_->StringByTypeIdx(idx);
   1302   if (descriptor[0] != 'L') {
   1303     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'";
   1304     return false;
   1305   } else if (strcmp(descriptor, "Ljava/lang/Class;") == 0) {
   1306     // An unlikely new instance on Class is not allowed. Fall back to interpreter to ensure an
   1307     // exception is thrown when this statement is executed (compiled code would not do that).
   1308     Fail(VERIFY_ERROR_INSTANTIATION);
   1309   }
   1310   return true;
   1311 }
   1312 
   1313 inline bool MethodVerifier::CheckPrototypeIndex(uint32_t idx) {
   1314   if (idx >= dex_file_->GetHeader().proto_ids_size_) {
   1315     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad prototype index " << idx << " (max "
   1316                                       << dex_file_->GetHeader().proto_ids_size_ << ")";
   1317     return false;
   1318   }
   1319   return true;
   1320 }
   1321 
   1322 inline bool MethodVerifier::CheckStringIndex(uint32_t idx) {
   1323   if (idx >= dex_file_->GetHeader().string_ids_size_) {
   1324     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max "
   1325                                       << dex_file_->GetHeader().string_ids_size_ << ")";
   1326     return false;
   1327   }
   1328   return true;
   1329 }
   1330 
   1331 inline bool MethodVerifier::CheckTypeIndex(dex::TypeIndex idx) {
   1332   if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) {
   1333     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1334                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1335     return false;
   1336   }
   1337   return true;
   1338 }
   1339 
   1340 bool MethodVerifier::CheckNewArray(dex::TypeIndex idx) {
   1341   if (idx.index_ >= dex_file_->GetHeader().type_ids_size_) {
   1342     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx.index_ << " (max "
   1343                                       << dex_file_->GetHeader().type_ids_size_ << ")";
   1344     return false;
   1345   }
   1346   int bracket_count = 0;
   1347   const char* descriptor = dex_file_->StringByTypeIdx(idx);
   1348   const char* cp = descriptor;
   1349   while (*cp++ == '[') {
   1350     bracket_count++;
   1351   }
   1352   if (bracket_count == 0) {
   1353     /* The given class must be an array type. */
   1354     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1355         << "can't new-array class '" << descriptor << "' (not an array)";
   1356     return false;
   1357   } else if (bracket_count > 255) {
   1358     /* It is illegal to create an array of more than 255 dimensions. */
   1359     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1360         << "can't new-array class '" << descriptor << "' (exceeds limit)";
   1361     return false;
   1362   }
   1363   return true;
   1364 }
   1365 
   1366 bool MethodVerifier::CheckArrayData(uint32_t cur_offset) {
   1367   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
   1368   const uint16_t* insns = code_item_->insns_ + cur_offset;
   1369   const uint16_t* array_data;
   1370   int32_t array_data_offset;
   1371 
   1372   DCHECK_LT(cur_offset, insn_count);
   1373   /* make sure the start of the array data table is in range */
   1374   array_data_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   1375   if (static_cast<int32_t>(cur_offset) + array_data_offset < 0 ||
   1376       cur_offset + array_data_offset + 2 >= insn_count) {
   1377     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset
   1378                                       << ", data offset " << array_data_offset
   1379                                       << ", count " << insn_count;
   1380     return false;
   1381   }
   1382   /* offset to array data table is a relative branch-style offset */
   1383   array_data = insns + array_data_offset;
   1384   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
   1385   if (!IsAligned<4>(array_data)) {
   1386     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset
   1387                                       << ", data offset " << array_data_offset;
   1388     return false;
   1389   }
   1390   // Make sure the array-data is marked as an opcode. This ensures that it was reached when
   1391   // traversing the code item linearly. It is an approximation for a by-spec padding value.
   1392   if (!GetInstructionFlags(cur_offset + array_data_offset).IsOpcode()) {
   1393     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array data table at " << cur_offset
   1394                                       << ", data offset " << array_data_offset
   1395                                       << " not correctly visited, probably bad padding.";
   1396     return false;
   1397   }
   1398 
   1399   uint32_t value_width = array_data[1];
   1400   uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]);
   1401   uint32_t table_size = 4 + (value_width * value_count + 1) / 2;
   1402   /* make sure the end of the switch is in range */
   1403   if (cur_offset + array_data_offset + table_size > insn_count) {
   1404     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset
   1405                                       << ", data offset " << array_data_offset << ", end "
   1406                                       << cur_offset + array_data_offset + table_size
   1407                                       << ", count " << insn_count;
   1408     return false;
   1409   }
   1410   return true;
   1411 }
   1412 
   1413 bool MethodVerifier::CheckBranchTarget(uint32_t cur_offset) {
   1414   int32_t offset;
   1415   bool isConditional, selfOkay;
   1416   if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) {
   1417     return false;
   1418   }
   1419   if (!selfOkay && offset == 0) {
   1420     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at"
   1421                                       << reinterpret_cast<void*>(cur_offset);
   1422     return false;
   1423   }
   1424   // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime
   1425   // to have identical "wrap-around" behavior, but it's unwise to depend on that.
   1426   if (((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset)) {
   1427     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow "
   1428                                       << reinterpret_cast<void*>(cur_offset) << " +" << offset;
   1429     return false;
   1430   }
   1431   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
   1432   int32_t abs_offset = cur_offset + offset;
   1433   if (abs_offset < 0 ||
   1434       (uint32_t) abs_offset >= insn_count ||
   1435       !GetInstructionFlags(abs_offset).IsOpcode()) {
   1436     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> "
   1437                                       << reinterpret_cast<void*>(abs_offset) << ") at "
   1438                                       << reinterpret_cast<void*>(cur_offset);
   1439     return false;
   1440   }
   1441   GetInstructionFlags(abs_offset).SetBranchTarget();
   1442   return true;
   1443 }
   1444 
   1445 bool MethodVerifier::GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional,
   1446                                   bool* selfOkay) {
   1447   const uint16_t* insns = code_item_->insns_ + cur_offset;
   1448   *pConditional = false;
   1449   *selfOkay = false;
   1450   switch (*insns & 0xff) {
   1451     case Instruction::GOTO:
   1452       *pOffset = ((int16_t) *insns) >> 8;
   1453       break;
   1454     case Instruction::GOTO_32:
   1455       *pOffset = insns[1] | (((uint32_t) insns[2]) << 16);
   1456       *selfOkay = true;
   1457       break;
   1458     case Instruction::GOTO_16:
   1459       *pOffset = (int16_t) insns[1];
   1460       break;
   1461     case Instruction::IF_EQ:
   1462     case Instruction::IF_NE:
   1463     case Instruction::IF_LT:
   1464     case Instruction::IF_GE:
   1465     case Instruction::IF_GT:
   1466     case Instruction::IF_LE:
   1467     case Instruction::IF_EQZ:
   1468     case Instruction::IF_NEZ:
   1469     case Instruction::IF_LTZ:
   1470     case Instruction::IF_GEZ:
   1471     case Instruction::IF_GTZ:
   1472     case Instruction::IF_LEZ:
   1473       *pOffset = (int16_t) insns[1];
   1474       *pConditional = true;
   1475       break;
   1476     default:
   1477       return false;
   1478   }
   1479   return true;
   1480 }
   1481 
   1482 bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) {
   1483   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
   1484   DCHECK_LT(cur_offset, insn_count);
   1485   const uint16_t* insns = code_item_->insns_ + cur_offset;
   1486   /* make sure the start of the switch is in range */
   1487   int32_t switch_offset = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   1488   if (static_cast<int32_t>(cur_offset) + switch_offset < 0 ||
   1489       cur_offset + switch_offset + 2 > insn_count) {
   1490     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset
   1491                                       << ", switch offset " << switch_offset
   1492                                       << ", count " << insn_count;
   1493     return false;
   1494   }
   1495   /* offset to switch table is a relative branch-style offset */
   1496   const uint16_t* switch_insns = insns + switch_offset;
   1497   // Make sure the table is at an even dex pc, that is, 32-bit aligned.
   1498   if (!IsAligned<4>(switch_insns)) {
   1499     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset
   1500                                       << ", switch offset " << switch_offset;
   1501     return false;
   1502   }
   1503   // Make sure the switch data is marked as an opcode. This ensures that it was reached when
   1504   // traversing the code item linearly. It is an approximation for a by-spec padding value.
   1505   if (!GetInstructionFlags(cur_offset + switch_offset).IsOpcode()) {
   1506     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "switch table at " << cur_offset
   1507                                       << ", switch offset " << switch_offset
   1508                                       << " not correctly visited, probably bad padding.";
   1509     return false;
   1510   }
   1511 
   1512   bool is_packed_switch = (*insns & 0xff) == Instruction::PACKED_SWITCH;
   1513 
   1514   uint32_t switch_count = switch_insns[1];
   1515   int32_t targets_offset;
   1516   uint16_t expected_signature;
   1517   if (is_packed_switch) {
   1518     /* 0=sig, 1=count, 2/3=firstKey */
   1519     targets_offset = 4;
   1520     expected_signature = Instruction::kPackedSwitchSignature;
   1521   } else {
   1522     /* 0=sig, 1=count, 2..count*2 = keys */
   1523     targets_offset = 2 + 2 * switch_count;
   1524     expected_signature = Instruction::kSparseSwitchSignature;
   1525   }
   1526   uint32_t table_size = targets_offset + switch_count * 2;
   1527   if (switch_insns[0] != expected_signature) {
   1528     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1529         << StringPrintf("wrong signature for switch table (%x, wanted %x)",
   1530                         switch_insns[0], expected_signature);
   1531     return false;
   1532   }
   1533   /* make sure the end of the switch is in range */
   1534   if (cur_offset + switch_offset + table_size > (uint32_t) insn_count) {
   1535     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset
   1536                                       << ", switch offset " << switch_offset
   1537                                       << ", end " << (cur_offset + switch_offset + table_size)
   1538                                       << ", count " << insn_count;
   1539     return false;
   1540   }
   1541 
   1542   constexpr int32_t keys_offset = 2;
   1543   if (switch_count > 1) {
   1544     if (is_packed_switch) {
   1545       /* for a packed switch, verify that keys do not overflow int32 */
   1546       int32_t first_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
   1547       int32_t max_first_key =
   1548           std::numeric_limits<int32_t>::max() - (static_cast<int32_t>(switch_count) - 1);
   1549       if (first_key > max_first_key) {
   1550         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: first_key=" << first_key
   1551                                           << ", switch_count=" << switch_count;
   1552         return false;
   1553       }
   1554     } else {
   1555       /* for a sparse switch, verify the keys are in ascending order */
   1556       int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
   1557       for (uint32_t targ = 1; targ < switch_count; targ++) {
   1558         int32_t key =
   1559             static_cast<int32_t>(switch_insns[keys_offset + targ * 2]) |
   1560             static_cast<int32_t>(switch_insns[keys_offset + targ * 2 + 1] << 16);
   1561         if (key <= last_key) {
   1562           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid sparse switch: last key=" << last_key
   1563                                             << ", this=" << key;
   1564           return false;
   1565         }
   1566         last_key = key;
   1567       }
   1568     }
   1569   }
   1570   /* verify each switch target */
   1571   for (uint32_t targ = 0; targ < switch_count; targ++) {
   1572     int32_t offset = static_cast<int32_t>(switch_insns[targets_offset + targ * 2]) |
   1573                      static_cast<int32_t>(switch_insns[targets_offset + targ * 2 + 1] << 16);
   1574     int32_t abs_offset = cur_offset + offset;
   1575     if (abs_offset < 0 ||
   1576         abs_offset >= static_cast<int32_t>(insn_count) ||
   1577         !GetInstructionFlags(abs_offset).IsOpcode()) {
   1578       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset
   1579                                         << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at "
   1580                                         << reinterpret_cast<void*>(cur_offset)
   1581                                         << "[" << targ << "]";
   1582       return false;
   1583     }
   1584     GetInstructionFlags(abs_offset).SetBranchTarget();
   1585   }
   1586   return true;
   1587 }
   1588 
   1589 bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) {
   1590   uint16_t registers_size = code_item_->registers_size_;
   1591   for (uint32_t idx = 0; idx < vA; idx++) {
   1592     if (arg[idx] >= registers_size) {
   1593       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx]
   1594                                         << ") in non-range invoke (>= " << registers_size << ")";
   1595       return false;
   1596     }
   1597   }
   1598 
   1599   return true;
   1600 }
   1601 
   1602 bool MethodVerifier::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) {
   1603   uint16_t registers_size = code_item_->registers_size_;
   1604   // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of
   1605   // integer overflow when adding them here.
   1606   if (vA + vC > registers_size) {
   1607     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC
   1608                                       << " in range invoke (> " << registers_size << ")";
   1609     return false;
   1610   }
   1611   return true;
   1612 }
   1613 
   1614 bool MethodVerifier::VerifyCodeFlow() {
   1615   uint16_t registers_size = code_item_->registers_size_;
   1616   uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1617 
   1618   /* Create and initialize table holding register status */
   1619   reg_table_.Init(kTrackCompilerInterestPoints,
   1620                   insn_flags_.get(),
   1621                   insns_size,
   1622                   registers_size,
   1623                   this);
   1624 
   1625   work_line_.reset(RegisterLine::Create(registers_size, this));
   1626   saved_line_.reset(RegisterLine::Create(registers_size, this));
   1627 
   1628   /* Initialize register types of method arguments. */
   1629   if (!SetTypesFromSignature()) {
   1630     DCHECK_NE(failures_.size(), 0U);
   1631     std::string prepend("Bad signature in ");
   1632     prepend += dex_file_->PrettyMethod(dex_method_idx_);
   1633     PrependToLastFailMessage(prepend);
   1634     return false;
   1635   }
   1636   // We may have a runtime failure here, clear.
   1637   have_pending_runtime_throw_failure_ = false;
   1638 
   1639   /* Perform code flow verification. */
   1640   if (!CodeFlowVerifyMethod()) {
   1641     DCHECK_NE(failures_.size(), 0U);
   1642     return false;
   1643   }
   1644   return true;
   1645 }
   1646 
   1647 std::ostream& MethodVerifier::DumpFailures(std::ostream& os) {
   1648   DCHECK_EQ(failures_.size(), failure_messages_.size());
   1649   for (size_t i = 0; i < failures_.size(); ++i) {
   1650       os << failure_messages_[i]->str() << "\n";
   1651   }
   1652   return os;
   1653 }
   1654 
   1655 void MethodVerifier::Dump(std::ostream& os) {
   1656   VariableIndentationOutputStream vios(&os);
   1657   Dump(&vios);
   1658 }
   1659 
   1660 void MethodVerifier::Dump(VariableIndentationOutputStream* vios) {
   1661   if (code_item_ == nullptr) {
   1662     vios->Stream() << "Native method\n";
   1663     return;
   1664   }
   1665   {
   1666     vios->Stream() << "Register Types:\n";
   1667     ScopedIndentation indent1(vios);
   1668     reg_types_.Dump(vios->Stream());
   1669   }
   1670   vios->Stream() << "Dumping instructions and register lines:\n";
   1671   ScopedIndentation indent1(vios);
   1672   const Instruction* inst = Instruction::At(code_item_->insns_);
   1673   for (size_t dex_pc = 0; dex_pc < code_item_->insns_size_in_code_units_;
   1674       dex_pc += inst->SizeInCodeUnits(), inst = inst->Next()) {
   1675     RegisterLine* reg_line = reg_table_.GetLine(dex_pc);
   1676     if (reg_line != nullptr) {
   1677       vios->Stream() << reg_line->Dump(this) << "\n";
   1678     }
   1679     vios->Stream()
   1680         << StringPrintf("0x%04zx", dex_pc) << ": " << GetInstructionFlags(dex_pc).ToString() << " ";
   1681     const bool kDumpHexOfInstruction = false;
   1682     if (kDumpHexOfInstruction) {
   1683       vios->Stream() << inst->DumpHex(5) << " ";
   1684     }
   1685     vios->Stream() << inst->DumpString(dex_file_) << "\n";
   1686   }
   1687 }
   1688 
   1689 static bool IsPrimitiveDescriptor(char descriptor) {
   1690   switch (descriptor) {
   1691     case 'I':
   1692     case 'C':
   1693     case 'S':
   1694     case 'B':
   1695     case 'Z':
   1696     case 'F':
   1697     case 'D':
   1698     case 'J':
   1699       return true;
   1700     default:
   1701       return false;
   1702   }
   1703 }
   1704 
   1705 bool MethodVerifier::SetTypesFromSignature() {
   1706   RegisterLine* reg_line = reg_table_.GetLine(0);
   1707 
   1708   // Should have been verified earlier.
   1709   DCHECK_GE(code_item_->registers_size_, code_item_->ins_size_);
   1710 
   1711   uint32_t arg_start = code_item_->registers_size_ - code_item_->ins_size_;
   1712   size_t expected_args = code_item_->ins_size_;   /* long/double count as two */
   1713 
   1714   // Include the "this" pointer.
   1715   size_t cur_arg = 0;
   1716   if (!IsStatic()) {
   1717     if (expected_args == 0) {
   1718       // Expect at least a receiver.
   1719       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected 0 args, but method is not static";
   1720       return false;
   1721     }
   1722 
   1723     // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
   1724     // argument as uninitialized. This restricts field access until the superclass constructor is
   1725     // called.
   1726     const RegType& declaring_class = GetDeclaringClass();
   1727     if (IsConstructor()) {
   1728       if (declaring_class.IsJavaLangObject()) {
   1729         // "this" is implicitly initialized.
   1730         reg_line->SetThisInitialized();
   1731         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
   1732       } else {
   1733         reg_line->SetRegisterType<LockOp::kClear>(
   1734             this,
   1735             arg_start + cur_arg,
   1736             reg_types_.UninitializedThisArgument(declaring_class));
   1737       }
   1738     } else {
   1739       reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, declaring_class);
   1740     }
   1741     cur_arg++;
   1742   }
   1743 
   1744   const DexFile::ProtoId& proto_id =
   1745       dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
   1746   DexFileParameterIterator iterator(*dex_file_, proto_id);
   1747 
   1748   for (; iterator.HasNext(); iterator.Next()) {
   1749     const char* descriptor = iterator.GetDescriptor();
   1750     if (descriptor == nullptr) {
   1751       LOG(FATAL) << "Null descriptor";
   1752     }
   1753     if (cur_arg >= expected_args) {
   1754       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1755                                         << " args, found more (" << descriptor << ")";
   1756       return false;
   1757     }
   1758     switch (descriptor[0]) {
   1759       case 'L':
   1760       case '[':
   1761         // We assume that reference arguments are initialized. The only way it could be otherwise
   1762         // (assuming the caller was verified) is if the current method is <init>, but in that case
   1763         // it's effectively considered initialized the instant we reach here (in the sense that we
   1764         // can return without doing anything or call virtual methods).
   1765         {
   1766           const RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
   1767           if (!reg_type.IsNonZeroReferenceTypes()) {
   1768             DCHECK(HasFailures());
   1769             return false;
   1770           }
   1771           reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_type);
   1772         }
   1773         break;
   1774       case 'Z':
   1775         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Boolean());
   1776         break;
   1777       case 'C':
   1778         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Char());
   1779         break;
   1780       case 'B':
   1781         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Byte());
   1782         break;
   1783       case 'I':
   1784         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Integer());
   1785         break;
   1786       case 'S':
   1787         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Short());
   1788         break;
   1789       case 'F':
   1790         reg_line->SetRegisterType<LockOp::kClear>(this, arg_start + cur_arg, reg_types_.Float());
   1791         break;
   1792       case 'J':
   1793       case 'D': {
   1794         if (cur_arg + 1 >= expected_args) {
   1795           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1796               << " args, found more (" << descriptor << ")";
   1797           return false;
   1798         }
   1799 
   1800         const RegType* lo_half;
   1801         const RegType* hi_half;
   1802         if (descriptor[0] == 'J') {
   1803           lo_half = &reg_types_.LongLo();
   1804           hi_half = &reg_types_.LongHi();
   1805         } else {
   1806           lo_half = &reg_types_.DoubleLo();
   1807           hi_half = &reg_types_.DoubleHi();
   1808         }
   1809         reg_line->SetRegisterTypeWide(this, arg_start + cur_arg, *lo_half, *hi_half);
   1810         cur_arg++;
   1811         break;
   1812       }
   1813       default:
   1814         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '"
   1815                                           << descriptor << "'";
   1816         return false;
   1817     }
   1818     cur_arg++;
   1819   }
   1820   if (cur_arg != expected_args) {
   1821     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1822                                       << " arguments, found " << cur_arg;
   1823     return false;
   1824   }
   1825   const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
   1826   // Validate return type. We don't do the type lookup; just want to make sure that it has the right
   1827   // format. Only major difference from the method argument format is that 'V' is supported.
   1828   bool result;
   1829   if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') {
   1830     result = descriptor[1] == '\0';
   1831   } else if (descriptor[0] == '[') {  // single/multi-dimensional array of object/primitive
   1832     size_t i = 0;
   1833     do {
   1834       i++;
   1835     } while (descriptor[i] == '[');  // process leading [
   1836     if (descriptor[i] == 'L') {  // object array
   1837       do {
   1838         i++;  // find closing ;
   1839       } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1840       result = descriptor[i] == ';';
   1841     } else {  // primitive array
   1842       result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0';
   1843     }
   1844   } else if (descriptor[0] == 'L') {
   1845     // could be more thorough here, but shouldn't be required
   1846     size_t i = 0;
   1847     do {
   1848       i++;
   1849     } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1850     result = descriptor[i] == ';';
   1851   } else {
   1852     result = false;
   1853   }
   1854   if (!result) {
   1855     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '"
   1856                                       << descriptor << "'";
   1857   }
   1858   return result;
   1859 }
   1860 
   1861 bool MethodVerifier::CodeFlowVerifyMethod() {
   1862   const uint16_t* insns = code_item_->insns_;
   1863   const uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1864 
   1865   /* Begin by marking the first instruction as "changed". */
   1866   GetInstructionFlags(0).SetChanged();
   1867   uint32_t start_guess = 0;
   1868 
   1869   /* Continue until no instructions are marked "changed". */
   1870   while (true) {
   1871     if (allow_thread_suspension_) {
   1872       self_->AllowThreadSuspension();
   1873     }
   1874     // Find the first marked one. Use "start_guess" as a way to find one quickly.
   1875     uint32_t insn_idx = start_guess;
   1876     for (; insn_idx < insns_size; insn_idx++) {
   1877       if (GetInstructionFlags(insn_idx).IsChanged())
   1878         break;
   1879     }
   1880     if (insn_idx == insns_size) {
   1881       if (start_guess != 0) {
   1882         /* try again, starting from the top */
   1883         start_guess = 0;
   1884         continue;
   1885       } else {
   1886         /* all flags are clear */
   1887         break;
   1888       }
   1889     }
   1890     // We carry the working set of registers from instruction to instruction. If this address can
   1891     // be the target of a branch (or throw) instruction, or if we're skipping around chasing
   1892     // "changed" flags, we need to load the set of registers from the table.
   1893     // Because we always prefer to continue on to the next instruction, we should never have a
   1894     // situation where we have a stray "changed" flag set on an instruction that isn't a branch
   1895     // target.
   1896     work_insn_idx_ = insn_idx;
   1897     if (GetInstructionFlags(insn_idx).IsBranchTarget()) {
   1898       work_line_->CopyFromLine(reg_table_.GetLine(insn_idx));
   1899     } else if (kIsDebugBuild) {
   1900       /*
   1901        * Sanity check: retrieve the stored register line (assuming
   1902        * a full table) and make sure it actually matches.
   1903        */
   1904       RegisterLine* register_line = reg_table_.GetLine(insn_idx);
   1905       if (register_line != nullptr) {
   1906         if (work_line_->CompareLine(register_line) != 0) {
   1907           Dump(std::cout);
   1908           std::cout << info_messages_.str();
   1909           LOG(FATAL) << "work_line diverged in " << dex_file_->PrettyMethod(dex_method_idx_)
   1910                      << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n"
   1911                      << " work_line=" << work_line_->Dump(this) << "\n"
   1912                      << "  expected=" << register_line->Dump(this);
   1913         }
   1914       }
   1915     }
   1916     if (!CodeFlowVerifyInstruction(&start_guess)) {
   1917       std::string prepend(dex_file_->PrettyMethod(dex_method_idx_));
   1918       prepend += " failed to verify: ";
   1919       PrependToLastFailMessage(prepend);
   1920       return false;
   1921     }
   1922     /* Clear "changed" and mark as visited. */
   1923     GetInstructionFlags(insn_idx).SetVisited();
   1924     GetInstructionFlags(insn_idx).ClearChanged();
   1925   }
   1926 
   1927   if (kDebugVerify) {
   1928     /*
   1929      * Scan for dead code. There's nothing "evil" about dead code
   1930      * (besides the wasted space), but it indicates a flaw somewhere
   1931      * down the line, possibly in the verifier.
   1932      *
   1933      * If we've substituted "always throw" instructions into the stream,
   1934      * we are almost certainly going to have some dead code.
   1935      */
   1936     int dead_start = -1;
   1937     uint32_t insn_idx = 0;
   1938     for (; insn_idx < insns_size;
   1939          insn_idx += Instruction::At(code_item_->insns_ + insn_idx)->SizeInCodeUnits()) {
   1940       /*
   1941        * Switch-statement data doesn't get "visited" by scanner. It
   1942        * may or may not be preceded by a padding NOP (for alignment).
   1943        */
   1944       if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
   1945           insns[insn_idx] == Instruction::kSparseSwitchSignature ||
   1946           insns[insn_idx] == Instruction::kArrayDataSignature ||
   1947           (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) &&
   1948            (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
   1949             insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
   1950             insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
   1951         GetInstructionFlags(insn_idx).SetVisited();
   1952       }
   1953 
   1954       if (!GetInstructionFlags(insn_idx).IsVisited()) {
   1955         if (dead_start < 0)
   1956           dead_start = insn_idx;
   1957       } else if (dead_start >= 0) {
   1958         LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
   1959                         << "-" << reinterpret_cast<void*>(insn_idx - 1);
   1960         dead_start = -1;
   1961       }
   1962     }
   1963     if (dead_start >= 0) {
   1964       LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
   1965                       << "-" << reinterpret_cast<void*>(insn_idx - 1);
   1966     }
   1967     // To dump the state of the verify after a method, do something like:
   1968     // if (dex_file_->PrettyMethod(dex_method_idx_) ==
   1969     //     "boolean java.lang.String.equals(java.lang.Object)") {
   1970     //   LOG(INFO) << info_messages_.str();
   1971     // }
   1972   }
   1973   return true;
   1974 }
   1975 
   1976 // Returns the index of the first final instance field of the given class, or kDexNoIndex if there
   1977 // is no such field.
   1978 static uint32_t GetFirstFinalInstanceFieldIndex(const DexFile& dex_file, dex::TypeIndex type_idx) {
   1979   const DexFile::ClassDef* class_def = dex_file.FindClassDef(type_idx);
   1980   DCHECK(class_def != nullptr);
   1981   const uint8_t* class_data = dex_file.GetClassData(*class_def);
   1982   DCHECK(class_data != nullptr);
   1983   ClassDataItemIterator it(dex_file, class_data);
   1984   // Skip static fields.
   1985   while (it.HasNextStaticField()) {
   1986     it.Next();
   1987   }
   1988   while (it.HasNextInstanceField()) {
   1989     if ((it.GetFieldAccessFlags() & kAccFinal) != 0) {
   1990       return it.GetMemberIndex();
   1991     }
   1992     it.Next();
   1993   }
   1994   return DexFile::kDexNoIndex;
   1995 }
   1996 
   1997 // Setup a register line for the given return instruction.
   1998 static void AdjustReturnLine(MethodVerifier* verifier,
   1999                              const Instruction* ret_inst,
   2000                              RegisterLine* line) {
   2001   Instruction::Code opcode = ret_inst->Opcode();
   2002 
   2003   switch (opcode) {
   2004     case Instruction::RETURN_VOID:
   2005     case Instruction::RETURN_VOID_NO_BARRIER:
   2006       SafelyMarkAllRegistersAsConflicts(verifier, line);
   2007       break;
   2008 
   2009     case Instruction::RETURN:
   2010     case Instruction::RETURN_OBJECT:
   2011       line->MarkAllRegistersAsConflictsExcept(verifier, ret_inst->VRegA_11x());
   2012       break;
   2013 
   2014     case Instruction::RETURN_WIDE:
   2015       line->MarkAllRegistersAsConflictsExceptWide(verifier, ret_inst->VRegA_11x());
   2016       break;
   2017 
   2018     default:
   2019       LOG(FATAL) << "Unknown return opcode " << opcode;
   2020       UNREACHABLE();
   2021   }
   2022 }
   2023 
   2024 bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
   2025   // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about.
   2026   // We want the state _before_ the instruction, for the case where the dex pc we're
   2027   // interested in is itself a monitor-enter instruction (which is a likely place
   2028   // for a thread to be suspended).
   2029   if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) {
   2030     monitor_enter_dex_pcs_->clear();  // The new work line is more accurate than the previous one.
   2031     for (size_t i = 0; i < work_line_->GetMonitorEnterCount(); ++i) {
   2032       monitor_enter_dex_pcs_->push_back(work_line_->GetMonitorEnterDexPc(i));
   2033     }
   2034   }
   2035 
   2036   /*
   2037    * Once we finish decoding the instruction, we need to figure out where
   2038    * we can go from here. There are three possible ways to transfer
   2039    * control to another statement:
   2040    *
   2041    * (1) Continue to the next instruction. Applies to all but
   2042    *     unconditional branches, method returns, and exception throws.
   2043    * (2) Branch to one or more possible locations. Applies to branches
   2044    *     and switch statements.
   2045    * (3) Exception handlers. Applies to any instruction that can
   2046    *     throw an exception that is handled by an encompassing "try"
   2047    *     block.
   2048    *
   2049    * We can also return, in which case there is no successor instruction
   2050    * from this point.
   2051    *
   2052    * The behavior can be determined from the opcode flags.
   2053    */
   2054   const uint16_t* insns = code_item_->insns_ + work_insn_idx_;
   2055   const Instruction* inst = Instruction::At(insns);
   2056   int opcode_flags = Instruction::FlagsOf(inst->Opcode());
   2057 
   2058   int32_t branch_target = 0;
   2059   bool just_set_result = false;
   2060   if (kDebugVerify) {
   2061     // Generate processing back trace to debug verifier
   2062     LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n"
   2063                     << work_line_->Dump(this) << "\n";
   2064   }
   2065 
   2066   /*
   2067    * Make a copy of the previous register state. If the instruction
   2068    * can throw an exception, we will copy/merge this into the "catch"
   2069    * address rather than work_line, because we don't want the result
   2070    * from the "successful" code path (e.g. a check-cast that "improves"
   2071    * a type) to be visible to the exception handler.
   2072    */
   2073   if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) {
   2074     saved_line_->CopyFromLine(work_line_.get());
   2075   } else if (kIsDebugBuild) {
   2076     saved_line_->FillWithGarbage();
   2077   }
   2078   DCHECK(!have_pending_runtime_throw_failure_);  // Per-instruction flag, should not be set here.
   2079 
   2080 
   2081   // We need to ensure the work line is consistent while performing validation. When we spot a
   2082   // peephole pattern we compute a new line for either the fallthrough instruction or the
   2083   // branch target.
   2084   RegisterLineArenaUniquePtr branch_line;
   2085   RegisterLineArenaUniquePtr fallthrough_line;
   2086 
   2087   switch (inst->Opcode()) {
   2088     case Instruction::NOP:
   2089       /*
   2090        * A "pure" NOP has no effect on anything. Data tables start with
   2091        * a signature that looks like a NOP; if we see one of these in
   2092        * the course of executing code then we have a problem.
   2093        */
   2094       if (inst->VRegA_10x() != 0) {
   2095         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream";
   2096       }
   2097       break;
   2098 
   2099     case Instruction::MOVE:
   2100       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr);
   2101       break;
   2102     case Instruction::MOVE_FROM16:
   2103       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr);
   2104       break;
   2105     case Instruction::MOVE_16:
   2106       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr);
   2107       break;
   2108     case Instruction::MOVE_WIDE:
   2109       work_line_->CopyRegister2(this, inst->VRegA_12x(), inst->VRegB_12x());
   2110       break;
   2111     case Instruction::MOVE_WIDE_FROM16:
   2112       work_line_->CopyRegister2(this, inst->VRegA_22x(), inst->VRegB_22x());
   2113       break;
   2114     case Instruction::MOVE_WIDE_16:
   2115       work_line_->CopyRegister2(this, inst->VRegA_32x(), inst->VRegB_32x());
   2116       break;
   2117     case Instruction::MOVE_OBJECT:
   2118       work_line_->CopyRegister1(this, inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef);
   2119       break;
   2120     case Instruction::MOVE_OBJECT_FROM16:
   2121       work_line_->CopyRegister1(this, inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef);
   2122       break;
   2123     case Instruction::MOVE_OBJECT_16:
   2124       work_line_->CopyRegister1(this, inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef);
   2125       break;
   2126 
   2127     /*
   2128      * The move-result instructions copy data out of a "pseudo-register"
   2129      * with the results from the last method invocation. In practice we
   2130      * might want to hold the result in an actual CPU register, so the
   2131      * Dalvik spec requires that these only appear immediately after an
   2132      * invoke or filled-new-array.
   2133      *
   2134      * These calls invalidate the "result" register. (This is now
   2135      * redundant with the reset done below, but it can make the debug info
   2136      * easier to read in some cases.)
   2137      */
   2138     case Instruction::MOVE_RESULT:
   2139       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), false);
   2140       break;
   2141     case Instruction::MOVE_RESULT_WIDE:
   2142       work_line_->CopyResultRegister2(this, inst->VRegA_11x());
   2143       break;
   2144     case Instruction::MOVE_RESULT_OBJECT:
   2145       work_line_->CopyResultRegister1(this, inst->VRegA_11x(), true);
   2146       break;
   2147 
   2148     case Instruction::MOVE_EXCEPTION: {
   2149       // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case
   2150       // where one entrypoint to the catch block is not actually an exception path.
   2151       if (work_insn_idx_ == 0) {
   2152         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0";
   2153         break;
   2154       }
   2155       /*
   2156        * This statement can only appear as the first instruction in an exception handler. We verify
   2157        * that as part of extracting the exception type from the catch block list.
   2158        */
   2159       const RegType& res_type = GetCaughtExceptionType();
   2160       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_11x(), res_type);
   2161       break;
   2162     }
   2163     case Instruction::RETURN_VOID:
   2164       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2165         if (!GetMethodReturnType().IsConflict()) {
   2166           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
   2167         }
   2168       }
   2169       break;
   2170     case Instruction::RETURN:
   2171       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2172         /* check the method signature */
   2173         const RegType& return_type = GetMethodReturnType();
   2174         if (!return_type.IsCategory1Types()) {
   2175           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
   2176                                             << return_type;
   2177         } else {
   2178           // Compilers may generate synthetic functions that write byte values into boolean fields.
   2179           // Also, it may use integer values for boolean, byte, short, and character return types.
   2180           const uint32_t vregA = inst->VRegA_11x();
   2181           const RegType& src_type = work_line_->GetRegisterType(this, vregA);
   2182           bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
   2183                           ((return_type.IsBoolean() || return_type.IsByte() ||
   2184                            return_type.IsShort() || return_type.IsChar()) &&
   2185                            src_type.IsInteger()));
   2186           /* check the register contents */
   2187           bool success =
   2188               work_line_->VerifyRegisterType(this, vregA, use_src ? src_type : return_type);
   2189           if (!success) {
   2190             AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA));
   2191           }
   2192         }
   2193       }
   2194       break;
   2195     case Instruction::RETURN_WIDE:
   2196       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2197         /* check the method signature */
   2198         const RegType& return_type = GetMethodReturnType();
   2199         if (!return_type.IsCategory2Types()) {
   2200           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
   2201         } else {
   2202           /* check the register contents */
   2203           const uint32_t vregA = inst->VRegA_11x();
   2204           bool success = work_line_->VerifyRegisterType(this, vregA, return_type);
   2205           if (!success) {
   2206             AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA));
   2207           }
   2208         }
   2209       }
   2210       break;
   2211     case Instruction::RETURN_OBJECT:
   2212       if (!IsInstanceConstructor() || work_line_->CheckConstructorReturn(this)) {
   2213         const RegType& return_type = GetMethodReturnType();
   2214         if (!return_type.IsReferenceTypes()) {
   2215           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
   2216         } else {
   2217           /* return_type is the *expected* return type, not register value */
   2218           DCHECK(!return_type.IsZero());
   2219           DCHECK(!return_type.IsUninitializedReference());
   2220           const uint32_t vregA = inst->VRegA_11x();
   2221           const RegType& reg_type = work_line_->GetRegisterType(this, vregA);
   2222           // Disallow returning undefined, conflict & uninitialized values and verify that the
   2223           // reference in vAA is an instance of the "return_type."
   2224           if (reg_type.IsUndefined()) {
   2225             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning undefined register";
   2226           } else if (reg_type.IsConflict()) {
   2227             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning register with conflict";
   2228           } else if (reg_type.IsUninitializedTypes()) {
   2229             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning uninitialized object '"
   2230                                               << reg_type << "'";
   2231           } else if (!reg_type.IsReferenceTypes()) {
   2232             // We really do expect a reference here.
   2233             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object returns a non-reference type "
   2234                                               << reg_type;
   2235           } else if (!return_type.IsAssignableFrom(reg_type, this)) {
   2236             if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) {
   2237               Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type
   2238                   << "' or '" << reg_type << "'";
   2239             } else {
   2240               bool soft_error = false;
   2241               // Check whether arrays are involved. They will show a valid class status, even
   2242               // if their components are erroneous.
   2243               if (reg_type.IsArrayTypes() && return_type.IsArrayTypes()) {
   2244                 return_type.CanAssignArray(reg_type, reg_types_, class_loader_, this, &soft_error);
   2245                 if (soft_error) {
   2246                   Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "array with erroneous component type: "
   2247                         << reg_type << " vs " << return_type;
   2248                 }
   2249               }
   2250 
   2251               if (!soft_error) {
   2252                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
   2253                     << "', but expected from declaration '" << return_type << "'";
   2254               }
   2255             }
   2256           }
   2257         }
   2258       }
   2259       break;
   2260 
   2261       /* could be boolean, int, float, or a null reference */
   2262     case Instruction::CONST_4: {
   2263       int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
   2264       work_line_->SetRegisterType<LockOp::kClear>(
   2265           this, inst->VRegA_11n(), DetermineCat1Constant(val, need_precise_constants_));
   2266       break;
   2267     }
   2268     case Instruction::CONST_16: {
   2269       int16_t val = static_cast<int16_t>(inst->VRegB_21s());
   2270       work_line_->SetRegisterType<LockOp::kClear>(
   2271           this, inst->VRegA_21s(), DetermineCat1Constant(val, need_precise_constants_));
   2272       break;
   2273     }
   2274     case Instruction::CONST: {
   2275       int32_t val = inst->VRegB_31i();
   2276       work_line_->SetRegisterType<LockOp::kClear>(
   2277           this, inst->VRegA_31i(), DetermineCat1Constant(val, need_precise_constants_));
   2278       break;
   2279     }
   2280     case Instruction::CONST_HIGH16: {
   2281       int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
   2282       work_line_->SetRegisterType<LockOp::kClear>(
   2283           this, inst->VRegA_21h(), DetermineCat1Constant(val, need_precise_constants_));
   2284       break;
   2285     }
   2286       /* could be long or double; resolved upon use */
   2287     case Instruction::CONST_WIDE_16: {
   2288       int64_t val = static_cast<int16_t>(inst->VRegB_21s());
   2289       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2290       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2291       work_line_->SetRegisterTypeWide(this, inst->VRegA_21s(), lo, hi);
   2292       break;
   2293     }
   2294     case Instruction::CONST_WIDE_32: {
   2295       int64_t val = static_cast<int32_t>(inst->VRegB_31i());
   2296       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2297       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2298       work_line_->SetRegisterTypeWide(this, inst->VRegA_31i(), lo, hi);
   2299       break;
   2300     }
   2301     case Instruction::CONST_WIDE: {
   2302       int64_t val = inst->VRegB_51l();
   2303       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2304       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2305       work_line_->SetRegisterTypeWide(this, inst->VRegA_51l(), lo, hi);
   2306       break;
   2307     }
   2308     case Instruction::CONST_WIDE_HIGH16: {
   2309       int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
   2310       const RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   2311       const RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   2312       work_line_->SetRegisterTypeWide(this, inst->VRegA_21h(), lo, hi);
   2313       break;
   2314     }
   2315     case Instruction::CONST_STRING:
   2316       work_line_->SetRegisterType<LockOp::kClear>(
   2317           this, inst->VRegA_21c(), reg_types_.JavaLangString());
   2318       break;
   2319     case Instruction::CONST_STRING_JUMBO:
   2320       work_line_->SetRegisterType<LockOp::kClear>(
   2321           this, inst->VRegA_31c(), reg_types_.JavaLangString());
   2322       break;
   2323     case Instruction::CONST_CLASS: {
   2324       // Get type from instruction if unresolved then we need an access check
   2325       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2326       const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c()));
   2327       // Register holds class, ie its type is class, on error it will hold Conflict.
   2328       work_line_->SetRegisterType<LockOp::kClear>(
   2329           this, inst->VRegA_21c(), res_type.IsConflict() ? res_type
   2330                                                          : reg_types_.JavaLangClass());
   2331       break;
   2332     }
   2333     case Instruction::MONITOR_ENTER:
   2334       work_line_->PushMonitor(this, inst->VRegA_11x(), work_insn_idx_);
   2335       // Check whether the previous instruction is a move-object with vAA as a source, creating
   2336       // untracked lock aliasing.
   2337       if (0 != work_insn_idx_ && !GetInstructionFlags(work_insn_idx_).IsBranchTarget()) {
   2338         uint32_t prev_idx = work_insn_idx_ - 1;
   2339         while (0 != prev_idx && !GetInstructionFlags(prev_idx).IsOpcode()) {
   2340           prev_idx--;
   2341         }
   2342         const Instruction* prev_inst = Instruction::At(code_item_->insns_ + prev_idx);
   2343         switch (prev_inst->Opcode()) {
   2344           case Instruction::MOVE_OBJECT:
   2345           case Instruction::MOVE_OBJECT_16:
   2346           case Instruction::MOVE_OBJECT_FROM16:
   2347             if (prev_inst->VRegB() == inst->VRegA_11x()) {
   2348               // Redo the copy. This won't change the register types, but update the lock status
   2349               // for the aliased register.
   2350               work_line_->CopyRegister1(this,
   2351                                         prev_inst->VRegA(),
   2352                                         prev_inst->VRegB(),
   2353                                         kTypeCategoryRef);
   2354             }
   2355             break;
   2356 
   2357           default:  // Other instruction types ignored.
   2358             break;
   2359         }
   2360       }
   2361       break;
   2362     case Instruction::MONITOR_EXIT:
   2363       /*
   2364        * monitor-exit instructions are odd. They can throw exceptions,
   2365        * but when they do they act as if they succeeded and the PC is
   2366        * pointing to the following instruction. (This behavior goes back
   2367        * to the need to handle asynchronous exceptions, a now-deprecated
   2368        * feature that Dalvik doesn't support.)
   2369        *
   2370        * In practice we don't need to worry about this. The only
   2371        * exceptions that can be thrown from monitor-exit are for a
   2372        * null reference and -exit without a matching -enter. If the
   2373        * structured locking checks are working, the former would have
   2374        * failed on the -enter instruction, and the latter is impossible.
   2375        *
   2376        * This is fortunate, because issue 3221411 prevents us from
   2377        * chasing the "can throw" path when monitor verification is
   2378        * enabled. If we can fully verify the locking we can ignore
   2379        * some catch blocks (which will show up as "dead" code when
   2380        * we skip them here); if we can't, then the code path could be
   2381        * "live" so we still need to check it.
   2382        */
   2383       opcode_flags &= ~Instruction::kThrow;
   2384       work_line_->PopMonitor(this, inst->VRegA_11x());
   2385       break;
   2386     case Instruction::CHECK_CAST:
   2387     case Instruction::INSTANCE_OF: {
   2388       /*
   2389        * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This
   2390        * could be a "upcast" -- not expected, so we don't try to address it.)
   2391        *
   2392        * If it fails, an exception is thrown, which we deal with later by ignoring the update to
   2393        * dec_insn.vA when branching to a handler.
   2394        */
   2395       const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
   2396       const dex::TypeIndex type_idx((is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c());
   2397       const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
   2398       if (res_type.IsConflict()) {
   2399         // If this is a primitive type, fail HARD.
   2400         ObjPtr<mirror::Class> klass =
   2401             ClassLinker::LookupResolvedType(type_idx, dex_cache_.Get(), class_loader_.Get());
   2402         if (klass != nullptr && klass->IsPrimitive()) {
   2403           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type "
   2404               << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in "
   2405               << GetDeclaringClass();
   2406           break;
   2407         }
   2408 
   2409         DCHECK_NE(failures_.size(), 0U);
   2410         if (!is_checkcast) {
   2411           work_line_->SetRegisterType<LockOp::kClear>(this,
   2412                                                       inst->VRegA_22c(),
   2413                                                       reg_types_.Boolean());
   2414         }
   2415         break;  // bad class
   2416       }
   2417       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2418       uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
   2419       const RegType& orig_type = work_line_->GetRegisterType(this, orig_type_reg);
   2420       if (!res_type.IsNonZeroReferenceTypes()) {
   2421         if (is_checkcast) {
   2422           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
   2423         } else {
   2424           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type;
   2425         }
   2426       } else if (!orig_type.IsReferenceTypes()) {
   2427         if (is_checkcast) {
   2428           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg;
   2429         } else {
   2430           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg;
   2431         }
   2432       } else if (orig_type.IsUninitializedTypes()) {
   2433         if (is_checkcast) {
   2434           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on uninitialized reference in v"
   2435                                             << orig_type_reg;
   2436         } else {
   2437           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on uninitialized reference in v"
   2438                                             << orig_type_reg;
   2439         }
   2440       } else {
   2441         if (is_checkcast) {
   2442           work_line_->SetRegisterType<LockOp::kKeep>(this, inst->VRegA_21c(), res_type);
   2443         } else {
   2444           work_line_->SetRegisterType<LockOp::kClear>(this,
   2445                                                       inst->VRegA_22c(),
   2446                                                       reg_types_.Boolean());
   2447         }
   2448       }
   2449       break;
   2450     }
   2451     case Instruction::ARRAY_LENGTH: {
   2452       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegB_12x());
   2453       if (res_type.IsReferenceTypes()) {
   2454         if (!res_type.IsArrayTypes() && !res_type.IsZero()) {  // ie not an array or null
   2455           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   2456         } else {
   2457           work_line_->SetRegisterType<LockOp::kClear>(this,
   2458                                                       inst->VRegA_12x(),
   2459                                                       reg_types_.Integer());
   2460         }
   2461       } else {
   2462         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   2463       }
   2464       break;
   2465     }
   2466     case Instruction::NEW_INSTANCE: {
   2467       const RegType& res_type = ResolveClassAndCheckAccess(dex::TypeIndex(inst->VRegB_21c()));
   2468       if (res_type.IsConflict()) {
   2469         DCHECK_NE(failures_.size(), 0U);
   2470         break;  // bad class
   2471       }
   2472       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   2473       // can't create an instance of an interface or abstract class */
   2474       if (!res_type.IsInstantiableTypes()) {
   2475         Fail(VERIFY_ERROR_INSTANTIATION)
   2476             << "new-instance on primitive, interface or abstract class" << res_type;
   2477         // Soft failure so carry on to set register type.
   2478       }
   2479       const RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
   2480       // Any registers holding previous allocations from this address that have not yet been
   2481       // initialized must be marked invalid.
   2482       work_line_->MarkUninitRefsAsInvalid(this, uninit_type);
   2483       // add the new uninitialized reference to the register state
   2484       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_21c(), uninit_type);
   2485       break;
   2486     }
   2487     case Instruction::NEW_ARRAY:
   2488       VerifyNewArray(inst, false, false);
   2489       break;
   2490     case Instruction::FILLED_NEW_ARRAY:
   2491       VerifyNewArray(inst, true, false);
   2492       just_set_result = true;  // Filled new array sets result register
   2493       break;
   2494     case Instruction::FILLED_NEW_ARRAY_RANGE:
   2495       VerifyNewArray(inst, true, true);
   2496       just_set_result = true;  // Filled new array range sets result register
   2497       break;
   2498     case Instruction::CMPL_FLOAT:
   2499     case Instruction::CMPG_FLOAT:
   2500       if (!work_line_->VerifyRegisterType(this, inst->VRegB_23x(), reg_types_.Float())) {
   2501         break;
   2502       }
   2503       if (!work_line_->VerifyRegisterType(this, inst->VRegC_23x(), reg_types_.Float())) {
   2504         break;
   2505       }
   2506       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2507       break;
   2508     case Instruction::CMPL_DOUBLE:
   2509     case Instruction::CMPG_DOUBLE:
   2510       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.DoubleLo(),
   2511                                               reg_types_.DoubleHi())) {
   2512         break;
   2513       }
   2514       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.DoubleLo(),
   2515                                               reg_types_.DoubleHi())) {
   2516         break;
   2517       }
   2518       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2519       break;
   2520     case Instruction::CMP_LONG:
   2521       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegB_23x(), reg_types_.LongLo(),
   2522                                               reg_types_.LongHi())) {
   2523         break;
   2524       }
   2525       if (!work_line_->VerifyRegisterTypeWide(this, inst->VRegC_23x(), reg_types_.LongLo(),
   2526                                               reg_types_.LongHi())) {
   2527         break;
   2528       }
   2529       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Integer());
   2530       break;
   2531     case Instruction::THROW: {
   2532       const RegType& res_type = work_line_->GetRegisterType(this, inst->VRegA_11x());
   2533       if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type, this)) {
   2534         if (res_type.IsUninitializedTypes()) {
   2535           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown exception not initialized";
   2536         } else if (!res_type.IsReferenceTypes()) {
   2537           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "thrown value of non-reference type " << res_type;
   2538         } else {
   2539           Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT)
   2540                 << "thrown class " << res_type << " not instanceof Throwable";
   2541         }
   2542       }
   2543       break;
   2544     }
   2545     case Instruction::GOTO:
   2546     case Instruction::GOTO_16:
   2547     case Instruction::GOTO_32:
   2548       /* no effect on or use of registers */
   2549       break;
   2550 
   2551     case Instruction::PACKED_SWITCH:
   2552     case Instruction::SPARSE_SWITCH:
   2553       /* verify that vAA is an integer, or can be converted to one */
   2554       work_line_->VerifyRegisterType(this, inst->VRegA_31t(), reg_types_.Integer());
   2555       break;
   2556 
   2557     case Instruction::FILL_ARRAY_DATA: {
   2558       /* Similar to the verification done for APUT */
   2559       const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegA_31t());
   2560       /* array_type can be null if the reg type is Zero */
   2561       if (!array_type.IsZero()) {
   2562         if (!array_type.IsArrayTypes()) {
   2563           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
   2564                                             << array_type;
   2565         } else if (array_type.IsUnresolvedTypes()) {
   2566           // If it's an unresolved array type, it must be non-primitive.
   2567           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data for array of type "
   2568                                             << array_type;
   2569         } else {
   2570           const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   2571           DCHECK(!component_type.IsConflict());
   2572           if (component_type.IsNonZeroReferenceTypes()) {
   2573             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
   2574                                               << component_type;
   2575           } else {
   2576             // Now verify if the element width in the table matches the element width declared in
   2577             // the array
   2578             const uint16_t* array_data =
   2579                 insns + (insns[1] | (static_cast<int32_t>(insns[2]) << 16));
   2580             if (array_data[0] != Instruction::kArrayDataSignature) {
   2581               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data";
   2582             } else {
   2583               size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
   2584               // Since we don't compress the data in Dex, expect to see equal width of data stored
   2585               // in the table and expected from the array class.
   2586               if (array_data[1] != elem_width) {
   2587                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1]
   2588                                                   << " vs " << elem_width << ")";
   2589               }
   2590             }
   2591           }
   2592         }
   2593       }
   2594       break;
   2595     }
   2596     case Instruction::IF_EQ:
   2597     case Instruction::IF_NE: {
   2598       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
   2599       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
   2600       bool mismatch = false;
   2601       if (reg_type1.IsZero()) {  // zero then integral or reference expected
   2602         mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
   2603       } else if (reg_type1.IsReferenceTypes()) {  // both references?
   2604         mismatch = !reg_type2.IsReferenceTypes();
   2605       } else {  // both integral?
   2606         mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes();
   2607       }
   2608       if (mismatch) {
   2609         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << ","
   2610                                           << reg_type2 << ") must both be references or integral";
   2611       }
   2612       break;
   2613     }
   2614     case Instruction::IF_LT:
   2615     case Instruction::IF_GE:
   2616     case Instruction::IF_GT:
   2617     case Instruction::IF_LE: {
   2618       const RegType& reg_type1 = work_line_->GetRegisterType(this, inst->VRegA_22t());
   2619       const RegType& reg_type2 = work_line_->GetRegisterType(this, inst->VRegB_22t());
   2620       if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
   2621         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
   2622                                           << reg_type2 << ") must be integral";
   2623       }
   2624       break;
   2625     }
   2626     case Instruction::IF_EQZ:
   2627     case Instruction::IF_NEZ: {
   2628       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
   2629       if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
   2630         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   2631                                           << " unexpected as arg to if-eqz/if-nez";
   2632       }
   2633 
   2634       // Find previous instruction - its existence is a precondition to peephole optimization.
   2635       uint32_t instance_of_idx = 0;
   2636       if (0 != work_insn_idx_) {
   2637         instance_of_idx = work_insn_idx_ - 1;
   2638         while (0 != instance_of_idx && !GetInstructionFlags(instance_of_idx).IsOpcode()) {
   2639           instance_of_idx--;
   2640         }
   2641         if (FailOrAbort(this, GetInstructionFlags(instance_of_idx).IsOpcode(),
   2642                         "Unable to get previous instruction of if-eqz/if-nez for work index ",
   2643                         work_insn_idx_)) {
   2644           break;
   2645         }
   2646       } else {
   2647         break;
   2648       }
   2649 
   2650       const Instruction* instance_of_inst = Instruction::At(code_item_->insns_ + instance_of_idx);
   2651 
   2652       /* Check for peep-hole pattern of:
   2653        *    ...;
   2654        *    instance-of vX, vY, T;
   2655        *    ifXXX vX, label ;
   2656        *    ...;
   2657        * label:
   2658        *    ...;
   2659        * and sharpen the type of vY to be type T.
   2660        * Note, this pattern can't be if:
   2661        *  - if there are other branches to this branch,
   2662        *  - when vX == vY.
   2663        */
   2664       if (!CurrentInsnFlags()->IsBranchTarget() &&
   2665           (Instruction::INSTANCE_OF == instance_of_inst->Opcode()) &&
   2666           (inst->VRegA_21t() == instance_of_inst->VRegA_22c()) &&
   2667           (instance_of_inst->VRegA_22c() != instance_of_inst->VRegB_22c())) {
   2668         // Check the type of the instance-of is different than that of registers type, as if they
   2669         // are the same there is no work to be done here. Check that the conversion is not to or
   2670         // from an unresolved type as type information is imprecise. If the instance-of is to an
   2671         // interface then ignore the type information as interfaces can only be treated as Objects
   2672         // and we don't want to disallow field and other operations on the object. If the value
   2673         // being instance-of checked against is known null (zero) then allow the optimization as
   2674         // we didn't have type information. If the merge of the instance-of type with the original
   2675         // type is assignable to the original then allow optimization. This check is performed to
   2676         // ensure that subsequent merges don't lose type information - such as becoming an
   2677         // interface from a class that would lose information relevant to field checks.
   2678         const RegType& orig_type = work_line_->GetRegisterType(this, instance_of_inst->VRegB_22c());
   2679         const RegType& cast_type = ResolveClassAndCheckAccess(
   2680             dex::TypeIndex(instance_of_inst->VRegC_22c()));
   2681 
   2682         if (!orig_type.Equals(cast_type) &&
   2683             !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
   2684             cast_type.HasClass() &&             // Could be conflict type, make sure it has a class.
   2685             !cast_type.GetClass()->IsInterface() &&
   2686             (orig_type.IsZero() ||
   2687                 orig_type.IsStrictlyAssignableFrom(
   2688                     cast_type.Merge(orig_type, &reg_types_, this), this))) {
   2689           RegisterLine* update_line = RegisterLine::Create(code_item_->registers_size_, this);
   2690           if (inst->Opcode() == Instruction::IF_EQZ) {
   2691             fallthrough_line.reset(update_line);
   2692           } else {
   2693             branch_line.reset(update_line);
   2694           }
   2695           update_line->CopyFromLine(work_line_.get());
   2696           update_line->SetRegisterType<LockOp::kKeep>(this,
   2697                                                       instance_of_inst->VRegB_22c(),
   2698                                                       cast_type);
   2699           if (!GetInstructionFlags(instance_of_idx).IsBranchTarget() && 0 != instance_of_idx) {
   2700             // See if instance-of was preceded by a move-object operation, common due to the small
   2701             // register encoding space of instance-of, and propagate type information to the source
   2702             // of the move-object.
   2703             uint32_t move_idx = instance_of_idx - 1;
   2704             while (0 != move_idx && !GetInstructionFlags(move_idx).IsOpcode()) {
   2705               move_idx--;
   2706             }
   2707             if (FailOrAbort(this, GetInstructionFlags(move_idx).IsOpcode(),
   2708                             "Unable to get previous instruction of if-eqz/if-nez for work index ",
   2709                             work_insn_idx_)) {
   2710               break;
   2711             }
   2712             const Instruction* move_inst = Instruction::At(code_item_->insns_ + move_idx);
   2713             switch (move_inst->Opcode()) {
   2714               case Instruction::MOVE_OBJECT:
   2715                 if (move_inst->VRegA_12x() == instance_of_inst->VRegB_22c()) {
   2716                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2717                                                               move_inst->VRegB_12x(),
   2718                                                               cast_type);
   2719                 }
   2720                 break;
   2721               case Instruction::MOVE_OBJECT_FROM16:
   2722                 if (move_inst->VRegA_22x() == instance_of_inst->VRegB_22c()) {
   2723                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2724                                                               move_inst->VRegB_22x(),
   2725                                                               cast_type);
   2726                 }
   2727                 break;
   2728               case Instruction::MOVE_OBJECT_16:
   2729                 if (move_inst->VRegA_32x() == instance_of_inst->VRegB_22c()) {
   2730                   update_line->SetRegisterType<LockOp::kKeep>(this,
   2731                                                               move_inst->VRegB_32x(),
   2732                                                               cast_type);
   2733                 }
   2734                 break;
   2735               default:
   2736                 break;
   2737             }
   2738           }
   2739         }
   2740       }
   2741 
   2742       break;
   2743     }
   2744     case Instruction::IF_LTZ:
   2745     case Instruction::IF_GEZ:
   2746     case Instruction::IF_GTZ:
   2747     case Instruction::IF_LEZ: {
   2748       const RegType& reg_type = work_line_->GetRegisterType(this, inst->VRegA_21t());
   2749       if (!reg_type.IsIntegralTypes()) {
   2750         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   2751                                           << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
   2752       }
   2753       break;
   2754     }
   2755     case Instruction::AGET_BOOLEAN:
   2756       VerifyAGet(inst, reg_types_.Boolean(), true);
   2757       break;
   2758     case Instruction::AGET_BYTE:
   2759       VerifyAGet(inst, reg_types_.Byte(), true);
   2760       break;
   2761     case Instruction::AGET_CHAR:
   2762       VerifyAGet(inst, reg_types_.Char(), true);
   2763       break;
   2764     case Instruction::AGET_SHORT:
   2765       VerifyAGet(inst, reg_types_.Short(), true);
   2766       break;
   2767     case Instruction::AGET:
   2768       VerifyAGet(inst, reg_types_.Integer(), true);
   2769       break;
   2770     case Instruction::AGET_WIDE:
   2771       VerifyAGet(inst, reg_types_.LongLo(), true);
   2772       break;
   2773     case Instruction::AGET_OBJECT:
   2774       VerifyAGet(inst, reg_types_.JavaLangObject(false), false);
   2775       break;
   2776 
   2777     case Instruction::APUT_BOOLEAN:
   2778       VerifyAPut(inst, reg_types_.Boolean(), true);
   2779       break;
   2780     case Instruction::APUT_BYTE:
   2781       VerifyAPut(inst, reg_types_.Byte(), true);
   2782       break;
   2783     case Instruction::APUT_CHAR:
   2784       VerifyAPut(inst, reg_types_.Char(), true);
   2785       break;
   2786     case Instruction::APUT_SHORT:
   2787       VerifyAPut(inst, reg_types_.Short(), true);
   2788       break;
   2789     case Instruction::APUT:
   2790       VerifyAPut(inst, reg_types_.Integer(), true);
   2791       break;
   2792     case Instruction::APUT_WIDE:
   2793       VerifyAPut(inst, reg_types_.LongLo(), true);
   2794       break;
   2795     case Instruction::APUT_OBJECT:
   2796       VerifyAPut(inst, reg_types_.JavaLangObject(false), false);
   2797       break;
   2798 
   2799     case Instruction::IGET_BOOLEAN:
   2800       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, false);
   2801       break;
   2802     case Instruction::IGET_BYTE:
   2803       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, false);
   2804       break;
   2805     case Instruction::IGET_CHAR:
   2806       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, false);
   2807       break;
   2808     case Instruction::IGET_SHORT:
   2809       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, false);
   2810       break;
   2811     case Instruction::IGET:
   2812       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, false);
   2813       break;
   2814     case Instruction::IGET_WIDE:
   2815       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, false);
   2816       break;
   2817     case Instruction::IGET_OBJECT:
   2818       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2819                                                     false);
   2820       break;
   2821 
   2822     case Instruction::IPUT_BOOLEAN:
   2823       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, false);
   2824       break;
   2825     case Instruction::IPUT_BYTE:
   2826       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, false);
   2827       break;
   2828     case Instruction::IPUT_CHAR:
   2829       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, false);
   2830       break;
   2831     case Instruction::IPUT_SHORT:
   2832       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, false);
   2833       break;
   2834     case Instruction::IPUT:
   2835       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, false);
   2836       break;
   2837     case Instruction::IPUT_WIDE:
   2838       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, false);
   2839       break;
   2840     case Instruction::IPUT_OBJECT:
   2841       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2842                                                     false);
   2843       break;
   2844 
   2845     case Instruction::SGET_BOOLEAN:
   2846       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, true);
   2847       break;
   2848     case Instruction::SGET_BYTE:
   2849       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, true);
   2850       break;
   2851     case Instruction::SGET_CHAR:
   2852       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, true);
   2853       break;
   2854     case Instruction::SGET_SHORT:
   2855       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, true);
   2856       break;
   2857     case Instruction::SGET:
   2858       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, true);
   2859       break;
   2860     case Instruction::SGET_WIDE:
   2861       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, true);
   2862       break;
   2863     case Instruction::SGET_OBJECT:
   2864       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2865                                                     true);
   2866       break;
   2867 
   2868     case Instruction::SPUT_BOOLEAN:
   2869       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, true);
   2870       break;
   2871     case Instruction::SPUT_BYTE:
   2872       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, true);
   2873       break;
   2874     case Instruction::SPUT_CHAR:
   2875       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, true);
   2876       break;
   2877     case Instruction::SPUT_SHORT:
   2878       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, true);
   2879       break;
   2880     case Instruction::SPUT:
   2881       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, true);
   2882       break;
   2883     case Instruction::SPUT_WIDE:
   2884       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, true);
   2885       break;
   2886     case Instruction::SPUT_OBJECT:
   2887       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2888                                                     true);
   2889       break;
   2890 
   2891     case Instruction::INVOKE_VIRTUAL:
   2892     case Instruction::INVOKE_VIRTUAL_RANGE:
   2893     case Instruction::INVOKE_SUPER:
   2894     case Instruction::INVOKE_SUPER_RANGE: {
   2895       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
   2896                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
   2897       bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
   2898                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
   2899       MethodType type = is_super ? METHOD_SUPER : METHOD_VIRTUAL;
   2900       ArtMethod* called_method = VerifyInvocationArgs(inst, type, is_range);
   2901       const RegType* return_type = nullptr;
   2902       if (called_method != nullptr) {
   2903         mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
   2904         if (return_type_class != nullptr) {
   2905           return_type = &FromClass(called_method->GetReturnTypeDescriptor(),
   2906                                    return_type_class,
   2907                                    return_type_class->CannotBeAssignedFromOtherTypes());
   2908         } else {
   2909           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   2910           self_->ClearException();
   2911         }
   2912       }
   2913       if (return_type == nullptr) {
   2914         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2915         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2916         dex::TypeIndex return_type_idx =
   2917             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2918         const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   2919         return_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   2920       }
   2921       if (!return_type->IsLowHalf()) {
   2922         work_line_->SetResultRegisterType(this, *return_type);
   2923       } else {
   2924         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   2925       }
   2926       just_set_result = true;
   2927       break;
   2928     }
   2929     case Instruction::INVOKE_DIRECT:
   2930     case Instruction::INVOKE_DIRECT_RANGE: {
   2931       bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
   2932       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT, is_range);
   2933       const char* return_type_descriptor;
   2934       bool is_constructor;
   2935       const RegType* return_type = nullptr;
   2936       if (called_method == nullptr) {
   2937         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2938         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2939         is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0;
   2940         dex::TypeIndex return_type_idx =
   2941             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2942         return_type_descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
   2943       } else {
   2944         is_constructor = called_method->IsConstructor();
   2945         return_type_descriptor = called_method->GetReturnTypeDescriptor();
   2946         mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
   2947         if (return_type_class != nullptr) {
   2948           return_type = &FromClass(return_type_descriptor,
   2949                                    return_type_class,
   2950                                    return_type_class->CannotBeAssignedFromOtherTypes());
   2951         } else {
   2952           DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   2953           self_->ClearException();
   2954         }
   2955       }
   2956       if (is_constructor) {
   2957         /*
   2958          * Some additional checks when calling a constructor. We know from the invocation arg check
   2959          * that the "this" argument is an instance of called_method->klass. Now we further restrict
   2960          * that to require that called_method->klass is the same as this->klass or this->super,
   2961          * allowing the latter only if the "this" argument is the same as the "this" argument to
   2962          * this method (which implies that we're in a constructor ourselves).
   2963          */
   2964         const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   2965         if (this_type.IsConflict())  // failure.
   2966           break;
   2967 
   2968         /* no null refs allowed (?) */
   2969         if (this_type.IsZero()) {
   2970           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref";
   2971           break;
   2972         }
   2973 
   2974         /* must be in same class or in superclass */
   2975         // const RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
   2976         // TODO: re-enable constructor type verification
   2977         // if (this_super_klass.IsConflict()) {
   2978           // Unknown super class, fail so we re-check at runtime.
   2979           // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
   2980           // break;
   2981         // }
   2982 
   2983         /* arg must be an uninitialized reference */
   2984         if (!this_type.IsUninitializedTypes()) {
   2985           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference "
   2986               << this_type;
   2987           break;
   2988         }
   2989 
   2990         /*
   2991          * Replace the uninitialized reference with an initialized one. We need to do this for all
   2992          * registers that have the same object instance in them, not just the "this" register.
   2993          */
   2994         work_line_->MarkRefsAsInitialized(this, this_type);
   2995       }
   2996       if (return_type == nullptr) {
   2997         return_type = &reg_types_.FromDescriptor(GetClassLoader(), return_type_descriptor, false);
   2998       }
   2999       if (!return_type->IsLowHalf()) {
   3000         work_line_->SetResultRegisterType(this, *return_type);
   3001       } else {
   3002         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   3003       }
   3004       just_set_result = true;
   3005       break;
   3006     }
   3007     case Instruction::INVOKE_STATIC:
   3008     case Instruction::INVOKE_STATIC_RANGE: {
   3009         bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
   3010         ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_STATIC, is_range);
   3011         const char* descriptor;
   3012         if (called_method == nullptr) {
   3013           uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3014           const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   3015           dex::TypeIndex return_type_idx =
   3016               dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   3017           descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   3018         } else {
   3019           descriptor = called_method->GetReturnTypeDescriptor();
   3020         }
   3021         const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3022         if (!return_type.IsLowHalf()) {
   3023           work_line_->SetResultRegisterType(this, return_type);
   3024         } else {
   3025           work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3026         }
   3027         just_set_result = true;
   3028       }
   3029       break;
   3030     case Instruction::INVOKE_INTERFACE:
   3031     case Instruction::INVOKE_INTERFACE_RANGE: {
   3032       bool is_range =  (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
   3033       ArtMethod* abs_method = VerifyInvocationArgs(inst, METHOD_INTERFACE, is_range);
   3034       if (abs_method != nullptr) {
   3035         mirror::Class* called_interface = abs_method->GetDeclaringClass();
   3036         if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
   3037           Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
   3038               << abs_method->PrettyMethod() << "'";
   3039           break;
   3040         }
   3041       }
   3042       /* Get the type of the "this" arg, which should either be a sub-interface of called
   3043        * interface or Object (see comments in RegType::JoinClass).
   3044        */
   3045       const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   3046       if (this_type.IsZero()) {
   3047         /* null pointer always passes (and always fails at runtime) */
   3048       } else {
   3049         if (this_type.IsUninitializedTypes()) {
   3050           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object "
   3051               << this_type;
   3052           break;
   3053         }
   3054         // In the past we have tried to assert that "called_interface" is assignable
   3055         // from "this_type.GetClass()", however, as we do an imprecise Join
   3056         // (RegType::JoinClass) we don't have full information on what interfaces are
   3057         // implemented by "this_type". For example, two classes may implement the same
   3058         // interfaces and have a common parent that doesn't implement the interface. The
   3059         // join will set "this_type" to the parent class and a test that this implements
   3060         // the interface will incorrectly fail.
   3061       }
   3062       /*
   3063        * We don't have an object instance, so we can't find the concrete method. However, all of
   3064        * the type information is in the abstract method, so we're good.
   3065        */
   3066       const char* descriptor;
   3067       if (abs_method == nullptr) {
   3068         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3069         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   3070         dex::TypeIndex return_type_idx =
   3071             dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   3072         descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   3073       } else {
   3074         descriptor = abs_method->GetReturnTypeDescriptor();
   3075       }
   3076       const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3077       if (!return_type.IsLowHalf()) {
   3078         work_line_->SetResultRegisterType(this, return_type);
   3079       } else {
   3080         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3081       }
   3082       just_set_result = true;
   3083       break;
   3084     }
   3085     case Instruction::INVOKE_POLYMORPHIC:
   3086     case Instruction::INVOKE_POLYMORPHIC_RANGE: {
   3087       bool is_range = (inst->Opcode() == Instruction::INVOKE_POLYMORPHIC_RANGE);
   3088       ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_POLYMORPHIC, is_range);
   3089       if (called_method == nullptr) {
   3090         // Convert potential soft failures in VerifyInvocationArgs() to hard errors.
   3091         if (failure_messages_.size() > 0) {
   3092           std::string message = failure_messages_.back()->str();
   3093           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << message;
   3094         } else {
   3095           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-polymorphic verification failure.";
   3096         }
   3097         break;
   3098       }
   3099       if (!CheckSignaturePolymorphicMethod(called_method) ||
   3100           !CheckSignaturePolymorphicReceiver(inst)) {
   3101         break;
   3102       }
   3103       const uint32_t proto_idx = (is_range) ? inst->VRegH_4rcc() : inst->VRegH_45cc();
   3104       const char* return_descriptor =
   3105           dex_file_->GetReturnTypeDescriptor(dex_file_->GetProtoId(proto_idx));
   3106       const RegType& return_type =
   3107           reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false);
   3108       if (!return_type.IsLowHalf()) {
   3109         work_line_->SetResultRegisterType(this, return_type);
   3110       } else {
   3111         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3112       }
   3113       just_set_result = true;
   3114       break;
   3115     }
   3116     case Instruction::INVOKE_CUSTOM:
   3117     case Instruction::INVOKE_CUSTOM_RANGE: {
   3118       // Verify registers based on method_type in the call site.
   3119       bool is_range = (inst->Opcode() == Instruction::INVOKE_CUSTOM_RANGE);
   3120 
   3121       // Step 1. Check the call site that produces the method handle for invocation
   3122       const uint32_t call_site_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
   3123       if (!CheckCallSite(call_site_idx)) {
   3124         DCHECK(HasFailures());
   3125         break;
   3126       }
   3127 
   3128       // Step 2. Check the register arguments correspond to the expected arguments for the
   3129       // method handle produced by step 1. The dex file verifier has checked ranges for
   3130       // the first three arguments and CheckCallSite has checked the method handle type.
   3131       CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx));
   3132       it.Next();  // Skip to name.
   3133       it.Next();  // Skip to method type of the method handle
   3134       const uint32_t proto_idx = static_cast<uint32_t>(it.GetJavaValue().i);
   3135       const DexFile::ProtoId& proto_id = dex_file_->GetProtoId(proto_idx);
   3136       DexFileParameterIterator param_it(*dex_file_, proto_id);
   3137       // Treat method as static as it has yet to be determined.
   3138       VerifyInvocationArgsFromIterator(&param_it, inst, METHOD_STATIC, is_range, nullptr);
   3139       const char* return_descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
   3140 
   3141       // Step 3. Propagate return type information
   3142       const RegType& return_type =
   3143           reg_types_.FromDescriptor(GetClassLoader(), return_descriptor, false);
   3144       if (!return_type.IsLowHalf()) {
   3145         work_line_->SetResultRegisterType(this, return_type);
   3146       } else {
   3147         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3148       }
   3149       just_set_result = true;
   3150       // TODO: Add compiler support for invoke-custom (b/35337872).
   3151       Fail(VERIFY_ERROR_FORCE_INTERPRETER);
   3152       break;
   3153     }
   3154     case Instruction::NEG_INT:
   3155     case Instruction::NOT_INT:
   3156       work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer());
   3157       break;
   3158     case Instruction::NEG_LONG:
   3159     case Instruction::NOT_LONG:
   3160       work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3161                                    reg_types_.LongLo(), reg_types_.LongHi());
   3162       break;
   3163     case Instruction::NEG_FLOAT:
   3164       work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Float());
   3165       break;
   3166     case Instruction::NEG_DOUBLE:
   3167       work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3168                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3169       break;
   3170     case Instruction::INT_TO_LONG:
   3171       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3172                                      reg_types_.Integer());
   3173       break;
   3174     case Instruction::INT_TO_FLOAT:
   3175       work_line_->CheckUnaryOp(this, inst, reg_types_.Float(), reg_types_.Integer());
   3176       break;
   3177     case Instruction::INT_TO_DOUBLE:
   3178       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3179                                      reg_types_.Integer());
   3180       break;
   3181     case Instruction::LONG_TO_INT:
   3182       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
   3183                                        reg_types_.LongLo(), reg_types_.LongHi());
   3184       break;
   3185     case Instruction::LONG_TO_FLOAT:
   3186       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
   3187                                        reg_types_.LongLo(), reg_types_.LongHi());
   3188       break;
   3189     case Instruction::LONG_TO_DOUBLE:
   3190       work_line_->CheckUnaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3191                                    reg_types_.LongLo(), reg_types_.LongHi());
   3192       break;
   3193     case Instruction::FLOAT_TO_INT:
   3194       work_line_->CheckUnaryOp(this, inst, reg_types_.Integer(), reg_types_.Float());
   3195       break;
   3196     case Instruction::FLOAT_TO_LONG:
   3197       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3198                                      reg_types_.Float());
   3199       break;
   3200     case Instruction::FLOAT_TO_DOUBLE:
   3201       work_line_->CheckUnaryOpToWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3202                                      reg_types_.Float());
   3203       break;
   3204     case Instruction::DOUBLE_TO_INT:
   3205       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Integer(),
   3206                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3207       break;
   3208     case Instruction::DOUBLE_TO_LONG:
   3209       work_line_->CheckUnaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3210                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3211       break;
   3212     case Instruction::DOUBLE_TO_FLOAT:
   3213       work_line_->CheckUnaryOpFromWide(this, inst, reg_types_.Float(),
   3214                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3215       break;
   3216     case Instruction::INT_TO_BYTE:
   3217       work_line_->CheckUnaryOp(this, inst, reg_types_.Byte(), reg_types_.Integer());
   3218       break;
   3219     case Instruction::INT_TO_CHAR:
   3220       work_line_->CheckUnaryOp(this, inst, reg_types_.Char(), reg_types_.Integer());
   3221       break;
   3222     case Instruction::INT_TO_SHORT:
   3223       work_line_->CheckUnaryOp(this, inst, reg_types_.Short(), reg_types_.Integer());
   3224       break;
   3225 
   3226     case Instruction::ADD_INT:
   3227     case Instruction::SUB_INT:
   3228     case Instruction::MUL_INT:
   3229     case Instruction::REM_INT:
   3230     case Instruction::DIV_INT:
   3231     case Instruction::SHL_INT:
   3232     case Instruction::SHR_INT:
   3233     case Instruction::USHR_INT:
   3234       work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3235                                 reg_types_.Integer(), false);
   3236       break;
   3237     case Instruction::AND_INT:
   3238     case Instruction::OR_INT:
   3239     case Instruction::XOR_INT:
   3240       work_line_->CheckBinaryOp(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3241                                 reg_types_.Integer(), true);
   3242       break;
   3243     case Instruction::ADD_LONG:
   3244     case Instruction::SUB_LONG:
   3245     case Instruction::MUL_LONG:
   3246     case Instruction::DIV_LONG:
   3247     case Instruction::REM_LONG:
   3248     case Instruction::AND_LONG:
   3249     case Instruction::OR_LONG:
   3250     case Instruction::XOR_LONG:
   3251       work_line_->CheckBinaryOpWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3252                                     reg_types_.LongLo(), reg_types_.LongHi(),
   3253                                     reg_types_.LongLo(), reg_types_.LongHi());
   3254       break;
   3255     case Instruction::SHL_LONG:
   3256     case Instruction::SHR_LONG:
   3257     case Instruction::USHR_LONG:
   3258       /* shift distance is Int, making these different from other binary operations */
   3259       work_line_->CheckBinaryOpWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3260                                          reg_types_.Integer());
   3261       break;
   3262     case Instruction::ADD_FLOAT:
   3263     case Instruction::SUB_FLOAT:
   3264     case Instruction::MUL_FLOAT:
   3265     case Instruction::DIV_FLOAT:
   3266     case Instruction::REM_FLOAT:
   3267       work_line_->CheckBinaryOp(this, inst, reg_types_.Float(), reg_types_.Float(),
   3268                                 reg_types_.Float(), false);
   3269       break;
   3270     case Instruction::ADD_DOUBLE:
   3271     case Instruction::SUB_DOUBLE:
   3272     case Instruction::MUL_DOUBLE:
   3273     case Instruction::DIV_DOUBLE:
   3274     case Instruction::REM_DOUBLE:
   3275       work_line_->CheckBinaryOpWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3276                                     reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3277                                     reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3278       break;
   3279     case Instruction::ADD_INT_2ADDR:
   3280     case Instruction::SUB_INT_2ADDR:
   3281     case Instruction::MUL_INT_2ADDR:
   3282     case Instruction::REM_INT_2ADDR:
   3283     case Instruction::SHL_INT_2ADDR:
   3284     case Instruction::SHR_INT_2ADDR:
   3285     case Instruction::USHR_INT_2ADDR:
   3286       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3287                                      reg_types_.Integer(), false);
   3288       break;
   3289     case Instruction::AND_INT_2ADDR:
   3290     case Instruction::OR_INT_2ADDR:
   3291     case Instruction::XOR_INT_2ADDR:
   3292       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3293                                      reg_types_.Integer(), true);
   3294       break;
   3295     case Instruction::DIV_INT_2ADDR:
   3296       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Integer(), reg_types_.Integer(),
   3297                                      reg_types_.Integer(), false);
   3298       break;
   3299     case Instruction::ADD_LONG_2ADDR:
   3300     case Instruction::SUB_LONG_2ADDR:
   3301     case Instruction::MUL_LONG_2ADDR:
   3302     case Instruction::DIV_LONG_2ADDR:
   3303     case Instruction::REM_LONG_2ADDR:
   3304     case Instruction::AND_LONG_2ADDR:
   3305     case Instruction::OR_LONG_2ADDR:
   3306     case Instruction::XOR_LONG_2ADDR:
   3307       work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3308                                          reg_types_.LongLo(), reg_types_.LongHi(),
   3309                                          reg_types_.LongLo(), reg_types_.LongHi());
   3310       break;
   3311     case Instruction::SHL_LONG_2ADDR:
   3312     case Instruction::SHR_LONG_2ADDR:
   3313     case Instruction::USHR_LONG_2ADDR:
   3314       work_line_->CheckBinaryOp2addrWideShift(this, inst, reg_types_.LongLo(), reg_types_.LongHi(),
   3315                                               reg_types_.Integer());
   3316       break;
   3317     case Instruction::ADD_FLOAT_2ADDR:
   3318     case Instruction::SUB_FLOAT_2ADDR:
   3319     case Instruction::MUL_FLOAT_2ADDR:
   3320     case Instruction::DIV_FLOAT_2ADDR:
   3321     case Instruction::REM_FLOAT_2ADDR:
   3322       work_line_->CheckBinaryOp2addr(this, inst, reg_types_.Float(), reg_types_.Float(),
   3323                                      reg_types_.Float(), false);
   3324       break;
   3325     case Instruction::ADD_DOUBLE_2ADDR:
   3326     case Instruction::SUB_DOUBLE_2ADDR:
   3327     case Instruction::MUL_DOUBLE_2ADDR:
   3328     case Instruction::DIV_DOUBLE_2ADDR:
   3329     case Instruction::REM_DOUBLE_2ADDR:
   3330       work_line_->CheckBinaryOp2addrWide(this, inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   3331                                          reg_types_.DoubleLo(),  reg_types_.DoubleHi(),
   3332                                          reg_types_.DoubleLo(), reg_types_.DoubleHi());
   3333       break;
   3334     case Instruction::ADD_INT_LIT16:
   3335     case Instruction::RSUB_INT_LIT16:
   3336     case Instruction::MUL_INT_LIT16:
   3337     case Instruction::DIV_INT_LIT16:
   3338     case Instruction::REM_INT_LIT16:
   3339       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
   3340                                  true);
   3341       break;
   3342     case Instruction::AND_INT_LIT16:
   3343     case Instruction::OR_INT_LIT16:
   3344     case Instruction::XOR_INT_LIT16:
   3345       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
   3346                                  true);
   3347       break;
   3348     case Instruction::ADD_INT_LIT8:
   3349     case Instruction::RSUB_INT_LIT8:
   3350     case Instruction::MUL_INT_LIT8:
   3351     case Instruction::DIV_INT_LIT8:
   3352     case Instruction::REM_INT_LIT8:
   3353     case Instruction::SHL_INT_LIT8:
   3354     case Instruction::SHR_INT_LIT8:
   3355     case Instruction::USHR_INT_LIT8:
   3356       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), false,
   3357                                  false);
   3358       break;
   3359     case Instruction::AND_INT_LIT8:
   3360     case Instruction::OR_INT_LIT8:
   3361     case Instruction::XOR_INT_LIT8:
   3362       work_line_->CheckLiteralOp(this, inst, reg_types_.Integer(), reg_types_.Integer(), true,
   3363                                  false);
   3364       break;
   3365 
   3366     // Special instructions.
   3367     case Instruction::RETURN_VOID_NO_BARRIER:
   3368       if (IsConstructor() && !IsStatic()) {
   3369         auto& declaring_class = GetDeclaringClass();
   3370         if (declaring_class.IsUnresolvedReference()) {
   3371           // We must iterate over the fields, even if we cannot use mirror classes to do so. Do it
   3372           // manually over the underlying dex file.
   3373           uint32_t first_index = GetFirstFinalInstanceFieldIndex(*dex_file_,
   3374               dex_file_->GetMethodId(dex_method_idx_).class_idx_);
   3375           if (first_index != DexFile::kDexNoIndex) {
   3376             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for field "
   3377                               << first_index;
   3378           }
   3379           break;
   3380         }
   3381         auto* klass = declaring_class.GetClass();
   3382         for (uint32_t i = 0, num_fields = klass->NumInstanceFields(); i < num_fields; ++i) {
   3383           if (klass->GetInstanceField(i)->IsFinal()) {
   3384             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-no-barrier not expected for "
   3385                 << klass->GetInstanceField(i)->PrettyField();
   3386             break;
   3387           }
   3388         }
   3389       }
   3390       // Handle this like a RETURN_VOID now. Code is duplicated to separate standard from
   3391       // quickened opcodes (otherwise this could be a fall-through).
   3392       if (!IsConstructor()) {
   3393         if (!GetMethodReturnType().IsConflict()) {
   3394           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
   3395         }
   3396       }
   3397       break;
   3398     // Note: the following instructions encode offsets derived from class linking.
   3399     // As such they use Class*/Field*/Executable* as these offsets only have
   3400     // meaning if the class linking and resolution were successful.
   3401     case Instruction::IGET_QUICK:
   3402       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true);
   3403       break;
   3404     case Instruction::IGET_WIDE_QUICK:
   3405       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true);
   3406       break;
   3407     case Instruction::IGET_OBJECT_QUICK:
   3408       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false);
   3409       break;
   3410     case Instruction::IGET_BOOLEAN_QUICK:
   3411       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true);
   3412       break;
   3413     case Instruction::IGET_BYTE_QUICK:
   3414       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true);
   3415       break;
   3416     case Instruction::IGET_CHAR_QUICK:
   3417       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true);
   3418       break;
   3419     case Instruction::IGET_SHORT_QUICK:
   3420       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true);
   3421       break;
   3422     case Instruction::IPUT_QUICK:
   3423       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true);
   3424       break;
   3425     case Instruction::IPUT_BOOLEAN_QUICK:
   3426       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true);
   3427       break;
   3428     case Instruction::IPUT_BYTE_QUICK:
   3429       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true);
   3430       break;
   3431     case Instruction::IPUT_CHAR_QUICK:
   3432       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true);
   3433       break;
   3434     case Instruction::IPUT_SHORT_QUICK:
   3435       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true);
   3436       break;
   3437     case Instruction::IPUT_WIDE_QUICK:
   3438       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true);
   3439       break;
   3440     case Instruction::IPUT_OBJECT_QUICK:
   3441       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false);
   3442       break;
   3443     case Instruction::INVOKE_VIRTUAL_QUICK:
   3444     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
   3445       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   3446       ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range);
   3447       if (called_method != nullptr) {
   3448         const char* descriptor = called_method->GetReturnTypeDescriptor();
   3449         const RegType& return_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3450         if (!return_type.IsLowHalf()) {
   3451           work_line_->SetResultRegisterType(this, return_type);
   3452         } else {
   3453           work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   3454         }
   3455         just_set_result = true;
   3456       }
   3457       break;
   3458     }
   3459 
   3460     /* These should never appear during verification. */
   3461     case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
   3462     case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
   3463     case Instruction::UNUSED_FE ... Instruction::UNUSED_FF:
   3464     case Instruction::UNUSED_79:
   3465     case Instruction::UNUSED_7A:
   3466       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_);
   3467       break;
   3468 
   3469     /*
   3470      * DO NOT add a "default" clause here. Without it the compiler will
   3471      * complain if an instruction is missing (which is desirable).
   3472      */
   3473   }  // end - switch (dec_insn.opcode)
   3474 
   3475   if (have_pending_hard_failure_) {
   3476     if (Runtime::Current()->IsAotCompiler()) {
   3477       /* When AOT compiling, check that the last failure is a hard failure */
   3478       if (failures_[failures_.size() - 1] != VERIFY_ERROR_BAD_CLASS_HARD) {
   3479         LOG(ERROR) << "Pending failures:";
   3480         for (auto& error : failures_) {
   3481           LOG(ERROR) << error;
   3482         }
   3483         for (auto& error_msg : failure_messages_) {
   3484           LOG(ERROR) << error_msg->str();
   3485         }
   3486         LOG(FATAL) << "Pending hard failure, but last failure not hard.";
   3487       }
   3488     }
   3489     /* immediate failure, reject class */
   3490     info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_);
   3491     return false;
   3492   } else if (have_pending_runtime_throw_failure_) {
   3493     /* checking interpreter will throw, mark following code as unreachable */
   3494     opcode_flags = Instruction::kThrow;
   3495     // Note: the flag must be reset as it is only global to decouple Fail and is semantically per
   3496     //       instruction. However, RETURN checking may throw LOCKING errors, so we clear at the
   3497     //       very end.
   3498   }
   3499   /*
   3500    * If we didn't just set the result register, clear it out. This ensures that you can only use
   3501    * "move-result" immediately after the result is set. (We could check this statically, but it's
   3502    * not expensive and it makes our debugging output cleaner.)
   3503    */
   3504   if (!just_set_result) {
   3505     work_line_->SetResultTypeToUnknown(this);
   3506   }
   3507 
   3508   /*
   3509    * Handle "branch". Tag the branch target.
   3510    *
   3511    * NOTE: instructions like Instruction::EQZ provide information about the
   3512    * state of the register when the branch is taken or not taken. For example,
   3513    * somebody could get a reference field, check it for zero, and if the
   3514    * branch is taken immediately store that register in a boolean field
   3515    * since the value is known to be zero. We do not currently account for
   3516    * that, and will reject the code.
   3517    *
   3518    * TODO: avoid re-fetching the branch target
   3519    */
   3520   if ((opcode_flags & Instruction::kBranch) != 0) {
   3521     bool isConditional, selfOkay;
   3522     if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) {
   3523       /* should never happen after static verification */
   3524       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch";
   3525       return false;
   3526     }
   3527     DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0);
   3528     if (!CheckNotMoveExceptionOrMoveResult(code_item_->insns_, work_insn_idx_ + branch_target)) {
   3529       return false;
   3530     }
   3531     /* update branch target, set "changed" if appropriate */
   3532     if (nullptr != branch_line) {
   3533       if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) {
   3534         return false;
   3535       }
   3536     } else {
   3537       if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) {
   3538         return false;
   3539       }
   3540     }
   3541   }
   3542 
   3543   /*
   3544    * Handle "switch". Tag all possible branch targets.
   3545    *
   3546    * We've already verified that the table is structurally sound, so we
   3547    * just need to walk through and tag the targets.
   3548    */
   3549   if ((opcode_flags & Instruction::kSwitch) != 0) {
   3550     int offset_to_switch = insns[1] | (static_cast<int32_t>(insns[2]) << 16);
   3551     const uint16_t* switch_insns = insns + offset_to_switch;
   3552     int switch_count = switch_insns[1];
   3553     int offset_to_targets, targ;
   3554 
   3555     if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
   3556       /* 0 = sig, 1 = count, 2/3 = first key */
   3557       offset_to_targets = 4;
   3558     } else {
   3559       /* 0 = sig, 1 = count, 2..count * 2 = keys */
   3560       DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH);
   3561       offset_to_targets = 2 + 2 * switch_count;
   3562     }
   3563 
   3564     /* verify each switch target */
   3565     for (targ = 0; targ < switch_count; targ++) {
   3566       int offset;
   3567       uint32_t abs_offset;
   3568 
   3569       /* offsets are 32-bit, and only partly endian-swapped */
   3570       offset = switch_insns[offset_to_targets + targ * 2] |
   3571          (static_cast<int32_t>(switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
   3572       abs_offset = work_insn_idx_ + offset;
   3573       DCHECK_LT(abs_offset, code_item_->insns_size_in_code_units_);
   3574       if (!CheckNotMoveExceptionOrMoveResult(code_item_->insns_, abs_offset)) {
   3575         return false;
   3576       }
   3577       if (!UpdateRegisters(abs_offset, work_line_.get(), false)) {
   3578         return false;
   3579       }
   3580     }
   3581   }
   3582 
   3583   /*
   3584    * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a
   3585    * "try" block when they throw, control transfers out of the method.)
   3586    */
   3587   if ((opcode_flags & Instruction::kThrow) != 0 && GetInstructionFlags(work_insn_idx_).IsInTry()) {
   3588     bool has_catch_all_handler = false;
   3589     CatchHandlerIterator iterator(*code_item_, work_insn_idx_);
   3590 
   3591     // Need the linker to try and resolve the handled class to check if it's Throwable.
   3592     ClassLinker* linker = Runtime::Current()->GetClassLinker();
   3593 
   3594     for (; iterator.HasNext(); iterator.Next()) {
   3595       dex::TypeIndex handler_type_idx = iterator.GetHandlerTypeIndex();
   3596       if (!handler_type_idx.IsValid()) {
   3597         has_catch_all_handler = true;
   3598       } else {
   3599         // It is also a catch-all if it is java.lang.Throwable.
   3600         mirror::Class* klass = linker->ResolveType(*dex_file_, handler_type_idx, dex_cache_,
   3601                                                    class_loader_);
   3602         if (klass != nullptr) {
   3603           if (klass == mirror::Throwable::GetJavaLangThrowable()) {
   3604             has_catch_all_handler = true;
   3605           }
   3606         } else {
   3607           // Clear exception.
   3608           DCHECK(self_->IsExceptionPending());
   3609           self_->ClearException();
   3610         }
   3611       }
   3612       /*
   3613        * Merge registers into the "catch" block. We want to use the "savedRegs" rather than
   3614        * "work_regs", because at runtime the exception will be thrown before the instruction
   3615        * modifies any registers.
   3616        */
   3617       if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) {
   3618         return false;
   3619       }
   3620     }
   3621 
   3622     /*
   3623      * If the monitor stack depth is nonzero, there must be a "catch all" handler for this
   3624      * instruction. This does apply to monitor-exit because of async exception handling.
   3625      */
   3626     if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) {
   3627       /*
   3628        * The state in work_line reflects the post-execution state. If the current instruction is a
   3629        * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws,
   3630        * it will do so before grabbing the lock).
   3631        */
   3632       if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) {
   3633         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   3634             << "expected to be within a catch-all for an instruction where a monitor is held";
   3635         return false;
   3636       }
   3637     }
   3638   }
   3639 
   3640   /* Handle "continue". Tag the next consecutive instruction.
   3641    *  Note: Keep the code handling "continue" case below the "branch" and "switch" cases,
   3642    *        because it changes work_line_ when performing peephole optimization
   3643    *        and this change should not be used in those cases.
   3644    */
   3645   if ((opcode_flags & Instruction::kContinue) != 0) {
   3646     DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst);
   3647     uint32_t next_insn_idx = work_insn_idx_ + inst->SizeInCodeUnits();
   3648     if (next_insn_idx >= code_item_->insns_size_in_code_units_) {
   3649       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area";
   3650       return false;
   3651     }
   3652     // The only way to get to a move-exception instruction is to get thrown there. Make sure the
   3653     // next instruction isn't one.
   3654     if (!CheckNotMoveException(code_item_->insns_, next_insn_idx)) {
   3655       return false;
   3656     }
   3657     if (nullptr != fallthrough_line) {
   3658       // Make workline consistent with fallthrough computed from peephole optimization.
   3659       work_line_->CopyFromLine(fallthrough_line.get());
   3660     }
   3661     if (GetInstructionFlags(next_insn_idx).IsReturn()) {
   3662       // For returns we only care about the operand to the return, all other registers are dead.
   3663       const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn_idx);
   3664       AdjustReturnLine(this, ret_inst, work_line_.get());
   3665     }
   3666     RegisterLine* next_line = reg_table_.GetLine(next_insn_idx);
   3667     if (next_line != nullptr) {
   3668       // Merge registers into what we have for the next instruction, and set the "changed" flag if
   3669       // needed. If the merge changes the state of the registers then the work line will be
   3670       // updated.
   3671       if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) {
   3672         return false;
   3673       }
   3674     } else {
   3675       /*
   3676        * We're not recording register data for the next instruction, so we don't know what the
   3677        * prior state was. We have to assume that something has changed and re-evaluate it.
   3678        */
   3679       GetInstructionFlags(next_insn_idx).SetChanged();
   3680     }
   3681   }
   3682 
   3683   /* If we're returning from the method, make sure monitor stack is empty. */
   3684   if ((opcode_flags & Instruction::kReturn) != 0) {
   3685     work_line_->VerifyMonitorStackEmpty(this);
   3686   }
   3687 
   3688   /*
   3689    * Update start_guess. Advance to the next instruction of that's
   3690    * possible, otherwise use the branch target if one was found. If
   3691    * neither of those exists we're in a return or throw; leave start_guess
   3692    * alone and let the caller sort it out.
   3693    */
   3694   if ((opcode_flags & Instruction::kContinue) != 0) {
   3695     DCHECK_EQ(Instruction::At(code_item_->insns_ + work_insn_idx_), inst);
   3696     *start_guess = work_insn_idx_ + inst->SizeInCodeUnits();
   3697   } else if ((opcode_flags & Instruction::kBranch) != 0) {
   3698     /* we're still okay if branch_target is zero */
   3699     *start_guess = work_insn_idx_ + branch_target;
   3700   }
   3701 
   3702   DCHECK_LT(*start_guess, code_item_->insns_size_in_code_units_);
   3703   DCHECK(GetInstructionFlags(*start_guess).IsOpcode());
   3704 
   3705   if (have_pending_runtime_throw_failure_) {
   3706     have_any_pending_runtime_throw_failure_ = true;
   3707     // Reset the pending_runtime_throw flag now.
   3708     have_pending_runtime_throw_failure_ = false;
   3709   }
   3710 
   3711   return true;
   3712 }  // NOLINT(readability/fn_size)
   3713 
   3714 void MethodVerifier::UninstantiableError(const char* descriptor) {
   3715   Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
   3716                                            << "non-instantiable klass " << descriptor;
   3717 }
   3718 
   3719 inline bool MethodVerifier::IsInstantiableOrPrimitive(mirror::Class* klass) {
   3720   return klass->IsInstantiable() || klass->IsPrimitive();
   3721 }
   3722 
   3723 const RegType& MethodVerifier::ResolveClassAndCheckAccess(dex::TypeIndex class_idx) {
   3724   mirror::Class* klass = can_load_classes_
   3725       ? Runtime::Current()->GetClassLinker()->ResolveType(
   3726           *dex_file_, class_idx, dex_cache_, class_loader_)
   3727       : ClassLinker::LookupResolvedType(class_idx, dex_cache_.Get(), class_loader_.Get()).Ptr();
   3728   if (can_load_classes_ && klass == nullptr) {
   3729     DCHECK(self_->IsExceptionPending());
   3730     self_->ClearException();
   3731   }
   3732   const RegType* result = nullptr;
   3733   if (klass != nullptr) {
   3734     bool precise = klass->CannotBeAssignedFromOtherTypes();
   3735     if (precise && !IsInstantiableOrPrimitive(klass)) {
   3736       const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3737       UninstantiableError(descriptor);
   3738       precise = false;
   3739     }
   3740     result = reg_types_.FindClass(klass, precise);
   3741     if (result == nullptr) {
   3742       const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3743       result = reg_types_.InsertClass(descriptor, klass, precise);
   3744     }
   3745   } else {
   3746     const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3747     result = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   3748   }
   3749   DCHECK(result != nullptr);
   3750   if (result->IsConflict()) {
   3751     const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   3752     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
   3753         << "' in " << GetDeclaringClass();
   3754     return *result;
   3755   }
   3756 
   3757   // Record result of class resolution attempt.
   3758   VerifierDeps::MaybeRecordClassResolution(*dex_file_, class_idx, klass);
   3759 
   3760   // Check if access is allowed. Unresolved types use xxxWithAccessCheck to
   3761   // check at runtime if access is allowed and so pass here. If result is
   3762   // primitive, skip the access check.
   3763   if (result->IsNonZeroReferenceTypes() && !result->IsUnresolvedTypes()) {
   3764     const RegType& referrer = GetDeclaringClass();
   3765     if (!referrer.IsUnresolvedTypes() && !referrer.CanAccess(*result)) {
   3766       Fail(VERIFY_ERROR_ACCESS_CLASS) << "illegal class access: '"
   3767                                       << referrer << "' -> '" << *result << "'";
   3768     }
   3769   }
   3770   return *result;
   3771 }
   3772 
   3773 const RegType& MethodVerifier::GetCaughtExceptionType() {
   3774   const RegType* common_super = nullptr;
   3775   if (code_item_->tries_size_ != 0) {
   3776     const uint8_t* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
   3777     uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
   3778     for (uint32_t i = 0; i < handlers_size; i++) {
   3779       CatchHandlerIterator iterator(handlers_ptr);
   3780       for (; iterator.HasNext(); iterator.Next()) {
   3781         if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) {
   3782           if (!iterator.GetHandlerTypeIndex().IsValid()) {
   3783             common_super = &reg_types_.JavaLangThrowable(false);
   3784           } else {
   3785             const RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
   3786             if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception, this)) {
   3787               DCHECK(!exception.IsUninitializedTypes());  // Comes from dex, shouldn't be uninit.
   3788               if (exception.IsUnresolvedTypes()) {
   3789                 // We don't know enough about the type. Fail here and let runtime handle it.
   3790                 Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception;
   3791                 return exception;
   3792               } else {
   3793                 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception;
   3794                 return reg_types_.Conflict();
   3795               }
   3796             } else if (common_super == nullptr) {
   3797               common_super = &exception;
   3798             } else if (common_super->Equals(exception)) {
   3799               // odd case, but nothing to do
   3800             } else {
   3801               common_super = &common_super->Merge(exception, &reg_types_, this);
   3802               if (FailOrAbort(this,
   3803                               reg_types_.JavaLangThrowable(false).IsAssignableFrom(
   3804                                   *common_super, this),
   3805                               "java.lang.Throwable is not assignable-from common_super at ",
   3806                               work_insn_idx_)) {
   3807                 break;
   3808               }
   3809             }
   3810           }
   3811         }
   3812       }
   3813       handlers_ptr = iterator.EndDataPointer();
   3814     }
   3815   }
   3816   if (common_super == nullptr) {
   3817     /* no catch blocks, or no catches with classes we can find */
   3818     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler";
   3819     return reg_types_.Conflict();
   3820   }
   3821   return *common_super;
   3822 }
   3823 
   3824 inline static MethodResolutionKind GetMethodResolutionKind(
   3825     MethodType method_type, bool is_interface) {
   3826   if (method_type == METHOD_DIRECT || method_type == METHOD_STATIC) {
   3827     return kDirectMethodResolution;
   3828   } else if (method_type == METHOD_INTERFACE) {
   3829     return kInterfaceMethodResolution;
   3830   } else if (method_type == METHOD_SUPER && is_interface) {
   3831     return kInterfaceMethodResolution;
   3832   } else {
   3833     DCHECK(method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER
   3834            || method_type == METHOD_POLYMORPHIC);
   3835     return kVirtualMethodResolution;
   3836   }
   3837 }
   3838 
   3839 ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(
   3840     uint32_t dex_method_idx, MethodType method_type) {
   3841   const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
   3842   const RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
   3843   if (klass_type.IsConflict()) {
   3844     std::string append(" in attempt to access method ");
   3845     append += dex_file_->GetMethodName(method_id);
   3846     AppendToLastFailMessage(append);
   3847     return nullptr;
   3848   }
   3849   if (klass_type.IsUnresolvedTypes()) {
   3850     return nullptr;  // Can't resolve Class so no more to do here
   3851   }
   3852   mirror::Class* klass = klass_type.GetClass();
   3853   const RegType& referrer = GetDeclaringClass();
   3854   auto* cl = Runtime::Current()->GetClassLinker();
   3855   auto pointer_size = cl->GetImagePointerSize();
   3856   MethodResolutionKind res_kind = GetMethodResolutionKind(method_type, klass->IsInterface());
   3857 
   3858   ArtMethod* res_method = dex_cache_->GetResolvedMethod(dex_method_idx, pointer_size);
   3859   bool stash_method = false;
   3860   if (res_method == nullptr) {
   3861     const char* name = dex_file_->GetMethodName(method_id);
   3862     const Signature signature = dex_file_->GetMethodSignature(method_id);
   3863 
   3864     if (res_kind == kDirectMethodResolution) {
   3865       res_method = klass->FindDirectMethod(name, signature, pointer_size);
   3866     } else if (res_kind == kVirtualMethodResolution) {
   3867       res_method = klass->FindVirtualMethod(name, signature, pointer_size);
   3868     } else {
   3869       DCHECK_EQ(res_kind, kInterfaceMethodResolution);
   3870       res_method = klass->FindInterfaceMethod(name, signature, pointer_size);
   3871     }
   3872 
   3873     if (res_method != nullptr) {
   3874       stash_method = true;
   3875     } else {
   3876       // If a virtual or interface method wasn't found with the expected type, look in
   3877       // the direct methods. This can happen when the wrong invoke type is used or when
   3878       // a class has changed, and will be flagged as an error in later checks.
   3879       // Note that in this case, we do not put the resolved method in the Dex cache
   3880       // because it was not discovered using the expected type of method resolution.
   3881       if (res_kind != kDirectMethodResolution) {
   3882         // Record result of the initial resolution attempt.
   3883         VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_kind, nullptr);
   3884         // Change resolution type to 'direct' and try to resolve again.
   3885         res_kind = kDirectMethodResolution;
   3886         res_method = klass->FindDirectMethod(name, signature, pointer_size);
   3887       }
   3888     }
   3889   }
   3890 
   3891   // Record result of method resolution attempt.
   3892   VerifierDeps::MaybeRecordMethodResolution(*dex_file_, dex_method_idx, res_kind, res_method);
   3893 
   3894   if (res_method == nullptr) {
   3895     Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method "
   3896                                  << klass->PrettyDescriptor() << "."
   3897                                  << dex_file_->GetMethodName(method_id) << " "
   3898                                  << dex_file_->GetMethodSignature(method_id);
   3899     return nullptr;
   3900   }
   3901 
   3902   // Make sure calls to constructors are "direct". There are additional restrictions but we don't
   3903   // enforce them here.
   3904   if (res_method->IsConstructor() && method_type != METHOD_DIRECT) {
   3905     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor "
   3906                                       << res_method->PrettyMethod();
   3907     return nullptr;
   3908   }
   3909   // Disallow any calls to class initializers.
   3910   if (res_method->IsClassInitializer()) {
   3911     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
   3912                                       << res_method->PrettyMethod();
   3913     return nullptr;
   3914   }
   3915 
   3916   // Check that interface methods are static or match interface classes.
   3917   // We only allow statics if we don't have default methods enabled.
   3918   //
   3919   // Note: this check must be after the initializer check, as those are required to fail a class,
   3920   //       while this check implies an IncompatibleClassChangeError.
   3921   if (klass->IsInterface()) {
   3922     // methods called on interfaces should be invoke-interface, invoke-super, invoke-direct (if
   3923     // dex file version is 37 or greater), or invoke-static.
   3924     if (method_type != METHOD_INTERFACE &&
   3925         method_type != METHOD_STATIC &&
   3926         ((dex_file_->GetVersion() < DexFile::kDefaultMethodsVersion) ||
   3927          method_type != METHOD_DIRECT) &&
   3928         method_type != METHOD_SUPER) {
   3929       Fail(VERIFY_ERROR_CLASS_CHANGE)
   3930           << "non-interface method " << dex_file_->PrettyMethod(dex_method_idx)
   3931           << " is in an interface class " << klass->PrettyClass();
   3932       return nullptr;
   3933     }
   3934   } else {
   3935     if (method_type == METHOD_INTERFACE) {
   3936       Fail(VERIFY_ERROR_CLASS_CHANGE)
   3937           << "interface method " << dex_file_->PrettyMethod(dex_method_idx)
   3938           << " is in a non-interface class " << klass->PrettyClass();
   3939       return nullptr;
   3940     }
   3941   }
   3942 
   3943   // Only stash after the above passed. Otherwise the method wasn't guaranteed to be correct.
   3944   if (stash_method) {
   3945     dex_cache_->SetResolvedMethod(dex_method_idx, res_method, pointer_size);
   3946   }
   3947 
   3948   // Check if access is allowed.
   3949   if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
   3950     Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call "
   3951                                      << res_method->PrettyMethod()
   3952                                      << " from " << referrer << ")";
   3953     return res_method;
   3954   }
   3955   // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
   3956   if (res_method->IsPrivate() && (method_type == METHOD_VIRTUAL || method_type == METHOD_SUPER)) {
   3957     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method "
   3958                                       << res_method->PrettyMethod();
   3959     return nullptr;
   3960   }
   3961   // See if the method type implied by the invoke instruction matches the access flags for the
   3962   // target method. The flags for METHOD_POLYMORPHIC are based on there being precisely two
   3963   // signature polymorphic methods supported by the run-time which are native methods with variable
   3964   // arguments.
   3965   if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) ||
   3966       (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
   3967       ((method_type == METHOD_SUPER ||
   3968         method_type == METHOD_VIRTUAL ||
   3969         method_type == METHOD_INTERFACE) && res_method->IsDirect()) ||
   3970       ((method_type == METHOD_POLYMORPHIC) &&
   3971        (!res_method->IsNative() || !res_method->IsVarargs()))) {
   3972     Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method "
   3973                                        "type of " << res_method->PrettyMethod();
   3974     return nullptr;
   3975   }
   3976   return res_method;
   3977 }
   3978 
   3979 template <class T>
   3980 ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(
   3981     T* it, const Instruction* inst, MethodType method_type, bool is_range, ArtMethod* res_method) {
   3982   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
   3983   // match the call to the signature. Also, we might be calling through an abstract method
   3984   // definition (which doesn't have register count values).
   3985   const size_t expected_args = inst->VRegA();
   3986   /* caught by static verifier */
   3987   DCHECK(is_range || expected_args <= 5);
   3988 
   3989   // TODO(oth): Enable this path for invoke-polymorphic when b/33099829 is resolved.
   3990   if (method_type != METHOD_POLYMORPHIC) {
   3991     if (expected_args > code_item_->outs_size_) {
   3992       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
   3993                                         << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
   3994       return nullptr;
   3995     }
   3996   }
   3997 
   3998   /*
   3999    * Check the "this" argument, which must be an instance of the class that declared the method.
   4000    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
   4001    * rigorous check here (which is okay since we have to do it at runtime).
   4002    */
   4003   if (method_type != METHOD_STATIC) {
   4004     const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst);
   4005     if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
   4006       CHECK(have_pending_hard_failure_);
   4007       return nullptr;
   4008     }
   4009     bool is_init = false;
   4010     if (actual_arg_type.IsUninitializedTypes()) {
   4011       if (res_method) {
   4012         if (!res_method->IsConstructor()) {
   4013           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   4014           return nullptr;
   4015         }
   4016       } else {
   4017         // Check whether the name of the called method is "<init>"
   4018         const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   4019         if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) {
   4020           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   4021           return nullptr;
   4022         }
   4023       }
   4024       is_init = true;
   4025     }
   4026     const RegType& adjusted_type = is_init
   4027                                        ? GetRegTypeCache()->FromUninitialized(actual_arg_type)
   4028                                        : actual_arg_type;
   4029     if (method_type != METHOD_INTERFACE && !adjusted_type.IsZero()) {
   4030       const RegType* res_method_class;
   4031       // Miranda methods have the declaring interface as their declaring class, not the abstract
   4032       // class. It would be wrong to use this for the type check (interface type checks are
   4033       // postponed to runtime).
   4034       if (res_method != nullptr && !res_method->IsMiranda()) {
   4035         mirror::Class* klass = res_method->GetDeclaringClass();
   4036         std::string temp;
   4037         res_method_class = &FromClass(klass->GetDescriptor(&temp), klass,
   4038                                       klass->CannotBeAssignedFromOtherTypes());
   4039       } else {
   4040         const uint32_t method_idx = inst->VRegB();
   4041         const dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
   4042         res_method_class = &reg_types_.FromDescriptor(
   4043             GetClassLoader(),
   4044             dex_file_->StringByTypeIdx(class_idx),
   4045             false);
   4046       }
   4047       if (!res_method_class->IsAssignableFrom(adjusted_type, this)) {
   4048         Fail(adjusted_type.IsUnresolvedTypes()
   4049                  ? VERIFY_ERROR_NO_CLASS
   4050                  : VERIFY_ERROR_BAD_CLASS_SOFT)
   4051             << "'this' argument '" << actual_arg_type << "' not instance of '"
   4052             << *res_method_class << "'";
   4053         // Continue on soft failures. We need to find possible hard failures to avoid problems in
   4054         // the compiler.
   4055         if (have_pending_hard_failure_) {
   4056           return nullptr;
   4057         }
   4058       }
   4059     }
   4060   }
   4061 
   4062   uint32_t arg[5];
   4063   if (!is_range) {
   4064     inst->GetVarArgs(arg);
   4065   }
   4066   uint32_t sig_registers = (method_type == METHOD_STATIC) ? 0 : 1;
   4067   for ( ; it->HasNext(); it->Next()) {
   4068     if (sig_registers >= expected_args) {
   4069       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() <<
   4070           " argument registers, method signature has " << sig_registers + 1 << " or more";
   4071       return nullptr;
   4072     }
   4073 
   4074     const char* param_descriptor = it->GetDescriptor();
   4075 
   4076     if (param_descriptor == nullptr) {
   4077       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature "
   4078           "component";
   4079       return nullptr;
   4080     }
   4081 
   4082     const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), param_descriptor, false);
   4083     uint32_t get_reg = is_range ? inst->VRegC() + static_cast<uint32_t>(sig_registers) :
   4084         arg[sig_registers];
   4085     if (reg_type.IsIntegralTypes()) {
   4086       const RegType& src_type = work_line_->GetRegisterType(this, get_reg);
   4087       if (!src_type.IsIntegralTypes()) {
   4088         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
   4089             << " but expected " << reg_type;
   4090         return nullptr;
   4091       }
   4092     } else {
   4093       if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) {
   4094         // Continue on soft failures. We need to find possible hard failures to avoid problems in
   4095         // the compiler.
   4096         if (have_pending_hard_failure_) {
   4097           return nullptr;
   4098         }
   4099       } else if (reg_type.IsLongOrDoubleTypes()) {
   4100         // Check that registers are consecutive (for non-range invokes). Invokes are the only
   4101         // instructions not specifying register pairs by the first component, but require them
   4102         // nonetheless. Only check when there's an actual register in the parameters. If there's
   4103         // none, this will fail below.
   4104         if (!is_range && sig_registers + 1 < expected_args) {
   4105           uint32_t second_reg = arg[sig_registers + 1];
   4106           if (second_reg != get_reg + 1) {
   4107             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, long or double parameter "
   4108                 "at index " << sig_registers << " is not a pair: " << get_reg << " + "
   4109                 << second_reg << ".";
   4110             return nullptr;
   4111           }
   4112         }
   4113       }
   4114     }
   4115     sig_registers += reg_type.IsLongOrDoubleTypes() ?  2 : 1;
   4116   }
   4117   if (expected_args != sig_registers) {
   4118     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args <<
   4119         " argument registers, method signature has " << sig_registers;
   4120     return nullptr;
   4121   }
   4122   return res_method;
   4123 }
   4124 
   4125 void MethodVerifier::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst,
   4126                                                           MethodType method_type,
   4127                                                           bool is_range) {
   4128   // As the method may not have been resolved, make this static check against what we expect.
   4129   // The main reason for this code block is to fail hard when we find an illegal use, e.g.,
   4130   // wrong number of arguments or wrong primitive types, even if the method could not be resolved.
   4131   const uint32_t method_idx = inst->VRegB();
   4132   DexFileParameterIterator it(*dex_file_,
   4133                               dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_));
   4134   VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, nullptr);
   4135 }
   4136 
   4137 bool MethodVerifier::CheckCallSite(uint32_t call_site_idx) {
   4138   if (call_site_idx >= dex_file_->NumCallSiteIds()) {
   4139     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Bad call site id #" << call_site_idx
   4140                                       << " >= " << dex_file_->NumCallSiteIds();
   4141     return false;
   4142   }
   4143 
   4144   CallSiteArrayValueIterator it(*dex_file_, dex_file_->GetCallSiteId(call_site_idx));
   4145   // Check essential arguments are provided. The dex file verifier has verified indicies of the
   4146   // main values (method handle, name, method_type).
   4147   if (it.Size() < 3) {
   4148     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4149                                       << " has too few arguments: "
   4150                                       << it.Size() << "< 3";
   4151     return false;
   4152   }
   4153 
   4154   // Get and check the first argument: the method handle (index range
   4155   // checked by the dex file verifier).
   4156   uint32_t method_handle_idx = static_cast<uint32_t>(it.GetJavaValue().i);
   4157   it.Next();
   4158 
   4159   const DexFile::MethodHandleItem& mh = dex_file_->GetMethodHandle(method_handle_idx);
   4160   if (mh.method_handle_type_ != static_cast<uint16_t>(DexFile::MethodHandleType::kInvokeStatic)) {
   4161     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4162                                       << " argument 0 method handle type is not InvokeStatic";
   4163     return false;
   4164   }
   4165 
   4166   // Skip the second argument, the name to resolve, as checked by the
   4167   // dex file verifier.
   4168   it.Next();
   4169 
   4170   // Skip the third argument, the method type expected, as checked by
   4171   // the dex file verifier.
   4172   it.Next();
   4173 
   4174   // Check the bootstrap method handle and remaining arguments.
   4175   const DexFile::MethodId& method_id = dex_file_->GetMethodId(mh.field_or_method_idx_);
   4176   uint32_t length;
   4177   const char* shorty = dex_file_->GetMethodShorty(method_id, &length);
   4178 
   4179   if (it.Size() < length - 1) {
   4180     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4181                                       << " too few arguments for bootstrap method: "
   4182                                       << it.Size() << " < " << (length - 1);
   4183     return false;
   4184   }
   4185 
   4186   // Check the return type and first 3 arguments are references
   4187   // (CallSite, Lookup, String, MethodType). If they are not of the
   4188   // expected types (or subtypes), it will trigger a
   4189   // WrongMethodTypeException during execution.
   4190   if (shorty[0] != 'L') {
   4191     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4192                                       << " bootstrap return type is not a reference";
   4193     return false;
   4194   }
   4195 
   4196   for (uint32_t i = 1; i < 4; ++i) {
   4197     if (shorty[i] != 'L') {
   4198       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4199                                         << " bootstrap method argument " << (i - 1)
   4200                                         << " is not a reference";
   4201       return false;
   4202     }
   4203   }
   4204 
   4205   // Check the optional arguments.
   4206   for (uint32_t i = 4; i < length; ++i, it.Next()) {
   4207     bool match = false;
   4208     switch (it.GetValueType()) {
   4209       case EncodedArrayValueIterator::ValueType::kBoolean:
   4210       case EncodedArrayValueIterator::ValueType::kByte:
   4211       case EncodedArrayValueIterator::ValueType::kShort:
   4212       case EncodedArrayValueIterator::ValueType::kChar:
   4213       case EncodedArrayValueIterator::ValueType::kInt:
   4214         // These all fit within one register and encoders do not seem
   4215         // too exacting on the encoding type they use (ie using
   4216         // integer for all of these).
   4217         match = (strchr("ZBCSI", shorty[i]) != nullptr);
   4218         break;
   4219       case EncodedArrayValueIterator::ValueType::kLong:
   4220         match = ('J' == shorty[i]);
   4221         break;
   4222       case EncodedArrayValueIterator::ValueType::kFloat:
   4223         match = ('F' == shorty[i]);
   4224         break;
   4225       case EncodedArrayValueIterator::ValueType::kDouble:
   4226         match = ('D' == shorty[i]);
   4227         break;
   4228       case EncodedArrayValueIterator::ValueType::kMethodType:
   4229       case EncodedArrayValueIterator::ValueType::kMethodHandle:
   4230       case EncodedArrayValueIterator::ValueType::kString:
   4231       case EncodedArrayValueIterator::ValueType::kType:
   4232       case EncodedArrayValueIterator::ValueType::kNull:
   4233         match = ('L' == shorty[i]);
   4234         break;
   4235       case EncodedArrayValueIterator::ValueType::kField:
   4236       case EncodedArrayValueIterator::ValueType::kMethod:
   4237       case EncodedArrayValueIterator::ValueType::kEnum:
   4238       case EncodedArrayValueIterator::ValueType::kArray:
   4239       case EncodedArrayValueIterator::ValueType::kAnnotation:
   4240         // Unreachable based on current EncodedArrayValueIterator::Next().
   4241         UNREACHABLE();
   4242     }
   4243 
   4244     if (!match) {
   4245       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Call site #" << call_site_idx
   4246                                         << " bootstrap method argument " << (i - 1)
   4247                                         << " expected " << shorty[i]
   4248                                         << " got value type: " << it.GetValueType();
   4249       return false;
   4250     }
   4251   }
   4252   return true;
   4253 }
   4254 
   4255 class MethodParamListDescriptorIterator {
   4256  public:
   4257   explicit MethodParamListDescriptorIterator(ArtMethod* res_method) :
   4258       res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()),
   4259       params_size_(params_ == nullptr ? 0 : params_->Size()) {
   4260   }
   4261 
   4262   bool HasNext() {
   4263     return pos_ < params_size_;
   4264   }
   4265 
   4266   void Next() {
   4267     ++pos_;
   4268   }
   4269 
   4270   const char* GetDescriptor() REQUIRES_SHARED(Locks::mutator_lock_) {
   4271     return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_);
   4272   }
   4273 
   4274  private:
   4275   ArtMethod* res_method_;
   4276   size_t pos_;
   4277   const DexFile::TypeList* params_;
   4278   const size_t params_size_;
   4279 };
   4280 
   4281 ArtMethod* MethodVerifier::VerifyInvocationArgs(
   4282     const Instruction* inst, MethodType method_type, bool is_range) {
   4283   // Resolve the method. This could be an abstract or concrete method depending on what sort of call
   4284   // we're making.
   4285   const uint32_t method_idx = inst->VRegB();
   4286   ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type);
   4287   if (res_method == nullptr) {  // error or class is unresolved
   4288     // Check what we can statically.
   4289     if (!have_pending_hard_failure_) {
   4290       VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
   4291     }
   4292     return nullptr;
   4293   }
   4294 
   4295   // If we're using invoke-super(method), make sure that the executing method's class' superclass
   4296   // has a vtable entry for the target method. Or the target is on a interface.
   4297   if (method_type == METHOD_SUPER) {
   4298     dex::TypeIndex class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
   4299     const RegType& reference_type = reg_types_.FromDescriptor(
   4300         GetClassLoader(),
   4301         dex_file_->StringByTypeIdx(class_idx),
   4302         false);
   4303     if (reference_type.IsUnresolvedTypes()) {
   4304       Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Unable to find referenced class from invoke-super";
   4305       return nullptr;
   4306     }
   4307     if (reference_type.GetClass()->IsInterface()) {
   4308       // TODO Can we verify anything else.
   4309       if (class_idx == class_def_.class_idx_) {
   4310         Fail(VERIFY_ERROR_CLASS_CHANGE) << "Cannot invoke-super on self as interface";
   4311         return nullptr;
   4312       }
   4313       // TODO Revisit whether we want to allow invoke-super on direct interfaces only like the JLS
   4314       // does.
   4315       if (!GetDeclaringClass().HasClass()) {
   4316         Fail(VERIFY_ERROR_NO_CLASS) << "Unable to resolve the full class of 'this' used in an"
   4317                                     << "interface invoke-super";
   4318         return nullptr;
   4319       } else if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this)) {
   4320         Fail(VERIFY_ERROR_CLASS_CHANGE)
   4321             << "invoke-super in " << mirror::Class::PrettyClass(GetDeclaringClass().GetClass())
   4322             << " in method "
   4323             << dex_file_->PrettyMethod(dex_method_idx_) << " to method "
   4324             << dex_file_->PrettyMethod(method_idx) << " references "
   4325             << "non-super-interface type " << mirror::Class::PrettyClass(reference_type.GetClass());
   4326         return nullptr;
   4327       }
   4328     } else {
   4329       const RegType& super = GetDeclaringClass().GetSuperClass(&reg_types_);
   4330       if (super.IsUnresolvedTypes()) {
   4331         Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
   4332                                     << dex_file_->PrettyMethod(dex_method_idx_)
   4333                                     << " to super " << res_method->PrettyMethod();
   4334         return nullptr;
   4335       }
   4336       if (!reference_type.IsStrictlyAssignableFrom(GetDeclaringClass(), this) ||
   4337           (res_method->GetMethodIndex() >= super.GetClass()->GetVTableLength())) {
   4338         Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
   4339                                     << dex_file_->PrettyMethod(dex_method_idx_)
   4340                                     << " to super " << super
   4341                                     << "." << res_method->GetName()
   4342                                     << res_method->GetSignature();
   4343         return nullptr;
   4344       }
   4345     }
   4346   }
   4347 
   4348   if (method_type == METHOD_POLYMORPHIC) {
   4349     // Process the signature of the calling site that is invoking the method handle.
   4350     DexFileParameterIterator it(*dex_file_, dex_file_->GetProtoId(inst->VRegH()));
   4351     return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method);
   4352   } else {
   4353     // Process the target method's signature.
   4354     MethodParamListDescriptorIterator it(res_method);
   4355     return VerifyInvocationArgsFromIterator(&it, inst, method_type, is_range, res_method);
   4356   }
   4357 }
   4358 
   4359 bool MethodVerifier::CheckSignaturePolymorphicMethod(ArtMethod* method) {
   4360   mirror::Class* klass = method->GetDeclaringClass();
   4361   if (klass != mirror::MethodHandle::StaticClass()) {
   4362     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4363         << "Signature polymorphic method must be declared in java.lang.invoke.MethodClass";
   4364     return false;
   4365   }
   4366 
   4367   const char* method_name = method->GetName();
   4368   if (strcmp(method_name, "invoke") != 0 && strcmp(method_name, "invokeExact") != 0) {
   4369     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4370         << "Signature polymorphic method name invalid: " << method_name;
   4371     return false;
   4372   }
   4373 
   4374   const DexFile::TypeList* types = method->GetParameterTypeList();
   4375   if (types->Size() != 1) {
   4376     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4377         << "Signature polymorphic method has too many arguments " << types->Size() << " != 1";
   4378     return false;
   4379   }
   4380 
   4381   const dex::TypeIndex argument_type_index = types->GetTypeItem(0).type_idx_;
   4382   const char* argument_descriptor = method->GetTypeDescriptorFromTypeIdx(argument_type_index);
   4383   if (strcmp(argument_descriptor, "[Ljava/lang/Object;") != 0) {
   4384     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4385         << "Signature polymorphic method has unexpected argument type: " << argument_descriptor;
   4386     return false;
   4387   }
   4388 
   4389   const char* return_descriptor = method->GetReturnTypeDescriptor();
   4390   if (strcmp(return_descriptor, "Ljava/lang/Object;") != 0) {
   4391     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4392         << "Signature polymorphic method has unexpected return type: " << return_descriptor;
   4393     return false;
   4394   }
   4395 
   4396   return true;
   4397 }
   4398 
   4399 bool MethodVerifier::CheckSignaturePolymorphicReceiver(const Instruction* inst) {
   4400   const RegType& this_type = work_line_->GetInvocationThis(this, inst);
   4401   if (this_type.IsZero()) {
   4402     /* null pointer always passes (and always fails at run time) */
   4403     return true;
   4404   } else if (!this_type.IsNonZeroReferenceTypes()) {
   4405     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4406         << "invoke-polymorphic receiver is not a reference: "
   4407         << this_type;
   4408     return false;
   4409   } else if (this_type.IsUninitializedReference()) {
   4410     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4411         << "invoke-polymorphic receiver is uninitialized: "
   4412         << this_type;
   4413     return false;
   4414   } else if (!this_type.HasClass()) {
   4415     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4416         << "invoke-polymorphic receiver has no class: "
   4417         << this_type;
   4418     return false;
   4419   } else if (!this_type.GetClass()->IsSubClass(mirror::MethodHandle::StaticClass())) {
   4420     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   4421         << "invoke-polymorphic receiver is not a subclass of MethodHandle: "
   4422         << this_type;
   4423     return false;
   4424   }
   4425   return true;
   4426 }
   4427 
   4428 ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst, RegisterLine* reg_line,
   4429                                                  bool is_range, bool allow_failure) {
   4430   if (is_range) {
   4431     DCHECK_EQ(inst->Opcode(), Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   4432   } else {
   4433     DCHECK_EQ(inst->Opcode(), Instruction::INVOKE_VIRTUAL_QUICK);
   4434   }
   4435   const RegType& actual_arg_type = reg_line->GetInvocationThis(this, inst, allow_failure);
   4436   if (!actual_arg_type.HasClass()) {
   4437     VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
   4438     return nullptr;
   4439   }
   4440   mirror::Class* klass = actual_arg_type.GetClass();
   4441   mirror::Class* dispatch_class;
   4442   if (klass->IsInterface()) {
   4443     // Derive Object.class from Class.class.getSuperclass().
   4444     mirror::Class* object_klass = klass->GetClass()->GetSuperClass();
   4445     if (FailOrAbort(this, object_klass->IsObjectClass(),
   4446                     "Failed to find Object class in quickened invoke receiver", work_insn_idx_)) {
   4447       return nullptr;
   4448     }
   4449     dispatch_class = object_klass;
   4450   } else {
   4451     dispatch_class = klass;
   4452   }
   4453   if (!dispatch_class->HasVTable()) {
   4454     FailOrAbort(this, allow_failure, "Receiver class has no vtable for quickened invoke at ",
   4455                 work_insn_idx_);
   4456     return nullptr;
   4457   }
   4458   uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
   4459   auto* cl = Runtime::Current()->GetClassLinker();
   4460   auto pointer_size = cl->GetImagePointerSize();
   4461   if (static_cast<int32_t>(vtable_index) >= dispatch_class->GetVTableLength()) {
   4462     FailOrAbort(this, allow_failure,
   4463                 "Receiver class has not enough vtable slots for quickened invoke at ",
   4464                 work_insn_idx_);
   4465     return nullptr;
   4466   }
   4467   ArtMethod* res_method = dispatch_class->GetVTableEntry(vtable_index, pointer_size);
   4468   if (self_->IsExceptionPending()) {
   4469     FailOrAbort(this, allow_failure, "Unexpected exception pending for quickened invoke at ",
   4470                 work_insn_idx_);
   4471     return nullptr;
   4472   }
   4473   return res_method;
   4474 }
   4475 
   4476 ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst, bool is_range) {
   4477   DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_)
   4478       << dex_file_->PrettyMethod(dex_method_idx_, true) << "@" << work_insn_idx_;
   4479 
   4480   ArtMethod* res_method = GetQuickInvokedMethod(inst, work_line_.get(), is_range, false);
   4481   if (res_method == nullptr) {
   4482     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer method from " << inst->Name();
   4483     return nullptr;
   4484   }
   4485   if (FailOrAbort(this, !res_method->IsDirect(), "Quick-invoked method is direct at ",
   4486                   work_insn_idx_)) {
   4487     return nullptr;
   4488   }
   4489   if (FailOrAbort(this, !res_method->IsStatic(), "Quick-invoked method is static at ",
   4490                   work_insn_idx_)) {
   4491     return nullptr;
   4492   }
   4493 
   4494   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
   4495   // match the call to the signature. Also, we might be calling through an abstract method
   4496   // definition (which doesn't have register count values).
   4497   const RegType& actual_arg_type = work_line_->GetInvocationThis(this, inst);
   4498   if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
   4499     return nullptr;
   4500   }
   4501   const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   4502   /* caught by static verifier */
   4503   DCHECK(is_range || expected_args <= 5);
   4504   if (expected_args > code_item_->outs_size_) {
   4505     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
   4506         << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
   4507     return nullptr;
   4508   }
   4509 
   4510   /*
   4511    * Check the "this" argument, which must be an instance of the class that declared the method.
   4512    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
   4513    * rigorous check here (which is okay since we have to do it at runtime).
   4514    */
   4515   // Note: given an uninitialized type, this should always fail. Constructors aren't virtual.
   4516   if (actual_arg_type.IsUninitializedTypes() && !res_method->IsConstructor()) {
   4517     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   4518     return nullptr;
   4519   }
   4520   if (!actual_arg_type.IsZero()) {
   4521     mirror::Class* klass = res_method->GetDeclaringClass();
   4522     std::string temp;
   4523     const RegType& res_method_class =
   4524         FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes());
   4525     if (!res_method_class.IsAssignableFrom(actual_arg_type, this)) {
   4526       Fail(actual_arg_type.IsUninitializedTypes()    // Just overcautious - should have never
   4527                ? VERIFY_ERROR_BAD_CLASS_HARD         // quickened this.
   4528                : actual_arg_type.IsUnresolvedTypes()
   4529                      ? VERIFY_ERROR_NO_CLASS
   4530                      : VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
   4531           << "' not instance of '" << res_method_class << "'";
   4532       return nullptr;
   4533     }
   4534   }
   4535   /*
   4536    * Process the target method's signature. This signature may or may not
   4537    * have been verified, so we can't assume it's properly formed.
   4538    */
   4539   const DexFile::TypeList* params = res_method->GetParameterTypeList();
   4540   size_t params_size = params == nullptr ? 0 : params->Size();
   4541   uint32_t arg[5];
   4542   if (!is_range) {
   4543     inst->GetVarArgs(arg);
   4544   }
   4545   size_t actual_args = 1;
   4546   for (size_t param_index = 0; param_index < params_size; param_index++) {
   4547     if (actual_args >= expected_args) {
   4548       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invalid call to '"
   4549                                         << res_method->PrettyMethod()
   4550                                         << "'. Expected " << expected_args
   4551                                          << " arguments, processing argument " << actual_args
   4552                                         << " (where longs/doubles count twice).";
   4553       return nullptr;
   4554     }
   4555     const char* descriptor =
   4556         res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
   4557     if (descriptor == nullptr) {
   4558       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of "
   4559                                         << res_method->PrettyMethod()
   4560                                         << " missing signature component";
   4561       return nullptr;
   4562     }
   4563     const RegType& reg_type = reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   4564     uint32_t get_reg = is_range ? inst->VRegC_3rc() + actual_args : arg[actual_args];
   4565     if (!work_line_->VerifyRegisterType(this, get_reg, reg_type)) {
   4566       return res_method;
   4567     }
   4568     actual_args = reg_type.IsLongOrDoubleTypes() ? actual_args + 2 : actual_args + 1;
   4569   }
   4570   if (actual_args != expected_args) {
   4571     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of "
   4572                                       << res_method->PrettyMethod() << " expected "
   4573                                       << expected_args << " arguments, found " << actual_args;
   4574     return nullptr;
   4575   } else {
   4576     return res_method;
   4577   }
   4578 }
   4579 
   4580 void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) {
   4581   dex::TypeIndex type_idx;
   4582   if (!is_filled) {
   4583     DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY);
   4584     type_idx = dex::TypeIndex(inst->VRegC_22c());
   4585   } else if (!is_range) {
   4586     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY);
   4587     type_idx = dex::TypeIndex(inst->VRegB_35c());
   4588   } else {
   4589     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
   4590     type_idx = dex::TypeIndex(inst->VRegB_3rc());
   4591   }
   4592   const RegType& res_type = ResolveClassAndCheckAccess(type_idx);
   4593   if (res_type.IsConflict()) {  // bad class
   4594     DCHECK_NE(failures_.size(), 0U);
   4595   } else {
   4596     // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   4597     if (!res_type.IsArrayTypes()) {
   4598       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type;
   4599     } else if (!is_filled) {
   4600       /* make sure "size" register is valid type */
   4601       work_line_->VerifyRegisterType(this, inst->VRegB_22c(), reg_types_.Integer());
   4602       /* set register type to array class */
   4603       const RegType& precise_type = reg_types_.FromUninitialized(res_type);
   4604       work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_22c(), precise_type);
   4605     } else {
   4606       DCHECK(!res_type.IsUnresolvedMergedReference());
   4607       // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
   4608       // the list and fail. It's legal, if silly, for arg_count to be zero.
   4609       const RegType& expected_type = reg_types_.GetComponentType(res_type, GetClassLoader());
   4610       uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   4611       uint32_t arg[5];
   4612       if (!is_range) {
   4613         inst->GetVarArgs(arg);
   4614       }
   4615       for (size_t ui = 0; ui < arg_count; ui++) {
   4616         uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui];
   4617         if (!work_line_->VerifyRegisterType(this, get_reg, expected_type)) {
   4618           work_line_->SetResultRegisterType(this, reg_types_.Conflict());
   4619           return;
   4620         }
   4621       }
   4622       // filled-array result goes into "result" register
   4623       const RegType& precise_type = reg_types_.FromUninitialized(res_type);
   4624       work_line_->SetResultRegisterType(this, precise_type);
   4625     }
   4626   }
   4627 }
   4628 
   4629 void MethodVerifier::VerifyAGet(const Instruction* inst,
   4630                                 const RegType& insn_type, bool is_primitive) {
   4631   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
   4632   if (!index_type.IsArrayIndexTypes()) {
   4633     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   4634   } else {
   4635     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
   4636     if (array_type.IsZero()) {
   4637       have_pending_runtime_throw_failure_ = true;
   4638       // Null array class; this code path will fail at runtime. Infer a merge-able type from the
   4639       // instruction type. TODO: have a proper notion of bottom here.
   4640       if (!is_primitive || insn_type.IsCategory1Types()) {
   4641         // Reference or category 1
   4642         work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), reg_types_.Zero());
   4643       } else {
   4644         // Category 2
   4645         work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(),
   4646                                         reg_types_.FromCat2ConstLo(0, false),
   4647                                         reg_types_.FromCat2ConstHi(0, false));
   4648       }
   4649     } else if (!array_type.IsArrayTypes()) {
   4650       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
   4651     } else if (array_type.IsUnresolvedMergedReference()) {
   4652       // Unresolved array types must be reference array types.
   4653       if (is_primitive) {
   4654         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
   4655                     << " source for category 1 aget";
   4656       } else {
   4657         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aget for " << array_type
   4658             << " because of missing class";
   4659         // Approximate with java.lang.Object[].
   4660         work_line_->SetRegisterType<LockOp::kClear>(this,
   4661                                                     inst->VRegA_23x(),
   4662                                                     reg_types_.JavaLangObject(false));
   4663       }
   4664     } else {
   4665       /* verify the class */
   4666       const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   4667       if (!component_type.IsReferenceTypes() && !is_primitive) {
   4668         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   4669             << " source for aget-object";
   4670       } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) {
   4671         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
   4672             << " source for category 1 aget";
   4673       } else if (is_primitive && !insn_type.Equals(component_type) &&
   4674                  !((insn_type.IsInteger() && component_type.IsFloat()) ||
   4675                  (insn_type.IsLong() && component_type.IsDouble()))) {
   4676         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type
   4677             << " incompatible with aget of type " << insn_type;
   4678       } else {
   4679         // Use knowledge of the field type which is stronger than the type inferred from the
   4680         // instruction, which can't differentiate object types and ints from floats, longs from
   4681         // doubles.
   4682         if (!component_type.IsLowHalf()) {
   4683           work_line_->SetRegisterType<LockOp::kClear>(this, inst->VRegA_23x(), component_type);
   4684         } else {
   4685           work_line_->SetRegisterTypeWide(this, inst->VRegA_23x(), component_type,
   4686                                           component_type.HighHalf(&reg_types_));
   4687         }
   4688       }
   4689     }
   4690   }
   4691 }
   4692 
   4693 void MethodVerifier::VerifyPrimitivePut(const RegType& target_type, const RegType& insn_type,
   4694                                         const uint32_t vregA) {
   4695   // Primitive assignability rules are weaker than regular assignability rules.
   4696   bool instruction_compatible;
   4697   bool value_compatible;
   4698   const RegType& value_type = work_line_->GetRegisterType(this, vregA);
   4699   if (target_type.IsIntegralTypes()) {
   4700     instruction_compatible = target_type.Equals(insn_type);
   4701     value_compatible = value_type.IsIntegralTypes();
   4702   } else if (target_type.IsFloat()) {
   4703     instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
   4704     value_compatible = value_type.IsFloatTypes();
   4705   } else if (target_type.IsLong()) {
   4706     instruction_compatible = insn_type.IsLong();
   4707     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   4708     // as target_type depends on the resolved type of the field.
   4709     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   4710       const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
   4711       value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
   4712     } else {
   4713       value_compatible = false;
   4714     }
   4715   } else if (target_type.IsDouble()) {
   4716     instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
   4717     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   4718     // as target_type depends on the resolved type of the field.
   4719     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   4720       const RegType& value_type_hi = work_line_->GetRegisterType(this, vregA + 1);
   4721       value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
   4722     } else {
   4723       value_compatible = false;
   4724     }
   4725   } else {
   4726     instruction_compatible = false;  // reference with primitive store
   4727     value_compatible = false;  // unused
   4728   }
   4729   if (!instruction_compatible) {
   4730     // This is a global failure rather than a class change failure as the instructions and
   4731     // the descriptors for the type should have been consistent within the same file at
   4732     // compile time.
   4733     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
   4734         << "' but expected type '" << target_type << "'";
   4735     return;
   4736   }
   4737   if (!value_compatible) {
   4738     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
   4739         << " of type " << value_type << " but expected " << target_type << " for put";
   4740     return;
   4741   }
   4742 }
   4743 
   4744 void MethodVerifier::VerifyAPut(const Instruction* inst,
   4745                                 const RegType& insn_type, bool is_primitive) {
   4746   const RegType& index_type = work_line_->GetRegisterType(this, inst->VRegC_23x());
   4747   if (!index_type.IsArrayIndexTypes()) {
   4748     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   4749   } else {
   4750     const RegType& array_type = work_line_->GetRegisterType(this, inst->VRegB_23x());
   4751     if (array_type.IsZero()) {
   4752       // Null array type; this code path will fail at runtime.
   4753       // Still check that the given value matches the instruction's type.
   4754       // Note: this is, as usual, complicated by the fact the the instruction isn't fully typed
   4755       //       and fits multiple register types.
   4756       const RegType* modified_reg_type = &insn_type;
   4757       if ((modified_reg_type == &reg_types_.Integer()) ||
   4758           (modified_reg_type == &reg_types_.LongLo())) {
   4759         // May be integer or float | long or double. Overwrite insn_type accordingly.
   4760         const RegType& value_type = work_line_->GetRegisterType(this, inst->VRegA_23x());
   4761         if (modified_reg_type == &reg_types_.Integer()) {
   4762           if (&value_type == &reg_types_.Float()) {
   4763             modified_reg_type = &value_type;
   4764           }
   4765         } else {
   4766           if (&value_type == &reg_types_.DoubleLo()) {
   4767             modified_reg_type = &value_type;
   4768           }
   4769         }
   4770       }
   4771       work_line_->VerifyRegisterType(this, inst->VRegA_23x(), *modified_reg_type);
   4772     } else if (!array_type.IsArrayTypes()) {
   4773       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
   4774     } else if (array_type.IsUnresolvedMergedReference()) {
   4775       // Unresolved array types must be reference array types.
   4776       if (is_primitive) {
   4777         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
   4778                                           << "' but unresolved type '" << array_type << "'";
   4779       } else {
   4780         Fail(VERIFY_ERROR_NO_CLASS) << "cannot verify aput for " << array_type
   4781                                     << " because of missing class";
   4782       }
   4783     } else {
   4784       const RegType& component_type = reg_types_.GetComponentType(array_type, GetClassLoader());
   4785       const uint32_t vregA = inst->VRegA_23x();
   4786       if (is_primitive) {
   4787         VerifyPrimitivePut(component_type, insn_type, vregA);
   4788       } else {
   4789         if (!component_type.IsReferenceTypes()) {
   4790           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   4791               << " source for aput-object";
   4792         } else {
   4793           // The instruction agrees with the type of array, confirm the value to be stored does too
   4794           // Note: we use the instruction type (rather than the component type) for aput-object as
   4795           // incompatible classes will be caught at runtime as an array store exception
   4796           work_line_->VerifyRegisterType(this, vregA, insn_type);
   4797         }
   4798       }
   4799     }
   4800   }
   4801 }
   4802 
   4803 ArtField* MethodVerifier::GetStaticField(int field_idx) {
   4804   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4805   // Check access to class
   4806   const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
   4807   if (klass_type.IsConflict()) {  // bad class
   4808     AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s",
   4809                                          field_idx, dex_file_->GetFieldName(field_id),
   4810                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   4811     return nullptr;
   4812   }
   4813   if (klass_type.IsUnresolvedTypes()) {
   4814     return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
   4815   }
   4816   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   4817   ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_, class_loader_);
   4818 
   4819   // Record result of the field resolution attempt.
   4820   VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field);
   4821 
   4822   if (field == nullptr) {
   4823     VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
   4824               << dex_file_->GetFieldName(field_id) << ") in "
   4825               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   4826     DCHECK(self_->IsExceptionPending());
   4827     self_->ClearException();
   4828     return nullptr;
   4829   } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   4830                                                   field->GetAccessFlags())) {
   4831     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << field->PrettyField()
   4832                                     << " from " << GetDeclaringClass();
   4833     return nullptr;
   4834   } else if (!field->IsStatic()) {
   4835     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField() << " to be static";
   4836     return nullptr;
   4837   }
   4838   return field;
   4839 }
   4840 
   4841 ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_idx) {
   4842   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4843   // Check access to class.
   4844   const RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
   4845   if (klass_type.IsConflict()) {
   4846     AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s",
   4847                                          field_idx, dex_file_->GetFieldName(field_id),
   4848                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   4849     return nullptr;
   4850   }
   4851   if (klass_type.IsUnresolvedTypes()) {
   4852     return nullptr;  // Can't resolve Class so no more to do here
   4853   }
   4854   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   4855   ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, dex_cache_, class_loader_);
   4856 
   4857   // Record result of the field resolution attempt.
   4858   VerifierDeps::MaybeRecordFieldResolution(*dex_file_, field_idx, field);
   4859 
   4860   if (field == nullptr) {
   4861     VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
   4862               << dex_file_->GetFieldName(field_id) << ") in "
   4863               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   4864     DCHECK(self_->IsExceptionPending());
   4865     self_->ClearException();
   4866     return nullptr;
   4867   } else if (obj_type.IsZero()) {
   4868     // Cannot infer and check type, however, access will cause null pointer exception.
   4869     // Fall through into a few last soft failure checks below.
   4870   } else if (!obj_type.IsReferenceTypes()) {
   4871     // Trying to read a field from something that isn't a reference.
   4872     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
   4873                                       << "non-reference type " << obj_type;
   4874     return nullptr;
   4875   } else {
   4876     std::string temp;
   4877     ObjPtr<mirror::Class> klass = field->GetDeclaringClass();
   4878     const RegType& field_klass =
   4879         FromClass(klass->GetDescriptor(&temp),
   4880                   klass.Ptr(),
   4881                   klass->CannotBeAssignedFromOtherTypes());
   4882     if (obj_type.IsUninitializedTypes()) {
   4883       // Field accesses through uninitialized references are only allowable for constructors where
   4884       // the field is declared in this class.
   4885       // Note: this IsConstructor check is technically redundant, as UninitializedThis should only
   4886       //       appear in constructors.
   4887       if (!obj_type.IsUninitializedThisReference() ||
   4888           !IsConstructor() ||
   4889           !field_klass.Equals(GetDeclaringClass())) {
   4890         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << field->PrettyField()
   4891                                           << " of a not fully initialized object within the context"
   4892                                           << " of " << dex_file_->PrettyMethod(dex_method_idx_);
   4893         return nullptr;
   4894       }
   4895     } else if (!field_klass.IsAssignableFrom(obj_type, this)) {
   4896       // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class
   4897       // of C1. For resolution to occur the declared class of the field must be compatible with
   4898       // obj_type, we've discovered this wasn't so, so report the field didn't exist.
   4899       VerifyError type;
   4900       bool is_aot = Runtime::Current()->IsAotCompiler();
   4901       if (is_aot && (field_klass.IsUnresolvedTypes() || obj_type.IsUnresolvedTypes())) {
   4902         // Compiler & unresolved types involved, retry at runtime.
   4903         type = VerifyError::VERIFY_ERROR_NO_CLASS;
   4904       } else {
   4905         // Classes known (resolved; and thus assignability check is precise), or we are at runtime
   4906         // and still missing classes. This is a hard failure.
   4907         type = VerifyError::VERIFY_ERROR_BAD_CLASS_HARD;
   4908       }
   4909       Fail(type) << "cannot access instance field " << field->PrettyField()
   4910                  << " from object of type " << obj_type;
   4911       return nullptr;
   4912     }
   4913   }
   4914 
   4915   // Few last soft failure checks.
   4916   if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   4917                                            field->GetAccessFlags())) {
   4918     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << field->PrettyField()
   4919                                     << " from " << GetDeclaringClass();
   4920     return nullptr;
   4921   } else if (field->IsStatic()) {
   4922     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << field->PrettyField()
   4923                                     << " to not be static";
   4924     return nullptr;
   4925   }
   4926 
   4927   return field;
   4928 }
   4929 
   4930 template <MethodVerifier::FieldAccessType kAccType>
   4931 void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType& insn_type,
   4932                                          bool is_primitive, bool is_static) {
   4933   uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
   4934   ArtField* field;
   4935   if (is_static) {
   4936     field = GetStaticField(field_idx);
   4937   } else {
   4938     const RegType& object_type = work_line_->GetRegisterType(this, inst->VRegB_22c());
   4939 
   4940     // One is not allowed to access fields on uninitialized references, except to write to
   4941     // fields in the constructor (before calling another constructor).
   4942     // GetInstanceField does an assignability check which will fail for uninitialized types.
   4943     // We thus modify the type if the uninitialized reference is a "this" reference (this also
   4944     // checks at the same time that we're verifying a constructor).
   4945     bool should_adjust = (kAccType == FieldAccessType::kAccPut) &&
   4946                          object_type.IsUninitializedThisReference();
   4947     const RegType& adjusted_type = should_adjust
   4948                                        ? GetRegTypeCache()->FromUninitialized(object_type)
   4949                                        : object_type;
   4950     field = GetInstanceField(adjusted_type, field_idx);
   4951     if (UNLIKELY(have_pending_hard_failure_)) {
   4952       return;
   4953     }
   4954     if (should_adjust) {
   4955       if (field == nullptr) {
   4956         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "Might be accessing a superclass instance field prior "
   4957                                           << "to the superclass being initialized in "
   4958                                           << dex_file_->PrettyMethod(dex_method_idx_);
   4959       } else if (field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   4960         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access superclass instance field "
   4961                                           << field->PrettyField() << " of a not fully initialized "
   4962                                           << "object within the context of "
   4963                                           << dex_file_->PrettyMethod(dex_method_idx_);
   4964         return;
   4965       }
   4966     }
   4967   }
   4968   const RegType* field_type = nullptr;
   4969   if (field != nullptr) {
   4970     if (kAccType == FieldAccessType::kAccPut) {
   4971       if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   4972         Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField()
   4973                                         << " from other class " << GetDeclaringClass();
   4974         // Keep hunting for possible hard fails.
   4975       }
   4976     }
   4977 
   4978     ObjPtr<mirror::Class> field_type_class =
   4979         can_load_classes_ ? field->GetType<true>() : field->GetType<false>();
   4980     if (field_type_class != nullptr) {
   4981       field_type = &FromClass(field->GetTypeDescriptor(),
   4982                               field_type_class.Ptr(),
   4983                               field_type_class->CannotBeAssignedFromOtherTypes());
   4984     } else {
   4985       DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   4986       self_->ClearException();
   4987     }
   4988   }
   4989   if (field_type == nullptr) {
   4990     const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   4991     const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
   4992     field_type = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   4993   }
   4994   DCHECK(field_type != nullptr);
   4995   const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
   4996   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
   4997                 "Unexpected third access type");
   4998   if (kAccType == FieldAccessType::kAccPut) {
   4999     // sput or iput.
   5000     if (is_primitive) {
   5001       VerifyPrimitivePut(*field_type, insn_type, vregA);
   5002     } else {
   5003       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   5004         // If the field type is not a reference, this is a global failure rather than
   5005         // a class change failure as the instructions and the descriptors for the type
   5006         // should have been consistent within the same file at compile time.
   5007         VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT
   5008                                                            : VERIFY_ERROR_BAD_CLASS_HARD;
   5009         Fail(error) << "expected field " << ArtField::PrettyField(field)
   5010                     << " to be compatible with type '" << insn_type
   5011                     << "' but found type '" << *field_type
   5012                     << "' in put-object";
   5013         return;
   5014       }
   5015       work_line_->VerifyRegisterType(this, vregA, *field_type);
   5016     }
   5017   } else if (kAccType == FieldAccessType::kAccGet) {
   5018     // sget or iget.
   5019     if (is_primitive) {
   5020       if (field_type->Equals(insn_type) ||
   5021           (field_type->IsFloat() && insn_type.IsInteger()) ||
   5022           (field_type->IsDouble() && insn_type.IsLong())) {
   5023         // expected that read is of the correct primitive type or that int reads are reading
   5024         // floats or long reads are reading doubles
   5025       } else {
   5026         // This is a global failure rather than a class change failure as the instructions and
   5027         // the descriptors for the type should have been consistent within the same file at
   5028         // compile time
   5029         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field)
   5030                                           << " to be of type '" << insn_type
   5031                                           << "' but found type '" << *field_type << "' in get";
   5032         return;
   5033       }
   5034     } else {
   5035       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   5036         // If the field type is not a reference, this is a global failure rather than
   5037         // a class change failure as the instructions and the descriptors for the type
   5038         // should have been consistent within the same file at compile time.
   5039         VerifyError error = field_type->IsReferenceTypes() ? VERIFY_ERROR_BAD_CLASS_SOFT
   5040                                                            : VERIFY_ERROR_BAD_CLASS_HARD;
   5041         Fail(error) << "expected field " << ArtField::PrettyField(field)
   5042                     << " to be compatible with type '" << insn_type
   5043                     << "' but found type '" << *field_type
   5044                     << "' in get-object";
   5045         if (error != VERIFY_ERROR_BAD_CLASS_HARD) {
   5046           work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict());
   5047         }
   5048         return;
   5049       }
   5050     }
   5051     if (!field_type->IsLowHalf()) {
   5052       work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type);
   5053     } else {
   5054       work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(&reg_types_));
   5055     }
   5056   } else {
   5057     LOG(FATAL) << "Unexpected case.";
   5058   }
   5059 }
   5060 
   5061 ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
   5062                                                       RegisterLine* reg_line) {
   5063   DCHECK(IsInstructionIGetQuickOrIPutQuick(inst->Opcode())) << inst->Opcode();
   5064   const RegType& object_type = reg_line->GetRegisterType(this, inst->VRegB_22c());
   5065   if (!object_type.HasClass()) {
   5066     VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
   5067     return nullptr;
   5068   }
   5069   uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
   5070   ArtField* const f = ArtField::FindInstanceFieldWithOffset(object_type.GetClass(), field_offset);
   5071   DCHECK_EQ(f->GetOffset().Uint32Value(), field_offset);
   5072   if (f == nullptr) {
   5073     VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
   5074                    << "' from '" << mirror::Class::PrettyDescriptor(object_type.GetClass()) << "'";
   5075   }
   5076   return f;
   5077 }
   5078 
   5079 template <MethodVerifier::FieldAccessType kAccType>
   5080 void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, const RegType& insn_type,
   5081                                             bool is_primitive) {
   5082   DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
   5083 
   5084   ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
   5085   if (field == nullptr) {
   5086     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name();
   5087     return;
   5088   }
   5089 
   5090   // For an IPUT_QUICK, we now test for final flag of the field.
   5091   if (kAccType == FieldAccessType::kAccPut) {
   5092     if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   5093       Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << field->PrettyField()
   5094                                       << " from other class " << GetDeclaringClass();
   5095       return;
   5096     }
   5097   }
   5098 
   5099   // Get the field type.
   5100   const RegType* field_type;
   5101   {
   5102     ObjPtr<mirror::Class> field_type_class = can_load_classes_ ? field->GetType<true>() :
   5103         field->GetType<false>();
   5104 
   5105     if (field_type_class != nullptr) {
   5106       field_type = &FromClass(field->GetTypeDescriptor(),
   5107                               field_type_class.Ptr(),
   5108                               field_type_class->CannotBeAssignedFromOtherTypes());
   5109     } else {
   5110       Thread* self = Thread::Current();
   5111       DCHECK(!can_load_classes_ || self->IsExceptionPending());
   5112       self->ClearException();
   5113       field_type = &reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
   5114                                               field->GetTypeDescriptor(),
   5115                                               false);
   5116     }
   5117     if (field_type == nullptr) {
   5118       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field type from " << inst->Name();
   5119       return;
   5120     }
   5121   }
   5122 
   5123   const uint32_t vregA = inst->VRegA_22c();
   5124   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
   5125                 "Unexpected third access type");
   5126   if (kAccType == FieldAccessType::kAccPut) {
   5127     if (is_primitive) {
   5128       // Primitive field assignability rules are weaker than regular assignability rules
   5129       bool instruction_compatible;
   5130       bool value_compatible;
   5131       const RegType& value_type = work_line_->GetRegisterType(this, vregA);
   5132       if (field_type->IsIntegralTypes()) {
   5133         instruction_compatible = insn_type.IsIntegralTypes();
   5134         value_compatible = value_type.IsIntegralTypes();
   5135       } else if (field_type->IsFloat()) {
   5136         instruction_compatible = insn_type.IsInteger();  // no [is]put-float, so expect [is]put-int
   5137         value_compatible = value_type.IsFloatTypes();
   5138       } else if (field_type->IsLong()) {
   5139         instruction_compatible = insn_type.IsLong();
   5140         value_compatible = value_type.IsLongTypes();
   5141       } else if (field_type->IsDouble()) {
   5142         instruction_compatible = insn_type.IsLong();  // no [is]put-double, so expect [is]put-long
   5143         value_compatible = value_type.IsDoubleTypes();
   5144       } else {
   5145         instruction_compatible = false;  // reference field with primitive store
   5146         value_compatible = false;  // unused
   5147       }
   5148       if (!instruction_compatible) {
   5149         // This is a global failure rather than a class change failure as the instructions and
   5150         // the descriptors for the type should have been consistent within the same file at
   5151         // compile time
   5152         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field)
   5153                                           << " to be of type '" << insn_type
   5154                                           << "' but found type '" << *field_type
   5155                                           << "' in put";
   5156         return;
   5157       }
   5158       if (!value_compatible) {
   5159         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
   5160             << " of type " << value_type
   5161             << " but expected " << *field_type
   5162             << " for store to " << ArtField::PrettyField(field) << " in put";
   5163         return;
   5164       }
   5165     } else {
   5166       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   5167         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << ArtField::PrettyField(field)
   5168                                           << " to be compatible with type '" << insn_type
   5169                                           << "' but found type '" << *field_type
   5170                                           << "' in put-object";
   5171         return;
   5172       }
   5173       work_line_->VerifyRegisterType(this, vregA, *field_type);
   5174     }
   5175   } else if (kAccType == FieldAccessType::kAccGet) {
   5176     if (is_primitive) {
   5177       if (field_type->Equals(insn_type) ||
   5178           (field_type->IsFloat() && insn_type.IsIntegralTypes()) ||
   5179           (field_type->IsDouble() && insn_type.IsLongTypes())) {
   5180         // expected that read is of the correct primitive type or that int reads are reading
   5181         // floats or long reads are reading doubles
   5182       } else {
   5183         // This is a global failure rather than a class change failure as the instructions and
   5184         // the descriptors for the type should have been consistent within the same file at
   5185         // compile time
   5186         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << ArtField::PrettyField(field)
   5187                                           << " to be of type '" << insn_type
   5188                                           << "' but found type '" << *field_type << "' in Get";
   5189         return;
   5190       }
   5191     } else {
   5192       if (!insn_type.IsAssignableFrom(*field_type, this)) {
   5193         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << ArtField::PrettyField(field)
   5194                                           << " to be compatible with type '" << insn_type
   5195                                           << "' but found type '" << *field_type
   5196                                           << "' in get-object";
   5197         work_line_->SetRegisterType<LockOp::kClear>(this, vregA, reg_types_.Conflict());
   5198         return;
   5199       }
   5200     }
   5201     if (!field_type->IsLowHalf()) {
   5202       work_line_->SetRegisterType<LockOp::kClear>(this, vregA, *field_type);
   5203     } else {
   5204       work_line_->SetRegisterTypeWide(this, vregA, *field_type, field_type->HighHalf(&reg_types_));
   5205     }
   5206   } else {
   5207     LOG(FATAL) << "Unexpected case.";
   5208   }
   5209 }
   5210 
   5211 bool MethodVerifier::CheckNotMoveException(const uint16_t* insns, int insn_idx) {
   5212   if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
   5213     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception";
   5214     return false;
   5215   }
   5216   return true;
   5217 }
   5218 
   5219 bool MethodVerifier::CheckNotMoveResult(const uint16_t* insns, int insn_idx) {
   5220   if (((insns[insn_idx] & 0xff) >= Instruction::MOVE_RESULT) &&
   5221       ((insns[insn_idx] & 0xff) <= Instruction::MOVE_RESULT_OBJECT)) {
   5222     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-result*";
   5223     return false;
   5224   }
   5225   return true;
   5226 }
   5227 
   5228 bool MethodVerifier::CheckNotMoveExceptionOrMoveResult(const uint16_t* insns, int insn_idx) {
   5229   return (CheckNotMoveException(insns, insn_idx) && CheckNotMoveResult(insns, insn_idx));
   5230 }
   5231 
   5232 bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line,
   5233                                      bool update_merge_line) {
   5234   bool changed = true;
   5235   RegisterLine* target_line = reg_table_.GetLine(next_insn);
   5236   if (!GetInstructionFlags(next_insn).IsVisitedOrChanged()) {
   5237     /*
   5238      * We haven't processed this instruction before, and we haven't touched the registers here, so
   5239      * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the
   5240      * only way a register can transition out of "unknown", so this is not just an optimization.)
   5241      */
   5242     target_line->CopyFromLine(merge_line);
   5243     if (GetInstructionFlags(next_insn).IsReturn()) {
   5244       // Verify that the monitor stack is empty on return.
   5245       merge_line->VerifyMonitorStackEmpty(this);
   5246 
   5247       // For returns we only care about the operand to the return, all other registers are dead.
   5248       // Initialize them as conflicts so they don't add to GC and deoptimization information.
   5249       const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn);
   5250       AdjustReturnLine(this, ret_inst, target_line);
   5251       // Directly bail if a hard failure was found.
   5252       if (have_pending_hard_failure_) {
   5253         return false;
   5254       }
   5255     }
   5256   } else {
   5257     RegisterLineArenaUniquePtr copy;
   5258     if (kDebugVerify) {
   5259       copy.reset(RegisterLine::Create(target_line->NumRegs(), this));
   5260       copy->CopyFromLine(target_line);
   5261     }
   5262     changed = target_line->MergeRegisters(this, merge_line);
   5263     if (have_pending_hard_failure_) {
   5264       return false;
   5265     }
   5266     if (kDebugVerify && changed) {
   5267       LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]"
   5268                       << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
   5269                       << copy->Dump(this) << "  MERGE\n"
   5270                       << merge_line->Dump(this) << "  ==\n"
   5271                       << target_line->Dump(this) << "\n";
   5272     }
   5273     if (update_merge_line && changed) {
   5274       merge_line->CopyFromLine(target_line);
   5275     }
   5276   }
   5277   if (changed) {
   5278     GetInstructionFlags(next_insn).SetChanged();
   5279   }
   5280   return true;
   5281 }
   5282 
   5283 InstructionFlags* MethodVerifier::CurrentInsnFlags() {
   5284   return &GetInstructionFlags(work_insn_idx_);
   5285 }
   5286 
   5287 const RegType& MethodVerifier::GetMethodReturnType() {
   5288   if (return_type_ == nullptr) {
   5289     if (mirror_method_ != nullptr) {
   5290       mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_);
   5291       if (return_type_class != nullptr) {
   5292         return_type_ = &FromClass(mirror_method_->GetReturnTypeDescriptor(),
   5293                                   return_type_class,
   5294                                   return_type_class->CannotBeAssignedFromOtherTypes());
   5295       } else {
   5296         DCHECK(!can_load_classes_ || self_->IsExceptionPending());
   5297         self_->ClearException();
   5298       }
   5299     }
   5300     if (return_type_ == nullptr) {
   5301       const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   5302       const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id);
   5303       dex::TypeIndex return_type_idx = proto_id.return_type_idx_;
   5304       const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx));
   5305       return_type_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   5306     }
   5307   }
   5308   return *return_type_;
   5309 }
   5310 
   5311 const RegType& MethodVerifier::GetDeclaringClass() {
   5312   if (declaring_class_ == nullptr) {
   5313     const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   5314     const char* descriptor
   5315         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
   5316     if (mirror_method_ != nullptr) {
   5317       mirror::Class* klass = mirror_method_->GetDeclaringClass();
   5318       declaring_class_ = &FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes());
   5319     } else {
   5320       declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
   5321     }
   5322   }
   5323   return *declaring_class_;
   5324 }
   5325 
   5326 std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
   5327   RegisterLine* line = reg_table_.GetLine(dex_pc);
   5328   DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc);
   5329   std::vector<int32_t> result;
   5330   for (size_t i = 0; i < line->NumRegs(); ++i) {
   5331     const RegType& type = line->GetRegisterType(this, i);
   5332     if (type.IsConstant()) {
   5333       result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant);
   5334       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5335       result.push_back(const_val->ConstantValue());
   5336     } else if (type.IsConstantLo()) {
   5337       result.push_back(type.IsPreciseConstantLo() ? kConstant : kImpreciseConstant);
   5338       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5339       result.push_back(const_val->ConstantValueLo());
   5340     } else if (type.IsConstantHi()) {
   5341       result.push_back(type.IsPreciseConstantHi() ? kConstant : kImpreciseConstant);
   5342       const ConstantType* const_val = down_cast<const ConstantType*>(&type);
   5343       result.push_back(const_val->ConstantValueHi());
   5344     } else if (type.IsIntegralTypes()) {
   5345       result.push_back(kIntVReg);
   5346       result.push_back(0);
   5347     } else if (type.IsFloat()) {
   5348       result.push_back(kFloatVReg);
   5349       result.push_back(0);
   5350     } else if (type.IsLong()) {
   5351       result.push_back(kLongLoVReg);
   5352       result.push_back(0);
   5353       result.push_back(kLongHiVReg);
   5354       result.push_back(0);
   5355       ++i;
   5356     } else if (type.IsDouble()) {
   5357       result.push_back(kDoubleLoVReg);
   5358       result.push_back(0);
   5359       result.push_back(kDoubleHiVReg);
   5360       result.push_back(0);
   5361       ++i;
   5362     } else if (type.IsUndefined() || type.IsConflict() || type.IsHighHalf()) {
   5363       result.push_back(kUndefined);
   5364       result.push_back(0);
   5365     } else {
   5366       CHECK(type.IsNonZeroReferenceTypes());
   5367       result.push_back(kReferenceVReg);
   5368       result.push_back(0);
   5369     }
   5370   }
   5371   return result;
   5372 }
   5373 
   5374 const RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
   5375   if (precise) {
   5376     // Precise constant type.
   5377     return reg_types_.FromCat1Const(value, true);
   5378   } else {
   5379     // Imprecise constant type.
   5380     if (value < -32768) {
   5381       return reg_types_.IntConstant();
   5382     } else if (value < -128) {
   5383       return reg_types_.ShortConstant();
   5384     } else if (value < 0) {
   5385       return reg_types_.ByteConstant();
   5386     } else if (value == 0) {
   5387       return reg_types_.Zero();
   5388     } else if (value == 1) {
   5389       return reg_types_.One();
   5390     } else if (value < 128) {
   5391       return reg_types_.PosByteConstant();
   5392     } else if (value < 32768) {
   5393       return reg_types_.PosShortConstant();
   5394     } else if (value < 65536) {
   5395       return reg_types_.CharConstant();
   5396     } else {
   5397       return reg_types_.IntConstant();
   5398     }
   5399   }
   5400 }
   5401 
   5402 void MethodVerifier::Init() {
   5403   art::verifier::RegTypeCache::Init();
   5404 }
   5405 
   5406 void MethodVerifier::Shutdown() {
   5407   verifier::RegTypeCache::ShutDown();
   5408 }
   5409 
   5410 void MethodVerifier::VisitStaticRoots(RootVisitor* visitor) {
   5411   RegTypeCache::VisitStaticRoots(visitor);
   5412 }
   5413 
   5414 void MethodVerifier::VisitRoots(RootVisitor* visitor, const RootInfo& root_info) {
   5415   reg_types_.VisitRoots(visitor, root_info);
   5416 }
   5417 
   5418 const RegType& MethodVerifier::FromClass(const char* descriptor,
   5419                                          mirror::Class* klass,
   5420                                          bool precise) {
   5421   DCHECK(klass != nullptr);
   5422   if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) {
   5423     Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
   5424         << "non-instantiable klass " << descriptor;
   5425     precise = false;
   5426   }
   5427   return reg_types_.FromClass(descriptor, klass, precise);
   5428 }
   5429 
   5430 }  // namespace verifier
   5431 }  // namespace art
   5432