summaryrefslogtreecommitdiffstats
path: root/runtime
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-06-23 23:15:18 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2015-06-23 23:15:19 +0000
commit1a63351b4b68a9ffb4e55ce8185e13cda6893ec1 (patch)
tree86ad82b6a3a311db11b9981ec20552822a9d3954 /runtime
parent0cffac0c639d81e77d82c29ed423c91fb4da073b (diff)
parenta497d1cf500f3b06fb401c33e21d38f1bd0026ad (diff)
downloadart-1a63351b4b68a9ffb4e55ce8185e13cda6893ec1.zip
art-1a63351b4b68a9ffb4e55ce8185e13cda6893ec1.tar.gz
art-1a63351b4b68a9ffb4e55ce8185e13cda6893ec1.tar.bz2
Merge "ART: Follow-up to 507cc6f83bf6379728f2dd20391f2ed5fbfe6371" into mnc-dev
Diffstat (limited to 'runtime')
-rw-r--r--runtime/verifier/method_verifier.cc55
-rw-r--r--runtime/verifier/method_verifier.h8
2 files changed, 41 insertions, 22 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index 6c55356..5436100 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -2401,9 +2401,9 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
StackHandleScope<1> hs(self_);
mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
- return_type = &reg_types_.FromClass(called_method->GetReturnTypeDescriptor(),
- return_type_class,
- return_type_class->CannotBeAssignedFromOtherTypes());
+ return_type = &FromClass(called_method->GetReturnTypeDescriptor(),
+ return_type_class,
+ return_type_class->CannotBeAssignedFromOtherTypes());
} else {
DCHECK(!can_load_classes_ || self_->IsExceptionPending());
self_->ClearException();
@@ -2446,9 +2446,9 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
StackHandleScope<1> hs(self_);
mirror::Class* return_type_class = called_method->GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
- return_type = &reg_types_.FromClass(return_type_descriptor,
- return_type_class,
- return_type_class->CannotBeAssignedFromOtherTypes());
+ return_type = &FromClass(return_type_descriptor,
+ return_type_class,
+ return_type_class->CannotBeAssignedFromOtherTypes());
} else {
DCHECK(!can_load_classes_ || self_->IsExceptionPending());
self_->ClearException();
@@ -3164,7 +3164,7 @@ const RegType& MethodVerifier::ResolveClassAndCheckAccess(uint32_t class_idx) {
const RegType& referrer = GetDeclaringClass();
mirror::Class* klass = dex_cache_->GetResolvedType(class_idx);
const RegType& result = klass != nullptr ?
- reg_types_.FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
+ FromClass(descriptor, klass, klass->CannotBeAssignedFromOtherTypes()) :
reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
if (result.IsConflict()) {
Fail(VERIFY_ERROR_BAD_CLASS_SOFT) << "accessing broken descriptor '" << descriptor
@@ -3380,8 +3380,8 @@ ArtMethod* MethodVerifier::VerifyInvocationArgsFromIterator(
if (res_method != nullptr) {
mirror::Class* klass = res_method->GetDeclaringClass();
std::string temp;
- res_method_class = &reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
- klass->CannotBeAssignedFromOtherTypes());
+ res_method_class = &FromClass(klass->GetDescriptor(&temp), klass,
+ klass->CannotBeAssignedFromOtherTypes());
} else {
const uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c();
const uint16_t class_idx = dex_file_->GetMethodId(method_idx).class_idx_;
@@ -3622,8 +3622,7 @@ ArtMethod* MethodVerifier::VerifyInvokeVirtualQuickArgs(const Instruction* inst,
mirror::Class* klass = res_method->GetDeclaringClass();
std::string temp;
const RegType& res_method_class =
- reg_types_.FromClass(klass->GetDescriptor(&temp), klass,
- klass->CannotBeAssignedFromOtherTypes());
+ FromClass(klass->GetDescriptor(&temp), klass, klass->CannotBeAssignedFromOtherTypes());
if (!res_method_class.IsAssignableFrom(actual_arg_type)) {
Fail(actual_arg_type.IsUnresolvedTypes() ? VERIFY_ERROR_NO_CLASS :
VERIFY_ERROR_BAD_CLASS_SOFT) << "'this' argument '" << actual_arg_type
@@ -3933,8 +3932,8 @@ ArtField* MethodVerifier::GetInstanceField(const RegType& obj_type, int field_id
} else {
mirror::Class* klass = field->GetDeclaringClass();
const RegType& field_klass =
- reg_types_.FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
- klass, klass->CannotBeAssignedFromOtherTypes());
+ FromClass(dex_file_->GetFieldDeclaringClassDescriptor(field_id),
+ klass, klass->CannotBeAssignedFromOtherTypes());
if (obj_type.IsUninitializedTypes() &&
(!IsConstructor() || GetDeclaringClass().Equals(obj_type) ||
!field_klass.Equals(GetDeclaringClass()))) {
@@ -3984,8 +3983,8 @@ void MethodVerifier::VerifyISFieldAccess(const Instruction* inst, const RegType&
mirror::Class* field_type_class =
can_load_classes_ ? field->GetType<true>() : field->GetType<false>();
if (field_type_class != nullptr) {
- field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
- field_type_class->CannotBeAssignedFromOtherTypes());
+ field_type = &FromClass(field->GetTypeDescriptor(), field_type_class,
+ field_type_class->CannotBeAssignedFromOtherTypes());
} else {
DCHECK(!can_load_classes_ || self_->IsExceptionPending());
self_->ClearException();
@@ -4096,8 +4095,8 @@ void MethodVerifier::VerifyQuickFieldAccess(const Instruction* inst, const RegTy
field->GetType<false>();
if (field_type_class != nullptr) {
- field_type = &reg_types_.FromClass(field->GetTypeDescriptor(), field_type_class,
- field_type_class->CannotBeAssignedFromOtherTypes());
+ field_type = &FromClass(field->GetTypeDescriptor(), field_type_class,
+ field_type_class->CannotBeAssignedFromOtherTypes());
} else {
Thread* self = Thread::Current();
DCHECK(!can_load_classes_ || self->IsExceptionPending());
@@ -4289,9 +4288,9 @@ const RegType& MethodVerifier::GetMethodReturnType() {
if (mirror_method_ != nullptr) {
mirror::Class* return_type_class = mirror_method_->GetReturnType(can_load_classes_);
if (return_type_class != nullptr) {
- return_type_ = &reg_types_.FromClass(mirror_method_->GetReturnTypeDescriptor(),
- return_type_class,
- return_type_class->CannotBeAssignedFromOtherTypes());
+ return_type_ = &FromClass(mirror_method_->GetReturnTypeDescriptor(),
+ return_type_class,
+ return_type_class->CannotBeAssignedFromOtherTypes());
} else {
DCHECK(!can_load_classes_ || self_->IsExceptionPending());
self_->ClearException();
@@ -4315,8 +4314,8 @@ const RegType& MethodVerifier::GetDeclaringClass() {
= dex_file_->GetTypeDescriptor(dex_file_->GetTypeId(method_id.class_idx_));
if (mirror_method_ != nullptr) {
mirror::Class* klass = mirror_method_->GetDeclaringClass();
- declaring_class_ = &reg_types_.FromClass(descriptor, klass,
- klass->CannotBeAssignedFromOtherTypes());
+ declaring_class_ = &FromClass(descriptor, klass,
+ klass->CannotBeAssignedFromOtherTypes());
} else {
declaring_class_ = &reg_types_.FromDescriptor(GetClassLoader(), descriptor, false);
}
@@ -4416,5 +4415,17 @@ void MethodVerifier::VisitRoots(RootVisitor* visitor, const RootInfo& root_info)
reg_types_.VisitRoots(visitor, root_info);
}
+const RegType& MethodVerifier::FromClass(const char* descriptor,
+ mirror::Class* klass,
+ bool precise) {
+ DCHECK(klass != nullptr);
+ if (precise && !klass->IsInstantiable() && !klass->IsPrimitive()) {
+ Fail(VerifyError::VERIFY_ERROR_NO_CLASS) << "Could not create precise reference for "
+ << "non-instantiable klass " << descriptor;
+ precise = false;
+ }
+ return reg_types_.FromClass(descriptor, klass, precise);
+}
+
} // namespace verifier
} // namespace art
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 873b8ab..cd691a3 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -660,6 +660,14 @@ class MethodVerifier {
const RegType& DetermineCat1Constant(int32_t value, bool precise)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+ // Try to create a register type from the given class. In case a precise type is requested, but
+ // the class is not instantiable, a soft error (of type NO_CLASS) will be enqueued and a
+ // non-precise reference will be returned.
+ // Note: we reuse NO_CLASS as this will throw an exception at runtime, when the failing class is
+ // actually touched.
+ const RegType& FromClass(const char* descriptor, mirror::Class* klass, bool precise)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
// The thread we're verifying on.
Thread* const self_;