diff options
| author | 2013-11-20 12:44:55 +0000 | |
|---|---|---|
| committer | 2013-12-13 14:27:05 +0000 | |
| commit | e13717e796d338b08ea66f6a7e3470ca44de707f (patch) | |
| tree | eaa49dccd39c9c3c73b6d1831c930def0c0b14a2 | |
| parent | cf28cbff9f0557dea9ed60358a956859ba1b56aa (diff) | |
Per-DexFile locking for inliner initialization.
And clean up lock and compiler driver naming.
Change-Id: I1562c7f55c4b0174a36007ba6199360da06169ff
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.cc | 24 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_method_inliner.h | 12 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_to_method_inliner_map.cc | 37 | ||||
| -rw-r--r-- | compiler/dex/quick/dex_file_to_method_inliner_map.h | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/gen_invoke.cc | 2 | ||||
| -rw-r--r-- | compiler/dex/quick/mir_to_lir.h | 2 | ||||
| -rw-r--r-- | compiler/driver/compiler_driver.cc | 4 | ||||
| -rw-r--r-- | runtime/locks.h | 2 |
8 files changed, 56 insertions, 29 deletions
diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc index b21e37e13d..ba98225024 100644 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ b/compiler/dex/quick/dex_file_method_inliner.cc @@ -16,6 +16,10 @@ #include <algorithm> #include "base/macros.h" +#include "base/mutex.h" +#include "base/mutex-inl.h" +#include "thread.h" +#include "thread-inl.h" #include "dex/mir_graph.h" #include "dex_file_method_inliner.h" @@ -228,7 +232,8 @@ const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods }; DexFileMethodInliner::DexFileMethodInliner() - : dex_file_(NULL) { + : lock_("DexFileMethodInliner lock", kDexFileMethodInlinerLock), + dex_file_(NULL) { COMPILE_ASSERT(kClassCacheFirst == 0, kClassCacheFirst_not_0); COMPILE_ASSERT(arraysize(kClassCacheNames) == kClassCacheLast, bad_arraysize_kClassCacheNames); COMPILE_ASSERT(kNameCacheFirst == 0, kNameCacheFirst_not_0); @@ -240,16 +245,21 @@ DexFileMethodInliner::DexFileMethodInliner() DexFileMethodInliner::~DexFileMethodInliner() { } -bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index) const { +bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index) { + ReaderMutexLock mu(Thread::Current(), lock_); return intrinsics_.find(method_index) != intrinsics_.end(); } -bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) const { - auto it = intrinsics_.find(info->index); - if (it == intrinsics_.end()) { - return false; +bool DexFileMethodInliner::GenIntrinsic(Mir2Lir* backend, CallInfo* info) { + Intrinsic intrinsic; + { + ReaderMutexLock mu(Thread::Current(), lock_); + auto it = intrinsics_.find(info->index); + if (it == intrinsics_.end()) { + return false; + } + intrinsic = it->second; } - const Intrinsic& intrinsic = it->second; switch (intrinsic.opcode) { case kIntrinsicDoubleCvt: return backend->GenInlinedDoubleCvt(info); diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h index 948f4bbe56..9198f2a29d 100644 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ b/compiler/dex/quick/dex_file_method_inliner.h @@ -19,6 +19,9 @@ #include <stdint.h> #include <map> +#include "base/mutex.h" +#include "base/macros.h" +#include "locks.h" namespace art { @@ -95,12 +98,12 @@ class DexFileMethodInliner { /** * Check whether a particular method index corresponds to an intrinsic function. */ - bool IsIntrinsic(uint32_t method_index) const; + bool IsIntrinsic(uint32_t method_index) LOCKS_EXCLUDED(lock_); /** * Generate code for an intrinsic function invocation. */ - bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) const; + bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) LOCKS_EXCLUDED(lock_); private: /** @@ -300,14 +303,15 @@ class DexFileMethodInliner { * * Only DexFileToMethodInlinerMap may call this function to initialize the inliner. */ - void FindIntrinsics(const DexFile* dex_file); + void FindIntrinsics(const DexFile* dex_file) EXCLUSIVE_LOCKS_REQUIRED(lock_); friend class DexFileToMethodInlinerMap; + ReaderWriterMutex lock_; /* * Maps method indexes (for the particular DexFile) to Intrinsic defintions. */ - std::map<uint32_t, Intrinsic> intrinsics_; + std::map<uint32_t, Intrinsic> intrinsics_ GUARDED_BY(lock_); const DexFile* dex_file_; DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner); diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.cc b/compiler/dex/quick/dex_file_to_method_inliner_map.cc index 0107ed3ccb..2fec183289 100644 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.cc +++ b/compiler/dex/quick/dex_file_to_method_inliner_map.cc @@ -28,7 +28,7 @@ namespace art { DexFileToMethodInlinerMap::DexFileToMethodInlinerMap() - : lock_("inline_helper_mutex") { + : lock_("DexFileToMethodInlinerMap lock", kDexFileToMethodInlinerMapLock) { } DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { @@ -37,26 +37,37 @@ DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { } } -const DexFileMethodInliner& DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { +DexFileMethodInliner* DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { Thread* self = Thread::Current(); { - ReaderMutexLock lock(self, lock_); + ReaderMutexLock mu(self, lock_); auto it = inliners_.find(dex_file); if (it != inliners_.end()) { - return *it->second; + return it->second; } } - WriterMutexLock lock(self, lock_); - DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found - if (*inliner) { - return **inliner; + // We need to acquire our lock_ to modify inliners_ but we want to release it + // before we initialize the new inliner. However, we need to acquire the + // new inliner's lock_ before we release our lock_ to prevent another thread + // from using the uninitialized inliner. This requires explicit calls to + // ExclusiveLock()/ExclusiveUnlock() on one of the locks, the other one + // can use WriterMutexLock. + DexFileMethodInliner* locked_inliner; + { + WriterMutexLock mu(self, lock_); + DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found + if (*inliner) { + return *inliner; + } + *inliner = new DexFileMethodInliner; + DCHECK(*inliner != nullptr); + locked_inliner = *inliner; + locked_inliner->lock_.ExclusiveLock(self); // Acquire inliner's lock_ before releasing lock_. } - *inliner = new DexFileMethodInliner(); - DCHECK(*inliner != nullptr); - // TODO: per-dex file locking for the intrinsics container filling. - (*inliner)->FindIntrinsics(dex_file); - return **inliner; + locked_inliner->FindIntrinsics(dex_file); + locked_inliner->lock_.ExclusiveUnlock(self); + return locked_inliner; } } // namespace art diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.h b/compiler/dex/quick/dex_file_to_method_inliner_map.h index 476f002bb5..6d5b8893c5 100644 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.h +++ b/compiler/dex/quick/dex_file_to_method_inliner_map.h @@ -40,7 +40,7 @@ class DexFileToMethodInlinerMap { DexFileToMethodInlinerMap(); ~DexFileToMethodInlinerMap(); - const DexFileMethodInliner& GetMethodInliner(const DexFile* dex_file) LOCKS_EXCLUDED(lock_); + DexFileMethodInliner* GetMethodInliner(const DexFile* dex_file) LOCKS_EXCLUDED(lock_); private: ReaderWriterMutex lock_; diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc index e66d4ea52c..ee6f9c8fe9 100644 --- a/compiler/dex/quick/gen_invoke.cc +++ b/compiler/dex/quick/gen_invoke.cc @@ -1242,7 +1242,7 @@ void Mir2Lir::GenInvoke(CallInfo* info) { if (inliner_ == nullptr) { QuickCompilerContext* context = reinterpret_cast<QuickCompilerContext*>( cu_->compiler_driver->GetCompilerContext()); - inliner_ = &context->GetInlinerMap()->GetMethodInliner(cu_->dex_file); + inliner_ = context->GetInlinerMap()->GetMethodInliner(cu_->dex_file); } if (inliner_->GenIntrinsic(this, info)) { return; diff --git a/compiler/dex/quick/mir_to_lir.h b/compiler/dex/quick/mir_to_lir.h index 2a54eb32cc..8415cbfb6d 100644 --- a/compiler/dex/quick/mir_to_lir.h +++ b/compiler/dex/quick/mir_to_lir.h @@ -827,7 +827,7 @@ class Mir2Lir : public Backend { LIR* first_lir_insn_; LIR* last_lir_insn_; // Lazily retrieved method inliner for intrinsics. - const DexFileMethodInliner* inliner_; + DexFileMethodInliner* inliner_; }; // Class Mir2Lir } // namespace art diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 43ed28c762..1879a94bff 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -284,10 +284,10 @@ class AOTCompilationStats { }; extern "C" void ArtInitCompilerContext(art::CompilerDriver& driver); -extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver& compiler); +extern "C" void ArtInitQuickCompilerContext(art::CompilerDriver& driver); extern "C" void ArtUnInitCompilerContext(art::CompilerDriver& driver); -extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver& compiler); +extern "C" void ArtUnInitQuickCompilerContext(art::CompilerDriver& driver); extern "C" art::CompiledMethod* ArtCompileMethod(art::CompilerDriver& driver, const art::DexFile::CodeItem* code_item, diff --git a/runtime/locks.h b/runtime/locks.h index 2308e951b0..72d4f652ff 100644 --- a/runtime/locks.h +++ b/runtime/locks.h @@ -41,6 +41,8 @@ enum LockLevel { kRosAllocBracketLock, kRosAllocBulkFreeLock, kAllocSpaceLock, + kDexFileMethodInlinerLock, + kDexFileToMethodInlinerMapLock, kMarkSweepMarkStackLock, kDefaultMutexLevel, kMarkSweepLargeObjectLock, |