summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ian Rogers <irogers@google.com> 2014-09-12 23:10:21 -0700
committer Ian Rogers <irogers@google.com> 2014-09-12 23:10:21 -0700
commitecaebd37bc9af576ddfe1be0bd4f3889e88d6f23 (patch)
treef461acc73a65791f5a1a5c0d2b7d42b35add9c5b
parent9b43d91b21c83cb5fb3f618e3f8053fd7c39c906 (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.cc28
-rw-r--r--runtime/dex_file.h1
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);