summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2014-04-17 16:40:01 -0700
committerIan Rogers <irogers@google.com>2014-04-17 16:45:06 -0700
commit9bc54406ba3377980cfce44901dc2be246178ba9 (patch)
tree12b9a514ef37c5cd01a99f3c6ffa83e3b03be7c0
parent94e8a97310af35cb0bae309e796b554cdb586ca5 (diff)
downloadart-9bc54406ba3377980cfce44901dc2be246178ba9.zip
art-9bc54406ba3377980cfce44901dc2be246178ba9.tar.gz
art-9bc54406ba3377980cfce44901dc2be246178ba9.tar.bz2
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
-rw-r--r--runtime/runtime.cc4
-rw-r--r--runtime/runtime.h4
-rw-r--r--runtime/verifier/method_verifier.cc70
3 files changed, 23 insertions, 55 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index eb0522a..611ce0b 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<std::string>* 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 462711e..1ee0b1a 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 dbde7c7..535c76d 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<mirror::DexCache> dex_cache(self, mh.GetDexCache());
SirtRef<mirror::ClassLoader> 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<mirror::ArtMethod>* vtable = this_class->GetVTable();
- CHECK(vtable != NULL);
+ mirror::ObjectArray<mirror::ArtMethod>* 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<int32_t>(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<uint32_t>(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,