diff options
author | Andreas Gampe <agampe@google.com> | 2014-07-31 16:23:49 -0700 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2014-08-06 15:57:05 -0700 |
commit | 58a5af8568d224ca7eccf2483396ff9862f8d1ee (patch) | |
tree | 4dfac17316970040e079244523b9b1e2ea163f05 | |
parent | 1b192268f167f603fc372f02f9067f3ce5d82daf (diff) | |
download | art-58a5af8568d224ca7eccf2483396ff9862f8d1ee.zip art-58a5af8568d224ca7eccf2483396ff9862f8d1ee.tar.gz art-58a5af8568d224ca7eccf2483396ff9862f8d1ee.tar.bz2 |
ART: Add guards to the dex cache and its shortcuts
Do not return fields, methods or classes if the (declaring) class is
erroneous.
Bug: 16692788
Change-Id: If43c2414ad0eb22db5eba7cf66396c7f16c26597
-rw-r--r-- | compiler/driver/compiler_driver.cc | 8 | ||||
-rw-r--r-- | runtime/class_linker-inl.h | 25 | ||||
-rw-r--r-- | runtime/class_linker.cc | 25 | ||||
-rw-r--r-- | runtime/class_linker_test.cc | 20 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 4 | ||||
-rw-r--r-- | runtime/entrypoints/entrypoint_utils.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/portable/portable_throw_entrypoints.cc | 2 | ||||
-rw-r--r-- | runtime/entrypoints/quick/quick_trampoline_entrypoints.cc | 6 | ||||
-rw-r--r-- | runtime/method_helper-inl.h | 2 | ||||
-rw-r--r-- | runtime/mirror/art_method-inl.h | 53 | ||||
-rw-r--r-- | runtime/mirror/art_method.h | 20 | ||||
-rw-r--r-- | runtime/mirror/dex_cache.h | 12 | ||||
-rw-r--r-- | runtime/verifier/reg_type_cache.cc | 2 |
13 files changed, 125 insertions, 56 deletions
diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index ed126ad..6b0cc50 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -811,11 +811,15 @@ void CompilerDriver::UpdateImageClasses(TimingLogger* timings) { bool CompilerDriver::CanAssumeTypeIsPresentInDexCache(const DexFile& dex_file, uint32_t type_idx) { if (IsImage() && IsImageClass(dex_file.StringDataByIdx(dex_file.GetTypeId(type_idx).descriptor_idx_))) { - if (kIsDebugBuild) { + { ScopedObjectAccess soa(Thread::Current()); mirror::DexCache* dex_cache = Runtime::Current()->GetClassLinker()->FindDexCache(dex_file); mirror::Class* resolved_class = dex_cache->GetResolvedType(type_idx); - CHECK(resolved_class != NULL); + if (resolved_class == nullptr) { + // Erroneous class. + stats_->TypeNotInDexCache(); + return false; + } } stats_->TypeInDexCache(); return true; diff --git a/runtime/class_linker-inl.h b/runtime/class_linker-inl.h index cf25810..9921bdd 100644 --- a/runtime/class_linker-inl.h +++ b/runtime/class_linker-inl.h @@ -77,7 +77,7 @@ inline mirror::String* ClassLinker::ResolveString(uint32_t string_idx, inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtMethod* referrer) { - mirror::Class* resolved_type = referrer->GetDexCacheResolvedTypes()->Get(type_idx); + mirror::Class* resolved_type = referrer->GetDexCacheResolvedType(type_idx); if (UNLIKELY(resolved_type == nullptr)) { mirror::Class* declaring_class = referrer->GetDeclaringClass(); StackHandleScope<2> hs(Thread::Current()); @@ -85,9 +85,8 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); - if (resolved_type != nullptr) { - DCHECK_EQ(dex_cache->GetResolvedType(type_idx), resolved_type); - } + // Note: We cannot check here to see whether we added the type to the cache. The type + // might be an erroneous class, which results in it being hidden from us. } return resolved_type; } @@ -102,9 +101,8 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtFie Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_type = ResolveType(dex_file, type_idx, dex_cache, class_loader); - if (resolved_type != nullptr) { - DCHECK_EQ(dex_cache->GetResolvedType(type_idx), resolved_type); - } + // Note: We cannot check here to see whether we added the type to the cache. The type + // might be an erroneous class, which results in it being hidden from us. } return resolved_type; } @@ -112,8 +110,7 @@ inline mirror::Class* ClassLinker::ResolveType(uint16_t type_idx, mirror::ArtFie inline mirror::ArtMethod* ClassLinker::GetResolvedMethod(uint32_t method_idx, mirror::ArtMethod* referrer, InvokeType type) { - mirror::ArtMethod* resolved_method = - referrer->GetDexCacheResolvedMethods()->Get(method_idx); + mirror::ArtMethod* resolved_method = referrer->GetDexCacheResolvedMethod(method_idx); if (resolved_method == nullptr || resolved_method->IsRuntimeMethod()) { return nullptr; } @@ -135,9 +132,8 @@ inline mirror::ArtMethod* ClassLinker::ResolveMethod(Thread* self, uint32_t meth const DexFile* dex_file = h_dex_cache->GetDexFile(); resolved_method = ResolveMethod(*dex_file, method_idx, h_dex_cache, h_class_loader, h_referrer, type); - if (resolved_method != nullptr) { - DCHECK_EQ(h_dex_cache->GetResolvedMethod(method_idx), resolved_method); - } + // Note: We cannot check here to see whether we added the method to the cache. It + // might be an erroneous class, which results in it being hidden from us. return resolved_method; } @@ -156,9 +152,8 @@ inline mirror::ArtField* ClassLinker::ResolveField(uint32_t field_idx, mirror::A Handle<mirror::ClassLoader> class_loader(hs.NewHandle(declaring_class->GetClassLoader())); const DexFile& dex_file = *dex_cache->GetDexFile(); resolved_field = ResolveField(dex_file, field_idx, dex_cache, class_loader, is_static); - if (resolved_field != nullptr) { - DCHECK_EQ(dex_cache->GetResolvedField(field_idx), resolved_field); - } + // Note: We cannot check here to see whether we added the field to the cache. The type + // might be an erroneous class, which results in it being hidden from us. } return resolved_field; } diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index f0b1b95..72572a0 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -3488,22 +3488,21 @@ mirror::ArtMethod* ClassLinker::FindMethodForProxy(mirror::Class* proxy_class, DCHECK(proxy_class->IsProxyClass()); DCHECK(proxy_method->IsProxyMethod()); // Locate the dex cache of the original interface/Object - mirror::DexCache* dex_cache = NULL; + mirror::DexCache* dex_cache = nullptr; { - mirror::ObjectArray<mirror::Class>* resolved_types = proxy_method->GetDexCacheResolvedTypes(); ReaderMutexLock mu(Thread::Current(), dex_lock_); for (size_t i = 0; i != dex_caches_.size(); ++i) { mirror::DexCache* a_dex_cache = GetDexCache(i); - if (a_dex_cache->GetResolvedTypes() == resolved_types) { + if (proxy_method->HasSameDexCacheResolvedTypes(a_dex_cache->GetResolvedTypes())) { dex_cache = a_dex_cache; break; } } } - CHECK(dex_cache != NULL); + CHECK(dex_cache != nullptr); uint32_t method_idx = proxy_method->GetDexMethodIndex(); mirror::ArtMethod* resolved_method = dex_cache->GetResolvedMethod(method_idx); - CHECK(resolved_method != NULL); + CHECK(resolved_method != nullptr); return resolved_method; } @@ -3583,8 +3582,8 @@ static void CheckProxyMethod(Handle<mirror::ArtMethod> method, Handle<mirror::Ar // The proxy method doesn't have its own dex cache or dex file and so it steals those of its // interface prototype. The exception to this are Constructors and the Class of the Proxy itself. CHECK_EQ(prototype->GetDexCacheStrings(), method->GetDexCacheStrings()); - CHECK_EQ(prototype->GetDexCacheResolvedMethods(), method->GetDexCacheResolvedMethods()); - CHECK_EQ(prototype->GetDexCacheResolvedTypes(), method->GetDexCacheResolvedTypes()); + CHECK(prototype->HasSameDexCacheResolvedMethods(method.Get())); + CHECK(prototype->HasSameDexCacheResolvedTypes(method.Get())); CHECK_EQ(prototype->GetDexMethodIndex(), method->GetDexMethodIndex()); MethodHelper mh(method); @@ -4952,7 +4951,7 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi bool is_static) { DCHECK(dex_cache.Get() != nullptr); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); - if (resolved != NULL) { + if (resolved != nullptr) { return resolved; } const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx); @@ -4960,9 +4959,9 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi StackHandleScope<1> hs(self); Handle<mirror::Class> klass( hs.NewHandle(ResolveType(dex_file, field_id.class_idx_, dex_cache, class_loader))); - if (klass.Get() == NULL) { + if (klass.Get() == nullptr) { DCHECK(Thread::Current()->IsExceptionPending()); - return NULL; + return nullptr; } if (is_static) { @@ -4971,7 +4970,7 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi resolved = klass->FindInstanceField(dex_cache.Get(), field_idx); } - if (resolved == NULL) { + if (resolved == nullptr) { const char* name = dex_file.GetFieldName(field_id); const char* type = dex_file.GetFieldTypeDescriptor(field_id); if (is_static) { @@ -4979,7 +4978,7 @@ mirror::ArtField* ClassLinker::ResolveField(const DexFile& dex_file, uint32_t fi } else { resolved = klass->FindInstanceField(name, type); } - if (resolved == NULL) { + if (resolved == nullptr) { ThrowNoSuchFieldError(is_static ? "static " : "instance ", klass.Get(), type, name); return NULL; } @@ -4994,7 +4993,7 @@ mirror::ArtField* ClassLinker::ResolveFieldJLS(const DexFile& dex_file, Handle<mirror::ClassLoader> class_loader) { DCHECK(dex_cache.Get() != nullptr); mirror::ArtField* resolved = dex_cache->GetResolvedField(field_idx); - if (resolved != NULL) { + if (resolved != nullptr) { return resolved; } const DexFile::FieldId& field_id = dex_file.GetFieldId(field_idx); diff --git a/runtime/class_linker_test.cc b/runtime/class_linker_test.cc index 8e16d9b..8d93265 100644 --- a/runtime/class_linker_test.cc +++ b/runtime/class_linker_test.cc @@ -156,20 +156,20 @@ class ClassLinkerTest : public CommonRuntimeTest { } void AssertMethod(mirror::ArtMethod* method) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - EXPECT_TRUE(method != NULL); - EXPECT_TRUE(method->GetClass() != NULL); - EXPECT_TRUE(method->GetName() != NULL); + EXPECT_TRUE(method != nullptr); + EXPECT_TRUE(method->GetClass() != nullptr); + EXPECT_TRUE(method->GetName() != nullptr); EXPECT_TRUE(method->GetSignature() != Signature::NoSignature()); - EXPECT_TRUE(method->GetDexCacheStrings() != NULL); - EXPECT_TRUE(method->GetDexCacheResolvedMethods() != NULL); - EXPECT_TRUE(method->GetDexCacheResolvedTypes() != NULL); + EXPECT_TRUE(method->GetDexCacheStrings() != nullptr); + EXPECT_TRUE(method->HasDexCacheResolvedMethods()); + EXPECT_TRUE(method->HasDexCacheResolvedTypes()); EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetStrings(), method->GetDexCacheStrings()); - EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedMethods(), - method->GetDexCacheResolvedMethods()); - EXPECT_EQ(method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes(), - method->GetDexCacheResolvedTypes()); + EXPECT_TRUE(method->HasSameDexCacheResolvedMethods( + method->GetDeclaringClass()->GetDexCache()->GetResolvedMethods())); + EXPECT_TRUE(method->HasSameDexCacheResolvedTypes( + method->GetDeclaringClass()->GetDexCache()->GetResolvedTypes())); } void AssertField(mirror::Class* klass, mirror::ArtField* field) diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index cb0be04..af71c19 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -40,7 +40,7 @@ template <const bool kAccessCheck> static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, mirror::ArtMethod* method, Thread* self, bool* slow_path) { - mirror::Class* klass = method->GetDexCacheResolvedTypes()->GetWithoutChecks(type_idx); + mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx); if (UNLIKELY(klass == NULL)) { klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); *slow_path = true; @@ -178,7 +178,7 @@ static inline mirror::Class* CheckArrayAlloc(uint32_t type_idx, *slow_path = true; return nullptr; // Failure } - mirror::Class* klass = method->GetDexCacheResolvedTypes()->GetWithoutChecks(type_idx); + mirror::Class* klass = method->GetDexCacheResolvedType<false>(type_idx); if (UNLIKELY(klass == nullptr)) { // Not in dex cache so try to resolve klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); *slow_path = true; diff --git a/runtime/entrypoints/entrypoint_utils.cc b/runtime/entrypoints/entrypoint_utils.cc index c1c7631..be3895a 100644 --- a/runtime/entrypoints/entrypoint_utils.cc +++ b/runtime/entrypoints/entrypoint_utils.cc @@ -41,7 +41,7 @@ static inline mirror::Class* CheckFilledNewArrayAlloc(uint32_t type_idx, mirror: ThrowNegativeArraySizeException(component_count); return nullptr; // Failure } - mirror::Class* klass = referrer->GetDexCacheResolvedTypes()->GetWithoutChecks(type_idx); + mirror::Class* klass = referrer->GetDexCacheResolvedType<false>(type_idx); if (UNLIKELY(klass == NULL)) { // Not in dex cache so try to resolve klass = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, referrer); if (klass == NULL) { // Error diff --git a/runtime/entrypoints/portable/portable_throw_entrypoints.cc b/runtime/entrypoints/portable/portable_throw_entrypoints.cc index be6231c..4317358 100644 --- a/runtime/entrypoints/portable/portable_throw_entrypoints.cc +++ b/runtime/entrypoints/portable/portable_throw_entrypoints.cc @@ -98,7 +98,7 @@ extern "C" int32_t art_portable_find_catch_block_from_code(mirror::ArtMethod* cu } // Does this catch exception type apply? mirror::Class* iter_exception_type = - current_method->GetDexCacheResolvedTypes()->Get(iter_type_idx); + current_method->GetDexCacheResolvedType(iter_type_idx); if (UNLIKELY(iter_exception_type == NULL)) { // TODO: check, the verifier (class linker?) should take care of resolving all exception // classes early. diff --git a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc index fa198d7..4730701 100644 --- a/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc +++ b/runtime/entrypoints/quick/quick_trampoline_entrypoints.cc @@ -790,8 +790,8 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, // We came here because of sharpening. Ensure the dex cache is up-to-date on the method index // of the sharpened method. - if (called->GetDexCacheResolvedMethods() == caller->GetDexCacheResolvedMethods()) { - caller->GetDexCacheResolvedMethods()->Set<false>(called->GetDexMethodIndex(), called); + if (called->HasSameDexCacheResolvedMethods(caller)) { + caller->SetDexCacheResolvedMethod(called->GetDexMethodIndex(), called); } else { // Calling from one dex file to another, need to compute the method index appropriate to // the caller's dex file. Since we get here only if the original called was a runtime @@ -801,7 +801,7 @@ extern "C" const void* artQuickResolutionTrampoline(mirror::ArtMethod* called, MethodHelper mh(hs.NewHandle(called)); uint32_t method_index = mh.FindDexMethodIndexInOtherDexFile(*dex_file, dex_method_idx); if (method_index != DexFile::kDexNoIndex) { - caller->GetDexCacheResolvedMethods()->Set<false>(method_index, called); + caller->SetDexCacheResolvedMethod(method_index, called); } } } diff --git a/runtime/method_helper-inl.h b/runtime/method_helper-inl.h index 4f95a28..3a5056a 100644 --- a/runtime/method_helper-inl.h +++ b/runtime/method_helper-inl.h @@ -28,7 +28,7 @@ namespace art { inline mirror::Class* MethodHelper::GetClassFromTypeIdx(uint16_t type_idx, bool resolve) { mirror::ArtMethod* method = GetMethod(); - mirror::Class* type = method->GetDexCacheResolvedTypes()->Get(type_idx); + mirror::Class* type = method->GetDexCacheResolvedType(type_idx); if (type == nullptr && resolve) { type = Runtime::Current()->GetClassLinker()->ResolveType(type_idx, method); CHECK(type != nullptr || Thread::Current()->IsExceptionPending()); diff --git a/runtime/mirror/art_method-inl.h b/runtime/mirror/art_method-inl.h index 73de683..0dd1588 100644 --- a/runtime/mirror/art_method-inl.h +++ b/runtime/mirror/art_method-inl.h @@ -19,6 +19,8 @@ #include "art_method.h" +#include "art_field.h" +#include "class.h" #include "class_linker.h" #include "dex_cache.h" #include "dex_file.h" @@ -87,11 +89,60 @@ inline ObjectArray<ArtMethod>* ArtMethod::GetDexCacheResolvedMethods() { OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_methods_)); } +inline ArtMethod* ArtMethod::GetDexCacheResolvedMethod(uint16_t method_index) { + ArtMethod* method = GetDexCacheResolvedMethods()->Get(method_index); + if (method != nullptr && !method->GetDeclaringClass()->IsErroneous()) { + return method; + } else { + return nullptr; + } +} + +inline void ArtMethod::SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method) { + GetDexCacheResolvedMethods()->Set<false>(method_idx, new_method); +} + +inline bool ArtMethod::HasDexCacheResolvedMethods() { + return GetDexCacheResolvedMethods() != nullptr; +} + +inline bool ArtMethod::HasSameDexCacheResolvedMethods(ObjectArray<ArtMethod>* other_cache) { + return GetDexCacheResolvedMethods() == other_cache; +} + +inline bool ArtMethod::HasSameDexCacheResolvedMethods(ArtMethod* other) { + return GetDexCacheResolvedMethods() == other->GetDexCacheResolvedMethods(); +} + + inline ObjectArray<Class>* ArtMethod::GetDexCacheResolvedTypes() { return GetFieldObject<ObjectArray<Class>>( OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_)); } +template <bool kWithCheck> +inline Class* ArtMethod::GetDexCacheResolvedType(uint32_t type_index) { + Class* klass; + if (kWithCheck) { + klass = GetDexCacheResolvedTypes()->Get(type_index); + } else { + klass = GetDexCacheResolvedTypes()->GetWithoutChecks(type_index); + } + return (klass != nullptr && !klass->IsErroneous()) ? klass : nullptr; +} + +inline bool ArtMethod::HasDexCacheResolvedTypes() { + return GetDexCacheResolvedTypes() != nullptr; +} + +inline bool ArtMethod::HasSameDexCacheResolvedTypes(ObjectArray<Class>* other_cache) { + return GetDexCacheResolvedTypes() == other_cache; +} + +inline bool ArtMethod::HasSameDexCacheResolvedTypes(ArtMethod* other) { + return GetDexCacheResolvedTypes() == other->GetDexCacheResolvedTypes(); +} + inline uint32_t ArtMethod::GetCodeSize() { DCHECK(!IsRuntimeMethod() && !IsProxyMethod()) << PrettyMethod(this); const void* code = EntryPointToCodePointer(GetEntryPointFromQuickCompiledCode()); @@ -396,7 +447,7 @@ inline const DexFile::CodeItem* ArtMethod::GetCodeItem() { inline bool ArtMethod::IsResolvedTypeIdx(uint16_t type_idx) { mirror::ArtMethod* method = GetInterfaceMethodIfProxy(); - return method->GetDexCacheResolvedTypes()->Get(type_idx) != nullptr; + return method->GetDexCacheResolvedType(type_idx) != nullptr; } inline int32_t ArtMethod::GetLineNumFromDexPC(uint32_t dex_pc) { diff --git a/runtime/mirror/art_method.h b/runtime/mirror/art_method.h index 01e6149..4ebceff 100644 --- a/runtime/mirror/art_method.h +++ b/runtime/mirror/art_method.h @@ -216,13 +216,25 @@ class MANAGED ArtMethod FINAL : public Object { return OFFSET_OF_OBJECT_MEMBER(ArtMethod, dex_cache_resolved_types_); } - ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + ArtMethod* GetDexCacheResolvedMethod(uint16_t method_idx) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + void SetDexCacheResolvedMethod(uint16_t method_idx, ArtMethod* new_method) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void SetDexCacheResolvedMethods(ObjectArray<ArtMethod>* new_dex_cache_methods) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasSameDexCacheResolvedMethods(ArtMethod* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasSameDexCacheResolvedMethods(ObjectArray<ArtMethod>* other_cache) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); - ObjectArray<Class>* GetDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + template <bool kWithCheck = true> + Class* GetDexCacheResolvedType(uint32_t type_idx) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); void SetDexCacheResolvedTypes(ObjectArray<Class>* new_dex_cache_types) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasSameDexCacheResolvedTypes(ArtMethod* other) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + bool HasSameDexCacheResolvedTypes(ObjectArray<Class>* other_cache) + SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); // Find the method that this method overrides ArtMethod* FindOverriddenMethod() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); @@ -518,6 +530,10 @@ class MANAGED ArtMethod FINAL : public Object { static GcRoot<Class> java_lang_reflect_ArtMethod_; private: + ObjectArray<ArtMethod>* GetDexCacheResolvedMethods() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + + ObjectArray<Class>* GetDexCacheResolvedTypes() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); + friend struct art::ArtMethodOffsets; // for verifying offset information DISALLOW_IMPLICIT_CONSTRUCTORS(ArtMethod); }; diff --git a/runtime/mirror/dex_cache.h b/runtime/mirror/dex_cache.h index 2c5fbcd..3c947ab 100644 --- a/runtime/mirror/dex_cache.h +++ b/runtime/mirror/dex_cache.h @@ -17,7 +17,9 @@ #ifndef ART_RUNTIME_MIRROR_DEX_CACHE_H_ #define ART_RUNTIME_MIRROR_DEX_CACHE_H_ +#include "art_field.h" #include "art_method.h" +#include "class.h" #include "object.h" #include "object_array.h" @@ -30,9 +32,6 @@ union JValue; namespace mirror { -class ArtField; -class ArtMethod; -class Class; class String; // C++ mirror of java.lang.DexCache. @@ -115,7 +114,12 @@ class MANAGED DexCache FINAL : public Object { ArtField* GetResolvedField(uint32_t field_idx) ALWAYS_INLINE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { - return GetResolvedFields()->Get(field_idx); + ArtField* field = GetResolvedFields()->Get(field_idx); + if (UNLIKELY(field == nullptr || field->GetDeclaringClass()->IsErroneous())) { + return nullptr; + } else { + return field; + } } void SetResolvedField(uint32_t field_idx, ArtField* resolved) ALWAYS_INLINE diff --git a/runtime/verifier/reg_type_cache.cc b/runtime/verifier/reg_type_cache.cc index 255b506..c0e4351 100644 --- a/runtime/verifier/reg_type_cache.cc +++ b/runtime/verifier/reg_type_cache.cc @@ -209,7 +209,7 @@ RegType& RegTypeCache::From(mirror::ClassLoader* loader, const char* descriptor, } RegType& RegTypeCache::FromClass(const char* descriptor, mirror::Class* klass, bool precise) { - DCHECK(klass != nullptr && !klass->IsErroneous()); + DCHECK(klass != nullptr); if (klass->IsPrimitive()) { // Note: precise isn't used for primitive classes. A char is assignable to an int. All // primitive classes are final. |