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