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