Don't resolve types in verifier when we can't load classes.
Added a boolean parameter to GetReturnType which tells us whether or
not we can resolve types. We pass in can_load_classes_.
Bug: 11689500
Change-Id: Ib3d35f441e08c2409ce14ac269854012dc978ddd
diff --git a/runtime/object_utils.h b/runtime/object_utils.h
index 084e1e2..407aa65 100644
--- a/runtime/object_utils.h
+++ b/runtime/object_utils.h
@@ -417,12 +417,12 @@
return GetDexFile().GetProtoParameters(proto);
}
- mirror::Class* GetReturnType() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ mirror::Class* GetReturnType(bool resolve = true) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
const DexFile& dex_file = GetDexFile();
const DexFile::MethodId& method_id = dex_file.GetMethodId(method_->GetDexMethodIndex());
const DexFile::ProtoId& proto_id = dex_file.GetMethodPrototype(method_id);
uint16_t return_type_idx = proto_id.return_type_idx_;
- return GetClassFromTypeIdx(return_type_idx);
+ return GetClassFromTypeIdx(return_type_idx, resolve);
}
const char* GetReturnTypeDescriptor() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -532,10 +532,10 @@
return method_->GetDexCacheResolvedTypes()->Get(type_idx) != NULL;
}
- mirror::Class* GetClassFromTypeIdx(uint16_t type_idx)
+ mirror::Class* GetClassFromTypeIdx(uint16_t type_idx, bool resolve = true)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::Class* type = method_->GetDexCacheResolvedTypes()->Get(type_idx);
- if (type == NULL) {
+ if (type == NULL && resolve) {
type = GetClassLinker()->ResolveType(type_idx, method_);
CHECK(type != NULL || Thread::Current()->IsExceptionPending());
}
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 9a2de47..d2681df 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2129,13 +2129,13 @@
const RegType* return_type = nullptr;
if (called_method != nullptr) {
MethodHelper mh(called_method);
- mirror::Class* return_type_class = mh.GetReturnType();
+ mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
return_type = ®_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
return_type_class->CannotBeAssignedFromOtherTypes());
} else {
Thread* self = Thread::Current();
- DCHECK(self->IsExceptionPending());
+ DCHECK(!can_load_classes_ || self->IsExceptionPending());
self->ClearException();
}
}
@@ -3518,10 +3518,14 @@
const RegType* field_type = nullptr;
if (field != NULL) {
FieldHelper fh(field);
- mirror::Class* field_type_class = fh.GetType(false);
+ mirror::Class* field_type_class = fh.GetType(can_load_classes_);
if (field_type_class != nullptr) {
field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
+ } else {
+ Thread* self = Thread::Current();
+ DCHECK(!can_load_classes_ || self->IsExceptionPending());
+ self->ClearException();
}
}
if (field_type == nullptr) {
@@ -3580,10 +3584,14 @@
return;
}
FieldHelper fh(field);
- mirror::Class* field_type_class = fh.GetType(false);
+ mirror::Class* field_type_class = fh.GetType(can_load_classes_);
if (field_type_class != nullptr) {
field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
+ } else {
+ Thread* self = Thread::Current();
+ DCHECK(!can_load_classes_ || self->IsExceptionPending());
+ self->ClearException();
}
}
if (field_type == nullptr) {
@@ -3673,12 +3681,15 @@
return;
}
FieldHelper fh(field);
- mirror::Class* field_type_class = fh.GetType(false);
+ mirror::Class* field_type_class = fh.GetType(can_load_classes_);
const RegType* field_type;
if (field_type_class != nullptr) {
field_type = ®_types_.FromClass(fh.GetTypeDescriptor(), field_type_class,
field_type_class->CannotBeAssignedFromOtherTypes());
} else {
+ Thread* self = Thread::Current();
+ DCHECK(!can_load_classes_ || self->IsExceptionPending());
+ self->ClearException();
field_type = ®_types_.FromDescriptor(field->GetDeclaringClass()->GetClassLoader(),
fh.GetTypeDescriptor(), false);
}
@@ -3856,13 +3867,13 @@
if (return_type_ == nullptr) {
if (mirror_method_ != NULL) {
MethodHelper mh(mirror_method_);
- mirror::Class* return_type_class = mh.GetReturnType();
+ mirror::Class* return_type_class = mh.GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
return_type_ = ®_types_.FromClass(mh.GetReturnTypeDescriptor(), return_type_class,
return_type_class->CannotBeAssignedFromOtherTypes());
} else {
Thread* self = Thread::Current();
- DCHECK(self->IsExceptionPending());
+ DCHECK(!can_load_classes_ || self->IsExceptionPending());
self->ClearException();
}
}