Make tsan happy.
tsan was unhappy with our static Mutex, claiming a race between the constructor
writing the 'rank_' field and Mutex::Lock reading it. My understanding of the
GCC static initialization acquire/release code is that it includes memory
barriers that should make this safe, so I'm reaching out to the tsan guys. In
the meantime, let's just make this MethodVerifier lock & collection like the
other MethodVerifier locks & collections.
WARNING: Possible data race during read of size 4 at 0x1A42F09C: {{{
T2 (Compiler Worker) (L{}):
#0 art::Mutex::Lock /home/enh/local-disk/clean-dalvik-dev/art/src/mutex.cc:89
#1 art::verifier::MethodVerifier::IsClassRejected /usr/local/google/home/enh/clean-dalvik-dev/art/src/mutex.h:77
#2 art::Compiler::CompileClass /home/enh/local-disk/clean-dalvik-dev/art/src/compiler.cc:1420
#3 art::WorkerThread::Go /home/enh/local-disk/clean-dalvik-dev/art/src/compiler.cc:1013
Concurrent write(s) happened at (OR AFTER) these points:
T1 (Compiler Worker) (L{}):
#0 art::Mutex::Mutex /home/enh/local-disk/clean-dalvik-dev/art/src/mutex.cc:67
#1 art::verifier::MethodVerifier::IsClassRejected /home/enh/local-disk/clean-dalvik-dev/art/src/verifier/method_verifier.cc:3334
#2 art::Compiler::CompileClass /home/enh/local-disk/clean-dalvik-dev/art/src/compiler.cc:1420
#3 art::WorkerThread::Go /home/enh/local-disk/clean-dalvik-dev/art/src/compiler.cc:1013
Address 0x1A42F09C is 28 bytes inside data symbol "_ZZN3art8verifierL22GetRejectedClassesLockEvE21rejected_classes_lock"
Race verifier data: 0x1A198B1E,0x1A198025
}}}
(cherry picked from commit 6356df46fb0ebff5467d3103b97c3c871940e402)
Change-Id: I26a9c91f133370161ab4679e36d9a02315d28847
diff --git a/src/verifier/method_verifier.cc b/src/verifier/method_verifier.cc
index 3e3808f..7140cca 100644
--- a/src/verifier/method_verifier.cc
+++ b/src/verifier/method_verifier.cc
@@ -3289,26 +3289,6 @@
}
}
-Mutex* MethodVerifier::gc_maps_lock_ = NULL;
-MethodVerifier::GcMapTable* MethodVerifier::gc_maps_ = NULL;
-
-void MethodVerifier::InitGcMaps() {
- gc_maps_lock_ = new Mutex("verifier GC maps lock");
- MutexLock mu(*gc_maps_lock_);
- gc_maps_ = new MethodVerifier::GcMapTable;
-}
-
-void MethodVerifier::DeleteGcMaps() {
- {
- MutexLock mu(*gc_maps_lock_);
- STLDeleteValues(gc_maps_);
- delete gc_maps_;
- gc_maps_ = NULL;
- }
- delete gc_maps_lock_;
- gc_maps_lock_ = NULL;
-}
-
void MethodVerifier::SetGcMap(Compiler::MethodReference ref, const std::vector<uint8_t>& gc_map) {
MutexLock mu(*gc_maps_lock_);
GcMapTable::iterator it = gc_maps_->find(ref);
@@ -3330,26 +3310,78 @@
return it->second;
}
-static Mutex& GetRejectedClassesLock() {
- static Mutex rejected_classes_lock("verifier rejected classes lock");
- return rejected_classes_lock;
+Mutex* MethodVerifier::gc_maps_lock_ = NULL;
+MethodVerifier::GcMapTable* MethodVerifier::gc_maps_ = NULL;
+
+Mutex* MethodVerifier::rejected_classes_lock_ = NULL;
+MethodVerifier::RejectedClassesTable* MethodVerifier::rejected_classes_ = NULL;
+
+#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
+Mutex* MethodVerifier::inferred_reg_category_maps_lock_ = NULL;
+MethodVerifier::InferredRegCategoryMapTable* MethodVerifier::inferred_reg_category_maps_ = NULL;
+#endif
+
+void MethodVerifier::Init() {
+ gc_maps_lock_ = new Mutex("verifier GC maps lock");
+ {
+ MutexLock mu(*gc_maps_lock_);
+ gc_maps_ = new MethodVerifier::GcMapTable;
+ }
+
+ rejected_classes_lock_ = new Mutex("verifier rejected classes lock");
+ {
+ MutexLock mu(*rejected_classes_lock_);
+ rejected_classes_ = new MethodVerifier::RejectedClassesTable;
+ }
+
+#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
+ inferred_reg_category_maps_lock_ = new Mutex("verifier GC maps lock");
+ {
+ MutexLock mu(*inferred_reg_category_maps_lock_);
+ inferred_reg_category_maps_ = new MethodVerifier::InferredRegCategoryMapTable;
+ }
+#endif
}
-static std::set<Compiler::ClassReference>& GetRejectedClasses() {
- static std::set<Compiler::ClassReference> rejected_classes;
- return rejected_classes;
+void MethodVerifier::Shutdown() {
+ {
+ MutexLock mu(*gc_maps_lock_);
+ STLDeleteValues(gc_maps_);
+ delete gc_maps_;
+ gc_maps_ = NULL;
+ }
+ delete gc_maps_lock_;
+ gc_maps_lock_ = NULL;
+
+ {
+ MutexLock mu(*rejected_classes_lock_);
+ delete rejected_classes_;
+ rejected_classes_ = NULL;
+ }
+ delete rejected_classes_lock_;
+ rejected_classes_lock_ = NULL;
+
+#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
+ {
+ MutexLock mu(*inferred_reg_category_maps_lock_);
+ STLDeleteValues(inferred_reg_category_maps_);
+ delete inferred_reg_category_maps_;
+ inferred_reg_category_maps_ = NULL;
+ }
+ delete inferred_reg_category_maps_lock_;
+ inferred_reg_category_maps_lock_ = NULL;
+#endif
}
void MethodVerifier::AddRejectedClass(Compiler::ClassReference ref) {
- MutexLock mu(GetRejectedClassesLock());
- GetRejectedClasses().insert(ref);
+ MutexLock mu(*rejected_classes_lock_);
+ rejected_classes_->insert(ref);
CHECK(IsClassRejected(ref));
}
bool MethodVerifier::IsClassRejected(Compiler::ClassReference ref) {
- MutexLock mu(GetRejectedClassesLock());
- std::set<Compiler::ClassReference>& rejected_classes(GetRejectedClasses());
- return (rejected_classes.find(ref) != rejected_classes.end());
+ MutexLock mu(*rejected_classes_lock_);
+ return (rejected_classes_->find(ref) != rejected_classes_->end());
}
#if defined(ART_USE_LLVM_COMPILER) || defined(ART_USE_GREENLAND_COMPILER)
@@ -3398,27 +3430,6 @@
return table.release();
}
-Mutex* MethodVerifier::inferred_reg_category_maps_lock_ = NULL;
-MethodVerifier::InferredRegCategoryMapTable* MethodVerifier::inferred_reg_category_maps_ = NULL;
-
-void MethodVerifier::InitInferredRegCategoryMaps() {
- inferred_reg_category_maps_lock_ = new Mutex("verifier GC maps lock");
- MutexLock mu(*inferred_reg_category_maps_lock_);
- inferred_reg_category_maps_ = new MethodVerifier::InferredRegCategoryMapTable;
-}
-
-void MethodVerifier::DeleteInferredRegCategoryMaps() {
- {
- MutexLock mu(*inferred_reg_category_maps_lock_);
- STLDeleteValues(inferred_reg_category_maps_);
- delete inferred_reg_category_maps_;
- inferred_reg_category_maps_ = NULL;
- }
- delete inferred_reg_category_maps_lock_;
- inferred_reg_category_maps_lock_ = NULL;
-}
-
-
void MethodVerifier::SetInferredRegCategoryMap(Compiler::MethodReference ref,
const InferredRegCategoryMap& inferred_reg_category_map) {
MutexLock mu(*inferred_reg_category_maps_lock_);