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 "base/logging.h"
     22 #include "base/mutex-inl.h"
     23 #include "class_linker.h"
     24 #include "compiler_callbacks.h"
     25 #include "dex_file-inl.h"
     26 #include "dex_instruction-inl.h"
     27 #include "dex_instruction_visitor.h"
     28 #include "field_helper.h"
     29 #include "gc/accounting/card_table-inl.h"
     30 #include "indenter.h"
     31 #include "intern_table.h"
     32 #include "leb128.h"
     33 #include "method_helper-inl.h"
     34 #include "mirror/art_field-inl.h"
     35 #include "mirror/art_method-inl.h"
     36 #include "mirror/class.h"
     37 #include "mirror/class-inl.h"
     38 #include "mirror/dex_cache-inl.h"
     39 #include "mirror/object-inl.h"
     40 #include "mirror/object_array-inl.h"
     41 #include "register_line-inl.h"
     42 #include "runtime.h"
     43 #include "scoped_thread_state_change.h"
     44 #include "handle_scope-inl.h"
     45 #include "verifier/dex_gc_map.h"
     46 
     47 namespace art {
     48 namespace verifier {
     49 
     50 static constexpr bool kTimeVerifyMethod = !kIsDebugBuild;
     51 static constexpr bool gDebugVerify = false;
     52 // TODO: Add a constant to method_verifier to turn on verbose logging?
     53 
     54 void PcToRegisterLineTable::Init(RegisterTrackingMode mode, InstructionFlags* flags,
     55                                  uint32_t insns_size, uint16_t registers_size,
     56                                  MethodVerifier* verifier) {
     57   DCHECK_GT(insns_size, 0U);
     58   register_lines_.reset(new RegisterLine*[insns_size]());
     59   size_ = insns_size;
     60   for (uint32_t i = 0; i < insns_size; i++) {
     61     bool interesting = false;
     62     switch (mode) {
     63       case kTrackRegsAll:
     64         interesting = flags[i].IsOpcode();
     65         break;
     66       case kTrackCompilerInterestPoints:
     67         interesting = flags[i].IsCompileTimeInfoPoint() || flags[i].IsBranchTarget();
     68         break;
     69       case kTrackRegsBranches:
     70         interesting = flags[i].IsBranchTarget();
     71         break;
     72       default:
     73         break;
     74     }
     75     if (interesting) {
     76       register_lines_[i] = RegisterLine::Create(registers_size, verifier);
     77     }
     78   }
     79 }
     80 
     81 PcToRegisterLineTable::~PcToRegisterLineTable() {
     82   for (size_t i = 0; i < size_; i++) {
     83     delete register_lines_[i];
     84     if (kIsDebugBuild) {
     85       register_lines_[i] = nullptr;
     86     }
     87   }
     88 }
     89 
     90 // Note: returns true on failure.
     91 ALWAYS_INLINE static inline bool FailOrAbort(MethodVerifier* verifier, bool condition,
     92                                              const char* error_msg, uint32_t work_insn_idx) {
     93   if (kIsDebugBuild) {
     94     // In a debug build, abort if the error condition is wrong.
     95     DCHECK(condition) << error_msg << work_insn_idx;
     96   } else {
     97     // In a non-debug build, just fail the class.
     98     if (!condition) {
     99       verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx;
    100       return true;
    101     }
    102   }
    103 
    104   return false;
    105 }
    106 
    107 MethodVerifier::FailureKind MethodVerifier::VerifyClass(mirror::Class* klass,
    108                                                         bool allow_soft_failures,
    109                                                         std::string* error) {
    110   if (klass->IsVerified()) {
    111     return kNoFailure;
    112   }
    113   bool early_failure = false;
    114   std::string failure_message;
    115   const DexFile& dex_file = klass->GetDexFile();
    116   const DexFile::ClassDef* class_def = klass->GetClassDef();
    117   mirror::Class* super = klass->GetSuperClass();
    118   std::string temp;
    119   if (super == nullptr && strcmp("Ljava/lang/Object;", klass->GetDescriptor(&temp)) != 0) {
    120     early_failure = true;
    121     failure_message = " that has no super class";
    122   } else if (super != nullptr && super->IsFinal()) {
    123     early_failure = true;
    124     failure_message = " that attempts to sub-class final class " + PrettyDescriptor(super);
    125   } else if (class_def == nullptr) {
    126     early_failure = true;
    127     failure_message = " that isn't present in dex file " + dex_file.GetLocation();
    128   }
    129   if (early_failure) {
    130     *error = "Verifier rejected class " + PrettyDescriptor(klass) + failure_message;
    131     if (Runtime::Current()->IsCompiler()) {
    132       ClassReference ref(&dex_file, klass->GetDexClassDefIndex());
    133       Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref);
    134     }
    135     return kHardFailure;
    136   }
    137   StackHandleScope<2> hs(Thread::Current());
    138   Handle<mirror::DexCache> dex_cache(hs.NewHandle(klass->GetDexCache()));
    139   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(klass->GetClassLoader()));
    140   return VerifyClass(&dex_file, dex_cache, class_loader, class_def, allow_soft_failures, error);
    141 }
    142 
    143 MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file,
    144                                                         Handle<mirror::DexCache> dex_cache,
    145                                                         Handle<mirror::ClassLoader> class_loader,
    146                                                         const DexFile::ClassDef* class_def,
    147                                                         bool allow_soft_failures,
    148                                                         std::string* error) {
    149   DCHECK(class_def != nullptr);
    150   const byte* class_data = dex_file->GetClassData(*class_def);
    151   if (class_data == nullptr) {
    152     // empty class, probably a marker interface
    153     return kNoFailure;
    154   }
    155   ClassDataItemIterator it(*dex_file, class_data);
    156   while (it.HasNextStaticField() || it.HasNextInstanceField()) {
    157     it.Next();
    158   }
    159   size_t error_count = 0;
    160   bool hard_fail = false;
    161   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    162   int64_t previous_direct_method_idx = -1;
    163   while (it.HasNextDirectMethod()) {
    164     uint32_t method_idx = it.GetMemberIndex();
    165     if (method_idx == previous_direct_method_idx) {
    166       // smali can create dex files with two encoded_methods sharing the same method_idx
    167       // http://code.google.com/p/smali/issues/detail?id=119
    168       it.Next();
    169       continue;
    170     }
    171     previous_direct_method_idx = method_idx;
    172     InvokeType type = it.GetMethodInvokeType(*class_def);
    173     mirror::ArtMethod* method =
    174         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
    175                               NullHandle<mirror::ArtMethod>(), type);
    176     if (method == nullptr) {
    177       DCHECK(Thread::Current()->IsExceptionPending());
    178       // We couldn't resolve the method, but continue regardless.
    179       Thread::Current()->ClearException();
    180     }
    181     MethodVerifier::FailureKind result = VerifyMethod(method_idx,
    182                                                       dex_file,
    183                                                       dex_cache,
    184                                                       class_loader,
    185                                                       class_def,
    186                                                       it.GetMethodCodeItem(),
    187                                                       method,
    188                                                       it.GetMethodAccessFlags(),
    189                                                       allow_soft_failures,
    190                                                       false);
    191     if (result != kNoFailure) {
    192       if (result == kHardFailure) {
    193         hard_fail = true;
    194         if (error_count > 0) {
    195           *error += "\n";
    196         }
    197         *error = "Verifier rejected class ";
    198         *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
    199         *error += " due to bad method ";
    200         *error += PrettyMethod(method_idx, *dex_file);
    201       }
    202       ++error_count;
    203     }
    204     it.Next();
    205   }
    206   int64_t previous_virtual_method_idx = -1;
    207   while (it.HasNextVirtualMethod()) {
    208     uint32_t method_idx = it.GetMemberIndex();
    209     if (method_idx == previous_virtual_method_idx) {
    210       // smali can create dex files with two encoded_methods sharing the same method_idx
    211       // http://code.google.com/p/smali/issues/detail?id=119
    212       it.Next();
    213       continue;
    214     }
    215     previous_virtual_method_idx = method_idx;
    216     InvokeType type = it.GetMethodInvokeType(*class_def);
    217     mirror::ArtMethod* method =
    218         linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader,
    219                               NullHandle<mirror::ArtMethod>(), type);
    220     if (method == nullptr) {
    221       DCHECK(Thread::Current()->IsExceptionPending());
    222       // We couldn't resolve the method, but continue regardless.
    223       Thread::Current()->ClearException();
    224     }
    225     MethodVerifier::FailureKind result = VerifyMethod(method_idx,
    226                                                       dex_file,
    227                                                       dex_cache,
    228                                                       class_loader,
    229                                                       class_def,
    230                                                       it.GetMethodCodeItem(),
    231                                                       method,
    232                                                       it.GetMethodAccessFlags(),
    233                                                       allow_soft_failures,
    234                                                       false);
    235     if (result != kNoFailure) {
    236       if (result == kHardFailure) {
    237         hard_fail = true;
    238         if (error_count > 0) {
    239           *error += "\n";
    240         }
    241         *error = "Verifier rejected class ";
    242         *error += PrettyDescriptor(dex_file->GetClassDescriptor(*class_def));
    243         *error += " due to bad method ";
    244         *error += PrettyMethod(method_idx, *dex_file);
    245       }
    246       ++error_count;
    247     }
    248     it.Next();
    249   }
    250   if (error_count == 0) {
    251     return kNoFailure;
    252   } else {
    253     return hard_fail ? kHardFailure : kSoftFailure;
    254   }
    255 }
    256 
    257 MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx,
    258                                                          const DexFile* dex_file,
    259                                                          Handle<mirror::DexCache> dex_cache,
    260                                                          Handle<mirror::ClassLoader> class_loader,
    261                                                          const DexFile::ClassDef* class_def,
    262                                                          const DexFile::CodeItem* code_item,
    263                                                          mirror::ArtMethod* method,
    264                                                          uint32_t method_access_flags,
    265                                                          bool allow_soft_failures,
    266                                                          bool need_precise_constants) {
    267   MethodVerifier::FailureKind result = kNoFailure;
    268   uint64_t start_ns = kTimeVerifyMethod ? NanoTime() : 0;
    269 
    270   MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item,
    271                            method_idx, method, method_access_flags, true, allow_soft_failures,
    272                            need_precise_constants);
    273   if (verifier.Verify()) {
    274     // Verification completed, however failures may be pending that didn't cause the verification
    275     // to hard fail.
    276     CHECK(!verifier.have_pending_hard_failure_);
    277     if (verifier.failures_.size() != 0) {
    278       if (VLOG_IS_ON(verifier)) {
    279           verifier.DumpFailures(VLOG_STREAM(verifier) << "Soft verification failures in "
    280                                 << PrettyMethod(method_idx, *dex_file) << "\n");
    281       }
    282       result = kSoftFailure;
    283     }
    284   } else {
    285     // Bad method data.
    286     CHECK_NE(verifier.failures_.size(), 0U);
    287     CHECK(verifier.have_pending_hard_failure_);
    288     verifier.DumpFailures(LOG(INFO) << "Verification error in "
    289                                     << PrettyMethod(method_idx, *dex_file) << "\n");
    290     if (gDebugVerify) {
    291       std::cout << "\n" << verifier.info_messages_.str();
    292       verifier.Dump(std::cout);
    293     }
    294     result = kHardFailure;
    295   }
    296   if (kTimeVerifyMethod) {
    297     uint64_t duration_ns = NanoTime() - start_ns;
    298     if (duration_ns > MsToNs(100)) {
    299       LOG(WARNING) << "Verification of " << PrettyMethod(method_idx, *dex_file)
    300                    << " took " << PrettyDuration(duration_ns);
    301     }
    302   }
    303   return result;
    304 }
    305 
    306 MethodVerifier* MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_idx,
    307                                                     const DexFile* dex_file,
    308                                                     Handle<mirror::DexCache> dex_cache,
    309                                                     Handle<mirror::ClassLoader> class_loader,
    310                                                     const DexFile::ClassDef* class_def,
    311                                                     const DexFile::CodeItem* code_item,
    312                                                     mirror::ArtMethod* method,
    313                                                     uint32_t method_access_flags) {
    314   MethodVerifier* verifier = new MethodVerifier(dex_file, &dex_cache, &class_loader, class_def,
    315                                                 code_item, dex_method_idx, method,
    316                                                 method_access_flags, true, true, true, true);
    317   verifier->Verify();
    318   verifier->DumpFailures(os);
    319   os << verifier->info_messages_.str();
    320   verifier->Dump(os);
    321 
    322   return verifier;
    323 }
    324 
    325 MethodVerifier::MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>* dex_cache,
    326                                Handle<mirror::ClassLoader>* class_loader,
    327                                const DexFile::ClassDef* class_def,
    328                                const DexFile::CodeItem* code_item, uint32_t dex_method_idx,
    329                                mirror::ArtMethod* method, uint32_t method_access_flags,
    330                                bool can_load_classes, bool allow_soft_failures,
    331                                bool need_precise_constants, bool verify_to_dump)
    332     : reg_types_(can_load_classes),
    333       work_insn_idx_(-1),
    334       dex_method_idx_(dex_method_idx),
    335       mirror_method_(method),
    336       method_access_flags_(method_access_flags),
    337       return_type_(nullptr),
    338       dex_file_(dex_file),
    339       dex_cache_(dex_cache),
    340       class_loader_(class_loader),
    341       class_def_(class_def),
    342       code_item_(code_item),
    343       declaring_class_(nullptr),
    344       interesting_dex_pc_(-1),
    345       monitor_enter_dex_pcs_(nullptr),
    346       have_pending_hard_failure_(false),
    347       have_pending_runtime_throw_failure_(false),
    348       new_instance_count_(0),
    349       monitor_enter_count_(0),
    350       can_load_classes_(can_load_classes),
    351       allow_soft_failures_(allow_soft_failures),
    352       need_precise_constants_(need_precise_constants),
    353       has_check_casts_(false),
    354       has_virtual_or_interface_invokes_(false),
    355       verify_to_dump_(verify_to_dump) {
    356   Runtime::Current()->AddMethodVerifier(this);
    357   DCHECK(class_def != nullptr);
    358 }
    359 
    360 MethodVerifier::~MethodVerifier() {
    361   Runtime::Current()->RemoveMethodVerifier(this);
    362   STLDeleteElements(&failure_messages_);
    363 }
    364 
    365 void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc,
    366                                       std::vector<uint32_t>* monitor_enter_dex_pcs) {
    367   StackHandleScope<2> hs(Thread::Current());
    368   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    369   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    370   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
    371                           m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false,
    372                           true, false);
    373   verifier.interesting_dex_pc_ = dex_pc;
    374   verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs;
    375   verifier.FindLocksAtDexPc();
    376 }
    377 
    378 void MethodVerifier::FindLocksAtDexPc() {
    379   CHECK(monitor_enter_dex_pcs_ != nullptr);
    380   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    381 
    382   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    383   // verification. In practice, the phase we want relies on data structures set up by all the
    384   // earlier passes, so we just run the full method verification and bail out early when we've
    385   // got what we wanted.
    386   Verify();
    387 }
    388 
    389 mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m,
    390                                                            uint32_t dex_pc) {
    391   StackHandleScope<2> hs(Thread::Current());
    392   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    393   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    394   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
    395                           m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
    396                           true, false);
    397   return verifier.FindAccessedFieldAtDexPc(dex_pc);
    398 }
    399 
    400 mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) {
    401   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    402 
    403   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    404   // verification. In practice, the phase we want relies on data structures set up by all the
    405   // earlier passes, so we just run the full method verification and bail out early when we've
    406   // got what we wanted.
    407   bool success = Verify();
    408   if (!success) {
    409     return nullptr;
    410   }
    411   RegisterLine* register_line = reg_table_.GetLine(dex_pc);
    412   if (register_line == nullptr) {
    413     return nullptr;
    414   }
    415   const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
    416   return GetQuickFieldAccess(inst, register_line);
    417 }
    418 
    419 mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m,
    420                                                             uint32_t dex_pc) {
    421   StackHandleScope<2> hs(Thread::Current());
    422   Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache()));
    423   Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader()));
    424   MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(),
    425                           m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true,
    426                           true, false);
    427   return verifier.FindInvokedMethodAtDexPc(dex_pc);
    428 }
    429 
    430 mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(uint32_t dex_pc) {
    431   CHECK(code_item_ != nullptr);  // This only makes sense for methods with code.
    432 
    433   // Strictly speaking, we ought to be able to get away with doing a subset of the full method
    434   // verification. In practice, the phase we want relies on data structures set up by all the
    435   // earlier passes, so we just run the full method verification and bail out early when we've
    436   // got what we wanted.
    437   bool success = Verify();
    438   if (!success) {
    439     return nullptr;
    440   }
    441   RegisterLine* register_line = reg_table_.GetLine(dex_pc);
    442   if (register_line == nullptr) {
    443     return nullptr;
    444   }
    445   const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc);
    446   const bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
    447   return GetQuickInvokedMethod(inst, register_line, is_range);
    448 }
    449 
    450 bool MethodVerifier::Verify() {
    451   // If there aren't any instructions, make sure that's expected, then exit successfully.
    452   if (code_item_ == nullptr) {
    453     if ((method_access_flags_ & (kAccNative | kAccAbstract)) == 0) {
    454       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "zero-length code in concrete non-native method";
    455       return false;
    456     } else {
    457       return true;
    458     }
    459   }
    460   // Sanity-check the register counts. ins + locals = registers, so make sure that ins <= registers.
    461   if (code_item_->ins_size_ > code_item_->registers_size_) {
    462     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad register counts (ins=" << code_item_->ins_size_
    463                                       << " regs=" << code_item_->registers_size_;
    464     return false;
    465   }
    466   // Allocate and initialize an array to hold instruction data.
    467   insn_flags_.reset(new InstructionFlags[code_item_->insns_size_in_code_units_]());
    468   // Run through the instructions and see if the width checks out.
    469   bool result = ComputeWidthsAndCountOps();
    470   // Flag instructions guarded by a "try" block and check exception handlers.
    471   result = result && ScanTryCatchBlocks();
    472   // Perform static instruction verification.
    473   result = result && VerifyInstructions();
    474   // Perform code-flow analysis and return.
    475   result = result && VerifyCodeFlow();
    476   // Compute information for compiler.
    477   if (result && Runtime::Current()->IsCompiler()) {
    478     result = Runtime::Current()->GetCompilerCallbacks()->MethodVerified(this);
    479   }
    480   return result;
    481 }
    482 
    483 std::ostream& MethodVerifier::Fail(VerifyError error) {
    484   switch (error) {
    485     case VERIFY_ERROR_NO_CLASS:
    486     case VERIFY_ERROR_NO_FIELD:
    487     case VERIFY_ERROR_NO_METHOD:
    488     case VERIFY_ERROR_ACCESS_CLASS:
    489     case VERIFY_ERROR_ACCESS_FIELD:
    490     case VERIFY_ERROR_ACCESS_METHOD:
    491     case VERIFY_ERROR_INSTANTIATION:
    492     case VERIFY_ERROR_CLASS_CHANGE:
    493       if (Runtime::Current()->IsCompiler() || !can_load_classes_) {
    494         // If we're optimistically running verification at compile time, turn NO_xxx, ACCESS_xxx,
    495         // class change and instantiation errors into soft verification errors so that we re-verify
    496         // at runtime. We may fail to find or to agree on access because of not yet available class
    497         // loaders, or class loaders that will differ at runtime. In these cases, we don't want to
    498         // affect the soundness of the code being compiled. Instead, the generated code runs "slow
    499         // paths" that dynamically perform the verification and cause the behavior to be that akin
    500         // to an interpreter.
    501         error = VERIFY_ERROR_BAD_CLASS_SOFT;
    502       } else {
    503         // If we fail again at runtime, mark that this instruction would throw and force this
    504         // method to be executed using the interpreter with checks.
    505         have_pending_runtime_throw_failure_ = true;
    506       }
    507       break;
    508       // Indication that verification should be retried at runtime.
    509     case VERIFY_ERROR_BAD_CLASS_SOFT:
    510       if (!allow_soft_failures_) {
    511         have_pending_hard_failure_ = true;
    512       }
    513       break;
    514       // Hard verification failures at compile time will still fail at runtime, so the class is
    515       // marked as rejected to prevent it from being compiled.
    516     case VERIFY_ERROR_BAD_CLASS_HARD: {
    517       if (Runtime::Current()->IsCompiler()) {
    518         ClassReference ref(dex_file_, dex_file_->GetIndexForClassDef(*class_def_));
    519         Runtime::Current()->GetCompilerCallbacks()->ClassRejected(ref);
    520       }
    521       have_pending_hard_failure_ = true;
    522       break;
    523     }
    524   }
    525   failures_.push_back(error);
    526   std::string location(StringPrintf("%s: [0x%X] ", PrettyMethod(dex_method_idx_, *dex_file_).c_str(),
    527                                     work_insn_idx_));
    528   std::ostringstream* failure_message = new std::ostringstream(location, std::ostringstream::ate);
    529   failure_messages_.push_back(failure_message);
    530   return *failure_message;
    531 }
    532 
    533 std::ostream& MethodVerifier::LogVerifyInfo() {
    534   return info_messages_ << "VFY: " << PrettyMethod(dex_method_idx_, *dex_file_)
    535                         << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
    536 }
    537 
    538 void MethodVerifier::PrependToLastFailMessage(std::string prepend) {
    539   size_t failure_num = failure_messages_.size();
    540   DCHECK_NE(failure_num, 0U);
    541   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    542   prepend += last_fail_message->str();
    543   failure_messages_[failure_num - 1] = new std::ostringstream(prepend, std::ostringstream::ate);
    544   delete last_fail_message;
    545 }
    546 
    547 void MethodVerifier::AppendToLastFailMessage(std::string append) {
    548   size_t failure_num = failure_messages_.size();
    549   DCHECK_NE(failure_num, 0U);
    550   std::ostringstream* last_fail_message = failure_messages_[failure_num - 1];
    551   (*last_fail_message) << append;
    552 }
    553 
    554 bool MethodVerifier::ComputeWidthsAndCountOps() {
    555   const uint16_t* insns = code_item_->insns_;
    556   size_t insns_size = code_item_->insns_size_in_code_units_;
    557   const Instruction* inst = Instruction::At(insns);
    558   size_t new_instance_count = 0;
    559   size_t monitor_enter_count = 0;
    560   size_t dex_pc = 0;
    561 
    562   while (dex_pc < insns_size) {
    563     Instruction::Code opcode = inst->Opcode();
    564     switch (opcode) {
    565       case Instruction::APUT_OBJECT:
    566       case Instruction::CHECK_CAST:
    567         has_check_casts_ = true;
    568         break;
    569       case Instruction::INVOKE_VIRTUAL:
    570       case Instruction::INVOKE_VIRTUAL_RANGE:
    571       case Instruction::INVOKE_INTERFACE:
    572       case Instruction::INVOKE_INTERFACE_RANGE:
    573         has_virtual_or_interface_invokes_ = true;
    574         break;
    575       case Instruction::MONITOR_ENTER:
    576         monitor_enter_count++;
    577         break;
    578       case Instruction::NEW_INSTANCE:
    579         new_instance_count++;
    580         break;
    581       default:
    582         break;
    583     }
    584     size_t inst_size = inst->SizeInCodeUnits();
    585     insn_flags_[dex_pc].SetLengthInCodeUnits(inst_size);
    586     dex_pc += inst_size;
    587     inst = inst->Next();
    588   }
    589 
    590   if (dex_pc != insns_size) {
    591     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "code did not end where expected ("
    592                                       << dex_pc << " vs. " << insns_size << ")";
    593     return false;
    594   }
    595 
    596   new_instance_count_ = new_instance_count;
    597   monitor_enter_count_ = monitor_enter_count;
    598   return true;
    599 }
    600 
    601 bool MethodVerifier::ScanTryCatchBlocks() {
    602   uint32_t tries_size = code_item_->tries_size_;
    603   if (tries_size == 0) {
    604     return true;
    605   }
    606   uint32_t insns_size = code_item_->insns_size_in_code_units_;
    607   const DexFile::TryItem* tries = DexFile::GetTryItems(*code_item_, 0);
    608 
    609   for (uint32_t idx = 0; idx < tries_size; idx++) {
    610     const DexFile::TryItem* try_item = &tries[idx];
    611     uint32_t start = try_item->start_addr_;
    612     uint32_t end = start + try_item->insn_count_;
    613     if ((start >= end) || (start >= insns_size) || (end > insns_size)) {
    614       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad exception entry: startAddr=" << start
    615                                         << " endAddr=" << end << " (size=" << insns_size << ")";
    616       return false;
    617     }
    618     if (!insn_flags_[start].IsOpcode()) {
    619       Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    620           << "'try' block starts inside an instruction (" << start << ")";
    621       return false;
    622     }
    623     for (uint32_t dex_pc = start; dex_pc < end;
    624         dex_pc += insn_flags_[dex_pc].GetLengthInCodeUnits()) {
    625       insn_flags_[dex_pc].SetInTry();
    626     }
    627   }
    628   // Iterate over each of the handlers to verify target addresses.
    629   const byte* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
    630   uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
    631   ClassLinker* linker = Runtime::Current()->GetClassLinker();
    632   for (uint32_t idx = 0; idx < handlers_size; idx++) {
    633     CatchHandlerIterator iterator(handlers_ptr);
    634     for (; iterator.HasNext(); iterator.Next()) {
    635       uint32_t dex_pc= iterator.GetHandlerAddress();
    636       if (!insn_flags_[dex_pc].IsOpcode()) {
    637         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    638             << "exception handler starts at bad address (" << dex_pc << ")";
    639         return false;
    640       }
    641       insn_flags_[dex_pc].SetBranchTarget();
    642       // Ensure exception types are resolved so that they don't need resolution to be delivered,
    643       // unresolved exception types will be ignored by exception delivery
    644       if (iterator.GetHandlerTypeIndex() != DexFile::kDexNoIndex16) {
    645         mirror::Class* exception_type = linker->ResolveType(*dex_file_,
    646                                                             iterator.GetHandlerTypeIndex(),
    647                                                             *dex_cache_, *class_loader_);
    648         if (exception_type == nullptr) {
    649           DCHECK(Thread::Current()->IsExceptionPending());
    650           Thread::Current()->ClearException();
    651         }
    652       }
    653     }
    654     handlers_ptr = iterator.EndDataPointer();
    655   }
    656   return true;
    657 }
    658 
    659 bool MethodVerifier::VerifyInstructions() {
    660   const Instruction* inst = Instruction::At(code_item_->insns_);
    661 
    662   /* Flag the start of the method as a branch target, and a GC point due to stack overflow errors */
    663   insn_flags_[0].SetBranchTarget();
    664   insn_flags_[0].SetCompileTimeInfoPoint();
    665 
    666   uint32_t insns_size = code_item_->insns_size_in_code_units_;
    667   for (uint32_t dex_pc = 0; dex_pc < insns_size;) {
    668     if (!VerifyInstruction(inst, dex_pc)) {
    669       DCHECK_NE(failures_.size(), 0U);
    670       return false;
    671     }
    672     /* Flag instructions that are garbage collection points */
    673     // All invoke points are marked as "Throw" points already.
    674     // We are relying on this to also count all the invokes as interesting.
    675     if (inst->IsBranch() || inst->IsSwitch() || inst->IsThrow()) {
    676       insn_flags_[dex_pc].SetCompileTimeInfoPoint();
    677     } else if (inst->IsReturn()) {
    678       insn_flags_[dex_pc].SetCompileTimeInfoPointAndReturn();
    679     }
    680     dex_pc += inst->SizeInCodeUnits();
    681     inst = inst->Next();
    682   }
    683   return true;
    684 }
    685 
    686 bool MethodVerifier::VerifyInstruction(const Instruction* inst, uint32_t code_offset) {
    687   bool result = true;
    688   switch (inst->GetVerifyTypeArgumentA()) {
    689     case Instruction::kVerifyRegA:
    690       result = result && CheckRegisterIndex(inst->VRegA());
    691       break;
    692     case Instruction::kVerifyRegAWide:
    693       result = result && CheckWideRegisterIndex(inst->VRegA());
    694       break;
    695   }
    696   switch (inst->GetVerifyTypeArgumentB()) {
    697     case Instruction::kVerifyRegB:
    698       result = result && CheckRegisterIndex(inst->VRegB());
    699       break;
    700     case Instruction::kVerifyRegBField:
    701       result = result && CheckFieldIndex(inst->VRegB());
    702       break;
    703     case Instruction::kVerifyRegBMethod:
    704       result = result && CheckMethodIndex(inst->VRegB());
    705       break;
    706     case Instruction::kVerifyRegBNewInstance:
    707       result = result && CheckNewInstance(inst->VRegB());
    708       break;
    709     case Instruction::kVerifyRegBString:
    710       result = result && CheckStringIndex(inst->VRegB());
    711       break;
    712     case Instruction::kVerifyRegBType:
    713       result = result && CheckTypeIndex(inst->VRegB());
    714       break;
    715     case Instruction::kVerifyRegBWide:
    716       result = result && CheckWideRegisterIndex(inst->VRegB());
    717       break;
    718   }
    719   switch (inst->GetVerifyTypeArgumentC()) {
    720     case Instruction::kVerifyRegC:
    721       result = result && CheckRegisterIndex(inst->VRegC());
    722       break;
    723     case Instruction::kVerifyRegCField:
    724       result = result && CheckFieldIndex(inst->VRegC());
    725       break;
    726     case Instruction::kVerifyRegCNewArray:
    727       result = result && CheckNewArray(inst->VRegC());
    728       break;
    729     case Instruction::kVerifyRegCType:
    730       result = result && CheckTypeIndex(inst->VRegC());
    731       break;
    732     case Instruction::kVerifyRegCWide:
    733       result = result && CheckWideRegisterIndex(inst->VRegC());
    734       break;
    735   }
    736   switch (inst->GetVerifyExtraFlags()) {
    737     case Instruction::kVerifyArrayData:
    738       result = result && CheckArrayData(code_offset);
    739       break;
    740     case Instruction::kVerifyBranchTarget:
    741       result = result && CheckBranchTarget(code_offset);
    742       break;
    743     case Instruction::kVerifySwitchTargets:
    744       result = result && CheckSwitchTargets(code_offset);
    745       break;
    746     case Instruction::kVerifyVarArgNonZero:
    747       // Fall-through.
    748     case Instruction::kVerifyVarArg: {
    749       if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgNonZero && inst->VRegA() <= 0) {
    750         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
    751                                              "non-range invoke";
    752         return false;
    753       }
    754       uint32_t args[Instruction::kMaxVarArgRegs];
    755       inst->GetVarArgs(args);
    756       result = result && CheckVarArgRegs(inst->VRegA(), args);
    757       break;
    758     }
    759     case Instruction::kVerifyVarArgRangeNonZero:
    760       // Fall-through.
    761     case Instruction::kVerifyVarArgRange:
    762       if (inst->GetVerifyExtraFlags() == Instruction::kVerifyVarArgRangeNonZero &&
    763           inst->VRegA() <= 0) {
    764         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << inst->VRegA() << ") in "
    765                                              "range invoke";
    766         return false;
    767       }
    768       result = result && CheckVarArgRangeRegs(inst->VRegA(), inst->VRegC());
    769       break;
    770     case Instruction::kVerifyError:
    771       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected opcode " << inst->Name();
    772       result = false;
    773       break;
    774   }
    775   if (inst->GetVerifyIsRuntimeOnly() && Runtime::Current()->IsCompiler() && !verify_to_dump_) {
    776     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "opcode only expected at runtime " << inst->Name();
    777     result = false;
    778   }
    779   return result;
    780 }
    781 
    782 bool MethodVerifier::CheckRegisterIndex(uint32_t idx) {
    783   if (idx >= code_item_->registers_size_) {
    784     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register index out of range (" << idx << " >= "
    785                                       << code_item_->registers_size_ << ")";
    786     return false;
    787   }
    788   return true;
    789 }
    790 
    791 bool MethodVerifier::CheckWideRegisterIndex(uint32_t idx) {
    792   if (idx + 1 >= code_item_->registers_size_) {
    793     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "wide register index out of range (" << idx
    794                                       << "+1 >= " << code_item_->registers_size_ << ")";
    795     return false;
    796   }
    797   return true;
    798 }
    799 
    800 bool MethodVerifier::CheckFieldIndex(uint32_t idx) {
    801   if (idx >= dex_file_->GetHeader().field_ids_size_) {
    802     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad field index " << idx << " (max "
    803                                       << dex_file_->GetHeader().field_ids_size_ << ")";
    804     return false;
    805   }
    806   return true;
    807 }
    808 
    809 bool MethodVerifier::CheckMethodIndex(uint32_t idx) {
    810   if (idx >= dex_file_->GetHeader().method_ids_size_) {
    811     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad method index " << idx << " (max "
    812                                       << dex_file_->GetHeader().method_ids_size_ << ")";
    813     return false;
    814   }
    815   return true;
    816 }
    817 
    818 bool MethodVerifier::CheckNewInstance(uint32_t idx) {
    819   if (idx >= dex_file_->GetHeader().type_ids_size_) {
    820     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
    821                                       << dex_file_->GetHeader().type_ids_size_ << ")";
    822     return false;
    823   }
    824   // We don't need the actual class, just a pointer to the class name.
    825   const char* descriptor = dex_file_->StringByTypeIdx(idx);
    826   if (descriptor[0] != 'L') {
    827     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "can't call new-instance on type '" << descriptor << "'";
    828     return false;
    829   }
    830   return true;
    831 }
    832 
    833 bool MethodVerifier::CheckStringIndex(uint32_t idx) {
    834   if (idx >= dex_file_->GetHeader().string_ids_size_) {
    835     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad string index " << idx << " (max "
    836                                       << dex_file_->GetHeader().string_ids_size_ << ")";
    837     return false;
    838   }
    839   return true;
    840 }
    841 
    842 bool MethodVerifier::CheckTypeIndex(uint32_t idx) {
    843   if (idx >= dex_file_->GetHeader().type_ids_size_) {
    844     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
    845                                       << dex_file_->GetHeader().type_ids_size_ << ")";
    846     return false;
    847   }
    848   return true;
    849 }
    850 
    851 bool MethodVerifier::CheckNewArray(uint32_t idx) {
    852   if (idx >= dex_file_->GetHeader().type_ids_size_) {
    853     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad type index " << idx << " (max "
    854                                       << dex_file_->GetHeader().type_ids_size_ << ")";
    855     return false;
    856   }
    857   int bracket_count = 0;
    858   const char* descriptor = dex_file_->StringByTypeIdx(idx);
    859   const char* cp = descriptor;
    860   while (*cp++ == '[') {
    861     bracket_count++;
    862   }
    863   if (bracket_count == 0) {
    864     /* The given class must be an array type. */
    865     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    866         << "can't new-array class '" << descriptor << "' (not an array)";
    867     return false;
    868   } else if (bracket_count > 255) {
    869     /* It is illegal to create an array of more than 255 dimensions. */
    870     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
    871         << "can't new-array class '" << descriptor << "' (exceeds limit)";
    872     return false;
    873   }
    874   return true;
    875 }
    876 
    877 bool MethodVerifier::CheckArrayData(uint32_t cur_offset) {
    878   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
    879   const uint16_t* insns = code_item_->insns_ + cur_offset;
    880   const uint16_t* array_data;
    881   int32_t array_data_offset;
    882 
    883   DCHECK_LT(cur_offset, insn_count);
    884   /* make sure the start of the array data table is in range */
    885   array_data_offset = insns[1] | (((int32_t) insns[2]) << 16);
    886   if ((int32_t) cur_offset + array_data_offset < 0 ||
    887       cur_offset + array_data_offset + 2 >= insn_count) {
    888     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data start: at " << cur_offset
    889                                       << ", data offset " << array_data_offset
    890                                       << ", count " << insn_count;
    891     return false;
    892   }
    893   /* offset to array data table is a relative branch-style offset */
    894   array_data = insns + array_data_offset;
    895   /* make sure the table is 32-bit aligned */
    896   if ((reinterpret_cast<uintptr_t>(array_data) & 0x03) != 0) {
    897     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned array data table: at " << cur_offset
    898                                       << ", data offset " << array_data_offset;
    899     return false;
    900   }
    901   uint32_t value_width = array_data[1];
    902   uint32_t value_count = *reinterpret_cast<const uint32_t*>(&array_data[2]);
    903   uint32_t table_size = 4 + (value_width * value_count + 1) / 2;
    904   /* make sure the end of the switch is in range */
    905   if (cur_offset + array_data_offset + table_size > insn_count) {
    906     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid array data end: at " << cur_offset
    907                                       << ", data offset " << array_data_offset << ", end "
    908                                       << cur_offset + array_data_offset + table_size
    909                                       << ", count " << insn_count;
    910     return false;
    911   }
    912   return true;
    913 }
    914 
    915 bool MethodVerifier::CheckBranchTarget(uint32_t cur_offset) {
    916   int32_t offset;
    917   bool isConditional, selfOkay;
    918   if (!GetBranchOffset(cur_offset, &offset, &isConditional, &selfOkay)) {
    919     return false;
    920   }
    921   if (!selfOkay && offset == 0) {
    922     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch offset of zero not allowed at"
    923                                       << reinterpret_cast<void*>(cur_offset);
    924     return false;
    925   }
    926   // Check for 32-bit overflow. This isn't strictly necessary if we can depend on the runtime
    927   // to have identical "wrap-around" behavior, but it's unwise to depend on that.
    928   if (((int64_t) cur_offset + (int64_t) offset) != (int64_t) (cur_offset + offset)) {
    929     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "branch target overflow "
    930                                       << reinterpret_cast<void*>(cur_offset) << " +" << offset;
    931     return false;
    932   }
    933   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
    934   int32_t abs_offset = cur_offset + offset;
    935   if (abs_offset < 0 ||
    936       (uint32_t) abs_offset >= insn_count ||
    937       !insn_flags_[abs_offset].IsOpcode()) {
    938     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid branch target " << offset << " (-> "
    939                                       << reinterpret_cast<void*>(abs_offset) << ") at "
    940                                       << reinterpret_cast<void*>(cur_offset);
    941     return false;
    942   }
    943   insn_flags_[abs_offset].SetBranchTarget();
    944   return true;
    945 }
    946 
    947 bool MethodVerifier::GetBranchOffset(uint32_t cur_offset, int32_t* pOffset, bool* pConditional,
    948                                   bool* selfOkay) {
    949   const uint16_t* insns = code_item_->insns_ + cur_offset;
    950   *pConditional = false;
    951   *selfOkay = false;
    952   switch (*insns & 0xff) {
    953     case Instruction::GOTO:
    954       *pOffset = ((int16_t) *insns) >> 8;
    955       break;
    956     case Instruction::GOTO_32:
    957       *pOffset = insns[1] | (((uint32_t) insns[2]) << 16);
    958       *selfOkay = true;
    959       break;
    960     case Instruction::GOTO_16:
    961       *pOffset = (int16_t) insns[1];
    962       break;
    963     case Instruction::IF_EQ:
    964     case Instruction::IF_NE:
    965     case Instruction::IF_LT:
    966     case Instruction::IF_GE:
    967     case Instruction::IF_GT:
    968     case Instruction::IF_LE:
    969     case Instruction::IF_EQZ:
    970     case Instruction::IF_NEZ:
    971     case Instruction::IF_LTZ:
    972     case Instruction::IF_GEZ:
    973     case Instruction::IF_GTZ:
    974     case Instruction::IF_LEZ:
    975       *pOffset = (int16_t) insns[1];
    976       *pConditional = true;
    977       break;
    978     default:
    979       return false;
    980       break;
    981   }
    982   return true;
    983 }
    984 
    985 bool MethodVerifier::CheckSwitchTargets(uint32_t cur_offset) {
    986   const uint32_t insn_count = code_item_->insns_size_in_code_units_;
    987   DCHECK_LT(cur_offset, insn_count);
    988   const uint16_t* insns = code_item_->insns_ + cur_offset;
    989   /* make sure the start of the switch is in range */
    990   int32_t switch_offset = insns[1] | ((int32_t) insns[2]) << 16;
    991   if ((int32_t) cur_offset + switch_offset < 0 || cur_offset + switch_offset + 2 >= insn_count) {
    992     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch start: at " << cur_offset
    993                                       << ", switch offset " << switch_offset
    994                                       << ", count " << insn_count;
    995     return false;
    996   }
    997   /* offset to switch table is a relative branch-style offset */
    998   const uint16_t* switch_insns = insns + switch_offset;
    999   /* make sure the table is 32-bit aligned */
   1000   if ((reinterpret_cast<uintptr_t>(switch_insns) & 0x03) != 0) {
   1001     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unaligned switch table: at " << cur_offset
   1002                                       << ", switch offset " << switch_offset;
   1003     return false;
   1004   }
   1005   uint32_t switch_count = switch_insns[1];
   1006   int32_t keys_offset, targets_offset;
   1007   uint16_t expected_signature;
   1008   if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
   1009     /* 0=sig, 1=count, 2/3=firstKey */
   1010     targets_offset = 4;
   1011     keys_offset = -1;
   1012     expected_signature = Instruction::kPackedSwitchSignature;
   1013   } else {
   1014     /* 0=sig, 1=count, 2..count*2 = keys */
   1015     keys_offset = 2;
   1016     targets_offset = 2 + 2 * switch_count;
   1017     expected_signature = Instruction::kSparseSwitchSignature;
   1018   }
   1019   uint32_t table_size = targets_offset + switch_count * 2;
   1020   if (switch_insns[0] != expected_signature) {
   1021     Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   1022         << StringPrintf("wrong signature for switch table (%x, wanted %x)",
   1023                         switch_insns[0], expected_signature);
   1024     return false;
   1025   }
   1026   /* make sure the end of the switch is in range */
   1027   if (cur_offset + switch_offset + table_size > (uint32_t) insn_count) {
   1028     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch end: at " << cur_offset
   1029                                       << ", switch offset " << switch_offset
   1030                                       << ", end " << (cur_offset + switch_offset + table_size)
   1031                                       << ", count " << insn_count;
   1032     return false;
   1033   }
   1034   /* for a sparse switch, verify the keys are in ascending order */
   1035   if (keys_offset > 0 && switch_count > 1) {
   1036     int32_t last_key = switch_insns[keys_offset] | (switch_insns[keys_offset + 1] << 16);
   1037     for (uint32_t targ = 1; targ < switch_count; targ++) {
   1038       int32_t key = (int32_t) switch_insns[keys_offset + targ * 2] |
   1039                     (int32_t) (switch_insns[keys_offset + targ * 2 + 1] << 16);
   1040       if (key <= last_key) {
   1041         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid packed switch: last key=" << last_key
   1042                                           << ", this=" << key;
   1043         return false;
   1044       }
   1045       last_key = key;
   1046     }
   1047   }
   1048   /* verify each switch target */
   1049   for (uint32_t targ = 0; targ < switch_count; targ++) {
   1050     int32_t offset = (int32_t) switch_insns[targets_offset + targ * 2] |
   1051                      (int32_t) (switch_insns[targets_offset + targ * 2 + 1] << 16);
   1052     int32_t abs_offset = cur_offset + offset;
   1053     if (abs_offset < 0 ||
   1054         abs_offset >= (int32_t) insn_count ||
   1055         !insn_flags_[abs_offset].IsOpcode()) {
   1056       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid switch target " << offset
   1057                                         << " (-> " << reinterpret_cast<void*>(abs_offset) << ") at "
   1058                                         << reinterpret_cast<void*>(cur_offset)
   1059                                         << "[" << targ << "]";
   1060       return false;
   1061     }
   1062     insn_flags_[abs_offset].SetBranchTarget();
   1063   }
   1064   return true;
   1065 }
   1066 
   1067 bool MethodVerifier::CheckVarArgRegs(uint32_t vA, uint32_t arg[]) {
   1068   if (vA > Instruction::kMaxVarArgRegs) {
   1069     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid arg count (" << vA << ") in non-range invoke)";
   1070     return false;
   1071   }
   1072   uint16_t registers_size = code_item_->registers_size_;
   1073   for (uint32_t idx = 0; idx < vA; idx++) {
   1074     if (arg[idx] >= registers_size) {
   1075       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index (" << arg[idx]
   1076                                         << ") in non-range invoke (>= " << registers_size << ")";
   1077       return false;
   1078     }
   1079   }
   1080 
   1081   return true;
   1082 }
   1083 
   1084 bool MethodVerifier::CheckVarArgRangeRegs(uint32_t vA, uint32_t vC) {
   1085   uint16_t registers_size = code_item_->registers_size_;
   1086   // vA/vC are unsigned 8-bit/16-bit quantities for /range instructions, so there's no risk of
   1087   // integer overflow when adding them here.
   1088   if (vA + vC > registers_size) {
   1089     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid reg index " << vA << "+" << vC
   1090                                       << " in range invoke (> " << registers_size << ")";
   1091     return false;
   1092   }
   1093   return true;
   1094 }
   1095 
   1096 bool MethodVerifier::VerifyCodeFlow() {
   1097   uint16_t registers_size = code_item_->registers_size_;
   1098   uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1099 
   1100   if (registers_size * insns_size > 4*1024*1024) {
   1101     LOG(WARNING) << "warning: method is huge (regs=" << registers_size
   1102                  << " insns_size=" << insns_size << ")";
   1103   }
   1104   /* Create and initialize table holding register status */
   1105   reg_table_.Init(kTrackCompilerInterestPoints,
   1106                   insn_flags_.get(),
   1107                   insns_size,
   1108                   registers_size,
   1109                   this);
   1110 
   1111 
   1112   work_line_.reset(RegisterLine::Create(registers_size, this));
   1113   saved_line_.reset(RegisterLine::Create(registers_size, this));
   1114 
   1115   /* Initialize register types of method arguments. */
   1116   if (!SetTypesFromSignature()) {
   1117     DCHECK_NE(failures_.size(), 0U);
   1118     std::string prepend("Bad signature in ");
   1119     prepend += PrettyMethod(dex_method_idx_, *dex_file_);
   1120     PrependToLastFailMessage(prepend);
   1121     return false;
   1122   }
   1123   /* Perform code flow verification. */
   1124   if (!CodeFlowVerifyMethod()) {
   1125     DCHECK_NE(failures_.size(), 0U);
   1126     return false;
   1127   }
   1128   return true;
   1129 }
   1130 
   1131 std::ostream& MethodVerifier::DumpFailures(std::ostream& os) {
   1132   DCHECK_EQ(failures_.size(), failure_messages_.size());
   1133   for (size_t i = 0; i < failures_.size(); ++i) {
   1134       os << failure_messages_[i]->str() << "\n";
   1135   }
   1136   return os;
   1137 }
   1138 
   1139 extern "C" void MethodVerifierGdbDump(MethodVerifier* v)
   1140     SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   1141   v->Dump(std::cerr);
   1142 }
   1143 
   1144 void MethodVerifier::Dump(std::ostream& os) {
   1145   if (code_item_ == nullptr) {
   1146     os << "Native method\n";
   1147     return;
   1148   }
   1149   {
   1150     os << "Register Types:\n";
   1151     Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
   1152     std::ostream indent_os(&indent_filter);
   1153     reg_types_.Dump(indent_os);
   1154   }
   1155   os << "Dumping instructions and register lines:\n";
   1156   Indenter indent_filter(os.rdbuf(), kIndentChar, kIndentBy1Count);
   1157   std::ostream indent_os(&indent_filter);
   1158   const Instruction* inst = Instruction::At(code_item_->insns_);
   1159   for (size_t dex_pc = 0; dex_pc < code_item_->insns_size_in_code_units_;
   1160       dex_pc += insn_flags_[dex_pc].GetLengthInCodeUnits()) {
   1161     RegisterLine* reg_line = reg_table_.GetLine(dex_pc);
   1162     if (reg_line != nullptr) {
   1163       indent_os << reg_line->Dump() << "\n";
   1164     }
   1165     indent_os << StringPrintf("0x%04zx", dex_pc) << ": " << insn_flags_[dex_pc].ToString() << " ";
   1166     const bool kDumpHexOfInstruction = false;
   1167     if (kDumpHexOfInstruction) {
   1168       indent_os << inst->DumpHex(5) << " ";
   1169     }
   1170     indent_os << inst->DumpString(dex_file_) << "\n";
   1171     inst = inst->Next();
   1172   }
   1173 }
   1174 
   1175 static bool IsPrimitiveDescriptor(char descriptor) {
   1176   switch (descriptor) {
   1177     case 'I':
   1178     case 'C':
   1179     case 'S':
   1180     case 'B':
   1181     case 'Z':
   1182     case 'F':
   1183     case 'D':
   1184     case 'J':
   1185       return true;
   1186     default:
   1187       return false;
   1188   }
   1189 }
   1190 
   1191 bool MethodVerifier::SetTypesFromSignature() {
   1192   RegisterLine* reg_line = reg_table_.GetLine(0);
   1193   int arg_start = code_item_->registers_size_ - code_item_->ins_size_;
   1194   size_t expected_args = code_item_->ins_size_;   /* long/double count as two */
   1195 
   1196   DCHECK_GE(arg_start, 0);      /* should have been verified earlier */
   1197   // Include the "this" pointer.
   1198   size_t cur_arg = 0;
   1199   if (!IsStatic()) {
   1200     // If this is a constructor for a class other than java.lang.Object, mark the first ("this")
   1201     // argument as uninitialized. This restricts field access until the superclass constructor is
   1202     // called.
   1203     RegType& declaring_class = GetDeclaringClass();
   1204     if (IsConstructor() && !declaring_class.IsJavaLangObject()) {
   1205       reg_line->SetRegisterType(arg_start + cur_arg,
   1206                                 reg_types_.UninitializedThisArgument(declaring_class));
   1207     } else {
   1208       reg_line->SetRegisterType(arg_start + cur_arg, declaring_class);
   1209     }
   1210     cur_arg++;
   1211   }
   1212 
   1213   const DexFile::ProtoId& proto_id =
   1214       dex_file_->GetMethodPrototype(dex_file_->GetMethodId(dex_method_idx_));
   1215   DexFileParameterIterator iterator(*dex_file_, proto_id);
   1216 
   1217   for (; iterator.HasNext(); iterator.Next()) {
   1218     const char* descriptor = iterator.GetDescriptor();
   1219     if (descriptor == nullptr) {
   1220       LOG(FATAL) << "Null descriptor";
   1221     }
   1222     if (cur_arg >= expected_args) {
   1223       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1224                                         << " args, found more (" << descriptor << ")";
   1225       return false;
   1226     }
   1227     switch (descriptor[0]) {
   1228       case 'L':
   1229       case '[':
   1230         // We assume that reference arguments are initialized. The only way it could be otherwise
   1231         // (assuming the caller was verified) is if the current method is <init>, but in that case
   1232         // it's effectively considered initialized the instant we reach here (in the sense that we
   1233         // can return without doing anything or call virtual methods).
   1234         {
   1235           RegType& reg_type = ResolveClassAndCheckAccess(iterator.GetTypeIdx());
   1236           if (!reg_type.IsNonZeroReferenceTypes()) {
   1237             DCHECK(HasFailures());
   1238             return false;
   1239           }
   1240           reg_line->SetRegisterType(arg_start + cur_arg, reg_type);
   1241         }
   1242         break;
   1243       case 'Z':
   1244         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Boolean());
   1245         break;
   1246       case 'C':
   1247         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Char());
   1248         break;
   1249       case 'B':
   1250         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Byte());
   1251         break;
   1252       case 'I':
   1253         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Integer());
   1254         break;
   1255       case 'S':
   1256         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Short());
   1257         break;
   1258       case 'F':
   1259         reg_line->SetRegisterType(arg_start + cur_arg, reg_types_.Float());
   1260         break;
   1261       case 'J':
   1262       case 'D': {
   1263         if (cur_arg + 1 >= expected_args) {
   1264           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1265               << " args, found more (" << descriptor << ")";
   1266           return false;
   1267         }
   1268 
   1269         RegType& lo_half = descriptor[0] == 'J' ? reg_types_.LongLo() : reg_types_.DoubleLo();
   1270         RegType& hi_half = descriptor[0] == 'J' ? reg_types_.LongHi() : reg_types_.DoubleHi();
   1271         reg_line->SetRegisterTypeWide(arg_start + cur_arg, lo_half, hi_half);
   1272         cur_arg++;
   1273         break;
   1274       }
   1275       default:
   1276         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected signature type char '"
   1277                                           << descriptor << "'";
   1278         return false;
   1279     }
   1280     cur_arg++;
   1281   }
   1282   if (cur_arg != expected_args) {
   1283     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected " << expected_args
   1284                                       << " arguments, found " << cur_arg;
   1285     return false;
   1286   }
   1287   const char* descriptor = dex_file_->GetReturnTypeDescriptor(proto_id);
   1288   // Validate return type. We don't do the type lookup; just want to make sure that it has the right
   1289   // format. Only major difference from the method argument format is that 'V' is supported.
   1290   bool result;
   1291   if (IsPrimitiveDescriptor(descriptor[0]) || descriptor[0] == 'V') {
   1292     result = descriptor[1] == '\0';
   1293   } else if (descriptor[0] == '[') {  // single/multi-dimensional array of object/primitive
   1294     size_t i = 0;
   1295     do {
   1296       i++;
   1297     } while (descriptor[i] == '[');  // process leading [
   1298     if (descriptor[i] == 'L') {  // object array
   1299       do {
   1300         i++;  // find closing ;
   1301       } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1302       result = descriptor[i] == ';';
   1303     } else {  // primitive array
   1304       result = IsPrimitiveDescriptor(descriptor[i]) && descriptor[i + 1] == '\0';
   1305     }
   1306   } else if (descriptor[0] == 'L') {
   1307     // could be more thorough here, but shouldn't be required
   1308     size_t i = 0;
   1309     do {
   1310       i++;
   1311     } while (descriptor[i] != ';' && descriptor[i] != '\0');
   1312     result = descriptor[i] == ';';
   1313   } else {
   1314     result = false;
   1315   }
   1316   if (!result) {
   1317     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected char in return type descriptor '"
   1318                                       << descriptor << "'";
   1319   }
   1320   return result;
   1321 }
   1322 
   1323 bool MethodVerifier::CodeFlowVerifyMethod() {
   1324   const uint16_t* insns = code_item_->insns_;
   1325   const uint32_t insns_size = code_item_->insns_size_in_code_units_;
   1326 
   1327   /* Begin by marking the first instruction as "changed". */
   1328   insn_flags_[0].SetChanged();
   1329   uint32_t start_guess = 0;
   1330 
   1331   /* Continue until no instructions are marked "changed". */
   1332   while (true) {
   1333     // Find the first marked one. Use "start_guess" as a way to find one quickly.
   1334     uint32_t insn_idx = start_guess;
   1335     for (; insn_idx < insns_size; insn_idx++) {
   1336       if (insn_flags_[insn_idx].IsChanged())
   1337         break;
   1338     }
   1339     if (insn_idx == insns_size) {
   1340       if (start_guess != 0) {
   1341         /* try again, starting from the top */
   1342         start_guess = 0;
   1343         continue;
   1344       } else {
   1345         /* all flags are clear */
   1346         break;
   1347       }
   1348     }
   1349     // We carry the working set of registers from instruction to instruction. If this address can
   1350     // be the target of a branch (or throw) instruction, or if we're skipping around chasing
   1351     // "changed" flags, we need to load the set of registers from the table.
   1352     // Because we always prefer to continue on to the next instruction, we should never have a
   1353     // situation where we have a stray "changed" flag set on an instruction that isn't a branch
   1354     // target.
   1355     work_insn_idx_ = insn_idx;
   1356     if (insn_flags_[insn_idx].IsBranchTarget()) {
   1357       work_line_->CopyFromLine(reg_table_.GetLine(insn_idx));
   1358     } else if (kIsDebugBuild) {
   1359       /*
   1360        * Sanity check: retrieve the stored register line (assuming
   1361        * a full table) and make sure it actually matches.
   1362        */
   1363       RegisterLine* register_line = reg_table_.GetLine(insn_idx);
   1364       if (register_line != nullptr) {
   1365         if (work_line_->CompareLine(register_line) != 0) {
   1366           Dump(std::cout);
   1367           std::cout << info_messages_.str();
   1368           LOG(FATAL) << "work_line diverged in " << PrettyMethod(dex_method_idx_, *dex_file_)
   1369                      << "@" << reinterpret_cast<void*>(work_insn_idx_) << "\n"
   1370                      << " work_line=" << *work_line_ << "\n"
   1371                      << "  expected=" << *register_line;
   1372         }
   1373       }
   1374     }
   1375     if (!CodeFlowVerifyInstruction(&start_guess)) {
   1376       std::string prepend(PrettyMethod(dex_method_idx_, *dex_file_));
   1377       prepend += " failed to verify: ";
   1378       PrependToLastFailMessage(prepend);
   1379       return false;
   1380     }
   1381     /* Clear "changed" and mark as visited. */
   1382     insn_flags_[insn_idx].SetVisited();
   1383     insn_flags_[insn_idx].ClearChanged();
   1384   }
   1385 
   1386   if (gDebugVerify) {
   1387     /*
   1388      * Scan for dead code. There's nothing "evil" about dead code
   1389      * (besides the wasted space), but it indicates a flaw somewhere
   1390      * down the line, possibly in the verifier.
   1391      *
   1392      * If we've substituted "always throw" instructions into the stream,
   1393      * we are almost certainly going to have some dead code.
   1394      */
   1395     int dead_start = -1;
   1396     uint32_t insn_idx = 0;
   1397     for (; insn_idx < insns_size; insn_idx += insn_flags_[insn_idx].GetLengthInCodeUnits()) {
   1398       /*
   1399        * Switch-statement data doesn't get "visited" by scanner. It
   1400        * may or may not be preceded by a padding NOP (for alignment).
   1401        */
   1402       if (insns[insn_idx] == Instruction::kPackedSwitchSignature ||
   1403           insns[insn_idx] == Instruction::kSparseSwitchSignature ||
   1404           insns[insn_idx] == Instruction::kArrayDataSignature ||
   1405           (insns[insn_idx] == Instruction::NOP && (insn_idx + 1 < insns_size) &&
   1406            (insns[insn_idx + 1] == Instruction::kPackedSwitchSignature ||
   1407             insns[insn_idx + 1] == Instruction::kSparseSwitchSignature ||
   1408             insns[insn_idx + 1] == Instruction::kArrayDataSignature))) {
   1409         insn_flags_[insn_idx].SetVisited();
   1410       }
   1411 
   1412       if (!insn_flags_[insn_idx].IsVisited()) {
   1413         if (dead_start < 0)
   1414           dead_start = insn_idx;
   1415       } else if (dead_start >= 0) {
   1416         LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
   1417                         << "-" << reinterpret_cast<void*>(insn_idx - 1);
   1418         dead_start = -1;
   1419       }
   1420     }
   1421     if (dead_start >= 0) {
   1422       LogVerifyInfo() << "dead code " << reinterpret_cast<void*>(dead_start)
   1423                       << "-" << reinterpret_cast<void*>(insn_idx - 1);
   1424     }
   1425     // To dump the state of the verify after a method, do something like:
   1426     // if (PrettyMethod(dex_method_idx_, *dex_file_) ==
   1427     //     "boolean java.lang.String.equals(java.lang.Object)") {
   1428     //   LOG(INFO) << info_messages_.str();
   1429     // }
   1430   }
   1431   return true;
   1432 }
   1433 
   1434 bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
   1435   // If we're doing FindLocksAtDexPc, check whether we're at the dex pc we care about.
   1436   // We want the state _before_ the instruction, for the case where the dex pc we're
   1437   // interested in is itself a monitor-enter instruction (which is a likely place
   1438   // for a thread to be suspended).
   1439   if (monitor_enter_dex_pcs_ != nullptr && work_insn_idx_ == interesting_dex_pc_) {
   1440     monitor_enter_dex_pcs_->clear();  // The new work line is more accurate than the previous one.
   1441     for (size_t i = 0; i < work_line_->GetMonitorEnterCount(); ++i) {
   1442       monitor_enter_dex_pcs_->push_back(work_line_->GetMonitorEnterDexPc(i));
   1443     }
   1444   }
   1445 
   1446   /*
   1447    * Once we finish decoding the instruction, we need to figure out where
   1448    * we can go from here. There are three possible ways to transfer
   1449    * control to another statement:
   1450    *
   1451    * (1) Continue to the next instruction. Applies to all but
   1452    *     unconditional branches, method returns, and exception throws.
   1453    * (2) Branch to one or more possible locations. Applies to branches
   1454    *     and switch statements.
   1455    * (3) Exception handlers. Applies to any instruction that can
   1456    *     throw an exception that is handled by an encompassing "try"
   1457    *     block.
   1458    *
   1459    * We can also return, in which case there is no successor instruction
   1460    * from this point.
   1461    *
   1462    * The behavior can be determined from the opcode flags.
   1463    */
   1464   const uint16_t* insns = code_item_->insns_ + work_insn_idx_;
   1465   const Instruction* inst = Instruction::At(insns);
   1466   int opcode_flags = Instruction::FlagsOf(inst->Opcode());
   1467 
   1468   int32_t branch_target = 0;
   1469   bool just_set_result = false;
   1470   if (gDebugVerify) {
   1471     // Generate processing back trace to debug verifier
   1472     LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n"
   1473                     << *work_line_.get() << "\n";
   1474   }
   1475 
   1476   /*
   1477    * Make a copy of the previous register state. If the instruction
   1478    * can throw an exception, we will copy/merge this into the "catch"
   1479    * address rather than work_line, because we don't want the result
   1480    * from the "successful" code path (e.g. a check-cast that "improves"
   1481    * a type) to be visible to the exception handler.
   1482    */
   1483   if ((opcode_flags & Instruction::kThrow) != 0 && CurrentInsnFlags()->IsInTry()) {
   1484     saved_line_->CopyFromLine(work_line_.get());
   1485   } else if (kIsDebugBuild) {
   1486     saved_line_->FillWithGarbage();
   1487   }
   1488 
   1489 
   1490   // We need to ensure the work line is consistent while performing validation. When we spot a
   1491   // peephole pattern we compute a new line for either the fallthrough instruction or the
   1492   // branch target.
   1493   std::unique_ptr<RegisterLine> branch_line;
   1494   std::unique_ptr<RegisterLine> fallthrough_line;
   1495 
   1496   switch (inst->Opcode()) {
   1497     case Instruction::NOP:
   1498       /*
   1499        * A "pure" NOP has no effect on anything. Data tables start with
   1500        * a signature that looks like a NOP; if we see one of these in
   1501        * the course of executing code then we have a problem.
   1502        */
   1503       if (inst->VRegA_10x() != 0) {
   1504         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "encountered data table in instruction stream";
   1505       }
   1506       break;
   1507 
   1508     case Instruction::MOVE:
   1509       work_line_->CopyRegister1(inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategory1nr);
   1510       break;
   1511     case Instruction::MOVE_FROM16:
   1512       work_line_->CopyRegister1(inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategory1nr);
   1513       break;
   1514     case Instruction::MOVE_16:
   1515       work_line_->CopyRegister1(inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategory1nr);
   1516       break;
   1517     case Instruction::MOVE_WIDE:
   1518       work_line_->CopyRegister2(inst->VRegA_12x(), inst->VRegB_12x());
   1519       break;
   1520     case Instruction::MOVE_WIDE_FROM16:
   1521       work_line_->CopyRegister2(inst->VRegA_22x(), inst->VRegB_22x());
   1522       break;
   1523     case Instruction::MOVE_WIDE_16:
   1524       work_line_->CopyRegister2(inst->VRegA_32x(), inst->VRegB_32x());
   1525       break;
   1526     case Instruction::MOVE_OBJECT:
   1527       work_line_->CopyRegister1(inst->VRegA_12x(), inst->VRegB_12x(), kTypeCategoryRef);
   1528       break;
   1529     case Instruction::MOVE_OBJECT_FROM16:
   1530       work_line_->CopyRegister1(inst->VRegA_22x(), inst->VRegB_22x(), kTypeCategoryRef);
   1531       break;
   1532     case Instruction::MOVE_OBJECT_16:
   1533       work_line_->CopyRegister1(inst->VRegA_32x(), inst->VRegB_32x(), kTypeCategoryRef);
   1534       break;
   1535 
   1536     /*
   1537      * The move-result instructions copy data out of a "pseudo-register"
   1538      * with the results from the last method invocation. In practice we
   1539      * might want to hold the result in an actual CPU register, so the
   1540      * Dalvik spec requires that these only appear immediately after an
   1541      * invoke or filled-new-array.
   1542      *
   1543      * These calls invalidate the "result" register. (This is now
   1544      * redundant with the reset done below, but it can make the debug info
   1545      * easier to read in some cases.)
   1546      */
   1547     case Instruction::MOVE_RESULT:
   1548       work_line_->CopyResultRegister1(inst->VRegA_11x(), false);
   1549       break;
   1550     case Instruction::MOVE_RESULT_WIDE:
   1551       work_line_->CopyResultRegister2(inst->VRegA_11x());
   1552       break;
   1553     case Instruction::MOVE_RESULT_OBJECT:
   1554       work_line_->CopyResultRegister1(inst->VRegA_11x(), true);
   1555       break;
   1556 
   1557     case Instruction::MOVE_EXCEPTION: {
   1558       // We do not allow MOVE_EXCEPTION as the first instruction in a method. This is a simple case
   1559       // where one entrypoint to the catch block is not actually an exception path.
   1560       if (work_insn_idx_ == 0) {
   1561         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "move-exception at pc 0x0";
   1562         break;
   1563       }
   1564       /*
   1565        * This statement can only appear as the first instruction in an exception handler. We verify
   1566        * that as part of extracting the exception type from the catch block list.
   1567        */
   1568       RegType& res_type = GetCaughtExceptionType();
   1569       work_line_->SetRegisterType(inst->VRegA_11x(), res_type);
   1570       break;
   1571     }
   1572     case Instruction::RETURN_VOID:
   1573       if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
   1574         if (!GetMethodReturnType().IsConflict()) {
   1575           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void not expected";
   1576         }
   1577       }
   1578       break;
   1579     case Instruction::RETURN:
   1580       if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
   1581         /* check the method signature */
   1582         RegType& return_type = GetMethodReturnType();
   1583         if (!return_type.IsCategory1Types()) {
   1584           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected non-category 1 return type "
   1585                                             << return_type;
   1586         } else {
   1587           // Compilers may generate synthetic functions that write byte values into boolean fields.
   1588           // Also, it may use integer values for boolean, byte, short, and character return types.
   1589           const uint32_t vregA = inst->VRegA_11x();
   1590           RegType& src_type = work_line_->GetRegisterType(vregA);
   1591           bool use_src = ((return_type.IsBoolean() && src_type.IsByte()) ||
   1592                           ((return_type.IsBoolean() || return_type.IsByte() ||
   1593                            return_type.IsShort() || return_type.IsChar()) &&
   1594                            src_type.IsInteger()));
   1595           /* check the register contents */
   1596           bool success =
   1597               work_line_->VerifyRegisterType(vregA, use_src ? src_type : return_type);
   1598           if (!success) {
   1599             AppendToLastFailMessage(StringPrintf(" return-1nr on invalid register v%d", vregA));
   1600           }
   1601         }
   1602       }
   1603       break;
   1604     case Instruction::RETURN_WIDE:
   1605       if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
   1606         /* check the method signature */
   1607         RegType& return_type = GetMethodReturnType();
   1608         if (!return_type.IsCategory2Types()) {
   1609           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-wide not expected";
   1610         } else {
   1611           /* check the register contents */
   1612           const uint32_t vregA = inst->VRegA_11x();
   1613           bool success = work_line_->VerifyRegisterType(vregA, return_type);
   1614           if (!success) {
   1615             AppendToLastFailMessage(StringPrintf(" return-wide on invalid register v%d", vregA));
   1616           }
   1617         }
   1618       }
   1619       break;
   1620     case Instruction::RETURN_OBJECT:
   1621       if (!IsConstructor() || work_line_->CheckConstructorReturn()) {
   1622         RegType& return_type = GetMethodReturnType();
   1623         if (!return_type.IsReferenceTypes()) {
   1624           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-object not expected";
   1625         } else {
   1626           /* return_type is the *expected* return type, not register value */
   1627           DCHECK(!return_type.IsZero());
   1628           DCHECK(!return_type.IsUninitializedReference());
   1629           const uint32_t vregA = inst->VRegA_11x();
   1630           RegType& reg_type = work_line_->GetRegisterType(vregA);
   1631           // Disallow returning uninitialized values and verify that the reference in vAA is an
   1632           // instance of the "return_type"
   1633           if (reg_type.IsUninitializedTypes()) {
   1634             Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "returning uninitialized object '"
   1635                                               << reg_type << "'";
   1636           } else if (!return_type.IsAssignableFrom(reg_type)) {
   1637             if (reg_type.IsUnresolvedTypes() || return_type.IsUnresolvedTypes()) {
   1638               Fail(VERIFY_ERROR_NO_CLASS) << " can't resolve returned type '" << return_type
   1639                   << "' or '" << reg_type << "'";
   1640             } else {
   1641               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "returning '" << reg_type
   1642                   << "', but expected from declaration '" << return_type << "'";
   1643             }
   1644           }
   1645         }
   1646       }
   1647       break;
   1648 
   1649       /* could be boolean, int, float, or a null reference */
   1650     case Instruction::CONST_4: {
   1651       int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28;
   1652       work_line_->SetRegisterType(inst->VRegA_11n(),
   1653                                   DetermineCat1Constant(val, need_precise_constants_));
   1654       break;
   1655     }
   1656     case Instruction::CONST_16: {
   1657       int16_t val = static_cast<int16_t>(inst->VRegB_21s());
   1658       work_line_->SetRegisterType(inst->VRegA_21s(),
   1659                                   DetermineCat1Constant(val, need_precise_constants_));
   1660       break;
   1661     }
   1662     case Instruction::CONST: {
   1663       int32_t val = inst->VRegB_31i();
   1664       work_line_->SetRegisterType(inst->VRegA_31i(),
   1665                                   DetermineCat1Constant(val, need_precise_constants_));
   1666       break;
   1667     }
   1668     case Instruction::CONST_HIGH16: {
   1669       int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
   1670       work_line_->SetRegisterType(inst->VRegA_21h(),
   1671                                   DetermineCat1Constant(val, need_precise_constants_));
   1672       break;
   1673     }
   1674       /* could be long or double; resolved upon use */
   1675     case Instruction::CONST_WIDE_16: {
   1676       int64_t val = static_cast<int16_t>(inst->VRegB_21s());
   1677       RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   1678       RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   1679       work_line_->SetRegisterTypeWide(inst->VRegA_21s(), lo, hi);
   1680       break;
   1681     }
   1682     case Instruction::CONST_WIDE_32: {
   1683       int64_t val = static_cast<int32_t>(inst->VRegB_31i());
   1684       RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   1685       RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   1686       work_line_->SetRegisterTypeWide(inst->VRegA_31i(), lo, hi);
   1687       break;
   1688     }
   1689     case Instruction::CONST_WIDE: {
   1690       int64_t val = inst->VRegB_51l();
   1691       RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   1692       RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   1693       work_line_->SetRegisterTypeWide(inst->VRegA_51l(), lo, hi);
   1694       break;
   1695     }
   1696     case Instruction::CONST_WIDE_HIGH16: {
   1697       int64_t val = static_cast<uint64_t>(inst->VRegB_21h()) << 48;
   1698       RegType& lo = reg_types_.FromCat2ConstLo(static_cast<int32_t>(val), true);
   1699       RegType& hi = reg_types_.FromCat2ConstHi(static_cast<int32_t>(val >> 32), true);
   1700       work_line_->SetRegisterTypeWide(inst->VRegA_21h(), lo, hi);
   1701       break;
   1702     }
   1703     case Instruction::CONST_STRING:
   1704       work_line_->SetRegisterType(inst->VRegA_21c(), reg_types_.JavaLangString());
   1705       break;
   1706     case Instruction::CONST_STRING_JUMBO:
   1707       work_line_->SetRegisterType(inst->VRegA_31c(), reg_types_.JavaLangString());
   1708       break;
   1709     case Instruction::CONST_CLASS: {
   1710       // Get type from instruction if unresolved then we need an access check
   1711       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   1712       RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
   1713       // Register holds class, ie its type is class, on error it will hold Conflict.
   1714       work_line_->SetRegisterType(inst->VRegA_21c(),
   1715                                   res_type.IsConflict() ? res_type
   1716                                                         : reg_types_.JavaLangClass(true));
   1717       break;
   1718     }
   1719     case Instruction::MONITOR_ENTER:
   1720       work_line_->PushMonitor(inst->VRegA_11x(), work_insn_idx_);
   1721       break;
   1722     case Instruction::MONITOR_EXIT:
   1723       /*
   1724        * monitor-exit instructions are odd. They can throw exceptions,
   1725        * but when they do they act as if they succeeded and the PC is
   1726        * pointing to the following instruction. (This behavior goes back
   1727        * to the need to handle asynchronous exceptions, a now-deprecated
   1728        * feature that Dalvik doesn't support.)
   1729        *
   1730        * In practice we don't need to worry about this. The only
   1731        * exceptions that can be thrown from monitor-exit are for a
   1732        * null reference and -exit without a matching -enter. If the
   1733        * structured locking checks are working, the former would have
   1734        * failed on the -enter instruction, and the latter is impossible.
   1735        *
   1736        * This is fortunate, because issue 3221411 prevents us from
   1737        * chasing the "can throw" path when monitor verification is
   1738        * enabled. If we can fully verify the locking we can ignore
   1739        * some catch blocks (which will show up as "dead" code when
   1740        * we skip them here); if we can't, then the code path could be
   1741        * "live" so we still need to check it.
   1742        */
   1743       opcode_flags &= ~Instruction::kThrow;
   1744       work_line_->PopMonitor(inst->VRegA_11x());
   1745       break;
   1746 
   1747     case Instruction::CHECK_CAST:
   1748     case Instruction::INSTANCE_OF: {
   1749       /*
   1750        * If this instruction succeeds, we will "downcast" register vA to the type in vB. (This
   1751        * could be a "upcast" -- not expected, so we don't try to address it.)
   1752        *
   1753        * If it fails, an exception is thrown, which we deal with later by ignoring the update to
   1754        * dec_insn.vA when branching to a handler.
   1755        */
   1756       const bool is_checkcast = (inst->Opcode() == Instruction::CHECK_CAST);
   1757       const uint32_t type_idx = (is_checkcast) ? inst->VRegB_21c() : inst->VRegC_22c();
   1758       RegType& res_type = ResolveClassAndCheckAccess(type_idx);
   1759       if (res_type.IsConflict()) {
   1760         // If this is a primitive type, fail HARD.
   1761         mirror::Class* klass = (*dex_cache_)->GetResolvedType(type_idx);
   1762         if (klass != nullptr && klass->IsPrimitive()) {
   1763           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "using primitive type "
   1764               << dex_file_->StringByTypeIdx(type_idx) << " in instanceof in "
   1765               << GetDeclaringClass();
   1766           break;
   1767         }
   1768 
   1769         DCHECK_NE(failures_.size(), 0U);
   1770         if (!is_checkcast) {
   1771           work_line_->SetRegisterType(inst->VRegA_22c(), reg_types_.Boolean());
   1772         }
   1773         break;  // bad class
   1774       }
   1775       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   1776       uint32_t orig_type_reg = (is_checkcast) ? inst->VRegA_21c() : inst->VRegB_22c();
   1777       RegType& orig_type = work_line_->GetRegisterType(orig_type_reg);
   1778       if (!res_type.IsNonZeroReferenceTypes()) {
   1779         if (is_checkcast) {
   1780           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on unexpected class " << res_type;
   1781         } else {
   1782           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on unexpected class " << res_type;
   1783         }
   1784       } else if (!orig_type.IsReferenceTypes()) {
   1785         if (is_checkcast) {
   1786           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "check-cast on non-reference in v" << orig_type_reg;
   1787         } else {
   1788           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance-of on non-reference in v" << orig_type_reg;
   1789         }
   1790       } else {
   1791         if (is_checkcast) {
   1792           work_line_->SetRegisterType(inst->VRegA_21c(), res_type);
   1793         } else {
   1794           work_line_->SetRegisterType(inst->VRegA_22c(), reg_types_.Boolean());
   1795         }
   1796       }
   1797       break;
   1798     }
   1799     case Instruction::ARRAY_LENGTH: {
   1800       RegType& res_type = work_line_->GetRegisterType(inst->VRegB_12x());
   1801       if (res_type.IsReferenceTypes()) {
   1802         if (!res_type.IsArrayTypes() && !res_type.IsZero()) {  // ie not an array or null
   1803           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   1804         } else {
   1805           work_line_->SetRegisterType(inst->VRegA_12x(), reg_types_.Integer());
   1806         }
   1807       } else {
   1808         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-length on non-array " << res_type;
   1809       }
   1810       break;
   1811     }
   1812     case Instruction::NEW_INSTANCE: {
   1813       RegType& res_type = ResolveClassAndCheckAccess(inst->VRegB_21c());
   1814       if (res_type.IsConflict()) {
   1815         DCHECK_NE(failures_.size(), 0U);
   1816         break;  // bad class
   1817       }
   1818       // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   1819       // can't create an instance of an interface or abstract class */
   1820       if (!res_type.IsInstantiableTypes()) {
   1821         Fail(VERIFY_ERROR_INSTANTIATION)
   1822             << "new-instance on primitive, interface or abstract class" << res_type;
   1823         // Soft failure so carry on to set register type.
   1824       }
   1825       RegType& uninit_type = reg_types_.Uninitialized(res_type, work_insn_idx_);
   1826       // Any registers holding previous allocations from this address that have not yet been
   1827       // initialized must be marked invalid.
   1828       work_line_->MarkUninitRefsAsInvalid(uninit_type);
   1829       // add the new uninitialized reference to the register state
   1830       work_line_->SetRegisterType(inst->VRegA_21c(), uninit_type);
   1831       break;
   1832     }
   1833     case Instruction::NEW_ARRAY:
   1834       VerifyNewArray(inst, false, false);
   1835       break;
   1836     case Instruction::FILLED_NEW_ARRAY:
   1837       VerifyNewArray(inst, true, false);
   1838       just_set_result = true;  // Filled new array sets result register
   1839       break;
   1840     case Instruction::FILLED_NEW_ARRAY_RANGE:
   1841       VerifyNewArray(inst, true, true);
   1842       just_set_result = true;  // Filled new array range sets result register
   1843       break;
   1844     case Instruction::CMPL_FLOAT:
   1845     case Instruction::CMPG_FLOAT:
   1846       if (!work_line_->VerifyRegisterType(inst->VRegB_23x(), reg_types_.Float())) {
   1847         break;
   1848       }
   1849       if (!work_line_->VerifyRegisterType(inst->VRegC_23x(), reg_types_.Float())) {
   1850         break;
   1851       }
   1852       work_line_->SetRegisterType(inst->VRegA_23x(), reg_types_.Integer());
   1853       break;
   1854     case Instruction::CMPL_DOUBLE:
   1855     case Instruction::CMPG_DOUBLE:
   1856       if (!work_line_->VerifyRegisterTypeWide(inst->VRegB_23x(), reg_types_.DoubleLo(),
   1857                                               reg_types_.DoubleHi())) {
   1858         break;
   1859       }
   1860       if (!work_line_->VerifyRegisterTypeWide(inst->VRegC_23x(), reg_types_.DoubleLo(),
   1861                                               reg_types_.DoubleHi())) {
   1862         break;
   1863       }
   1864       work_line_->SetRegisterType(inst->VRegA_23x(), reg_types_.Integer());
   1865       break;
   1866     case Instruction::CMP_LONG:
   1867       if (!work_line_->VerifyRegisterTypeWide(inst->VRegB_23x(), reg_types_.LongLo(),
   1868                                               reg_types_.LongHi())) {
   1869         break;
   1870       }
   1871       if (!work_line_->VerifyRegisterTypeWide(inst->VRegC_23x(), reg_types_.LongLo(),
   1872                                               reg_types_.LongHi())) {
   1873         break;
   1874       }
   1875       work_line_->SetRegisterType(inst->VRegA_23x(), reg_types_.Integer());
   1876       break;
   1877     case Instruction::THROW: {
   1878       RegType& res_type = work_line_->GetRegisterType(inst->VRegA_11x());
   1879       if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(res_type)) {
   1880         Fail(res_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS : VERIFY_ERROR_BAD_CLASS_SOFT)
   1881             << "thrown class " << res_type << " not instanceof Throwable";
   1882       }
   1883       break;
   1884     }
   1885     case Instruction::GOTO:
   1886     case Instruction::GOTO_16:
   1887     case Instruction::GOTO_32:
   1888       /* no effect on or use of registers */
   1889       break;
   1890 
   1891     case Instruction::PACKED_SWITCH:
   1892     case Instruction::SPARSE_SWITCH:
   1893       /* verify that vAA is an integer, or can be converted to one */
   1894       work_line_->VerifyRegisterType(inst->VRegA_31t(), reg_types_.Integer());
   1895       break;
   1896 
   1897     case Instruction::FILL_ARRAY_DATA: {
   1898       /* Similar to the verification done for APUT */
   1899       RegType& array_type = work_line_->GetRegisterType(inst->VRegA_31t());
   1900       /* array_type can be null if the reg type is Zero */
   1901       if (!array_type.IsZero()) {
   1902         if (!array_type.IsArrayTypes()) {
   1903           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with array type "
   1904                                             << array_type;
   1905         } else {
   1906           RegType& component_type = reg_types_.GetComponentType(array_type,
   1907                                                                       class_loader_->Get());
   1908           DCHECK(!component_type.IsConflict());
   1909           if (component_type.IsNonZeroReferenceTypes()) {
   1910             Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid fill-array-data with component type "
   1911                                               << component_type;
   1912           } else {
   1913             // Now verify if the element width in the table matches the element width declared in
   1914             // the array
   1915             const uint16_t* array_data = insns + (insns[1] | (((int32_t) insns[2]) << 16));
   1916             if (array_data[0] != Instruction::kArrayDataSignature) {
   1917               Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid magic for array-data";
   1918             } else {
   1919               size_t elem_width = Primitive::ComponentSize(component_type.GetPrimitiveType());
   1920               // Since we don't compress the data in Dex, expect to see equal width of data stored
   1921               // in the table and expected from the array class.
   1922               if (array_data[1] != elem_width) {
   1923                 Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array-data size mismatch (" << array_data[1]
   1924                                                   << " vs " << elem_width << ")";
   1925               }
   1926             }
   1927           }
   1928         }
   1929       }
   1930       break;
   1931     }
   1932     case Instruction::IF_EQ:
   1933     case Instruction::IF_NE: {
   1934       RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
   1935       RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
   1936       bool mismatch = false;
   1937       if (reg_type1.IsZero()) {  // zero then integral or reference expected
   1938         mismatch = !reg_type2.IsReferenceTypes() && !reg_type2.IsIntegralTypes();
   1939       } else if (reg_type1.IsReferenceTypes()) {  // both references?
   1940         mismatch = !reg_type2.IsReferenceTypes();
   1941       } else {  // both integral?
   1942         mismatch = !reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes();
   1943       }
   1944       if (mismatch) {
   1945         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to if-eq/if-ne (" << reg_type1 << ","
   1946                                           << reg_type2 << ") must both be references or integral";
   1947       }
   1948       break;
   1949     }
   1950     case Instruction::IF_LT:
   1951     case Instruction::IF_GE:
   1952     case Instruction::IF_GT:
   1953     case Instruction::IF_LE: {
   1954       RegType& reg_type1 = work_line_->GetRegisterType(inst->VRegA_22t());
   1955       RegType& reg_type2 = work_line_->GetRegisterType(inst->VRegB_22t());
   1956       if (!reg_type1.IsIntegralTypes() || !reg_type2.IsIntegralTypes()) {
   1957         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "args to 'if' (" << reg_type1 << ","
   1958                                           << reg_type2 << ") must be integral";
   1959       }
   1960       break;
   1961     }
   1962     case Instruction::IF_EQZ:
   1963     case Instruction::IF_NEZ: {
   1964       RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
   1965       if (!reg_type.IsReferenceTypes() && !reg_type.IsIntegralTypes()) {
   1966         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   1967                                           << " unexpected as arg to if-eqz/if-nez";
   1968       }
   1969 
   1970       // Find previous instruction - its existence is a precondition to peephole optimization.
   1971       uint32_t instance_of_idx = 0;
   1972       if (0 != work_insn_idx_) {
   1973         instance_of_idx = work_insn_idx_ - 1;
   1974         while (0 != instance_of_idx && !insn_flags_[instance_of_idx].IsOpcode()) {
   1975           instance_of_idx--;
   1976         }
   1977         if (FailOrAbort(this, insn_flags_[instance_of_idx].IsOpcode(),
   1978                         "Unable to get previous instruction of if-eqz/if-nez for work index ",
   1979                         work_insn_idx_)) {
   1980           break;
   1981         }
   1982       } else {
   1983         break;
   1984       }
   1985 
   1986       const Instruction* instance_of_inst = Instruction::At(code_item_->insns_ + instance_of_idx);
   1987 
   1988       /* Check for peep-hole pattern of:
   1989        *    ...;
   1990        *    instance-of vX, vY, T;
   1991        *    ifXXX vX, label ;
   1992        *    ...;
   1993        * label:
   1994        *    ...;
   1995        * and sharpen the type of vY to be type T.
   1996        * Note, this pattern can't be if:
   1997        *  - if there are other branches to this branch,
   1998        *  - when vX == vY.
   1999        */
   2000       if (!CurrentInsnFlags()->IsBranchTarget() &&
   2001           (Instruction::INSTANCE_OF == instance_of_inst->Opcode()) &&
   2002           (inst->VRegA_21t() == instance_of_inst->VRegA_22c()) &&
   2003           (instance_of_inst->VRegA_22c() != instance_of_inst->VRegB_22c())) {
   2004         // Check the type of the instance-of is different than that of registers type, as if they
   2005         // are the same there is no work to be done here. Check that the conversion is not to or
   2006         // from an unresolved type as type information is imprecise. If the instance-of is to an
   2007         // interface then ignore the type information as interfaces can only be treated as Objects
   2008         // and we don't want to disallow field and other operations on the object. If the value
   2009         // being instance-of checked against is known null (zero) then allow the optimization as
   2010         // we didn't have type information. If the merge of the instance-of type with the original
   2011         // type is assignable to the original then allow optimization. This check is performed to
   2012         // ensure that subsequent merges don't lose type information - such as becoming an
   2013         // interface from a class that would lose information relevant to field checks.
   2014         RegType& orig_type = work_line_->GetRegisterType(instance_of_inst->VRegB_22c());
   2015         RegType& cast_type = ResolveClassAndCheckAccess(instance_of_inst->VRegC_22c());
   2016 
   2017         if (!orig_type.Equals(cast_type) &&
   2018             !cast_type.IsUnresolvedTypes() && !orig_type.IsUnresolvedTypes() &&
   2019             cast_type.HasClass() &&             // Could be conflict type, make sure it has a class.
   2020             !cast_type.GetClass()->IsInterface() &&
   2021             (orig_type.IsZero() ||
   2022                 orig_type.IsStrictlyAssignableFrom(cast_type.Merge(orig_type, &reg_types_)))) {
   2023           RegisterLine* update_line = RegisterLine::Create(code_item_->registers_size_, this);
   2024           if (inst->Opcode() == Instruction::IF_EQZ) {
   2025             fallthrough_line.reset(update_line);
   2026           } else {
   2027             branch_line.reset(update_line);
   2028           }
   2029           update_line->CopyFromLine(work_line_.get());
   2030           update_line->SetRegisterType(instance_of_inst->VRegB_22c(), cast_type);
   2031           if (!insn_flags_[instance_of_idx].IsBranchTarget() && 0 != instance_of_idx) {
   2032             // See if instance-of was preceded by a move-object operation, common due to the small
   2033             // register encoding space of instance-of, and propagate type information to the source
   2034             // of the move-object.
   2035             uint32_t move_idx = instance_of_idx - 1;
   2036             while (0 != move_idx && !insn_flags_[move_idx].IsOpcode()) {
   2037               move_idx--;
   2038             }
   2039             if (FailOrAbort(this, insn_flags_[move_idx].IsOpcode(),
   2040                             "Unable to get previous instruction of if-eqz/if-nez for work index ",
   2041                             work_insn_idx_)) {
   2042               break;
   2043             }
   2044             const Instruction* move_inst = Instruction::At(code_item_->insns_ + move_idx);
   2045             switch (move_inst->Opcode()) {
   2046               case Instruction::MOVE_OBJECT:
   2047                 if (move_inst->VRegA_12x() == instance_of_inst->VRegB_22c()) {
   2048                   update_line->SetRegisterType(move_inst->VRegB_12x(), cast_type);
   2049                 }
   2050                 break;
   2051               case Instruction::MOVE_OBJECT_FROM16:
   2052                 if (move_inst->VRegA_22x() == instance_of_inst->VRegB_22c()) {
   2053                   update_line->SetRegisterType(move_inst->VRegB_22x(), cast_type);
   2054                 }
   2055                 break;
   2056               case Instruction::MOVE_OBJECT_16:
   2057                 if (move_inst->VRegA_32x() == instance_of_inst->VRegB_22c()) {
   2058                   update_line->SetRegisterType(move_inst->VRegB_32x(), cast_type);
   2059                 }
   2060                 break;
   2061               default:
   2062                 break;
   2063             }
   2064           }
   2065         }
   2066       }
   2067 
   2068       break;
   2069     }
   2070     case Instruction::IF_LTZ:
   2071     case Instruction::IF_GEZ:
   2072     case Instruction::IF_GTZ:
   2073     case Instruction::IF_LEZ: {
   2074       RegType& reg_type = work_line_->GetRegisterType(inst->VRegA_21t());
   2075       if (!reg_type.IsIntegralTypes()) {
   2076         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "type " << reg_type
   2077                                           << " unexpected as arg to if-ltz/if-gez/if-gtz/if-lez";
   2078       }
   2079       break;
   2080     }
   2081     case Instruction::AGET_BOOLEAN:
   2082       VerifyAGet(inst, reg_types_.Boolean(), true);
   2083       break;
   2084     case Instruction::AGET_BYTE:
   2085       VerifyAGet(inst, reg_types_.Byte(), true);
   2086       break;
   2087     case Instruction::AGET_CHAR:
   2088       VerifyAGet(inst, reg_types_.Char(), true);
   2089       break;
   2090     case Instruction::AGET_SHORT:
   2091       VerifyAGet(inst, reg_types_.Short(), true);
   2092       break;
   2093     case Instruction::AGET:
   2094       VerifyAGet(inst, reg_types_.Integer(), true);
   2095       break;
   2096     case Instruction::AGET_WIDE:
   2097       VerifyAGet(inst, reg_types_.LongLo(), true);
   2098       break;
   2099     case Instruction::AGET_OBJECT:
   2100       VerifyAGet(inst, reg_types_.JavaLangObject(false), false);
   2101       break;
   2102 
   2103     case Instruction::APUT_BOOLEAN:
   2104       VerifyAPut(inst, reg_types_.Boolean(), true);
   2105       break;
   2106     case Instruction::APUT_BYTE:
   2107       VerifyAPut(inst, reg_types_.Byte(), true);
   2108       break;
   2109     case Instruction::APUT_CHAR:
   2110       VerifyAPut(inst, reg_types_.Char(), true);
   2111       break;
   2112     case Instruction::APUT_SHORT:
   2113       VerifyAPut(inst, reg_types_.Short(), true);
   2114       break;
   2115     case Instruction::APUT:
   2116       VerifyAPut(inst, reg_types_.Integer(), true);
   2117       break;
   2118     case Instruction::APUT_WIDE:
   2119       VerifyAPut(inst, reg_types_.LongLo(), true);
   2120       break;
   2121     case Instruction::APUT_OBJECT:
   2122       VerifyAPut(inst, reg_types_.JavaLangObject(false), false);
   2123       break;
   2124 
   2125     case Instruction::IGET_BOOLEAN:
   2126       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, false);
   2127       break;
   2128     case Instruction::IGET_BYTE:
   2129       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, false);
   2130       break;
   2131     case Instruction::IGET_CHAR:
   2132       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, false);
   2133       break;
   2134     case Instruction::IGET_SHORT:
   2135       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, false);
   2136       break;
   2137     case Instruction::IGET:
   2138       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, false);
   2139       break;
   2140     case Instruction::IGET_WIDE:
   2141       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, false);
   2142       break;
   2143     case Instruction::IGET_OBJECT:
   2144       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2145                                                     false);
   2146       break;
   2147 
   2148     case Instruction::IPUT_BOOLEAN:
   2149       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, false);
   2150       break;
   2151     case Instruction::IPUT_BYTE:
   2152       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, false);
   2153       break;
   2154     case Instruction::IPUT_CHAR:
   2155       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, false);
   2156       break;
   2157     case Instruction::IPUT_SHORT:
   2158       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, false);
   2159       break;
   2160     case Instruction::IPUT:
   2161       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, false);
   2162       break;
   2163     case Instruction::IPUT_WIDE:
   2164       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, false);
   2165       break;
   2166     case Instruction::IPUT_OBJECT:
   2167       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2168                                                     false);
   2169       break;
   2170 
   2171     case Instruction::SGET_BOOLEAN:
   2172       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Boolean(), true, true);
   2173       break;
   2174     case Instruction::SGET_BYTE:
   2175       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Byte(), true, true);
   2176       break;
   2177     case Instruction::SGET_CHAR:
   2178       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Char(), true, true);
   2179       break;
   2180     case Instruction::SGET_SHORT:
   2181       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Short(), true, true);
   2182       break;
   2183     case Instruction::SGET:
   2184       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true, true);
   2185       break;
   2186     case Instruction::SGET_WIDE:
   2187       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true, true);
   2188       break;
   2189     case Instruction::SGET_OBJECT:
   2190       VerifyISFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false,
   2191                                                     true);
   2192       break;
   2193 
   2194     case Instruction::SPUT_BOOLEAN:
   2195       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Boolean(), true, true);
   2196       break;
   2197     case Instruction::SPUT_BYTE:
   2198       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Byte(), true, true);
   2199       break;
   2200     case Instruction::SPUT_CHAR:
   2201       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Char(), true, true);
   2202       break;
   2203     case Instruction::SPUT_SHORT:
   2204       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Short(), true, true);
   2205       break;
   2206     case Instruction::SPUT:
   2207       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true, true);
   2208       break;
   2209     case Instruction::SPUT_WIDE:
   2210       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true, true);
   2211       break;
   2212     case Instruction::SPUT_OBJECT:
   2213       VerifyISFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false,
   2214                                                     true);
   2215       break;
   2216 
   2217     case Instruction::INVOKE_VIRTUAL:
   2218     case Instruction::INVOKE_VIRTUAL_RANGE:
   2219     case Instruction::INVOKE_SUPER:
   2220     case Instruction::INVOKE_SUPER_RANGE: {
   2221       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE ||
   2222                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
   2223       bool is_super = (inst->Opcode() == Instruction::INVOKE_SUPER ||
   2224                        inst->Opcode() == Instruction::INVOKE_SUPER_RANGE);
   2225       mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_VIRTUAL, is_range,
   2226                                                               is_super);
   2227       RegType* return_type = nullptr;
   2228       if (called_method != nullptr) {
   2229         Thread* self = Thread::Current();
   2230         StackHandleScope<1> hs(self);
   2231         Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
   2232         MethodHelper mh(h_called_method);
   2233         mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
   2234         if (return_type_class != nullptr) {
   2235           return_type = &reg_types_.FromClass(h_called_method->GetReturnTypeDescriptor(),
   2236                                               return_type_class,
   2237                                               return_type_class->CannotBeAssignedFromOtherTypes());
   2238         } else {
   2239           DCHECK(!can_load_classes_ || self->IsExceptionPending());
   2240           self->ClearException();
   2241         }
   2242       }
   2243       if (return_type == nullptr) {
   2244         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2245         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2246         uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2247         const char* descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   2248         return_type = &reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   2249       }
   2250       if (!return_type->IsLowHalf()) {
   2251         work_line_->SetResultRegisterType(*return_type);
   2252       } else {
   2253         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   2254       }
   2255       just_set_result = true;
   2256       break;
   2257     }
   2258     case Instruction::INVOKE_DIRECT:
   2259     case Instruction::INVOKE_DIRECT_RANGE: {
   2260       bool is_range = (inst->Opcode() == Instruction::INVOKE_DIRECT_RANGE);
   2261       mirror::ArtMethod* called_method = VerifyInvocationArgs(inst, METHOD_DIRECT,
   2262                                                                    is_range, false);
   2263       const char* return_type_descriptor;
   2264       bool is_constructor;
   2265       RegType* return_type = nullptr;
   2266       if (called_method == nullptr) {
   2267         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2268         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2269         is_constructor = strcmp("<init>", dex_file_->StringDataByIdx(method_id.name_idx_)) == 0;
   2270         uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2271         return_type_descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
   2272       } else {
   2273         is_constructor = called_method->IsConstructor();
   2274         return_type_descriptor = called_method->GetReturnTypeDescriptor();
   2275         Thread* self = Thread::Current();
   2276         StackHandleScope<1> hs(self);
   2277         Handle<mirror::ArtMethod> h_called_method(hs.NewHandle(called_method));
   2278         MethodHelper mh(h_called_method);
   2279         mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
   2280         if (return_type_class != nullptr) {
   2281           return_type = &reg_types_.FromClass(return_type_descriptor,
   2282                                               return_type_class,
   2283                                               return_type_class->CannotBeAssignedFromOtherTypes());
   2284         } else {
   2285           DCHECK(!can_load_classes_ || self->IsExceptionPending());
   2286           self->ClearException();
   2287         }
   2288       }
   2289       if (is_constructor) {
   2290         /*
   2291          * Some additional checks when calling a constructor. We know from the invocation arg check
   2292          * that the "this" argument is an instance of called_method->klass. Now we further restrict
   2293          * that to require that called_method->klass is the same as this->klass or this->super,
   2294          * allowing the latter only if the "this" argument is the same as the "this" argument to
   2295          * this method (which implies that we're in a constructor ourselves).
   2296          */
   2297         RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
   2298         if (this_type.IsConflict())  // failure.
   2299           break;
   2300 
   2301         /* no null refs allowed (?) */
   2302         if (this_type.IsZero()) {
   2303           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unable to initialize null ref";
   2304           break;
   2305         }
   2306 
   2307         /* must be in same class or in superclass */
   2308         // RegType& this_super_klass = this_type.GetSuperClass(&reg_types_);
   2309         // TODO: re-enable constructor type verification
   2310         // if (this_super_klass.IsConflict()) {
   2311           // Unknown super class, fail so we re-check at runtime.
   2312           // Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "super class unknown for '" << this_type << "'";
   2313           // break;
   2314         // }
   2315 
   2316         /* arg must be an uninitialized reference */
   2317         if (!this_type.IsUninitializedTypes()) {
   2318           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Expected initialization on uninitialized reference "
   2319               << this_type;
   2320           break;
   2321         }
   2322 
   2323         /*
   2324          * Replace the uninitialized reference with an initialized one. We need to do this for all
   2325          * registers that have the same object instance in them, not just the "this" register.
   2326          */
   2327         work_line_->MarkRefsAsInitialized(this_type);
   2328       }
   2329       if (return_type == nullptr) {
   2330         return_type = &reg_types_.FromDescriptor(class_loader_->Get(),
   2331                                                  return_type_descriptor, false);
   2332       }
   2333       if (!return_type->IsLowHalf()) {
   2334         work_line_->SetResultRegisterType(*return_type);
   2335       } else {
   2336         work_line_->SetResultRegisterTypeWide(*return_type, return_type->HighHalf(&reg_types_));
   2337       }
   2338       just_set_result = true;
   2339       break;
   2340     }
   2341     case Instruction::INVOKE_STATIC:
   2342     case Instruction::INVOKE_STATIC_RANGE: {
   2343         bool is_range = (inst->Opcode() == Instruction::INVOKE_STATIC_RANGE);
   2344         mirror::ArtMethod* called_method = VerifyInvocationArgs(inst,
   2345                                                                      METHOD_STATIC,
   2346                                                                      is_range,
   2347                                                                      false);
   2348         const char* descriptor;
   2349         if (called_method == nullptr) {
   2350           uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2351           const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2352           uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2353           descriptor = dex_file_->StringByTypeIdx(return_type_idx);
   2354         } else {
   2355           descriptor = called_method->GetReturnTypeDescriptor();
   2356         }
   2357         RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
   2358                                                                false);
   2359         if (!return_type.IsLowHalf()) {
   2360           work_line_->SetResultRegisterType(return_type);
   2361         } else {
   2362           work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   2363         }
   2364         just_set_result = true;
   2365       }
   2366       break;
   2367     case Instruction::INVOKE_INTERFACE:
   2368     case Instruction::INVOKE_INTERFACE_RANGE: {
   2369       bool is_range =  (inst->Opcode() == Instruction::INVOKE_INTERFACE_RANGE);
   2370       mirror::ArtMethod* abs_method = VerifyInvocationArgs(inst,
   2371                                                                 METHOD_INTERFACE,
   2372                                                                 is_range,
   2373                                                                 false);
   2374       if (abs_method != nullptr) {
   2375         mirror::Class* called_interface = abs_method->GetDeclaringClass();
   2376         if (!called_interface->IsInterface() && !called_interface->IsObjectClass()) {
   2377           Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected interface class in invoke-interface '"
   2378               << PrettyMethod(abs_method) << "'";
   2379           break;
   2380         }
   2381       }
   2382       /* Get the type of the "this" arg, which should either be a sub-interface of called
   2383        * interface or Object (see comments in RegType::JoinClass).
   2384        */
   2385       RegType& this_type = work_line_->GetInvocationThis(inst, is_range);
   2386       if (this_type.IsZero()) {
   2387         /* null pointer always passes (and always fails at runtime) */
   2388       } else {
   2389         if (this_type.IsUninitializedTypes()) {
   2390           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "interface call on uninitialized object "
   2391               << this_type;
   2392           break;
   2393         }
   2394         // In the past we have tried to assert that "called_interface" is assignable
   2395         // from "this_type.GetClass()", however, as we do an imprecise Join
   2396         // (RegType::JoinClass) we don't have full information on what interfaces are
   2397         // implemented by "this_type". For example, two classes may implement the same
   2398         // interfaces and have a common parent that doesn't implement the interface. The
   2399         // join will set "this_type" to the parent class and a test that this implements
   2400         // the interface will incorrectly fail.
   2401       }
   2402       /*
   2403        * We don't have an object instance, so we can't find the concrete method. However, all of
   2404        * the type information is in the abstract method, so we're good.
   2405        */
   2406       const char* descriptor;
   2407       if (abs_method == nullptr) {
   2408         uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   2409         const DexFile::MethodId& method_id = dex_file_->GetMethodId(method_idx);
   2410         uint32_t return_type_idx = dex_file_->GetProtoId(method_id.proto_idx_).return_type_idx_;
   2411         descriptor =  dex_file_->StringByTypeIdx(return_type_idx);
   2412       } else {
   2413         descriptor = abs_method->GetReturnTypeDescriptor();
   2414       }
   2415       RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
   2416                                                              false);
   2417       if (!return_type.IsLowHalf()) {
   2418         work_line_->SetResultRegisterType(return_type);
   2419       } else {
   2420         work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   2421       }
   2422       just_set_result = true;
   2423       break;
   2424     }
   2425     case Instruction::NEG_INT:
   2426     case Instruction::NOT_INT:
   2427       work_line_->CheckUnaryOp(inst, reg_types_.Integer(), reg_types_.Integer());
   2428       break;
   2429     case Instruction::NEG_LONG:
   2430     case Instruction::NOT_LONG:
   2431       work_line_->CheckUnaryOpWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2432                                    reg_types_.LongLo(), reg_types_.LongHi());
   2433       break;
   2434     case Instruction::NEG_FLOAT:
   2435       work_line_->CheckUnaryOp(inst, reg_types_.Float(), reg_types_.Float());
   2436       break;
   2437     case Instruction::NEG_DOUBLE:
   2438       work_line_->CheckUnaryOpWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2439                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2440       break;
   2441     case Instruction::INT_TO_LONG:
   2442       work_line_->CheckUnaryOpToWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2443                                      reg_types_.Integer());
   2444       break;
   2445     case Instruction::INT_TO_FLOAT:
   2446       work_line_->CheckUnaryOp(inst, reg_types_.Float(), reg_types_.Integer());
   2447       break;
   2448     case Instruction::INT_TO_DOUBLE:
   2449       work_line_->CheckUnaryOpToWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2450                                      reg_types_.Integer());
   2451       break;
   2452     case Instruction::LONG_TO_INT:
   2453       work_line_->CheckUnaryOpFromWide(inst, reg_types_.Integer(),
   2454                                        reg_types_.LongLo(), reg_types_.LongHi());
   2455       break;
   2456     case Instruction::LONG_TO_FLOAT:
   2457       work_line_->CheckUnaryOpFromWide(inst, reg_types_.Float(),
   2458                                        reg_types_.LongLo(), reg_types_.LongHi());
   2459       break;
   2460     case Instruction::LONG_TO_DOUBLE:
   2461       work_line_->CheckUnaryOpWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2462                                    reg_types_.LongLo(), reg_types_.LongHi());
   2463       break;
   2464     case Instruction::FLOAT_TO_INT:
   2465       work_line_->CheckUnaryOp(inst, reg_types_.Integer(), reg_types_.Float());
   2466       break;
   2467     case Instruction::FLOAT_TO_LONG:
   2468       work_line_->CheckUnaryOpToWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2469                                      reg_types_.Float());
   2470       break;
   2471     case Instruction::FLOAT_TO_DOUBLE:
   2472       work_line_->CheckUnaryOpToWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2473                                      reg_types_.Float());
   2474       break;
   2475     case Instruction::DOUBLE_TO_INT:
   2476       work_line_->CheckUnaryOpFromWide(inst, reg_types_.Integer(),
   2477                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2478       break;
   2479     case Instruction::DOUBLE_TO_LONG:
   2480       work_line_->CheckUnaryOpWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2481                                    reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2482       break;
   2483     case Instruction::DOUBLE_TO_FLOAT:
   2484       work_line_->CheckUnaryOpFromWide(inst, reg_types_.Float(),
   2485                                        reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2486       break;
   2487     case Instruction::INT_TO_BYTE:
   2488       work_line_->CheckUnaryOp(inst, reg_types_.Byte(), reg_types_.Integer());
   2489       break;
   2490     case Instruction::INT_TO_CHAR:
   2491       work_line_->CheckUnaryOp(inst, reg_types_.Char(), reg_types_.Integer());
   2492       break;
   2493     case Instruction::INT_TO_SHORT:
   2494       work_line_->CheckUnaryOp(inst, reg_types_.Short(), reg_types_.Integer());
   2495       break;
   2496 
   2497     case Instruction::ADD_INT:
   2498     case Instruction::SUB_INT:
   2499     case Instruction::MUL_INT:
   2500     case Instruction::REM_INT:
   2501     case Instruction::DIV_INT:
   2502     case Instruction::SHL_INT:
   2503     case Instruction::SHR_INT:
   2504     case Instruction::USHR_INT:
   2505       work_line_->CheckBinaryOp(inst, reg_types_.Integer(), reg_types_.Integer(),
   2506                                 reg_types_.Integer(), false);
   2507       break;
   2508     case Instruction::AND_INT:
   2509     case Instruction::OR_INT:
   2510     case Instruction::XOR_INT:
   2511       work_line_->CheckBinaryOp(inst, reg_types_.Integer(), reg_types_.Integer(),
   2512                                 reg_types_.Integer(), true);
   2513       break;
   2514     case Instruction::ADD_LONG:
   2515     case Instruction::SUB_LONG:
   2516     case Instruction::MUL_LONG:
   2517     case Instruction::DIV_LONG:
   2518     case Instruction::REM_LONG:
   2519     case Instruction::AND_LONG:
   2520     case Instruction::OR_LONG:
   2521     case Instruction::XOR_LONG:
   2522       work_line_->CheckBinaryOpWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2523                                     reg_types_.LongLo(), reg_types_.LongHi(),
   2524                                     reg_types_.LongLo(), reg_types_.LongHi());
   2525       break;
   2526     case Instruction::SHL_LONG:
   2527     case Instruction::SHR_LONG:
   2528     case Instruction::USHR_LONG:
   2529       /* shift distance is Int, making these different from other binary operations */
   2530       work_line_->CheckBinaryOpWideShift(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2531                                          reg_types_.Integer());
   2532       break;
   2533     case Instruction::ADD_FLOAT:
   2534     case Instruction::SUB_FLOAT:
   2535     case Instruction::MUL_FLOAT:
   2536     case Instruction::DIV_FLOAT:
   2537     case Instruction::REM_FLOAT:
   2538       work_line_->CheckBinaryOp(inst,
   2539                                 reg_types_.Float(),
   2540                                 reg_types_.Float(),
   2541                                 reg_types_.Float(),
   2542                                 false);
   2543       break;
   2544     case Instruction::ADD_DOUBLE:
   2545     case Instruction::SUB_DOUBLE:
   2546     case Instruction::MUL_DOUBLE:
   2547     case Instruction::DIV_DOUBLE:
   2548     case Instruction::REM_DOUBLE:
   2549       work_line_->CheckBinaryOpWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2550                                     reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2551                                     reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2552       break;
   2553     case Instruction::ADD_INT_2ADDR:
   2554     case Instruction::SUB_INT_2ADDR:
   2555     case Instruction::MUL_INT_2ADDR:
   2556     case Instruction::REM_INT_2ADDR:
   2557     case Instruction::SHL_INT_2ADDR:
   2558     case Instruction::SHR_INT_2ADDR:
   2559     case Instruction::USHR_INT_2ADDR:
   2560       work_line_->CheckBinaryOp2addr(inst,
   2561                                      reg_types_.Integer(),
   2562                                      reg_types_.Integer(),
   2563                                      reg_types_.Integer(),
   2564                                      false);
   2565       break;
   2566     case Instruction::AND_INT_2ADDR:
   2567     case Instruction::OR_INT_2ADDR:
   2568     case Instruction::XOR_INT_2ADDR:
   2569       work_line_->CheckBinaryOp2addr(inst,
   2570                                      reg_types_.Integer(),
   2571                                      reg_types_.Integer(),
   2572                                      reg_types_.Integer(),
   2573                                      true);
   2574       break;
   2575     case Instruction::DIV_INT_2ADDR:
   2576       work_line_->CheckBinaryOp2addr(inst,
   2577                                      reg_types_.Integer(),
   2578                                      reg_types_.Integer(),
   2579                                      reg_types_.Integer(),
   2580                                      false);
   2581       break;
   2582     case Instruction::ADD_LONG_2ADDR:
   2583     case Instruction::SUB_LONG_2ADDR:
   2584     case Instruction::MUL_LONG_2ADDR:
   2585     case Instruction::DIV_LONG_2ADDR:
   2586     case Instruction::REM_LONG_2ADDR:
   2587     case Instruction::AND_LONG_2ADDR:
   2588     case Instruction::OR_LONG_2ADDR:
   2589     case Instruction::XOR_LONG_2ADDR:
   2590       work_line_->CheckBinaryOp2addrWide(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2591                                          reg_types_.LongLo(), reg_types_.LongHi(),
   2592                                          reg_types_.LongLo(), reg_types_.LongHi());
   2593       break;
   2594     case Instruction::SHL_LONG_2ADDR:
   2595     case Instruction::SHR_LONG_2ADDR:
   2596     case Instruction::USHR_LONG_2ADDR:
   2597       work_line_->CheckBinaryOp2addrWideShift(inst, reg_types_.LongLo(), reg_types_.LongHi(),
   2598                                               reg_types_.Integer());
   2599       break;
   2600     case Instruction::ADD_FLOAT_2ADDR:
   2601     case Instruction::SUB_FLOAT_2ADDR:
   2602     case Instruction::MUL_FLOAT_2ADDR:
   2603     case Instruction::DIV_FLOAT_2ADDR:
   2604     case Instruction::REM_FLOAT_2ADDR:
   2605       work_line_->CheckBinaryOp2addr(inst,
   2606                                      reg_types_.Float(),
   2607                                      reg_types_.Float(),
   2608                                      reg_types_.Float(),
   2609                                      false);
   2610       break;
   2611     case Instruction::ADD_DOUBLE_2ADDR:
   2612     case Instruction::SUB_DOUBLE_2ADDR:
   2613     case Instruction::MUL_DOUBLE_2ADDR:
   2614     case Instruction::DIV_DOUBLE_2ADDR:
   2615     case Instruction::REM_DOUBLE_2ADDR:
   2616       work_line_->CheckBinaryOp2addrWide(inst, reg_types_.DoubleLo(), reg_types_.DoubleHi(),
   2617                                          reg_types_.DoubleLo(),  reg_types_.DoubleHi(),
   2618                                          reg_types_.DoubleLo(), reg_types_.DoubleHi());
   2619       break;
   2620     case Instruction::ADD_INT_LIT16:
   2621     case Instruction::RSUB_INT:
   2622     case Instruction::MUL_INT_LIT16:
   2623     case Instruction::DIV_INT_LIT16:
   2624     case Instruction::REM_INT_LIT16:
   2625       work_line_->CheckLiteralOp(inst, reg_types_.Integer(), reg_types_.Integer(), false, true);
   2626       break;
   2627     case Instruction::AND_INT_LIT16:
   2628     case Instruction::OR_INT_LIT16:
   2629     case Instruction::XOR_INT_LIT16:
   2630       work_line_->CheckLiteralOp(inst, reg_types_.Integer(), reg_types_.Integer(), true, true);
   2631       break;
   2632     case Instruction::ADD_INT_LIT8:
   2633     case Instruction::RSUB_INT_LIT8:
   2634     case Instruction::MUL_INT_LIT8:
   2635     case Instruction::DIV_INT_LIT8:
   2636     case Instruction::REM_INT_LIT8:
   2637     case Instruction::SHL_INT_LIT8:
   2638     case Instruction::SHR_INT_LIT8:
   2639     case Instruction::USHR_INT_LIT8:
   2640       work_line_->CheckLiteralOp(inst, reg_types_.Integer(), reg_types_.Integer(), false, false);
   2641       break;
   2642     case Instruction::AND_INT_LIT8:
   2643     case Instruction::OR_INT_LIT8:
   2644     case Instruction::XOR_INT_LIT8:
   2645       work_line_->CheckLiteralOp(inst, reg_types_.Integer(), reg_types_.Integer(), true, false);
   2646       break;
   2647 
   2648     // Special instructions.
   2649     case Instruction::RETURN_VOID_BARRIER:
   2650       if (!IsConstructor() || IsStatic()) {
   2651           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "return-void-barrier not expected";
   2652       }
   2653       break;
   2654     // Note: the following instructions encode offsets derived from class linking.
   2655     // As such they use Class*/Field*/AbstractMethod* as these offsets only have
   2656     // meaning if the class linking and resolution were successful.
   2657     case Instruction::IGET_QUICK:
   2658       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.Integer(), true);
   2659       break;
   2660     case Instruction::IGET_WIDE_QUICK:
   2661       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.LongLo(), true);
   2662       break;
   2663     case Instruction::IGET_OBJECT_QUICK:
   2664       VerifyQuickFieldAccess<FieldAccessType::kAccGet>(inst, reg_types_.JavaLangObject(false), false);
   2665       break;
   2666     case Instruction::IPUT_QUICK:
   2667       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.Integer(), true);
   2668       break;
   2669     case Instruction::IPUT_WIDE_QUICK:
   2670       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.LongLo(), true);
   2671       break;
   2672     case Instruction::IPUT_OBJECT_QUICK:
   2673       VerifyQuickFieldAccess<FieldAccessType::kAccPut>(inst, reg_types_.JavaLangObject(false), false);
   2674       break;
   2675     case Instruction::INVOKE_VIRTUAL_QUICK:
   2676     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
   2677       bool is_range = (inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   2678       mirror::ArtMethod* called_method = VerifyInvokeVirtualQuickArgs(inst, is_range);
   2679       if (called_method != nullptr) {
   2680         const char* descriptor = called_method->GetReturnTypeDescriptor();
   2681         RegType& return_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor,
   2682                                                                false);
   2683         if (!return_type.IsLowHalf()) {
   2684           work_line_->SetResultRegisterType(return_type);
   2685         } else {
   2686           work_line_->SetResultRegisterTypeWide(return_type, return_type.HighHalf(&reg_types_));
   2687         }
   2688         just_set_result = true;
   2689       }
   2690       break;
   2691     }
   2692 
   2693     /* These should never appear during verification. */
   2694     case Instruction::UNUSED_3E:
   2695     case Instruction::UNUSED_3F:
   2696     case Instruction::UNUSED_40:
   2697     case Instruction::UNUSED_41:
   2698     case Instruction::UNUSED_42:
   2699     case Instruction::UNUSED_43:
   2700     case Instruction::UNUSED_79:
   2701     case Instruction::UNUSED_7A:
   2702     case Instruction::UNUSED_EB:
   2703     case Instruction::UNUSED_EC:
   2704     case Instruction::UNUSED_ED:
   2705     case Instruction::UNUSED_EE:
   2706     case Instruction::UNUSED_EF:
   2707     case Instruction::UNUSED_F0:
   2708     case Instruction::UNUSED_F1:
   2709     case Instruction::UNUSED_F2:
   2710     case Instruction::UNUSED_F3:
   2711     case Instruction::UNUSED_F4:
   2712     case Instruction::UNUSED_F5:
   2713     case Instruction::UNUSED_F6:
   2714     case Instruction::UNUSED_F7:
   2715     case Instruction::UNUSED_F8:
   2716     case Instruction::UNUSED_F9:
   2717     case Instruction::UNUSED_FA:
   2718     case Instruction::UNUSED_FB:
   2719     case Instruction::UNUSED_FC:
   2720     case Instruction::UNUSED_FD:
   2721     case Instruction::UNUSED_FE:
   2722     case Instruction::UNUSED_FF:
   2723       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Unexpected opcode " << inst->DumpString(dex_file_);
   2724       break;
   2725 
   2726     /*
   2727      * DO NOT add a "default" clause here. Without it the compiler will
   2728      * complain if an instruction is missing (which is desirable).
   2729      */
   2730   }  // end - switch (dec_insn.opcode)
   2731 
   2732   if (have_pending_hard_failure_) {
   2733     if (Runtime::Current()->IsCompiler()) {
   2734       /* When compiling, check that the last failure is a hard failure */
   2735       CHECK_EQ(failures_[failures_.size() - 1], VERIFY_ERROR_BAD_CLASS_HARD);
   2736     }
   2737     /* immediate failure, reject class */
   2738     info_messages_ << "Rejecting opcode " << inst->DumpString(dex_file_);
   2739     return false;
   2740   } else if (have_pending_runtime_throw_failure_) {
   2741     /* checking interpreter will throw, mark following code as unreachable */
   2742     opcode_flags = Instruction::kThrow;
   2743   }
   2744   /*
   2745    * If we didn't just set the result register, clear it out. This ensures that you can only use
   2746    * "move-result" immediately after the result is set. (We could check this statically, but it's
   2747    * not expensive and it makes our debugging output cleaner.)
   2748    */
   2749   if (!just_set_result) {
   2750     work_line_->SetResultTypeToUnknown();
   2751   }
   2752 
   2753 
   2754 
   2755   /*
   2756    * Handle "branch". Tag the branch target.
   2757    *
   2758    * NOTE: instructions like Instruction::EQZ provide information about the
   2759    * state of the register when the branch is taken or not taken. For example,
   2760    * somebody could get a reference field, check it for zero, and if the
   2761    * branch is taken immediately store that register in a boolean field
   2762    * since the value is known to be zero. We do not currently account for
   2763    * that, and will reject the code.
   2764    *
   2765    * TODO: avoid re-fetching the branch target
   2766    */
   2767   if ((opcode_flags & Instruction::kBranch) != 0) {
   2768     bool isConditional, selfOkay;
   2769     if (!GetBranchOffset(work_insn_idx_, &branch_target, &isConditional, &selfOkay)) {
   2770       /* should never happen after static verification */
   2771       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "bad branch";
   2772       return false;
   2773     }
   2774     DCHECK_EQ(isConditional, (opcode_flags & Instruction::kContinue) != 0);
   2775     if (!CheckNotMoveException(code_item_->insns_, work_insn_idx_ + branch_target)) {
   2776       return false;
   2777     }
   2778     /* update branch target, set "changed" if appropriate */
   2779     if (nullptr != branch_line.get()) {
   2780       if (!UpdateRegisters(work_insn_idx_ + branch_target, branch_line.get(), false)) {
   2781         return false;
   2782       }
   2783     } else {
   2784       if (!UpdateRegisters(work_insn_idx_ + branch_target, work_line_.get(), false)) {
   2785         return false;
   2786       }
   2787     }
   2788   }
   2789 
   2790   /*
   2791    * Handle "switch". Tag all possible branch targets.
   2792    *
   2793    * We've already verified that the table is structurally sound, so we
   2794    * just need to walk through and tag the targets.
   2795    */
   2796   if ((opcode_flags & Instruction::kSwitch) != 0) {
   2797     int offset_to_switch = insns[1] | (((int32_t) insns[2]) << 16);
   2798     const uint16_t* switch_insns = insns + offset_to_switch;
   2799     int switch_count = switch_insns[1];
   2800     int offset_to_targets, targ;
   2801 
   2802     if ((*insns & 0xff) == Instruction::PACKED_SWITCH) {
   2803       /* 0 = sig, 1 = count, 2/3 = first key */
   2804       offset_to_targets = 4;
   2805     } else {
   2806       /* 0 = sig, 1 = count, 2..count * 2 = keys */
   2807       DCHECK((*insns & 0xff) == Instruction::SPARSE_SWITCH);
   2808       offset_to_targets = 2 + 2 * switch_count;
   2809     }
   2810 
   2811     /* verify each switch target */
   2812     for (targ = 0; targ < switch_count; targ++) {
   2813       int offset;
   2814       uint32_t abs_offset;
   2815 
   2816       /* offsets are 32-bit, and only partly endian-swapped */
   2817       offset = switch_insns[offset_to_targets + targ * 2] |
   2818          (((int32_t) switch_insns[offset_to_targets + targ * 2 + 1]) << 16);
   2819       abs_offset = work_insn_idx_ + offset;
   2820       DCHECK_LT(abs_offset, code_item_->insns_size_in_code_units_);
   2821       if (!CheckNotMoveException(code_item_->insns_, abs_offset)) {
   2822         return false;
   2823       }
   2824       if (!UpdateRegisters(abs_offset, work_line_.get(), false)) {
   2825         return false;
   2826       }
   2827     }
   2828   }
   2829 
   2830   /*
   2831    * Handle instructions that can throw and that are sitting in a "try" block. (If they're not in a
   2832    * "try" block when they throw, control transfers out of the method.)
   2833    */
   2834   if ((opcode_flags & Instruction::kThrow) != 0 && insn_flags_[work_insn_idx_].IsInTry()) {
   2835     bool has_catch_all_handler = false;
   2836     CatchHandlerIterator iterator(*code_item_, work_insn_idx_);
   2837 
   2838     // Need the linker to try and resolve the handled class to check if it's Throwable.
   2839     ClassLinker* linker = Runtime::Current()->GetClassLinker();
   2840 
   2841     for (; iterator.HasNext(); iterator.Next()) {
   2842       uint16_t handler_type_idx = iterator.GetHandlerTypeIndex();
   2843       if (handler_type_idx == DexFile::kDexNoIndex16) {
   2844         has_catch_all_handler = true;
   2845       } else {
   2846         // It is also a catch-all if it is java.lang.Throwable.
   2847         mirror::Class* klass = linker->ResolveType(*dex_file_, handler_type_idx, *dex_cache_,
   2848                                                    *class_loader_);
   2849         if (klass != nullptr) {
   2850           if (klass == mirror::Throwable::GetJavaLangThrowable()) {
   2851             has_catch_all_handler = true;
   2852           }
   2853         } else {
   2854           // Clear exception.
   2855           Thread* self = Thread::Current();
   2856           DCHECK(self->IsExceptionPending());
   2857           self->ClearException();
   2858         }
   2859       }
   2860       /*
   2861        * Merge registers into the "catch" block. We want to use the "savedRegs" rather than
   2862        * "work_regs", because at runtime the exception will be thrown before the instruction
   2863        * modifies any registers.
   2864        */
   2865       if (!UpdateRegisters(iterator.GetHandlerAddress(), saved_line_.get(), false)) {
   2866         return false;
   2867       }
   2868     }
   2869 
   2870     /*
   2871      * If the monitor stack depth is nonzero, there must be a "catch all" handler for this
   2872      * instruction. This does apply to monitor-exit because of async exception handling.
   2873      */
   2874     if (work_line_->MonitorStackDepth() > 0 && !has_catch_all_handler) {
   2875       /*
   2876        * The state in work_line reflects the post-execution state. If the current instruction is a
   2877        * monitor-enter and the monitor stack was empty, we don't need a catch-all (if it throws,
   2878        * it will do so before grabbing the lock).
   2879        */
   2880       if (inst->Opcode() != Instruction::MONITOR_ENTER || work_line_->MonitorStackDepth() != 1) {
   2881         Fail(VERIFY_ERROR_BAD_CLASS_HARD)
   2882             << "expected to be within a catch-all for an instruction where a monitor is held";
   2883         return false;
   2884       }
   2885     }
   2886   }
   2887 
   2888   /* Handle "continue". Tag the next consecutive instruction.
   2889    *  Note: Keep the code handling "continue" case below the "branch" and "switch" cases,
   2890    *        because it changes work_line_ when performing peephole optimization
   2891    *        and this change should not be used in those cases.
   2892    */
   2893   if ((opcode_flags & Instruction::kContinue) != 0) {
   2894     uint32_t next_insn_idx = work_insn_idx_ + CurrentInsnFlags()->GetLengthInCodeUnits();
   2895     if (next_insn_idx >= code_item_->insns_size_in_code_units_) {
   2896       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Execution can walk off end of code area";
   2897       return false;
   2898     }
   2899     // The only way to get to a move-exception instruction is to get thrown there. Make sure the
   2900     // next instruction isn't one.
   2901     if (!CheckNotMoveException(code_item_->insns_, next_insn_idx)) {
   2902       return false;
   2903     }
   2904     if (nullptr != fallthrough_line.get()) {
   2905       // Make workline consistent with fallthrough computed from peephole optimization.
   2906       work_line_->CopyFromLine(fallthrough_line.get());
   2907     }
   2908     if (insn_flags_[next_insn_idx].IsReturn()) {
   2909       // For returns we only care about the operand to the return, all other registers are dead.
   2910       const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn_idx);
   2911       Instruction::Code opcode = ret_inst->Opcode();
   2912       if ((opcode == Instruction::RETURN_VOID) || (opcode == Instruction::RETURN_VOID_BARRIER)) {
   2913         work_line_->MarkAllRegistersAsConflicts();
   2914       } else {
   2915         if (opcode == Instruction::RETURN_WIDE) {
   2916           work_line_->MarkAllRegistersAsConflictsExceptWide(ret_inst->VRegA_11x());
   2917         } else {
   2918           work_line_->MarkAllRegistersAsConflictsExcept(ret_inst->VRegA_11x());
   2919         }
   2920       }
   2921     }
   2922     RegisterLine* next_line = reg_table_.GetLine(next_insn_idx);
   2923     if (next_line != nullptr) {
   2924       // Merge registers into what we have for the next instruction, and set the "changed" flag if
   2925       // needed. If the merge changes the state of the registers then the work line will be
   2926       // updated.
   2927       if (!UpdateRegisters(next_insn_idx, work_line_.get(), true)) {
   2928         return false;
   2929       }
   2930     } else {
   2931       /*
   2932        * We're not recording register data for the next instruction, so we don't know what the
   2933        * prior state was. We have to assume that something has changed and re-evaluate it.
   2934        */
   2935       insn_flags_[next_insn_idx].SetChanged();
   2936     }
   2937   }
   2938 
   2939   /* If we're returning from the method, make sure monitor stack is empty. */
   2940   if ((opcode_flags & Instruction::kReturn) != 0) {
   2941     if (!work_line_->VerifyMonitorStackEmpty()) {
   2942       return false;
   2943     }
   2944   }
   2945 
   2946   /*
   2947    * Update start_guess. Advance to the next instruction of that's
   2948    * possible, otherwise use the branch target if one was found. If
   2949    * neither of those exists we're in a return or throw; leave start_guess
   2950    * alone and let the caller sort it out.
   2951    */
   2952   if ((opcode_flags & Instruction::kContinue) != 0) {
   2953     *start_guess = work_insn_idx_ + insn_flags_[work_insn_idx_].GetLengthInCodeUnits();
   2954   } else if ((opcode_flags & Instruction::kBranch) != 0) {
   2955     /* we're still okay if branch_target is zero */
   2956     *start_guess = work_insn_idx_ + branch_target;
   2957   }
   2958 
   2959   DCHECK_LT(*start_guess, code_item_->insns_size_in_code_units_);
   2960   DCHECK(insn_flags_[*start_guess].IsOpcode());
   2961 
   2962   return true;
   2963 }  // NOLINT(readability/fn_size)
   2964 
   2965 RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
   2966   const char* descriptor = dex_file_->StringByTypeIdx(class_idx);
   2967   RegType& referrer = GetDeclaringClass();
   2968   mirror::Class* klass = (*dex_cache_)->GetResolvedType(class_idx);
   2969   RegType& result =
   2970       klass != nullptr ? reg_types_.FromClass(descriptor, klass,
   2971                                            klass->CannotBeAssignedFromOtherTypes())
   2972                     : reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   2973   if (result.IsConflict()) {
   2974     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
   2975         << "' in " << referrer;
   2976     return result;
   2977   }
   2978   if (klass == nullptr && !result.IsUnresolvedTypes()) {
   2979     (*dex_cache_)->SetResolvedType(class_idx, result.GetClass());
   2980   }
   2981   // Check if access is allowed. Unresolved types use xxxWithAccessCheck to
   2982   // check at runtime if access is allowed and so pass here. If result is
   2983   // primitive, skip the access check.
   2984   if (result.IsNonZeroReferenceTypes() && !result.IsUnresolvedTypes() &&
   2985       !referrer.IsUnresolvedTypes() && !referrer.CanAccess(result)) {
   2986     Fail(VERIFY_ERROR_ACCESS_CLASS) << "illegal class access: '"
   2987                                     << referrer << "' -> '" << result << "'";
   2988   }
   2989   return result;
   2990 }
   2991 
   2992 RegType& MethodVerifier::GetCaughtExceptionType() {
   2993   RegType* common_super = nullptr;
   2994   if (code_item_->tries_size_ != 0) {
   2995     const byte* handlers_ptr = DexFile::GetCatchHandlerData(*code_item_, 0);
   2996     uint32_t handlers_size = DecodeUnsignedLeb128(&handlers_ptr);
   2997     for (uint32_t i = 0; i < handlers_size; i++) {
   2998       CatchHandlerIterator iterator(handlers_ptr);
   2999       for (; iterator.HasNext(); iterator.Next()) {
   3000         if (iterator.GetHandlerAddress() == (uint32_t) work_insn_idx_) {
   3001           if (iterator.GetHandlerTypeIndex() == DexFile::kDexNoIndex16) {
   3002             common_super = &reg_types_.JavaLangThrowable(false);
   3003           } else {
   3004             RegType& exception = ResolveClassAndCheckAccess(iterator.GetHandlerTypeIndex());
   3005             if (!reg_types_.JavaLangThrowable(false).IsAssignableFrom(exception)) {
   3006               if (exception.IsUnresolvedTypes()) {
   3007                 // We don't know enough about the type. Fail here and let runtime handle it.
   3008                 Fail(VERIFY_ERROR_NO_CLASS) << "unresolved exception class " << exception;
   3009                 return exception;
   3010               } else {
   3011                 Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unexpected non-exception class " << exception;
   3012                 return reg_types_.Conflict();
   3013               }
   3014             } else if (common_super == nullptr) {
   3015               common_super = &exception;
   3016             } else if (common_super->Equals(exception)) {
   3017               // odd case, but nothing to do
   3018             } else {
   3019               common_super = &common_super->Merge(exception, &reg_types_);
   3020               if (FailOrAbort(this,
   3021                               reg_types_.JavaLangThrowable(false).IsAssignableFrom(*common_super),
   3022                               "java.lang.Throwable is not assignable-from common_super at ",
   3023                               work_insn_idx_)) {
   3024                 break;
   3025               }
   3026             }
   3027           }
   3028         }
   3029       }
   3030       handlers_ptr = iterator.EndDataPointer();
   3031     }
   3032   }
   3033   if (common_super == nullptr) {
   3034     /* no catch blocks, or no catches with classes we can find */
   3035     Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "unable to find exception handler";
   3036     return reg_types_.Conflict();
   3037   }
   3038   return *common_super;
   3039 }
   3040 
   3041 mirror::ArtMethod* MethodVerifier::ResolveMethodAndCheckAccess(uint32_t dex_method_idx,
   3042                                                                MethodType method_type) {
   3043   const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx);
   3044   RegType& klass_type = ResolveClassAndCheckAccess(method_id.class_idx_);
   3045   if (klass_type.IsConflict()) {
   3046     std::string append(" in attempt to access method ");
   3047     append += dex_file_->GetMethodName(method_id);
   3048     AppendToLastFailMessage(append);
   3049     return nullptr;
   3050   }
   3051   if (klass_type.IsUnresolvedTypes()) {
   3052     return nullptr;  // Can't resolve Class so no more to do here
   3053   }
   3054   mirror::Class* klass = klass_type.GetClass();
   3055   RegType& referrer = GetDeclaringClass();
   3056   mirror::ArtMethod* res_method = (*dex_cache_)->GetResolvedMethod(dex_method_idx);
   3057   if (res_method == nullptr) {
   3058     const char* name = dex_file_->GetMethodName(method_id);
   3059     const Signature signature = dex_file_->GetMethodSignature(method_id);
   3060 
   3061     if (method_type == METHOD_DIRECT || method_type == METHOD_STATIC) {
   3062       res_method = klass->FindDirectMethod(name, signature);
   3063     } else if (method_type == METHOD_INTERFACE) {
   3064       res_method = klass->FindInterfaceMethod(name, signature);
   3065     } else {
   3066       res_method = klass->FindVirtualMethod(name, signature);
   3067     }
   3068     if (res_method != nullptr) {
   3069       (*dex_cache_)->SetResolvedMethod(dex_method_idx, res_method);
   3070     } else {
   3071       // If a virtual or interface method wasn't found with the expected type, look in
   3072       // the direct methods. This can happen when the wrong invoke type is used or when
   3073       // a class has changed, and will be flagged as an error in later checks.
   3074       if (method_type == METHOD_INTERFACE || method_type == METHOD_VIRTUAL) {
   3075         res_method = klass->FindDirectMethod(name, signature);
   3076       }
   3077       if (res_method == nullptr) {
   3078         Fail(VERIFY_ERROR_NO_METHOD) << "couldn't find method "
   3079                                      << PrettyDescriptor(klass) << "." << name
   3080                                      << " " << signature;
   3081         return nullptr;
   3082       }
   3083     }
   3084   }
   3085   // Make sure calls to constructors are "direct". There are additional restrictions but we don't
   3086   // enforce them here.
   3087   if (res_method->IsConstructor() && method_type != METHOD_DIRECT) {
   3088     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting non-direct call to constructor "
   3089                                       << PrettyMethod(res_method);
   3090     return nullptr;
   3091   }
   3092   // Disallow any calls to class initializers.
   3093   if (res_method->IsClassInitializer()) {
   3094     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "rejecting call to class initializer "
   3095                                       << PrettyMethod(res_method);
   3096     return nullptr;
   3097   }
   3098   // Check if access is allowed.
   3099   if (!referrer.CanAccessMember(res_method->GetDeclaringClass(), res_method->GetAccessFlags())) {
   3100     Fail(VERIFY_ERROR_ACCESS_METHOD) << "illegal method access (call " << PrettyMethod(res_method)
   3101                                      << " from " << referrer << ")";
   3102     return res_method;
   3103   }
   3104   // Check that invoke-virtual and invoke-super are not used on private methods of the same class.
   3105   if (res_method->IsPrivate() && method_type == METHOD_VIRTUAL) {
   3106     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invoke-super/virtual can't be used on private method "
   3107                                       << PrettyMethod(res_method);
   3108     return nullptr;
   3109   }
   3110   // Check that interface methods match interface classes.
   3111   if (klass->IsInterface() && method_type != METHOD_INTERFACE) {
   3112     Fail(VERIFY_ERROR_CLASS_CHANGE) << "non-interface method " << PrettyMethod(res_method)
   3113                                     << " is in an interface class " << PrettyClass(klass);
   3114     return nullptr;
   3115   } else if (!klass->IsInterface() && method_type == METHOD_INTERFACE) {
   3116     Fail(VERIFY_ERROR_CLASS_CHANGE) << "interface method " << PrettyMethod(res_method)
   3117                                     << " is in a non-interface class " << PrettyClass(klass);
   3118     return nullptr;
   3119   }
   3120   // See if the method type implied by the invoke instruction matches the access flags for the
   3121   // target method.
   3122   if ((method_type == METHOD_DIRECT && (!res_method->IsDirect() || res_method->IsStatic())) ||
   3123       (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
   3124       ((method_type == METHOD_VIRTUAL || method_type == METHOD_INTERFACE) && res_method->IsDirect())
   3125       ) {
   3126     Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type (" << method_type << ") does not match method "
   3127                                        " type of " << PrettyMethod(res_method);
   3128     return nullptr;
   3129   }
   3130   return res_method;
   3131 }
   3132 
   3133 template <class T>
   3134 mirror::ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(T* it, const Instruction* inst,
   3135                                                                     MethodType method_type,
   3136                                                                     bool is_range,
   3137                                                                     mirror::ArtMethod* res_method) {
   3138   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
   3139   // match the call to the signature. Also, we might be calling through an abstract method
   3140   // definition (which doesn't have register count values).
   3141   const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   3142   /* caught by static verifier */
   3143   DCHECK(is_range || expected_args <= 5);
   3144   if (expected_args > code_item_->outs_size_) {
   3145     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
   3146         << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
   3147     return nullptr;
   3148   }
   3149 
   3150   uint32_t arg[5];
   3151   if (!is_range) {
   3152     inst->GetVarArgs(arg);
   3153   }
   3154   uint32_t sig_registers = 0;
   3155 
   3156   /*
   3157    * Check the "this" argument, which must be an instance of the class that declared the method.
   3158    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
   3159    * rigorous check here (which is okay since we have to do it at runtime).
   3160    */
   3161   if (method_type != METHOD_STATIC) {
   3162     RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
   3163     if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
   3164       CHECK(have_pending_hard_failure_);
   3165       return nullptr;
   3166     }
   3167     if (actual_arg_type.IsUninitializedReference()) {
   3168       if (res_method) {
   3169         if (!res_method->IsConstructor()) {
   3170           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   3171           return nullptr;
   3172         }
   3173       } else {
   3174         // Check whether the name of the called method is "<init>"
   3175         const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3176         if (strcmp(dex_file_->GetMethodName(dex_file_->GetMethodId(method_idx)), "<init>") != 0) {
   3177           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   3178           return nullptr;
   3179         }
   3180       }
   3181     }
   3182     if (method_type != METHOD_INTERFACE && !actual_arg_type.IsZero()) {
   3183       RegType* res_method_class;
   3184       if (res_method != nullptr) {
   3185         mirror::Class* klass = res_method->GetDeclaringClass();
   3186         std::string temp;
   3187         res_method_class = &reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
   3188                                                  klass->CannotBeAssignedFromOtherTypes());
   3189       } else {
   3190         const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3191         const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
   3192         res_method_class = &reg_types_.FromDescriptor(class_loader_->Get(),
   3193                                                       dex_file_->StringByTypeIdx(class_idx),
   3194                                                       false);
   3195       }
   3196       if (!res_method_class->IsAssignableFrom(actual_arg_type)) {
   3197         Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS:
   3198             VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
   3199                 << "' not instance of '" << *res_method_class << "'";
   3200         // Continue on soft failures. We need to find possible hard failures to avoid problems in
   3201         // the compiler.
   3202         if (have_pending_hard_failure_) {
   3203           return nullptr;
   3204         }
   3205       }
   3206     }
   3207     sig_registers = 1;
   3208   }
   3209 
   3210   for ( ; it->HasNext(); it->Next()) {
   3211     if (sig_registers >= expected_args) {
   3212       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << inst->VRegA() <<
   3213           " arguments, found " << sig_registers << " or more.";
   3214       return nullptr;
   3215     }
   3216 
   3217     const char* param_descriptor = it->GetDescriptor();
   3218 
   3219     if (param_descriptor == nullptr) {
   3220       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation because of missing signature "
   3221           "component";
   3222       return nullptr;
   3223     }
   3224 
   3225     RegType& reg_type = reg_types_.FromDescriptor(class_loader_->Get(), param_descriptor,
   3226                                                         false);
   3227     uint32_t get_reg = is_range ? inst->VRegC_3rc() + static_cast<uint32_t>(sig_registers) :
   3228         arg[sig_registers];
   3229     if (reg_type.IsIntegralTypes()) {
   3230       RegType& src_type = work_line_->GetRegisterType(get_reg);
   3231       if (!src_type.IsIntegralTypes()) {
   3232         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "register v" << get_reg << " has type " << src_type
   3233             << " but expected " << reg_type;
   3234         return res_method;
   3235       }
   3236     } else if (!work_line_->VerifyRegisterType(get_reg, reg_type)) {
   3237       // Continue on soft failures. We need to find possible hard failures to avoid problems in the
   3238       // compiler.
   3239       if (have_pending_hard_failure_) {
   3240         return res_method;
   3241       }
   3242     }
   3243     sig_registers += reg_type.IsLongOrDoubleTypes() ?  2 : 1;
   3244   }
   3245   if (expected_args != sig_registers) {
   3246     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation, expected " << expected_args <<
   3247         " arguments, found " << sig_registers;
   3248     return nullptr;
   3249   }
   3250   return res_method;
   3251 }
   3252 
   3253 void MethodVerifier::VerifyInvocationArgsUnresolvedMethod(const Instruction* inst,
   3254                                                           MethodType method_type,
   3255                                                           bool is_range) {
   3256   // As the method may not have been resolved, make this static check against what we expect.
   3257   // The main reason for this code block is to fail hard when we find an illegal use, e.g.,
   3258   // wrong number of arguments or wrong primitive types, even if the method could not be resolved.
   3259   const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3260   DexFileParameterIterator it(*dex_file_,
   3261                               dex_file_->GetProtoId(dex_file_->GetMethodId(method_idx).proto_idx_));
   3262   VerifyInvocationArgsFromIterator<DexFileParameterIterator>(&it, inst, method_type, is_range,
   3263                                                              nullptr);
   3264 }
   3265 
   3266 class MethodParamListDescriptorIterator {
   3267  public:
   3268   explicit MethodParamListDescriptorIterator(mirror::ArtMethod* res_method) :
   3269       res_method_(res_method), pos_(0), params_(res_method->GetParameterTypeList()),
   3270       params_size_(params_ == nullptr ? 0 : params_->Size()) {
   3271   }
   3272 
   3273   bool HasNext() {
   3274     return pos_ < params_size_;
   3275   }
   3276 
   3277   void Next() {
   3278     ++pos_;
   3279   }
   3280 
   3281   const char* GetDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
   3282     return res_method_->GetTypeDescriptorFromTypeIdx(params_->GetTypeItem(pos_).type_idx_);
   3283   }
   3284 
   3285  private:
   3286   mirror::ArtMethod* res_method_;
   3287   size_t pos_;
   3288   const DexFile::TypeList* params_;
   3289   const size_t params_size_;
   3290 };
   3291 
   3292 mirror::ArtMethod* MethodVerifier::VerifyInvocationArgs(const Instruction* inst,
   3293                                                              MethodType method_type,
   3294                                                              bool is_range,
   3295                                                              bool is_super) {
   3296   // Resolve the method. This could be an abstract or concrete method depending on what sort of call
   3297   // we're making.
   3298   const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
   3299 
   3300   mirror::ArtMethod* res_method = ResolveMethodAndCheckAccess(method_idx, method_type);
   3301   if (res_method == nullptr) {  // error or class is unresolved
   3302     // Check what we can statically.
   3303     if (!have_pending_hard_failure_) {
   3304       VerifyInvocationArgsUnresolvedMethod(inst, method_type, is_range);
   3305     }
   3306     return nullptr;
   3307   }
   3308 
   3309   // If we're using invoke-super(method), make sure that the executing method's class' superclass
   3310   // has a vtable entry for the target method.
   3311   if (is_super) {
   3312     DCHECK(method_type == METHOD_VIRTUAL);
   3313     RegType& super = GetDeclaringClass().GetSuperClass(&reg_types_);
   3314     if (super.IsUnresolvedTypes()) {
   3315       Fail(VERIFY_ERROR_NO_METHOD) << "unknown super class in invoke-super from "
   3316                                    << PrettyMethod(dex_method_idx_, *dex_file_)
   3317                                    << " to super " << PrettyMethod(res_method);
   3318       return nullptr;
   3319     }
   3320     mirror::Class* super_klass = super.GetClass();
   3321     if (res_method->GetMethodIndex() >= super_klass->GetVTableLength()) {
   3322       Fail(VERIFY_ERROR_NO_METHOD) << "invalid invoke-super from "
   3323                                    << PrettyMethod(dex_method_idx_, *dex_file_)
   3324                                    << " to super " << super
   3325                                    << "." << res_method->GetName()
   3326                                    << res_method->GetSignature();
   3327       return nullptr;
   3328     }
   3329   }
   3330 
   3331   // Process the target method's signature. This signature may or may not
   3332   MethodParamListDescriptorIterator it(res_method);
   3333   return VerifyInvocationArgsFromIterator<MethodParamListDescriptorIterator>(&it, inst, method_type,
   3334                                                                              is_range, res_method);
   3335 }
   3336 
   3337 mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst,
   3338                                                          RegisterLine* reg_line, bool is_range) {
   3339   DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK ||
   3340          inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK);
   3341   RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range);
   3342   if (!actual_arg_type.HasClass()) {
   3343     VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'";
   3344     return nullptr;
   3345   }
   3346   mirror::Class* klass = actual_arg_type.GetClass();
   3347   mirror::Class* dispatch_class;
   3348   if (klass->IsInterface()) {
   3349     // Derive Object.class from Class.class.getSuperclass().
   3350     mirror::Class* object_klass = klass->GetClass()->GetSuperClass();
   3351     if (FailOrAbort(this, object_klass->IsObjectClass(),
   3352                     "Failed to find Object class in quickened invoke receiver",
   3353                     work_insn_idx_)) {
   3354       return nullptr;
   3355     }
   3356     dispatch_class = object_klass;
   3357   } else {
   3358     dispatch_class = klass;
   3359   }
   3360   if (FailOrAbort(this, dispatch_class->HasVTable(),
   3361                   "Receiver class has no vtable for quickened invoke at ",
   3362                   work_insn_idx_)) {
   3363     return nullptr;
   3364   }
   3365   uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c();
   3366   if (FailOrAbort(this, static_cast<int32_t>(vtable_index) < dispatch_class->GetVTableLength(),
   3367                   "Receiver class has not enough vtable slots for quickened invoke at ",
   3368                   work_insn_idx_)) {
   3369     return nullptr;
   3370   }
   3371   mirror::ArtMethod* res_method = dispatch_class->GetVTableEntry(vtable_index);
   3372   if (FailOrAbort(this, !Thread::Current()->IsExceptionPending(),
   3373                   "Unexpected exception pending for quickened invoke at ",
   3374                   work_insn_idx_)) {
   3375     return nullptr;
   3376   }
   3377   return res_method;
   3378 }
   3379 
   3380 mirror::ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst,
   3381                                                                 bool is_range) {
   3382   DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
   3383   mirror::ArtMethod* res_method = GetQuickInvokedMethod(inst, work_line_.get(),
   3384                                                              is_range);
   3385   if (res_method == nullptr) {
   3386     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer method from " << inst->Name();
   3387     return nullptr;
   3388   }
   3389   if (FailOrAbort(this, !res_method->IsDirect(), "Quick-invoked method is direct at ",
   3390                   work_insn_idx_)) {
   3391     return nullptr;
   3392   }
   3393   if (FailOrAbort(this, !res_method->IsStatic(), "Quick-invoked method is static at ",
   3394                   work_insn_idx_)) {
   3395     return nullptr;
   3396   }
   3397 
   3398   // We use vAA as our expected arg count, rather than res_method->insSize, because we need to
   3399   // match the call to the signature. Also, we might be calling through an abstract method
   3400   // definition (which doesn't have register count values).
   3401   RegType& actual_arg_type = work_line_->GetInvocationThis(inst, is_range);
   3402   if (actual_arg_type.IsConflict()) {  // GetInvocationThis failed.
   3403     return nullptr;
   3404   }
   3405   const size_t expected_args = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   3406   /* caught by static verifier */
   3407   DCHECK(is_range || expected_args <= 5);
   3408   if (expected_args > code_item_->outs_size_) {
   3409     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid argument count (" << expected_args
   3410         << ") exceeds outsSize (" << code_item_->outs_size_ << ")";
   3411     return nullptr;
   3412   }
   3413 
   3414   /*
   3415    * Check the "this" argument, which must be an instance of the class that declared the method.
   3416    * For an interface class, we don't do the full interface merge (see JoinClass), so we can't do a
   3417    * rigorous check here (which is okay since we have to do it at runtime).
   3418    */
   3419   if (actual_arg_type.IsUninitializedReference() && !res_method->IsConstructor()) {
   3420     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "'this' arg must be initialized";
   3421     return nullptr;
   3422   }
   3423   if (!actual_arg_type.IsZero()) {
   3424     mirror::Class* klass = res_method->GetDeclaringClass();
   3425     std::string temp;
   3426     RegType& res_method_class =
   3427         reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
   3428                              klass->CannotBeAssignedFromOtherTypes());
   3429     if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
   3430       Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS :
   3431           VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
   3432           << "' not instance of '" << res_method_class << "'";
   3433       return nullptr;
   3434     }
   3435   }
   3436   /*
   3437    * Process the target method's signature. This signature may or may not
   3438    * have been verified, so we can't assume it's properly formed.
   3439    */
   3440   const DexFile::TypeList* params = res_method->GetParameterTypeList();
   3441   size_t params_size = params == nullptr ? 0 : params->Size();
   3442   uint32_t arg[5];
   3443   if (!is_range) {
   3444     inst->GetVarArgs(arg);
   3445   }
   3446   size_t actual_args = 1;
   3447   for (size_t param_index = 0; param_index < params_size; param_index++) {
   3448     if (actual_args >= expected_args) {
   3449       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invalid call to '" << PrettyMethod(res_method)
   3450                                         << "'. Expected " << expected_args
   3451                                          << " arguments, processing argument " << actual_args
   3452                                         << " (where longs/doubles count twice).";
   3453       return nullptr;
   3454     }
   3455     const char* descriptor =
   3456         res_method->GetTypeDescriptorFromTypeIdx(params->GetTypeItem(param_index).type_idx_);
   3457     if (descriptor == nullptr) {
   3458       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
   3459                                         << " missing signature component";
   3460       return nullptr;
   3461     }
   3462     RegType& reg_type = reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   3463     uint32_t get_reg = is_range ? inst->VRegC_3rc() + actual_args : arg[actual_args];
   3464     if (!work_line_->VerifyRegisterType(get_reg, reg_type)) {
   3465       return res_method;
   3466     }
   3467     actual_args = reg_type.IsLongOrDoubleTypes() ? actual_args + 2 : actual_args + 1;
   3468   }
   3469   if (actual_args != expected_args) {
   3470     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Rejecting invocation of " << PrettyMethod(res_method)
   3471               << " expected " << expected_args << " arguments, found " << actual_args;
   3472     return nullptr;
   3473   } else {
   3474     return res_method;
   3475   }
   3476 }
   3477 
   3478 void MethodVerifier::VerifyNewArray(const Instruction* inst, bool is_filled, bool is_range) {
   3479   uint32_t type_idx;
   3480   if (!is_filled) {
   3481     DCHECK_EQ(inst->Opcode(), Instruction::NEW_ARRAY);
   3482     type_idx = inst->VRegC_22c();
   3483   } else if (!is_range) {
   3484     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY);
   3485     type_idx = inst->VRegB_35c();
   3486   } else {
   3487     DCHECK_EQ(inst->Opcode(), Instruction::FILLED_NEW_ARRAY_RANGE);
   3488     type_idx = inst->VRegB_3rc();
   3489   }
   3490   RegType& res_type = ResolveClassAndCheckAccess(type_idx);
   3491   if (res_type.IsConflict()) {  // bad class
   3492     DCHECK_NE(failures_.size(), 0U);
   3493   } else {
   3494     // TODO: check Compiler::CanAccessTypeWithoutChecks returns false when res_type is unresolved
   3495     if (!res_type.IsArrayTypes()) {
   3496       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "new-array on non-array class " << res_type;
   3497     } else if (!is_filled) {
   3498       /* make sure "size" register is valid type */
   3499       work_line_->VerifyRegisterType(inst->VRegB_22c(), reg_types_.Integer());
   3500       /* set register type to array class */
   3501       RegType& precise_type = reg_types_.FromUninitialized(res_type);
   3502       work_line_->SetRegisterType(inst->VRegA_22c(), precise_type);
   3503     } else {
   3504       // Verify each register. If "arg_count" is bad, VerifyRegisterType() will run off the end of
   3505       // the list and fail. It's legal, if silly, for arg_count to be zero.
   3506       RegType& expected_type = reg_types_.GetComponentType(res_type, class_loader_->Get());
   3507       uint32_t arg_count = (is_range) ? inst->VRegA_3rc() : inst->VRegA_35c();
   3508       uint32_t arg[5];
   3509       if (!is_range) {
   3510         inst->GetVarArgs(arg);
   3511       }
   3512       for (size_t ui = 0; ui < arg_count; ui++) {
   3513         uint32_t get_reg = is_range ? inst->VRegC_3rc() + ui : arg[ui];
   3514         if (!work_line_->VerifyRegisterType(get_reg, expected_type)) {
   3515           work_line_->SetResultRegisterType(reg_types_.Conflict());
   3516           return;
   3517         }
   3518       }
   3519       // filled-array result goes into "result" register
   3520       RegType& precise_type = reg_types_.FromUninitialized(res_type);
   3521       work_line_->SetResultRegisterType(precise_type);
   3522     }
   3523   }
   3524 }
   3525 
   3526 void MethodVerifier::VerifyAGet(const Instruction* inst,
   3527                                 RegType& insn_type, bool is_primitive) {
   3528   RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
   3529   if (!index_type.IsArrayIndexTypes()) {
   3530     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   3531   } else {
   3532     RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
   3533     if (array_type.IsZero()) {
   3534       // Null array class; this code path will fail at runtime. Infer a merge-able type from the
   3535       // instruction type. TODO: have a proper notion of bottom here.
   3536       if (!is_primitive || insn_type.IsCategory1Types()) {
   3537         // Reference or category 1
   3538         work_line_->SetRegisterType(inst->VRegA_23x(), reg_types_.Zero());
   3539       } else {
   3540         // Category 2
   3541         work_line_->SetRegisterTypeWide(inst->VRegA_23x(), reg_types_.FromCat2ConstLo(0, false),
   3542                                         reg_types_.FromCat2ConstHi(0, false));
   3543       }
   3544     } else if (!array_type.IsArrayTypes()) {
   3545       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aget";
   3546     } else {
   3547       /* verify the class */
   3548       RegType& component_type = reg_types_.GetComponentType(array_type, class_loader_->Get());
   3549       if (!component_type.IsReferenceTypes() && !is_primitive) {
   3550         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   3551             << " source for aget-object";
   3552       } else if (component_type.IsNonZeroReferenceTypes() && is_primitive) {
   3553         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "reference array type " << array_type
   3554             << " source for category 1 aget";
   3555       } else if (is_primitive && !insn_type.Equals(component_type) &&
   3556                  !((insn_type.IsInteger() && component_type.IsFloat()) ||
   3557                  (insn_type.IsLong() && component_type.IsDouble()))) {
   3558         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "array type " << array_type
   3559             << " incompatible with aget of type " << insn_type;
   3560       } else {
   3561         // Use knowledge of the field type which is stronger than the type inferred from the
   3562         // instruction, which can't differentiate object types and ints from floats, longs from
   3563         // doubles.
   3564         if (!component_type.IsLowHalf()) {
   3565           work_line_->SetRegisterType(inst->VRegA_23x(), component_type);
   3566         } else {
   3567           work_line_->SetRegisterTypeWide(inst->VRegA_23x(), component_type,
   3568                                           component_type.HighHalf(&reg_types_));
   3569         }
   3570       }
   3571     }
   3572   }
   3573 }
   3574 
   3575 void MethodVerifier::VerifyPrimitivePut(RegType& target_type, RegType& insn_type,
   3576                                         const uint32_t vregA) {
   3577   // Primitive assignability rules are weaker than regular assignability rules.
   3578   bool instruction_compatible;
   3579   bool value_compatible;
   3580   RegType& value_type = work_line_->GetRegisterType(vregA);
   3581   if (target_type.IsIntegralTypes()) {
   3582     instruction_compatible = target_type.Equals(insn_type);
   3583     value_compatible = value_type.IsIntegralTypes();
   3584   } else if (target_type.IsFloat()) {
   3585     instruction_compatible = insn_type.IsInteger();  // no put-float, so expect put-int
   3586     value_compatible = value_type.IsFloatTypes();
   3587   } else if (target_type.IsLong()) {
   3588     instruction_compatible = insn_type.IsLong();
   3589     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   3590     // as target_type depends on the resolved type of the field.
   3591     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   3592       RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
   3593       value_compatible = value_type.IsLongTypes() && value_type.CheckWidePair(value_type_hi);
   3594     } else {
   3595       value_compatible = false;
   3596     }
   3597   } else if (target_type.IsDouble()) {
   3598     instruction_compatible = insn_type.IsLong();  // no put-double, so expect put-long
   3599     // Additional register check: this is not checked statically (as part of VerifyInstructions),
   3600     // as target_type depends on the resolved type of the field.
   3601     if (instruction_compatible && work_line_->NumRegs() > vregA + 1) {
   3602       RegType& value_type_hi = work_line_->GetRegisterType(vregA + 1);
   3603       value_compatible = value_type.IsDoubleTypes() && value_type.CheckWidePair(value_type_hi);
   3604     } else {
   3605       value_compatible = false;
   3606     }
   3607   } else {
   3608     instruction_compatible = false;  // reference with primitive store
   3609     value_compatible = false;  // unused
   3610   }
   3611   if (!instruction_compatible) {
   3612     // This is a global failure rather than a class change failure as the instructions and
   3613     // the descriptors for the type should have been consistent within the same file at
   3614     // compile time.
   3615     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "put insn has type '" << insn_type
   3616         << "' but expected type '" << target_type << "'";
   3617     return;
   3618   }
   3619   if (!value_compatible) {
   3620     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
   3621         << " of type " << value_type << " but expected " << target_type << " for put";
   3622     return;
   3623   }
   3624 }
   3625 
   3626 void MethodVerifier::VerifyAPut(const Instruction* inst,
   3627                                 RegType& insn_type, bool is_primitive) {
   3628   RegType& index_type = work_line_->GetRegisterType(inst->VRegC_23x());
   3629   if (!index_type.IsArrayIndexTypes()) {
   3630     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Invalid reg type for array index (" << index_type << ")";
   3631   } else {
   3632     RegType& array_type = work_line_->GetRegisterType(inst->VRegB_23x());
   3633     if (array_type.IsZero()) {
   3634       // Null array type; this code path will fail at runtime. Infer a merge-able type from the
   3635       // instruction type.
   3636     } else if (!array_type.IsArrayTypes()) {
   3637       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "not array type " << array_type << " with aput";
   3638     } else {
   3639       RegType& component_type = reg_types_.GetComponentType(array_type, class_loader_->Get());
   3640       const uint32_t vregA = inst->VRegA_23x();
   3641       if (is_primitive) {
   3642         VerifyPrimitivePut(component_type, insn_type, vregA);
   3643       } else {
   3644         if (!component_type.IsReferenceTypes()) {
   3645           Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "primitive array type " << array_type
   3646               << " source for aput-object";
   3647         } else {
   3648           // The instruction agrees with the type of array, confirm the value to be stored does too
   3649           // Note: we use the instruction type (rather than the component type) for aput-object as
   3650           // incompatible classes will be caught at runtime as an array store exception
   3651           work_line_->VerifyRegisterType(vregA, insn_type);
   3652         }
   3653       }
   3654     }
   3655   }
   3656 }
   3657 
   3658 mirror::ArtField* MethodVerifier::GetStaticField(int field_idx) {
   3659   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   3660   // Check access to class
   3661   RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
   3662   if (klass_type.IsConflict()) {  // bad class
   3663     AppendToLastFailMessage(StringPrintf(" in attempt to access static field %d (%s) in %s",
   3664                                          field_idx, dex_file_->GetFieldName(field_id),
   3665                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   3666     return nullptr;
   3667   }
   3668   if (klass_type.IsUnresolvedTypes()) {
   3669     return nullptr;  // Can't resolve Class so no more to do here, will do checking at runtime.
   3670   }
   3671   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   3672   mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, *dex_cache_,
   3673                                                           *class_loader_);
   3674   if (field == nullptr) {
   3675     VLOG(verifier) << "Unable to resolve static field " << field_idx << " ("
   3676               << dex_file_->GetFieldName(field_id) << ") in "
   3677               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   3678     DCHECK(Thread::Current()->IsExceptionPending());
   3679     Thread::Current()->ClearException();
   3680     return nullptr;
   3681   } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   3682                                                   field->GetAccessFlags())) {
   3683     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access static field " << PrettyField(field)
   3684                                     << " from " << GetDeclaringClass();
   3685     return nullptr;
   3686   } else if (!field->IsStatic()) {
   3687     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << PrettyField(field) << " to be static";
   3688     return nullptr;
   3689   }
   3690   return field;
   3691 }
   3692 
   3693 mirror::ArtField* MethodVerifier::GetInstanceField(RegType& obj_type, int field_idx) {
   3694   const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   3695   // Check access to class
   3696   RegType& klass_type = ResolveClassAndCheckAccess(field_id.class_idx_);
   3697   if (klass_type.IsConflict()) {
   3698     AppendToLastFailMessage(StringPrintf(" in attempt to access instance field %d (%s) in %s",
   3699                                          field_idx, dex_file_->GetFieldName(field_id),
   3700                                          dex_file_->GetFieldDeclaringClassDescriptor(field_id)));
   3701     return nullptr;
   3702   }
   3703   if (klass_type.IsUnresolvedTypes()) {
   3704     return nullptr;  // Can't resolve Class so no more to do here
   3705   }
   3706   ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
   3707   mirror::ArtField* field = class_linker->ResolveFieldJLS(*dex_file_, field_idx, *dex_cache_,
   3708                                                           *class_loader_);
   3709   if (field == nullptr) {
   3710     VLOG(verifier) << "Unable to resolve instance field " << field_idx << " ("
   3711               << dex_file_->GetFieldName(field_id) << ") in "
   3712               << dex_file_->GetFieldDeclaringClassDescriptor(field_id);
   3713     DCHECK(Thread::Current()->IsExceptionPending());
   3714     Thread::Current()->ClearException();
   3715     return nullptr;
   3716   } else if (!GetDeclaringClass().CanAccessMember(field->GetDeclaringClass(),
   3717                                                   field->GetAccessFlags())) {
   3718     Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot access instance field " << PrettyField(field)
   3719                                     << " from " << GetDeclaringClass();
   3720     return nullptr;
   3721   } else if (field->IsStatic()) {
   3722     Fail(VERIFY_ERROR_CLASS_CHANGE) << "expected field " << PrettyField(field)
   3723                                     << " to not be static";
   3724     return nullptr;
   3725   } else if (obj_type.IsZero()) {
   3726     // Cannot infer and check type, however, access will cause null pointer exception
   3727     return field;
   3728   } else if (!obj_type.IsReferenceTypes()) {
   3729     // Trying to read a field from something that isn't a reference
   3730     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has "
   3731                                       << "non-reference type " << obj_type;
   3732     return nullptr;
   3733   } else {
   3734     mirror::Class* klass = field->GetDeclaringClass();
   3735     RegType& field_klass =
   3736         reg_types_.FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
   3737                              klass, klass->CannotBeAssignedFromOtherTypes());
   3738     if (obj_type.IsUninitializedTypes() &&
   3739         (!IsConstructor() || GetDeclaringClass().Equals(obj_type) ||
   3740             !field_klass.Equals(GetDeclaringClass()))) {
   3741       // Field accesses through uninitialized references are only allowable for constructors where
   3742       // the field is declared in this class
   3743       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "cannot access instance field " << PrettyField(field)
   3744                                         << " of a not fully initialized object within the context"
   3745                                         << " of " << PrettyMethod(dex_method_idx_, *dex_file_);
   3746       return nullptr;
   3747     } else if (!field_klass.IsAssignableFrom(obj_type)) {
   3748       // Trying to access C1.field1 using reference of type C2, which is neither C1 or a sub-class
   3749       // of C1. For resolution to occur the declared class of the field must be compatible with
   3750       // obj_type, we've discovered this wasn't so, so report the field didn't exist.
   3751       Fail(VERIFY_ERROR_NO_FIELD) << "cannot access instance field " << PrettyField(field)
   3752                                   << " from object of type " << obj_type;
   3753       return nullptr;
   3754     } else {
   3755       return field;
   3756     }
   3757   }
   3758 }
   3759 
   3760 template <MethodVerifier::FieldAccessType kAccType>
   3761 void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, RegType& insn_type,
   3762                                          bool is_primitive, bool is_static) {
   3763   uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c();
   3764   mirror::ArtField* field;
   3765   if (is_static) {
   3766     field = GetStaticField(field_idx);
   3767   } else {
   3768     RegType& object_type = work_line_->GetRegisterType(inst->VRegB_22c());
   3769     field = GetInstanceField(object_type, field_idx);
   3770     if (UNLIKELY(have_pending_hard_failure_)) {
   3771       return;
   3772     }
   3773   }
   3774   RegType* field_type = nullptr;
   3775   if (field != nullptr) {
   3776     if (kAccType == FieldAccessType::kAccPut) {
   3777       if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   3778         Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
   3779                                         << " from other class " << GetDeclaringClass();
   3780         return;
   3781       }
   3782     }
   3783 
   3784     Thread* self = Thread::Current();
   3785     mirror::Class* field_type_class;
   3786     {
   3787       StackHandleScope<1> hs(self);
   3788       HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
   3789       field_type_class = FieldHelper(h_field).GetType(can_load_classes_);
   3790     }
   3791     if (field_type_class != nullptr) {
   3792       field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
   3793                                          field_type_class->CannotBeAssignedFromOtherTypes());
   3794     } else {
   3795       DCHECK(!can_load_classes_ || self->IsExceptionPending());
   3796       self->ClearException();
   3797     }
   3798   }
   3799   if (field_type == nullptr) {
   3800     const DexFile::FieldId& field_id = dex_file_->GetFieldId(field_idx);
   3801     const char* descriptor = dex_file_->GetFieldTypeDescriptor(field_id);
   3802     field_type = &reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   3803   }
   3804   DCHECK(field_type != nullptr);
   3805   const uint32_t vregA = (is_static) ? inst->VRegA_21c() : inst->VRegA_22c();
   3806   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
   3807                 "Unexpected third access type");
   3808   if (kAccType == FieldAccessType::kAccPut) {
   3809     // sput or iput.
   3810     if (is_primitive) {
   3811       VerifyPrimitivePut(*field_type, insn_type, vregA);
   3812     } else {
   3813       if (!insn_type.IsAssignableFrom(*field_type)) {
   3814         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
   3815                                                 << " to be compatible with type '" << insn_type
   3816                                                 << "' but found type '" << *field_type
   3817                                                 << "' in put-object";
   3818         return;
   3819       }
   3820       work_line_->VerifyRegisterType(vregA, *field_type);
   3821     }
   3822   } else if (kAccType == FieldAccessType::kAccGet) {
   3823     // sget or iget.
   3824     if (is_primitive) {
   3825       if (field_type->Equals(insn_type) ||
   3826           (field_type->IsFloat() && insn_type.IsInteger()) ||
   3827           (field_type->IsDouble() && insn_type.IsLong())) {
   3828         // expected that read is of the correct primitive type or that int reads are reading
   3829         // floats or long reads are reading doubles
   3830       } else {
   3831         // This is a global failure rather than a class change failure as the instructions and
   3832         // the descriptors for the type should have been consistent within the same file at
   3833         // compile time
   3834         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
   3835                                           << " to be of type '" << insn_type
   3836                                           << "' but found type '" << *field_type << "' in get";
   3837         return;
   3838       }
   3839     } else {
   3840       if (!insn_type.IsAssignableFrom(*field_type)) {
   3841         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
   3842                                           << " to be compatible with type '" << insn_type
   3843                                           << "' but found type '" << *field_type
   3844                                           << "' in get-object";
   3845         work_line_->SetRegisterType(vregA, reg_types_.Conflict());
   3846         return;
   3847       }
   3848     }
   3849     if (!field_type->IsLowHalf()) {
   3850       work_line_->SetRegisterType(vregA, *field_type);
   3851     } else {
   3852       work_line_->SetRegisterTypeWide(vregA, *field_type, field_type->HighHalf(&reg_types_));
   3853     }
   3854   } else {
   3855     LOG(FATAL) << "Unexpected case.";
   3856   }
   3857 }
   3858 
   3859 mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst,
   3860                                                       RegisterLine* reg_line) {
   3861   DCHECK(inst->Opcode() == Instruction::IGET_QUICK ||
   3862          inst->Opcode() == Instruction::IGET_WIDE_QUICK ||
   3863          inst->Opcode() == Instruction::IGET_OBJECT_QUICK ||
   3864          inst->Opcode() == Instruction::IPUT_QUICK ||
   3865          inst->Opcode() == Instruction::IPUT_WIDE_QUICK ||
   3866          inst->Opcode() == Instruction::IPUT_OBJECT_QUICK);
   3867   RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c());
   3868   if (!object_type.HasClass()) {
   3869     VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'";
   3870     return nullptr;
   3871   }
   3872   uint32_t field_offset = static_cast<uint32_t>(inst->VRegC_22c());
   3873   mirror::ArtField* f = mirror::ArtField::FindInstanceFieldWithOffset(object_type.GetClass(),
   3874                                                                       field_offset);
   3875   if (f == nullptr) {
   3876     VLOG(verifier) << "Failed to find instance field at offset '" << field_offset
   3877                    << "' from '" << PrettyDescriptor(object_type.GetClass()) << "'";
   3878   }
   3879   return f;
   3880 }
   3881 
   3882 template <MethodVerifier::FieldAccessType kAccType>
   3883 void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, RegType& insn_type,
   3884                                             bool is_primitive) {
   3885   DCHECK(Runtime::Current()->IsStarted() || verify_to_dump_);
   3886 
   3887   mirror::ArtField* field = GetQuickFieldAccess(inst, work_line_.get());
   3888   if (field == nullptr) {
   3889     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field from " << inst->Name();
   3890     return;
   3891   }
   3892 
   3893   // For an IPUT_QUICK, we now test for final flag of the field.
   3894   if (kAccType == FieldAccessType::kAccPut) {
   3895     if (field->IsFinal() && field->GetDeclaringClass() != GetDeclaringClass().GetClass()) {
   3896       Fail(VERIFY_ERROR_ACCESS_FIELD) << "cannot modify final field " << PrettyField(field)
   3897                                       << " from other class " << GetDeclaringClass();
   3898       return;
   3899     }
   3900   }
   3901 
   3902   // Get the field type.
   3903   RegType* field_type;
   3904   {
   3905     mirror::Class* field_type_class;
   3906     {
   3907       StackHandleScope<1> hs(Thread::Current());
   3908       HandleWrapper<mirror::ArtField> h_field(hs.NewHandleWrapper(&field));
   3909       field_type_class = FieldHelper(h_field).GetType(can_load_classes_);
   3910     }
   3911 
   3912     if (field_type_class != nullptr) {
   3913       field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
   3914                                          field_type_class->CannotBeAssignedFromOtherTypes());
   3915     } else {
   3916       Thread* self = Thread::Current();
   3917       DCHECK(!can_load_classes_ || self->IsExceptionPending());
   3918       self->ClearException();
   3919       field_type = &reg_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
   3920                                               field->GetTypeDescriptor(), false);
   3921     }
   3922     if (field_type == nullptr) {
   3923       Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "Cannot infer field type from " << inst->Name();
   3924       return;
   3925     }
   3926   }
   3927 
   3928   const uint32_t vregA = inst->VRegA_22c();
   3929   static_assert(kAccType == FieldAccessType::kAccPut || kAccType == FieldAccessType::kAccGet,
   3930                 "Unexpected third access type");
   3931   if (kAccType == FieldAccessType::kAccPut) {
   3932     if (is_primitive) {
   3933       // Primitive field assignability rules are weaker than regular assignability rules
   3934       bool instruction_compatible;
   3935       bool value_compatible;
   3936       RegType& value_type = work_line_->GetRegisterType(vregA);
   3937       if (field_type->IsIntegralTypes()) {
   3938         instruction_compatible = insn_type.IsIntegralTypes();
   3939         value_compatible = value_type.IsIntegralTypes();
   3940       } else if (field_type->IsFloat()) {
   3941         instruction_compatible = insn_type.IsInteger();  // no [is]put-float, so expect [is]put-int
   3942         value_compatible = value_type.IsFloatTypes();
   3943       } else if (field_type->IsLong()) {
   3944         instruction_compatible = insn_type.IsLong();
   3945         value_compatible = value_type.IsLongTypes();
   3946       } else if (field_type->IsDouble()) {
   3947         instruction_compatible = insn_type.IsLong();  // no [is]put-double, so expect [is]put-long
   3948         value_compatible = value_type.IsDoubleTypes();
   3949       } else {
   3950         instruction_compatible = false;  // reference field with primitive store
   3951         value_compatible = false;  // unused
   3952       }
   3953       if (!instruction_compatible) {
   3954         // This is a global failure rather than a class change failure as the instructions and
   3955         // the descriptors for the type should have been consistent within the same file at
   3956         // compile time
   3957         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
   3958                                           << " to be of type '" << insn_type
   3959                                           << "' but found type '" << *field_type
   3960                                           << "' in put";
   3961         return;
   3962       }
   3963       if (!value_compatible) {
   3964         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "unexpected value in v" << vregA
   3965             << " of type " << value_type
   3966             << " but expected " << *field_type
   3967             << " for store to " << PrettyField(field) << " in put";
   3968         return;
   3969       }
   3970     } else {
   3971       if (!insn_type.IsAssignableFrom(*field_type)) {
   3972         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
   3973                                           << " to be compatible with type '" << insn_type
   3974                                           << "' but found type '" << *field_type
   3975                                           << "' in put-object";
   3976         return;
   3977       }
   3978       work_line_->VerifyRegisterType(vregA, *field_type);
   3979     }
   3980   } else if (kAccType == FieldAccessType::kAccGet) {
   3981     if (is_primitive) {
   3982       if (field_type->Equals(insn_type) ||
   3983           (field_type->IsFloat() && insn_type.IsIntegralTypes()) ||
   3984           (field_type->IsDouble() && insn_type.IsLongTypes())) {
   3985         // expected that read is of the correct primitive type or that int reads are reading
   3986         // floats or long reads are reading doubles
   3987       } else {
   3988         // This is a global failure rather than a class change failure as the instructions and
   3989         // the descriptors for the type should have been consistent within the same file at
   3990         // compile time
   3991         Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "expected field " << PrettyField(field)
   3992                                           << " to be of type '" << insn_type
   3993                                           << "' but found type '" << *field_type << "' in Get";
   3994         return;
   3995       }
   3996     } else {
   3997       if (!insn_type.IsAssignableFrom(*field_type)) {
   3998         Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "expected field " << PrettyField(field)
   3999                                           << " to be compatible with type '" << insn_type
   4000                                           << "' but found type '" << *field_type
   4001                                           << "' in get-object";
   4002         work_line_->SetRegisterType(vregA, reg_types_.Conflict());
   4003         return;
   4004       }
   4005     }
   4006     if (!field_type->IsLowHalf()) {
   4007       work_line_->SetRegisterType(vregA, *field_type);
   4008     } else {
   4009       work_line_->SetRegisterTypeWide(vregA, *field_type, field_type->HighHalf(&reg_types_));
   4010     }
   4011   } else {
   4012     LOG(FATAL) << "Unexpected case.";
   4013   }
   4014 }
   4015 
   4016 bool MethodVerifier::CheckNotMoveException(const uint16_t* insns, int insn_idx) {
   4017   if ((insns[insn_idx] & 0xff) == Instruction::MOVE_EXCEPTION) {
   4018     Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "invalid use of move-exception";
   4019     return false;
   4020   }
   4021   return true;
   4022 }
   4023 
   4024 bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_line,
   4025                                      bool update_merge_line) {
   4026   bool changed = true;
   4027   RegisterLine* target_line = reg_table_.GetLine(next_insn);
   4028   if (!insn_flags_[next_insn].IsVisitedOrChanged()) {
   4029     /*
   4030      * We haven't processed this instruction before, and we haven't touched the registers here, so
   4031      * there's nothing to "merge". Copy the registers over and mark it as changed. (This is the
   4032      * only way a register can transition out of "unknown", so this is not just an optimization.)
   4033      */
   4034     if (!insn_flags_[next_insn].IsReturn()) {
   4035       target_line->CopyFromLine(merge_line);
   4036     } else {
   4037       // Verify that the monitor stack is empty on return.
   4038       if (!merge_line->VerifyMonitorStackEmpty()) {
   4039         return false;
   4040       }
   4041       // For returns we only care about the operand to the return, all other registers are dead.
   4042       // Initialize them as conflicts so they don't add to GC and deoptimization information.
   4043       const Instruction* ret_inst = Instruction::At(code_item_->insns_ + next_insn);
   4044       Instruction::Code opcode = ret_inst->Opcode();
   4045       if ((opcode == Instruction::RETURN_VOID) || (opcode == Instruction::RETURN_VOID_BARRIER)) {
   4046         target_line->MarkAllRegistersAsConflicts();
   4047       } else {
   4048         target_line->CopyFromLine(merge_line);
   4049         if (opcode == Instruction::RETURN_WIDE) {
   4050           target_line->MarkAllRegistersAsConflictsExceptWide(ret_inst->VRegA_11x());
   4051         } else {
   4052           target_line->MarkAllRegistersAsConflictsExcept(ret_inst->VRegA_11x());
   4053         }
   4054       }
   4055     }
   4056   } else {
   4057     std::unique_ptr<RegisterLine> copy(gDebugVerify ?
   4058                                            RegisterLine::Create(target_line->NumRegs(), this) :
   4059                                            nullptr);
   4060     if (gDebugVerify) {
   4061       copy->CopyFromLine(target_line);
   4062     }
   4063     changed = target_line->MergeRegisters(merge_line);
   4064     if (have_pending_hard_failure_) {
   4065       return false;
   4066     }
   4067     if (gDebugVerify && changed) {
   4068       LogVerifyInfo() << "Merging at [" << reinterpret_cast<void*>(work_insn_idx_) << "]"
   4069                       << " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
   4070                       << *copy.get() << "  MERGE\n"
   4071                       << *merge_line << "  ==\n"
   4072                       << *target_line << "\n";
   4073     }
   4074     if (update_merge_line && changed) {
   4075       merge_line->CopyFromLine(target_line);
   4076     }
   4077   }
   4078   if (changed) {
   4079     insn_flags_[next_insn].SetChanged();
   4080   }
   4081   return true;
   4082 }
   4083 
   4084 InstructionFlags* MethodVerifier::CurrentInsnFlags() {
   4085   return &insn_flags_[work_insn_idx_];
   4086 }
   4087 
   4088 RegType& MethodVerifier::GetMethodReturnType() {
   4089   if (return_type_ == nullptr) {
   4090     if (mirror_method_ != nullptr) {
   4091       Thread* self = Thread::Current();
   4092       StackHandleScope<1> hs(self);
   4093       mirror::Class* return_type_class;
   4094       {
   4095         HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_));
   4096         return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_);
   4097       }
   4098       if (return_type_class != nullptr) {
   4099         return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
   4100                                              return_type_class,
   4101                                              return_type_class->CannotBeAssignedFromOtherTypes());
   4102       } else {
   4103         DCHECK(!can_load_classes_ || self->IsExceptionPending());
   4104         self->ClearException();
   4105       }
   4106     }
   4107     if (return_type_ == nullptr) {
   4108       const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   4109       const DexFile::ProtoId& proto_id = dex_file_->GetMethodPrototype(method_id);
   4110       uint16_t return_type_idx = proto_id.return_type_idx_;
   4111       const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(return_type_idx));
   4112       return_type_ = &reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   4113     }
   4114   }
   4115   return *return_type_;
   4116 }
   4117 
   4118 RegType& MethodVerifier::GetDeclaringClass() {
   4119   if (declaring_class_ == nullptr) {
   4120     const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_);
   4121     const char* descriptor
   4122         = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
   4123     if (mirror_method_ != nullptr) {
   4124       mirror::Class* klass = mirror_method_->GetDeclaringClass();
   4125       declaring_class_ = &reg_types_.FromClass(descriptor, klass,
   4126                                                klass->CannotBeAssignedFromOtherTypes());
   4127     } else {
   4128       declaring_class_ = &reg_types_.FromDescriptor(class_loader_->Get(), descriptor, false);
   4129     }
   4130   }
   4131   return *declaring_class_;
   4132 }
   4133 
   4134 std::vector<int32_t> MethodVerifier::DescribeVRegs(uint32_t dex_pc) {
   4135   RegisterLine* line = reg_table_.GetLine(dex_pc);
   4136   DCHECK(line != nullptr) << "No register line at DEX pc " << StringPrintf("0x%x", dex_pc);
   4137   std::vector<int32_t> result;
   4138   for (size_t i = 0; i < line->NumRegs(); ++i) {
   4139     RegType& type = line->GetRegisterType(i);
   4140     if (type.IsConstant()) {
   4141       result.push_back(type.IsPreciseConstant() ? kConstant : kImpreciseConstant);
   4142       result.push_back(type.ConstantValue());
   4143     } else if (type.IsConstantLo()) {
   4144       result.push_back(type.IsPreciseConstantLo() ? kConstant : kImpreciseConstant);
   4145       result.push_back(type.ConstantValueLo());
   4146     } else if (type.IsConstantHi()) {
   4147       result.push_back(type.IsPreciseConstantHi() ? kConstant : kImpreciseConstant);
   4148       result.push_back(type.ConstantValueHi());
   4149     } else if (type.IsIntegralTypes()) {
   4150       result.push_back(kIntVReg);
   4151       result.push_back(0);
   4152     } else if (type.IsFloat()) {
   4153       result.push_back(kFloatVReg);
   4154       result.push_back(0);
   4155     } else if (type.IsLong()) {
   4156       result.push_back(kLongLoVReg);
   4157       result.push_back(0);
   4158       result.push_back(kLongHiVReg);
   4159       result.push_back(0);
   4160       ++i;
   4161     } else if (type.IsDouble()) {
   4162       result.push_back(kDoubleLoVReg);
   4163       result.push_back(0);
   4164       result.push_back(kDoubleHiVReg);
   4165       result.push_back(0);
   4166       ++i;
   4167     } else if (type.IsUndefined() || type.IsConflict() || type.IsHighHalf()) {
   4168       result.push_back(kUndefined);
   4169       result.push_back(0);
   4170     } else {
   4171       CHECK(type.IsNonZeroReferenceTypes());
   4172       result.push_back(kReferenceVReg);
   4173       result.push_back(0);
   4174     }
   4175   }
   4176   return result;
   4177 }
   4178 
   4179 RegType& MethodVerifier::DetermineCat1Constant(int32_t value, bool precise) {
   4180   if (precise) {
   4181     // Precise constant type.
   4182     return reg_types_.FromCat1Const(value, true);
   4183   } else {
   4184     // Imprecise constant type.
   4185     if (value < -32768) {
   4186       return reg_types_.IntConstant();
   4187     } else if (value < -128) {
   4188       return reg_types_.ShortConstant();
   4189     } else if (value < 0) {
   4190       return reg_types_.ByteConstant();
   4191     } else if (value == 0) {
   4192       return reg_types_.Zero();
   4193     } else if (value == 1) {
   4194       return reg_types_.One();
   4195     } else if (value < 128) {
   4196       return reg_types_.PosByteConstant();
   4197     } else if (value < 32768) {
   4198       return reg_types_.PosShortConstant();
   4199     } else if (value < 65536) {
   4200       return reg_types_.CharConstant();
   4201     } else {
   4202       return reg_types_.IntConstant();
   4203     }
   4204   }
   4205 }
   4206 
   4207 void MethodVerifier::Init() {
   4208   art::verifier::RegTypeCache::Init();
   4209 }
   4210 
   4211 void MethodVerifier::Shutdown() {
   4212   verifier::RegTypeCache::ShutDown();
   4213 }
   4214 
   4215 void MethodVerifier::VisitStaticRoots(RootCallback* callback, void* arg) {
   4216   RegTypeCache::VisitStaticRoots(callback, arg);
   4217 }
   4218 
   4219 void MethodVerifier::VisitRoots(RootCallback* callback, void* arg) {
   4220   reg_types_.VisitRoots(callback, arg);
   4221 }
   4222 
   4223 }  // namespace verifier
   4224 }  // namespace art
   4225