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