diff options
author | 2017-02-13 18:32:04 -0800 | |
---|---|---|
committer | 2017-02-13 19:34:54 -0800 | |
commit | 5812e20ff7cbc8efa0b8d7486ada2f58840a6ad5 (patch) | |
tree | be0e9fdeb90bcbad76b17b3aae4e746d977d80ee /runtime/mirror/dex_cache-inl.h | |
parent | 518f373324f355f8e58440dfbc3f5a1f2244bde7 (diff) |
Revert^3 "Hash-based dex cache type array."
Assert failing for "earchbox:search":
F zygote64: class_linker.cc:4612] Check failed: handle_scope_iface.Get() != nullptr
Test: m test-art-host
Bug: 34839984
Bug: 30627598
Bug: 34659969
This reverts commit 85c0f2ac03417f5125bc2ff1dab8109859c67d5c.
Change-Id: I39846c20295af5875b0f945be7035c73ded23135
Diffstat (limited to 'runtime/mirror/dex_cache-inl.h')
-rw-r--r-- | runtime/mirror/dex_cache-inl.h | 110 |
1 files changed, 41 insertions, 69 deletions
diff --git a/runtime/mirror/dex_cache-inl.h b/runtime/mirror/dex_cache-inl.h index bef3ad29a3..a59bb7b880 100644 --- a/runtime/mirror/dex_cache-inl.h +++ b/runtime/mirror/dex_cache-inl.h @@ -40,22 +40,14 @@ inline uint32_t DexCache::ClassSize(PointerSize pointer_size) { return Class::ComputeClassSize(true, vtable_entries, 0, 0, 0, 0, 0, pointer_size); } -inline uint32_t DexCache::StringSlotIndex(dex::StringIndex string_idx) { +inline mirror::String* DexCache::GetResolvedString(dex::StringIndex string_idx) { DCHECK_LT(string_idx.index_, GetDexFile()->NumStringIds()); - const uint32_t slot_idx = string_idx.index_ % kDexCacheStringCacheSize; - DCHECK_LT(slot_idx, NumStrings()); - return slot_idx; + return StringDexCachePair::Lookup(GetStrings(), string_idx.index_, NumStrings()).Read(); } -inline String* DexCache::GetResolvedString(dex::StringIndex string_idx) { - return GetStrings()[StringSlotIndex(string_idx)].load( - std::memory_order_relaxed).GetObjectForIndex(string_idx.index_); -} - -inline void DexCache::SetResolvedString(dex::StringIndex string_idx, ObjPtr<String> resolved) { - DCHECK(resolved != nullptr); - GetStrings()[StringSlotIndex(string_idx)].store( - StringDexCachePair(resolved, string_idx.index_), std::memory_order_relaxed); +inline void DexCache::SetResolvedString(dex::StringIndex string_idx, + ObjPtr<mirror::String> resolved) { + StringDexCachePair::Assign(GetStrings(), string_idx.index_, resolved.Ptr(), NumStrings()); Runtime* const runtime = Runtime::Current(); if (UNLIKELY(runtime->IsActiveTransaction())) { DCHECK(runtime->IsAotCompiler()); @@ -66,70 +58,50 @@ inline void DexCache::SetResolvedString(dex::StringIndex string_idx, ObjPtr<Stri } inline void DexCache::ClearString(dex::StringIndex string_idx) { + const uint32_t slot_idx = string_idx.index_ % NumStrings(); DCHECK(Runtime::Current()->IsAotCompiler()); - uint32_t slot_idx = StringSlotIndex(string_idx); StringDexCacheType* slot = &GetStrings()[slot_idx]; // This is racy but should only be called from the transactional interpreter. if (slot->load(std::memory_order_relaxed).index == string_idx.index_) { - StringDexCachePair cleared(nullptr, StringDexCachePair::InvalidIndexForSlot(slot_idx)); + StringDexCachePair cleared( + nullptr, + StringDexCachePair::InvalidIndexForSlot(slot_idx)); slot->store(cleared, std::memory_order_relaxed); } } -inline uint32_t DexCache::TypeSlotIndex(dex::TypeIndex type_idx) { - DCHECK_LT(type_idx.index_, GetDexFile()->NumTypeIds()); - const uint32_t slot_idx = type_idx.index_ % kDexCacheTypeCacheSize; - DCHECK_LT(slot_idx, NumResolvedTypes()); - return slot_idx; -} - inline Class* DexCache::GetResolvedType(dex::TypeIndex type_idx) { // It is theorized that a load acquire is not required since obtaining the resolved class will // always have an address dependency or a lock. - return GetResolvedTypes()[TypeSlotIndex(type_idx)].load( - std::memory_order_relaxed).GetObjectForIndex(type_idx.index_); + DCHECK_LT(type_idx.index_, NumResolvedTypes()); + return GetResolvedTypes()[type_idx.index_].Read(); } inline void DexCache::SetResolvedType(dex::TypeIndex type_idx, ObjPtr<Class> resolved) { - DCHECK(resolved != nullptr); + DCHECK_LT(type_idx.index_, NumResolvedTypes()); // NOTE: Unchecked, i.e. not throwing AIOOB. // TODO default transaction support. // Use a release store for SetResolvedType. This is done to prevent other threads from seeing a // class but not necessarily seeing the loaded members like the static fields array. // See b/32075261. - GetResolvedTypes()[TypeSlotIndex(type_idx)].store( - TypeDexCachePair(resolved, type_idx.index_), std::memory_order_release); + reinterpret_cast<Atomic<GcRoot<mirror::Class>>&>(GetResolvedTypes()[type_idx.index_]). + StoreRelease(GcRoot<Class>(resolved)); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } -inline void DexCache::ClearResolvedType(dex::TypeIndex type_idx) { - DCHECK(Runtime::Current()->IsAotCompiler()); - uint32_t slot_idx = TypeSlotIndex(type_idx); - TypeDexCacheType* slot = &GetResolvedTypes()[slot_idx]; - // This is racy but should only be called from the single-threaded ImageWriter and tests. - if (slot->load(std::memory_order_relaxed).index == type_idx.index_) { - TypeDexCachePair cleared(nullptr, TypeDexCachePair::InvalidIndexForSlot(slot_idx)); - slot->store(cleared, std::memory_order_relaxed); - } -} - -inline uint32_t DexCache::MethodTypeSlotIndex(uint32_t proto_idx) { +inline MethodType* DexCache::GetResolvedMethodType(uint32_t proto_idx) { DCHECK(Runtime::Current()->IsMethodHandlesEnabled()); DCHECK_LT(proto_idx, GetDexFile()->NumProtoIds()); - const uint32_t slot_idx = proto_idx % kDexCacheMethodTypeCacheSize; - DCHECK_LT(slot_idx, NumResolvedMethodTypes()); - return slot_idx; -} - -inline MethodType* DexCache::GetResolvedMethodType(uint32_t proto_idx) { - return GetResolvedMethodTypes()[MethodTypeSlotIndex(proto_idx)].load( - std::memory_order_relaxed).GetObjectForIndex(proto_idx); + return MethodTypeDexCachePair::Lookup( + GetResolvedMethodTypes(), proto_idx, NumResolvedMethodTypes()).Read(); } inline void DexCache::SetResolvedMethodType(uint32_t proto_idx, MethodType* resolved) { - DCHECK(resolved != nullptr); - GetResolvedMethodTypes()[MethodTypeSlotIndex(proto_idx)].store( - MethodTypeDexCachePair(resolved, proto_idx), std::memory_order_relaxed); + DCHECK(Runtime::Current()->IsMethodHandlesEnabled()); + DCHECK_LT(proto_idx, GetDexFile()->NumProtoIds()); + + MethodTypeDexCachePair::Assign(GetResolvedMethodTypes(), proto_idx, resolved, + NumResolvedMethodTypes()); // TODO: Fine-grained marking, so that we don't need to go through all arrays in full. Runtime::Current()->GetHeap()->WriteBarrierEveryFieldOf(this); } @@ -226,49 +198,49 @@ inline void DexCache::VisitReferences(ObjPtr<Class> klass, const Visitor& visito VisitInstanceFieldsReferences<kVerifyFlags, kReadBarrierOption>(klass, visitor); // Visit arrays after. if (kVisitNativeRoots) { - VisitDexCachePairs<String, kReadBarrierOption, Visitor>( + VisitDexCachePairs<mirror::String, kReadBarrierOption, Visitor>( GetStrings(), NumStrings(), visitor); - VisitDexCachePairs<Class, kReadBarrierOption, Visitor>( - GetResolvedTypes(), NumResolvedTypes(), visitor); + GcRoot<mirror::Class>* resolved_types = GetResolvedTypes(); + for (size_t i = 0, num_types = NumResolvedTypes(); i != num_types; ++i) { + visitor.VisitRootIfNonNull(resolved_types[i].AddressWithoutBarrier()); + } - VisitDexCachePairs<MethodType, kReadBarrierOption, Visitor>( + VisitDexCachePairs<mirror::MethodType, kReadBarrierOption, Visitor>( GetResolvedMethodTypes(), NumResolvedMethodTypes(), visitor); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupStrings(StringDexCacheType* dest, const Visitor& visitor) { - StringDexCacheType* src = GetStrings(); +inline void DexCache::FixupStrings(mirror::StringDexCacheType* dest, const Visitor& visitor) { + mirror::StringDexCacheType* src = GetStrings(); for (size_t i = 0, count = NumStrings(); i < count; ++i) { StringDexCachePair source = src[i].load(std::memory_order_relaxed); - String* ptr = source.object.Read<kReadBarrierOption>(); - String* new_source = visitor(ptr); + mirror::String* ptr = source.object.Read<kReadBarrierOption>(); + mirror::String* new_source = visitor(ptr); source.object = GcRoot<String>(new_source); dest[i].store(source, std::memory_order_relaxed); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupResolvedTypes(TypeDexCacheType* dest, const Visitor& visitor) { - TypeDexCacheType* src = GetResolvedTypes(); +inline void DexCache::FixupResolvedTypes(GcRoot<mirror::Class>* dest, const Visitor& visitor) { + GcRoot<mirror::Class>* src = GetResolvedTypes(); for (size_t i = 0, count = NumResolvedTypes(); i < count; ++i) { - TypeDexCachePair source = src[i].load(std::memory_order_relaxed); - Class* ptr = source.object.Read<kReadBarrierOption>(); - Class* new_source = visitor(ptr); - source.object = GcRoot<Class>(new_source); - dest[i].store(source, std::memory_order_relaxed); + mirror::Class* source = src[i].Read<kReadBarrierOption>(); + mirror::Class* new_source = visitor(source); + dest[i] = GcRoot<mirror::Class>(new_source); } } template <ReadBarrierOption kReadBarrierOption, typename Visitor> -inline void DexCache::FixupResolvedMethodTypes(MethodTypeDexCacheType* dest, +inline void DexCache::FixupResolvedMethodTypes(mirror::MethodTypeDexCacheType* dest, const Visitor& visitor) { - MethodTypeDexCacheType* src = GetResolvedMethodTypes(); + mirror::MethodTypeDexCacheType* src = GetResolvedMethodTypes(); for (size_t i = 0, count = NumResolvedMethodTypes(); i < count; ++i) { MethodTypeDexCachePair source = src[i].load(std::memory_order_relaxed); - MethodType* ptr = source.object.Read<kReadBarrierOption>(); - MethodType* new_source = visitor(ptr); + mirror::MethodType* ptr = source.object.Read<kReadBarrierOption>(); + mirror::MethodType* new_source = visitor(ptr); source.object = GcRoot<MethodType>(new_source); dest[i].store(source, std::memory_order_relaxed); } |