From 9bc54406ba3377980cfce44901dc2be246178ba9 Mon Sep 17 00:00:00 2001 From: Ian Rogers Date: Thu, 17 Apr 2014 16:40:01 -0700 Subject: [PATCH] Interpreter-only mode should cause dex-to-dex compilation. Also, fix quick iget/iput that had similar issues to: https://android-review.googlesource.com/91423 Also, remove fall-back resolution code from quick invokes/igets/iputs as we allow class loading for the exception throw and regular verification already allows class loading. Bug: 14133618 Change-Id: I51199e6e2392da0354f64b157e79af494c183778 --- runtime/runtime.cc | 4 +++ runtime/runtime.h | 4 +++ runtime/verifier/method_verifier.cc | 70 ++++++++----------------------------- 3 files changed, 23 insertions(+), 55 deletions(-) diff --git a/runtime/runtime.cc b/runtime/runtime.cc index eb0522ad0..611ce0bb9 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1230,6 +1230,10 @@ void Runtime::SetFaultMessage(const std::string& message) { void Runtime::AddCurrentRuntimeFeaturesAsDex2OatArguments(std::vector* argv) const { + if (GetInstrumentation()->InterpretOnly()) { + argv->push_back("--compiler-filter=interpret-only"); + } + argv->push_back("--runtime-arg"); std::string checkstr = "-implicit-checks"; diff --git a/runtime/runtime.h b/runtime/runtime.h index 462711ed7..1ee0b1add 100644 --- a/runtime/runtime.h +++ b/runtime/runtime.h @@ -359,6 +359,10 @@ class Runtime { bool InitZygote(); void DidForkFromZygote(); + const instrumentation::Instrumentation* GetInstrumentation() const { + return &instrumentation_; + } + instrumentation::Instrumentation* GetInstrumentation() { return &instrumentation_; } diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index dbde7c763..535c76dd1 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -361,7 +361,7 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(mirror::ArtMethod* m, SirtRef dex_cache(self, mh.GetDexCache()); SirtRef class_loader(self, mh.GetClassLoader()); MethodVerifier verifier(&mh.GetDexFile(), &dex_cache, &class_loader, &mh.GetClassDef(), - mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), false, + mh.GetCodeItem(), m->GetDexMethodIndex(), m, m->GetAccessFlags(), true, true); return verifier.FindAccessedFieldAtDexPc(dex_pc); } @@ -375,11 +375,11 @@ mirror::ArtField* MethodVerifier::FindAccessedFieldAtDexPc(uint32_t dex_pc) { // got what we wanted. bool success = Verify(); if (!success) { - return NULL; + return nullptr; } RegisterLine* register_line = reg_table_.GetLine(dex_pc); if (register_line == NULL) { - return NULL; + return nullptr; } const Instruction* inst = Instruction::At(code_item_->insns_ + dex_pc); return GetQuickFieldAccess(inst, register_line); @@ -3118,37 +3118,14 @@ mirror::ArtMethod* MethodVerifier::GetQuickInvokedMethod(const Instruction* inst DCHECK(inst->Opcode() == Instruction::INVOKE_VIRTUAL_QUICK || inst->Opcode() == Instruction::INVOKE_VIRTUAL_RANGE_QUICK); const RegType& actual_arg_type = reg_line->GetInvocationThis(inst, is_range); - if (actual_arg_type.IsConflict()) { // GetInvocationThis failed. - return nullptr; - } else if (actual_arg_type.IsZero()) { // Invoke on "null" instance: we can't go further. + if (!actual_arg_type.HasClass()) { + VLOG(verifier) << "Failed to get mirror::Class* from '" << actual_arg_type << "'"; return nullptr; } - mirror::Class* this_class = NULL; - if (!actual_arg_type.IsUnresolvedTypes()) { - this_class = actual_arg_type.GetClass(); - } else { - const std::string& descriptor(actual_arg_type.GetDescriptor()); - // Try to resolve type. - const RegType& resolved_arg_type = reg_types_.FromDescriptor(class_loader_->get(), - descriptor.c_str(), false); - if (!resolved_arg_type.HasClass()) { - return nullptr; // Resolution failed. - } - this_class = resolved_arg_type.GetClass(); - if (this_class == NULL) { - Thread* self = Thread::Current(); - self->ClearException(); - // Look for a system class - this_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(), false).GetClass(); - } - } - if (this_class == NULL) { - return NULL; - } - mirror::ObjectArray* vtable = this_class->GetVTable(); - CHECK(vtable != NULL); + mirror::ObjectArray* vtable = actual_arg_type.GetClass()->GetVTable(); + CHECK(vtable != nullptr); uint16_t vtable_index = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); - CHECK(vtable_index < vtable->GetLength()); + CHECK_LT(static_cast(vtable_index), vtable->GetLength()); mirror::ArtMethod* res_method = vtable->Get(vtable_index); CHECK(!Thread::Current()->IsExceptionPending()); return res_method; @@ -3636,12 +3613,12 @@ static mirror::ArtField* FindInstanceFieldWithOffset(mirror::Class* klass, uint3 if (klass->GetSuperClass() != NULL) { return FindInstanceFieldWithOffset(klass->GetSuperClass(), field_offset); } else { - return NULL; + VLOG(verifier) << "Failed to find instance field at offset '" << field_offset + << "' from '" << PrettyDescriptor(klass) << "'"; + return nullptr; } } -// Returns the access field of a quick field access (iget/iput-quick) or NULL -// if it cannot be found. mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, RegisterLine* reg_line) { DCHECK(inst->Opcode() == Instruction::IGET_QUICK || @@ -3651,29 +3628,12 @@ mirror::ArtField* MethodVerifier::GetQuickFieldAccess(const Instruction* inst, inst->Opcode() == Instruction::IPUT_WIDE_QUICK || inst->Opcode() == Instruction::IPUT_OBJECT_QUICK); const RegType& object_type = reg_line->GetRegisterType(inst->VRegB_22c()); - mirror::Class* object_class = NULL; - if (!object_type.IsUnresolvedTypes()) { - object_class = object_type.GetClass(); - } else { - // We need to resolve the class from its descriptor. - const std::string& descriptor(object_type.GetDescriptor()); - Thread* self = Thread::Current(); - object_class = reg_types_.FromDescriptor(class_loader_->get(), descriptor.c_str(), - false).GetClass(); - if (object_class == NULL) { - self->ClearException(); - // Look for a system class - object_class = reg_types_.FromDescriptor(nullptr, descriptor.c_str(), - false).GetClass(); - } - } - if (object_class == NULL) { - // Failed to get the Class* from reg type. - LOG(WARNING) << "Failed to get Class* from " << object_type; - return NULL; + if (!object_type.HasClass()) { + VLOG(verifier) << "Failed to get mirror::Class* from '" << object_type << "'"; + return nullptr; } uint32_t field_offset = static_cast(inst->VRegC_22c()); - return FindInstanceFieldWithOffset(object_class, field_offset); + return FindInstanceFieldWithOffset(object_type.GetClass(), field_offset); } void MethodVerifier::VerifyIGetQuick(const Instruction* inst, const RegType& insn_type, -- 2.11.0