Change intern table to not use WaitHoldingLocks

Bug: 22423014
Change-Id: I9e16b8cb4def72fff73f1783a182877105feb7aa
diff --git a/runtime/intern_table.h b/runtime/intern_table.h
index 67a8b34..ef08d74 100644
--- a/runtime/intern_table.h
+++ b/runtime/intern_table.h
@@ -19,10 +19,12 @@
 
 #include <unordered_set>
 
+#include "atomic.h"
 #include "base/allocator.h"
 #include "base/hash_set.h"
 #include "base/mutex.h"
 #include "gc_root.h"
+#include "gc/weak_root_state.h"
 #include "object_callbacks.h"
 
 namespace art {
@@ -54,18 +56,22 @@
  public:
   InternTable();
 
-  // Interns a potentially new string in the 'strong' table. (See above.)
+  // Interns a potentially new string in the 'strong' table. May cause thread suspension.
   mirror::String* InternStrong(int32_t utf16_length, const char* utf8_data)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Interns a potentially new string in the 'strong' table. (See above.)
+  // Only used by image writer.
+  mirror::String* InternImageString(mirror::String* s)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
+  // Interns a potentially new string in the 'strong' table. May cause thread suspension.
   mirror::String* InternStrong(const char* utf8_data)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Interns a potentially new string in the 'strong' table. (See above.)
+  // Interns a potentially new string in the 'strong' table. May cause thread suspension.
   mirror::String* InternStrong(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
-  // Interns a potentially new string in the 'weak' table. (See above.)
+  // Interns a potentially new string in the 'weak' table. May cause thread suspension.
   mirror::String* InternWeak(mirror::String* s) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   void SweepInternTableWeaks(IsMarkedVisitor* visitor)
@@ -89,6 +95,7 @@
   void AllowNewInterns() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void EnsureNewInternsDisallowed() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
   void BroadcastForNewInterns() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+  void EnsureNewWeakInternsDisallowed() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
   // Adds all of the resolved image strings from the image space into the intern table. The
   // advantage of doing this is preventing expensive DexFile::FindStringId calls.
@@ -112,6 +119,10 @@
   size_t WriteToMemory(uint8_t* ptr) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
       LOCKS_EXCLUDED(Locks::intern_table_lock_);
 
+  // Change the weak root state. May broadcast to waiters.
+  void ChangeWeakRootState(gc::WeakRootState new_state)
+      LOCKS_EXCLUDED(Locks::intern_table_lock_);
+
  private:
   class StringHashEquals {
    public:
@@ -176,7 +187,7 @@
   };
 
   // Insert if non null, otherwise return null.
-  mirror::String* Insert(mirror::String* s, bool is_strong)
+  mirror::String* Insert(mirror::String* s, bool is_strong, bool holding_locks)
       LOCKS_EXCLUDED(Locks::intern_table_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
@@ -221,10 +232,17 @@
       EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
       SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
 
+  // Change the weak root state. May broadcast to waiters.
+  void ChangeWeakRootStateLocked(gc::WeakRootState new_state)
+      EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_);
+
+  // Wait until we can read weak roots.
+  void WaitUntilAccessible(Thread* self) EXCLUSIVE_LOCKS_REQUIRED(Locks::intern_table_lock_)
+      SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
+
   bool image_added_to_intern_table_ GUARDED_BY(Locks::intern_table_lock_);
   bool log_new_roots_ GUARDED_BY(Locks::intern_table_lock_);
-  bool allow_new_interns_ GUARDED_BY(Locks::intern_table_lock_);
-  ConditionVariable new_intern_condition_ GUARDED_BY(Locks::intern_table_lock_);
+  ConditionVariable weak_intern_condition_ GUARDED_BY(Locks::intern_table_lock_);
   // Since this contains (strong) roots, they need a read barrier to
   // enable concurrent intern table (strong) root scan. Do not
   // directly access the strings in it. Use functions that contain
@@ -236,6 +254,8 @@
   // not directly access the strings in it. Use functions that contain
   // read barriers.
   Table weak_interns_ GUARDED_BY(Locks::intern_table_lock_);
+  // Weak root state, used for concurrent system weak processing and more.
+  gc::WeakRootState weak_root_state_ GUARDED_BY(Locks::intern_table_lock_);
 };
 
 }  // namespace art