diff options
author | Andreas Gampe <agampe@google.com> | 2015-06-23 23:15:18 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2015-06-23 23:15:19 +0000 |
commit | 1a63351b4b68a9ffb4e55ce8185e13cda6893ec1 (patch) | |
tree | 86ad82b6a3a311db11b9981ec20552822a9d3954 /runtime | |
parent | 0cffac0c639d81e77d82c29ed423c91fb4da073b (diff) | |
parent | a497d1cf500f3b06fb401c33e21d38f1bd0026ad (diff) | |
download | art-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.cc | 55 | ||||
-rw-r--r-- | runtime/verifier/method_verifier.h | 8 |
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 = ®_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 = ®_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 = ®_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 = ®_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 = ®_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_ = ®_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_ = ®_types_.FromClass(descriptor, klass, - klass->CannotBeAssignedFromOtherTypes()); + declaring_class_ = &FromClass(descriptor, klass, + klass->CannotBeAssignedFromOtherTypes()); } else { declaring_class_ = ®_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_; |