diff options
| author | 2014-09-12 23:10:21 -0700 | |
|---|---|---|
| committer | 2014-09-12 23:10:21 -0700 | |
| commit | ecaebd37bc9af576ddfe1be0bd4f3889e88d6f23 (patch) | |
| tree | f461acc73a65791f5a1a5c0d2b7d42b35add9c5b | |
| parent | 9b43d91b21c83cb5fb3f618e3f8053fd7c39c906 (diff) | |
Remove dex file index building mutex.
First thread to get to max misses builds the index and sets an atomic, other
threads continue and return null. Avoids lock contention and removes a member
variable.
Change-Id: Ia91e4a8fd915941aea849f019c85b67894ec6e71
| -rw-r--r-- | runtime/dex_file.cc | 28 | ||||
| -rw-r--r-- | runtime/dex_file.h | 1 |
2 files changed, 14 insertions, 15 deletions
diff --git a/runtime/dex_file.cc b/runtime/dex_file.cc index 8656bd3cbe..6ef62c5cd6 100644 --- a/runtime/dex_file.cc +++ b/runtime/dex_file.cc @@ -354,8 +354,7 @@ DexFile::DexFile(const byte* base, size_t size, proto_ids_(reinterpret_cast<const ProtoId*>(base + header_->proto_ids_off_)), class_defs_(reinterpret_cast<const ClassDef*>(base + header_->class_defs_off_)), find_class_def_misses_(0), - class_def_index_(nullptr), - build_class_def_index_mutex_("DexFile index creation mutex") { + class_def_index_(nullptr) { CHECK(begin_ != NULL) << GetLocation(); CHECK_GT(size_, 0U) << GetLocation(); } @@ -444,20 +443,21 @@ const DexFile::ClassDef* DexFile::FindClassDef(const char* descriptor) const { // up. This isn't done eagerly at construction as construction is not performed in multi-threaded // sections of tools like dex2oat. If we're lazy we hopefully increase the chance of balancing // out which thread builds the index. - find_class_def_misses_++; const uint32_t kMaxFailedDexClassDefLookups = 100; - if (find_class_def_misses_ > kMaxFailedDexClassDefLookups) { - MutexLock mu(Thread::Current(), build_class_def_index_mutex_); - // Are we the first ones building the index? - if (class_def_index_.LoadSequentiallyConsistent() == nullptr) { - index = new Index(num_class_defs); - for (uint32_t i = 0; i < num_class_defs; ++i) { - const ClassDef& class_def = GetClassDef(i); - const char* descriptor = GetClassDescriptor(class_def); - index->insert(std::make_pair(descriptor, &class_def)); - } - class_def_index_.StoreSequentiallyConsistent(index); + uint32_t old_misses = find_class_def_misses_.FetchAndAddSequentiallyConsistent(1); + if (old_misses == kMaxFailedDexClassDefLookups) { + // Are we the ones moving the miss count past the max? Sanity check the index doesn't exist. + CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr); + // Build the index. + index = new Index(num_class_defs); + for (uint32_t i = 0; i < num_class_defs; ++i) { + const ClassDef& class_def = GetClassDef(i); + const char* descriptor = GetClassDescriptor(class_def); + index->insert(std::make_pair(descriptor, &class_def)); } + // Sanity check the index still doesn't exist, only 1 thread should build it. + CHECK(class_def_index_.LoadSequentiallyConsistent() == nullptr); + class_def_index_.StoreSequentiallyConsistent(index); } return nullptr; } diff --git a/runtime/dex_file.h b/runtime/dex_file.h index 1b46a12ae8..1cec264be0 100644 --- a/runtime/dex_file.h +++ b/runtime/dex_file.h @@ -979,7 +979,6 @@ class DexFile { }; typedef std::unordered_map<const char*, const ClassDef*, UTF16HashCmp, UTF16HashCmp> Index; mutable Atomic<Index*> class_def_index_; - mutable Mutex build_class_def_index_mutex_ DEFAULT_MUTEX_ACQUIRED_AFTER; }; std::ostream& operator<<(std::ostream& os, const DexFile& dex_file); |