diff options
-rw-r--r-- | compiler/dex/mir_graph.cc | 80 | ||||
-rw-r--r-- | oatdump/oatdump.cc | 10 | ||||
-rw-r--r-- | runtime/debugger.cc | 5 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 2 | ||||
-rw-r--r-- | runtime/monitor.cc | 2 | ||||
-rw-r--r-- | runtime/parsed_options.cc | 6 | ||||
-rw-r--r-- | runtime/parsed_options.h | 2 | ||||
-rw-r--r-- | runtime/quick_exception_handler.cc | 5 | ||||
-rw-r--r-- | runtime/runtime.cc | 11 | ||||
-rw-r--r-- | runtime/runtime.h | 7 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.cc | 63 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.h | 9 |
12 files changed, 107 insertions, 95 deletions
diff --git a/compiler/dex/mir_graph.cc b/compiler/dex/mir_graph.cc index edfd57fd8a..574b6ea66f 100644 --- a/compiler/dex/mir_graph.cc +++ b/compiler/dex/mir_graph.cc @@ -274,7 +274,7 @@ BasicBlock* MIRGraph::SplitBlock(DexOffset code_offset, */ BasicBlock* MIRGraph::FindBlock(DexOffset code_offset, bool split, bool create, BasicBlock** immed_pred_block_p) { - if (code_offset >= cu_->code_item->insns_size_in_code_units_) { + if (code_offset >= current_code_item_->insns_size_in_code_units_) { return NULL; } @@ -348,10 +348,10 @@ bool MIRGraph::IsBadMonitorExitCatch(NarrowDexOffset monitor_exit_offset, // (We don't want to ignore all monitor-exit catches since one could enclose a synchronized // block in a try-block and catch the NPE, Error or Throwable and we should let it through; // even though a throwing monitor-exit certainly indicates a bytecode error.) - const Instruction* monitor_exit = Instruction::At(cu_->code_item->insns_ + monitor_exit_offset); + const Instruction* monitor_exit = Instruction::At(current_code_item_->insns_ + monitor_exit_offset); DCHECK(monitor_exit->Opcode() == Instruction::MONITOR_EXIT); int monitor_reg = monitor_exit->VRegA_11x(); - const Instruction* check_insn = Instruction::At(cu_->code_item->insns_ + catch_offset); + const Instruction* check_insn = Instruction::At(current_code_item_->insns_ + catch_offset); DCHECK(check_insn->Opcode() == Instruction::MOVE_EXCEPTION); if (check_insn->VRegA_11x() == monitor_reg) { // Unexpected move-exception to the same register. Probably not the pattern we're looking for. @@ -1228,8 +1228,6 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) { bool nop = false; SSARepresentation* ssa_rep = mir->ssa_rep; Instruction::Format dalvik_format = Instruction::k10x; // Default to no-operand format. - int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0; - int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0; // Handle special cases. if ((opcode == kMirOpCheck) || (opcode == kMirOpCheckPart2)) { @@ -1238,8 +1236,6 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) { // Recover the original Dex instruction. insn = mir->meta.throw_insn->dalvikInsn; ssa_rep = mir->meta.throw_insn->ssa_rep; - defs = ssa_rep->num_defs; - uses = ssa_rep->num_uses; opcode = insn.opcode; } else if (opcode == kMirOpNop) { str.append("["); @@ -1248,6 +1244,8 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) { opcode = insn.opcode; nop = true; } + int defs = (ssa_rep != NULL) ? ssa_rep->num_defs : 0; + int uses = (ssa_rep != NULL) ? ssa_rep->num_uses : 0; if (MIR::DecodedInstruction::IsPseudoMirOp(opcode)) { str.append(extended_mir_op_names_[opcode - kMirOpFirst]); @@ -1259,40 +1257,21 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) { if (opcode == kMirOpPhi) { BasicBlockId* incoming = mir->meta.phi_incoming; - str.append(StringPrintf(" %s = (%s", - GetSSANameWithConst(ssa_rep->defs[0], true).c_str(), - GetSSANameWithConst(ssa_rep->uses[0], true).c_str())); - str.append(StringPrintf(":%d", incoming[0])); - int i; - for (i = 1; i < uses; i++) { - str.append(StringPrintf(", %s:%d", - GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), - incoming[i])); - } - str.append(")"); - } else if ((flags & Instruction::kBranch) != 0) { - // For branches, decode the instructions to print out the branch targets. - int offset = 0; - switch (dalvik_format) { - case Instruction::k21t: - str.append(StringPrintf(" %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str())); - offset = insn.vB; - break; - case Instruction::k22t: - str.append(StringPrintf(" %s, %s,", GetSSANameWithConst(ssa_rep->uses[0], false).c_str(), - GetSSANameWithConst(ssa_rep->uses[1], false).c_str())); - offset = insn.vC; - break; - case Instruction::k10t: - case Instruction::k20t: - case Instruction::k30t: - offset = insn.vA; - break; - default: - LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode; + if (defs > 0 && uses > 0) { + str.append(StringPrintf(" %s = (%s", + GetSSANameWithConst(ssa_rep->defs[0], true).c_str(), + GetSSANameWithConst(ssa_rep->uses[0], true).c_str())); + str.append(StringPrintf(":%d", incoming[0])); + int i; + for (i = 1; i < uses; i++) { + str.append(StringPrintf(", %s:%d", + GetSSANameWithConst(ssa_rep->uses[i], true).c_str(), + incoming[i])); + } + str.append(")"); + } else { + str.append(StringPrintf(" v%d", mir->dalvikInsn.vA)); } - str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset, - offset > 0 ? '+' : '-', offset > 0 ? offset : -offset)); } else { // For invokes-style formats, treat wide regs as a pair of singles. bool show_singles = ((dalvik_format == Instruction::k35c) || @@ -1339,6 +1318,27 @@ char* MIRGraph::GetDalvikDisassembly(const MIR* mir) { // Nothing left to print. } } + if ((flags & Instruction::kBranch) != 0) { + // For branches, decode the instructions to print out the branch targets. + int offset = 0; + switch (dalvik_format) { + case Instruction::k21t: + offset = insn.vB; + break; + case Instruction::k22t: + offset = insn.vC; + break; + case Instruction::k10t: + case Instruction::k20t: + case Instruction::k30t: + offset = insn.vA; + break; + default: + LOG(FATAL) << "Unexpected branch format " << dalvik_format << " from " << insn.opcode; + } + str.append(StringPrintf(" 0x%x (%c%x)", mir->offset + offset, + offset > 0 ? '+' : '-', offset > 0 ? offset : -offset)); + } } if (nop) { str.append("]--optimized away"); diff --git a/oatdump/oatdump.cc b/oatdump/oatdump.cc index 75bc49b7d4..2114ada055 100644 --- a/oatdump/oatdump.cc +++ b/oatdump/oatdump.cc @@ -427,12 +427,13 @@ class OatDumper { Runtime* runtime = Runtime::Current(); if (runtime != nullptr) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<1> hs(soa.Self()); + StackHandleScope<2> hs(soa.Self()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(runtime->GetClassLinker()->FindDexCache(dex_file))); NullHandle<mirror::ClassLoader> class_loader; + Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr)); verifier::MethodVerifier verifier(&dex_file, &dex_cache, &class_loader, &class_def, - code_item, dex_method_idx, nullptr, method_access_flags, + code_item, dex_method_idx, method, method_access_flags, true, true, true); verifier.Verify(); DumpCode(*indent2_os, &verifier, oat_method, code_item); @@ -698,12 +699,13 @@ class OatDumper { uint32_t method_access_flags) { if ((method_access_flags & kAccNative) == 0) { ScopedObjectAccess soa(Thread::Current()); - StackHandleScope<2> hs(soa.Self()); + StackHandleScope<3> hs(soa.Self()); Handle<mirror::DexCache> dex_cache( hs.NewHandle(Runtime::Current()->GetClassLinker()->FindDexCache(*dex_file))); auto class_loader(hs.NewHandle<mirror::ClassLoader>(nullptr)); + Handle<mirror::ArtMethod> method(hs.NewHandle<mirror::ArtMethod>(nullptr)); verifier::MethodVerifier::VerifyMethodAndDump(os, dex_method_idx, dex_file, dex_cache, - class_loader, &class_def, code_item, nullptr, + class_loader, &class_def, code_item, method, method_access_flags); } } diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 6d2f21e1e5..5b00a37f07 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -3031,12 +3031,13 @@ static bool IsMethodPossiblyInlined(Thread* self, mirror::ArtMethod* m) // should never be null. We could just check we never encounter this case. return false; } - StackHandleScope<2> hs(self); + StackHandleScope<3> hs(self); mirror::Class* declaring_class = m->GetDeclaringClass(); Handle<mirror::DexCache> dex_cache(hs.NewHandle(declaring_class->GetDexCache())); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); + Handle<mirror::ArtMethod> method(hs.NewHandle(m)); verifier::MethodVerifier verifier(dex_cache->GetDexFile(), &dex_cache, &class_loader, - &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m, + &m->GetClassDef(), code_item, m->GetDexMethodIndex(), method, m->GetAccessFlags(), false, true, false); // Note: we don't need to verify the method. return InlineMethodAnalyser::AnalyseMethodCode(&verifier, nullptr); diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index f0b7685acf..1e01164287 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -224,7 +224,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+- */ bool support_homogeneous_space_compaction = - background_collector_type == gc::kCollectorTypeHomogeneousSpaceCompact || + background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact || use_homogeneous_space_compaction_for_oom; // We may use the same space the main space for the non moving space if we don't need to compact // from the main space. diff --git a/runtime/monitor.cc b/runtime/monitor.cc index 5dd16efa02..a87d7c1fee 100644 --- a/runtime/monitor.cc +++ b/runtime/monitor.cc @@ -238,7 +238,7 @@ void Monitor::Lock(Thread* self) { } // Contended. const bool log_contention = (lock_profiling_threshold_ != 0); - uint64_t wait_start_ms = log_contention ? 0 : MilliTime(); + uint64_t wait_start_ms = log_contention ? MilliTime() : 0; mirror::ArtMethod* owners_method = locking_method_; uint32_t owners_dex_pc = locking_dex_pc_; // Do this before releasing the lock so that we don't get deflated. diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc index 26360d77e2..9757ad9a9e 100644 --- a/runtime/parsed_options.cc +++ b/runtime/parsed_options.cc @@ -394,10 +394,6 @@ bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognize } else if (option == "-XX:IgnoreMaxFootprint") { ignore_max_footprint_ = true; } else if (option == "-XX:LowMemoryMode") { - if (background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact) { - // Use semispace instead of homogenous space compact for low memory mode. - background_collector_type_ = gc::kCollectorTypeSS; - } low_memory_mode_ = true; // TODO Might want to turn off must_relocate here. } else if (option == "-XX:UseTLAB") { @@ -613,7 +609,7 @@ bool ParsedOptions::Parse(const RuntimeOptions& options, bool ignore_unrecognize return false; } } else if (StartsWith(option, "-XX:NativeBridge=")) { - if (!ParseStringAfterChar(option, '=', &native_bridge_library_path_)) { + if (!ParseStringAfterChar(option, '=', &native_bridge_library_filename_)) { return false; } } else if (StartsWith(option, "-ea") || diff --git a/runtime/parsed_options.h b/runtime/parsed_options.h index 1afd610a53..5c71f9895c 100644 --- a/runtime/parsed_options.h +++ b/runtime/parsed_options.h @@ -46,7 +46,7 @@ class ParsedOptions { bool check_jni_; bool force_copy_; std::string jni_trace_; - std::string native_bridge_library_path_; + std::string native_bridge_library_filename_; CompilerCallbacks* compiler_callbacks_; bool is_zygote_; bool must_relocate_; diff --git a/runtime/quick_exception_handler.cc b/runtime/quick_exception_handler.cc index 98eeda7263..1e933a2b8c 100644 --- a/runtime/quick_exception_handler.cc +++ b/runtime/quick_exception_handler.cc @@ -206,12 +206,13 @@ class DeoptimizeStackVisitor FINAL : public StackVisitor { const Instruction* inst = Instruction::At(code_item->insns_ + dex_pc); uint32_t new_dex_pc = dex_pc + inst->SizeInCodeUnits(); ShadowFrame* new_frame = ShadowFrame::Create(num_regs, nullptr, m, new_dex_pc); - StackHandleScope<2> hs(self_); + StackHandleScope<3> hs(self_); mirror::Class* declaring_class = m->GetDeclaringClass(); Handle<mirror::DexCache> h_dex_cache(hs.NewHandle(declaring_class->GetDexCache())); Handle<mirror::ClassLoader> h_class_loader(hs.NewHandle(declaring_class->GetClassLoader())); + Handle<mirror::ArtMethod> h_method(hs.NewHandle(m)); verifier::MethodVerifier verifier(h_dex_cache->GetDexFile(), &h_dex_cache, &h_class_loader, - &m->GetClassDef(), code_item, m->GetDexMethodIndex(), m, + &m->GetClassDef(), code_item, m->GetDexMethodIndex(), h_method, m->GetAccessFlags(), false, true, true); verifier.Verify(); const std::vector<int32_t> kinds(verifier.DescribeVRegs(dex_pc)); diff --git a/runtime/runtime.cc b/runtime/runtime.cc index ee8cbe1c62..84df444be2 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -712,11 +712,12 @@ bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) self->ClearException(); // Look for a native bridge. - native_bridge_library_path_ = options->native_bridge_library_path_; - if (!native_bridge_library_path_.empty()) { - android::SetupNativeBridge(native_bridge_library_path_.c_str(), &native_bridge_art_callbacks_); - VLOG(startup) << "Runtime::Setup native bridge library: " << native_bridge_library_path_; - } + native_bridge_library_filename_ = options->native_bridge_library_filename_; + android::SetupNativeBridge(native_bridge_library_filename_.c_str(), &native_bridge_art_callbacks_); + VLOG(startup) << "Runtime::Setup native bridge library: " + << (native_bridge_library_filename_.empty() ? + "(empty)" : native_bridge_library_filename_); + VLOG(startup) << "Runtime::Init exiting"; return true; } diff --git a/runtime/runtime.h b/runtime/runtime.h index 34ccdcb3da..259691adc1 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -617,13 +617,14 @@ class Runtime { bool implicit_so_checks_; // StackOverflow checks are implicit. bool implicit_suspend_checks_; // Thread suspension checks are implicit. - // The path to the native bridge library. If this is not empty the native bridge will be - // initialized and loaded from the pointed path. + // The filename to the native bridge library. If this is not empty the native bridge will be + // initialized and loaded from the given file (initialized and available). An empty value means + // that there's no native bridge (initialized but not available). // // The native bridge allows running native code compiled for a foreign ISA. The way it works is, // if standard dlopen fails to load native library associated with native activity, it calls to // the native bridge to load it and then gets the trampoline for the entry to native activity. - std::string native_bridge_library_path_; + std::string native_bridge_library_filename_; // Native bridge library runtime callbacks. They represent the runtime interface to native bridge. // diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index 69627f51df..60194532a6 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -138,6 +138,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, while (it.HasNextStaticField() || it.HasNextInstanceField()) { it.Next(); } + Thread* self = Thread::Current(); size_t error_count = 0; bool hard_fail = false; ClassLinker* linker = Runtime::Current()->GetClassLinker(); @@ -156,17 +157,19 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), type); if (method == NULL) { - DCHECK(Thread::Current()->IsExceptionPending()); + DCHECK(self->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. - Thread::Current()->ClearException(); + self->ClearException(); } + StackHandleScope<1> hs(self); + Handle<mirror::ArtMethod> h_method(hs.NewHandle(method)); MethodVerifier::FailureKind result = VerifyMethod(method_idx, dex_file, dex_cache, class_loader, class_def, it.GetMethodCodeItem(), - method, + h_method, it.GetMemberAccessFlags(), allow_soft_failures, false); @@ -200,17 +203,19 @@ MethodVerifier::FailureKind MethodVerifier::VerifyClass(const DexFile* dex_file, linker->ResolveMethod(*dex_file, method_idx, dex_cache, class_loader, NullHandle<mirror::ArtMethod>(), type); if (method == NULL) { - DCHECK(Thread::Current()->IsExceptionPending()); + DCHECK(self->IsExceptionPending()); // We couldn't resolve the method, but continue regardless. - Thread::Current()->ClearException(); + self->ClearException(); } + StackHandleScope<1> hs(self); + Handle<mirror::ArtMethod> h_method(hs.NewHandle(method)); MethodVerifier::FailureKind result = VerifyMethod(method_idx, dex_file, dex_cache, class_loader, class_def, it.GetMethodCodeItem(), - method, + h_method, it.GetMemberAccessFlags(), allow_soft_failures, false); @@ -242,7 +247,7 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, + Handle<mirror::ArtMethod> method, uint32_t method_access_flags, bool allow_soft_failures, bool need_precise_constants) { @@ -250,8 +255,8 @@ MethodVerifier::FailureKind MethodVerifier::VerifyMethod(uint32_t method_idx, uint64_t start_ns = NanoTime(); MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item, - method_idx, method, method_access_flags, true, allow_soft_failures, - need_precise_constants); + method_idx, method, method_access_flags, true, allow_soft_failures, + need_precise_constants); if (verifier.Verify()) { // Verification completed, however failures may be pending that didn't cause the verification // to hard fail. @@ -289,7 +294,7 @@ void MethodVerifier::VerifyMethodAndDump(std::ostream& os, uint32_t dex_method_i Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, + Handle<mirror::ArtMethod> method, uint32_t method_access_flags) { MethodVerifier verifier(dex_file, &dex_cache, &class_loader, class_def, code_item, dex_method_idx, method, method_access_flags, true, true, true); @@ -303,7 +308,7 @@ MethodVerifier::MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache> Handle<mirror::ClassLoader>* class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, uint32_t dex_method_idx, - mirror::ArtMethod* method, uint32_t method_access_flags, + Handle<mirror::ArtMethod> method, uint32_t method_access_flags, bool can_load_classes, bool allow_soft_failures, bool need_precise_constants) : reg_types_(can_load_classes), @@ -340,12 +345,13 @@ MethodVerifier::~MethodVerifier() { void MethodVerifier::FindLocksAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc, std::vector<uint32_t>* monitor_enter_dex_pcs) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); + Handle<mirror::ArtMethod> method(hs.NewHandle(m)); MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(), - m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false, - true, false); + m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(), + false, true, false); verifier.interesting_dex_pc_ = dex_pc; verifier.monitor_enter_dex_pcs_ = monitor_enter_dex_pcs; verifier.FindLocksAtDexPc(); @@ -364,12 +370,13 @@ void MethodVerifier::FindLocksAtDexPc() { mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); + Handle<mirror::ArtMethod> method(hs.NewHandle(m)); MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(), - m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true, - true, false); + m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(), + true, true, false); return verifier.FindAccessedFieldAtDexPc(dex_pc); } @@ -394,12 +401,13 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) { mirror::ArtMethod* MethodVerifier::FindInvokedMethodAtDexPc(mirror::ArtMethod* m, uint32_t dex_pc) { - StackHandleScope<2> hs(Thread::Current()); + StackHandleScope<3> hs(Thread::Current()); Handle<mirror::DexCache> dex_cache(hs.NewHandle(m->GetDexCache())); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(m->GetClassLoader())); + Handle<mirror::ArtMethod> method(hs.NewHandle(m)); MethodVerifier verifier(m->GetDexFile(), &dex_cache, &class_loader, &m->GetClassDef(), - m->GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true, - true, false); + m->GetCodeItem(), m->GetDexMethodIndex(), method, m->GetAccessFlags(), + true, true, false); return verifier.FindInvokedMethodAtDexPc(dex_pc); } @@ -3644,6 +3652,11 @@ mirror::ArtField* MethodVerifier::GetInstanceField(RegType& obj_type, int field_ } else if (obj_type.IsZero()) { // Cannot infer and check type, however, access will cause null pointer exception return field; + } else if (!obj_type.IsReferenceTypes()) { + // Trying to read a field from something that isn't a reference + Fail(VERIFY_ERROR_BAD_CLASS_HARD) << "instance field access on object that has " + << "non-reference type " << obj_type; + return NULL; } else { mirror::Class* klass = field->GetDeclaringClass(); RegType& field_klass = @@ -4017,14 +4030,10 @@ InstructionFlags* MethodVerifier::CurrentInsnFlags() { RegType& MethodVerifier::GetMethodReturnType() { if (return_type_ == nullptr) { - if (mirror_method_ != NULL) { + if (mirror_method_.Get() != nullptr) { Thread* self = Thread::Current(); - StackHandleScope<1> hs(self); mirror::Class* return_type_class; - { - HandleWrapper<mirror::ArtMethod> h_mirror_method(hs.NewHandleWrapper(&mirror_method_)); - return_type_class = MethodHelper(h_mirror_method).GetReturnType(can_load_classes_); - } + return_type_class = MethodHelper(mirror_method_).GetReturnType(can_load_classes_); if (return_type_class != nullptr) { return_type_ = ®_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(), return_type_class, @@ -4050,7 +4059,7 @@ RegType& MethodVerifier::GetDeclaringClass() { const DexFile::MethodId& method_id = dex_file_->GetMethodId(dex_method_idx_); const char* descriptor = dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_)); - if (mirror_method_ != NULL) { + if (mirror_method_.Get() != nullptr) { mirror::Class* klass = mirror_method_->GetDeclaringClass(); declaring_class_ = ®_types_.FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()); diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h index e63a90c2ba..78cbe0693d 100644 --- a/runtime/verifier/method_verifier.h +++ b/runtime/verifier/method_verifier.h @@ -27,6 +27,7 @@ #include "class_reference.h" #include "dex_file.h" #include "dex_instruction.h" +#include "handle.h" #include "instruction_flags.h" #include "method_reference.h" #include "reg_type.h" @@ -152,7 +153,7 @@ class MethodVerifier { Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, uint32_t method_access_flags) + Handle<mirror::ArtMethod> method, uint32_t method_access_flags) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); uint8_t EncodePcToReferenceMapData() const; @@ -203,7 +204,7 @@ class MethodVerifier { MethodVerifier(const DexFile* dex_file, Handle<mirror::DexCache>* dex_cache, Handle<mirror::ClassLoader>* class_loader, const DexFile::ClassDef* class_def, - const DexFile::CodeItem* code_item, uint32_t method_idx, mirror::ArtMethod* method, + const DexFile::CodeItem* code_item, uint32_t method_idx, Handle<mirror::ArtMethod> method, uint32_t access_flags, bool can_load_classes, bool allow_soft_failures, bool need_precise_constants) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -256,7 +257,7 @@ class MethodVerifier { Handle<mirror::ClassLoader> class_loader, const DexFile::ClassDef* class_def_idx, const DexFile::CodeItem* code_item, - mirror::ArtMethod* method, uint32_t method_access_flags, + Handle<mirror::ArtMethod> method, uint32_t method_access_flags, bool allow_soft_failures, bool need_precise_constants) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -639,7 +640,7 @@ class MethodVerifier { const uint32_t dex_method_idx_; // The method we're working on. // Its object representation if known. - mirror::ArtMethod* mirror_method_ GUARDED_BY(Locks::mutator_lock_); + Handle<mirror::ArtMethod> mirror_method_ GUARDED_BY(Locks::mutator_lock_); const uint32_t method_access_flags_; // Method's access flags. RegType* return_type_; // Lazily computed return type of the method. const DexFile* const dex_file_; // The dex file containing the method. |