1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2011 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_INTERN_TABLE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_INTERN_TABLE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "base/dchecked_vector.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/gc_visited_arena_pool.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/hash_set.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h" 25*795d594fSAndroid Build Coastguard Worker #include "gc/weak_root_state.h" 26*795d594fSAndroid Build Coastguard Worker #include "gc_root.h" 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 29*795d594fSAndroid Build Coastguard Worker 30*795d594fSAndroid Build Coastguard Worker class IsMarkedVisitor; 31*795d594fSAndroid Build Coastguard Worker 32*795d594fSAndroid Build Coastguard Worker namespace gc { 33*795d594fSAndroid Build Coastguard Worker namespace space { 34*795d594fSAndroid Build Coastguard Worker class ImageSpace; 35*795d594fSAndroid Build Coastguard Worker } // namespace space 36*795d594fSAndroid Build Coastguard Worker } // namespace gc 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker enum VisitRootFlags : uint8_t; 39*795d594fSAndroid Build Coastguard Worker 40*795d594fSAndroid Build Coastguard Worker namespace linker { 41*795d594fSAndroid Build Coastguard Worker class ImageWriter; 42*795d594fSAndroid Build Coastguard Worker } // namespace linker 43*795d594fSAndroid Build Coastguard Worker 44*795d594fSAndroid Build Coastguard Worker namespace mirror { 45*795d594fSAndroid Build Coastguard Worker class String; 46*795d594fSAndroid Build Coastguard Worker } // namespace mirror 47*795d594fSAndroid Build Coastguard Worker class Transaction; 48*795d594fSAndroid Build Coastguard Worker 49*795d594fSAndroid Build Coastguard Worker /** 50*795d594fSAndroid Build Coastguard Worker * Used to intern strings. 51*795d594fSAndroid Build Coastguard Worker * 52*795d594fSAndroid Build Coastguard Worker * There are actually two tables: one that holds strong references to its strings, and one that 53*795d594fSAndroid Build Coastguard Worker * holds weak references. The former is used for string literals, for which there is an effective 54*795d594fSAndroid Build Coastguard Worker * reference from the constant pool. The latter is used for strings interned at runtime via 55*795d594fSAndroid Build Coastguard Worker * String.intern. Some code (XML parsers being a prime example) relies on being able to intern 56*795d594fSAndroid Build Coastguard Worker * arbitrarily many strings for the duration of a parse without permanently increasing the memory 57*795d594fSAndroid Build Coastguard Worker * footprint. 58*795d594fSAndroid Build Coastguard Worker */ 59*795d594fSAndroid Build Coastguard Worker class InternTable { 60*795d594fSAndroid Build Coastguard Worker public: 61*795d594fSAndroid Build Coastguard Worker // Modified UTF-8-encoded string treated as UTF16. 62*795d594fSAndroid Build Coastguard Worker class Utf8String { 63*795d594fSAndroid Build Coastguard Worker public: Utf8String(uint32_t utf16_length,const char * utf8_data)64*795d594fSAndroid Build Coastguard Worker Utf8String(uint32_t utf16_length, const char* utf8_data) 65*795d594fSAndroid Build Coastguard Worker : utf16_length_(utf16_length), utf8_data_(utf8_data) { } 66*795d594fSAndroid Build Coastguard Worker GetHash()67*795d594fSAndroid Build Coastguard Worker uint32_t GetHash() const { return Hash(utf16_length_, utf8_data_); } GetUtf16Length()68*795d594fSAndroid Build Coastguard Worker uint32_t GetUtf16Length() const { return utf16_length_; } GetUtf8Data()69*795d594fSAndroid Build Coastguard Worker const char* GetUtf8Data() const { return utf8_data_; } 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker static uint32_t Hash(uint32_t utf16_length, const char* utf8_data); 72*795d594fSAndroid Build Coastguard Worker 73*795d594fSAndroid Build Coastguard Worker private: 74*795d594fSAndroid Build Coastguard Worker uint32_t utf16_length_; 75*795d594fSAndroid Build Coastguard Worker const char* utf8_data_; 76*795d594fSAndroid Build Coastguard Worker }; 77*795d594fSAndroid Build Coastguard Worker 78*795d594fSAndroid Build Coastguard Worker class StringHash { 79*795d594fSAndroid Build Coastguard Worker public: 80*795d594fSAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS: Used from unannotated `HashSet<>` functions. 81*795d594fSAndroid Build Coastguard Worker size_t operator()(const GcRoot<mirror::String>& root) const NO_THREAD_SAFETY_ANALYSIS; 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker // Utf8String can be used for lookup. While we're passing the hash explicitly to all 84*795d594fSAndroid Build Coastguard Worker // `HashSet<>` functions, they `DCHECK()` the supplied hash against the hash we provide here. operator()85*795d594fSAndroid Build Coastguard Worker size_t operator()(const Utf8String& key) const { 86*795d594fSAndroid Build Coastguard Worker static_assert(std::is_same_v<uint32_t, decltype(key.GetHash())>); 87*795d594fSAndroid Build Coastguard Worker return key.GetHash(); 88*795d594fSAndroid Build Coastguard Worker } 89*795d594fSAndroid Build Coastguard Worker }; 90*795d594fSAndroid Build Coastguard Worker 91*795d594fSAndroid Build Coastguard Worker class StringEquals { 92*795d594fSAndroid Build Coastguard Worker public: 93*795d594fSAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS: Used from unannotated `HashSet<>` functions. 94*795d594fSAndroid Build Coastguard Worker bool operator()(const GcRoot<mirror::String>& a, const GcRoot<mirror::String>& b) const 95*795d594fSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS; 96*795d594fSAndroid Build Coastguard Worker 97*795d594fSAndroid Build Coastguard Worker // Utf8String can be used for lookup. 98*795d594fSAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS: Used from unannotated `HashSet<>` functions. 99*795d594fSAndroid Build Coastguard Worker bool operator()(const GcRoot<mirror::String>& a, const Utf8String& b) const 100*795d594fSAndroid Build Coastguard Worker NO_THREAD_SAFETY_ANALYSIS; 101*795d594fSAndroid Build Coastguard Worker }; 102*795d594fSAndroid Build Coastguard Worker 103*795d594fSAndroid Build Coastguard Worker class GcRootEmptyFn { 104*795d594fSAndroid Build Coastguard Worker public: MakeEmpty(GcRoot<mirror::String> & item)105*795d594fSAndroid Build Coastguard Worker void MakeEmpty(GcRoot<mirror::String>& item) const { 106*795d594fSAndroid Build Coastguard Worker item = GcRoot<mirror::String>(); 107*795d594fSAndroid Build Coastguard Worker } IsEmpty(const GcRoot<mirror::String> & item)108*795d594fSAndroid Build Coastguard Worker bool IsEmpty(const GcRoot<mirror::String>& item) const { 109*795d594fSAndroid Build Coastguard Worker return item.IsNull(); 110*795d594fSAndroid Build Coastguard Worker } 111*795d594fSAndroid Build Coastguard Worker }; 112*795d594fSAndroid Build Coastguard Worker 113*795d594fSAndroid Build Coastguard Worker using UnorderedSet = 114*795d594fSAndroid Build Coastguard Worker HashSet<GcRoot<mirror::String>, 115*795d594fSAndroid Build Coastguard Worker GcRootEmptyFn, 116*795d594fSAndroid Build Coastguard Worker StringHash, 117*795d594fSAndroid Build Coastguard Worker StringEquals, 118*795d594fSAndroid Build Coastguard Worker GcRootArenaAllocator<GcRoot<mirror::String>, kAllocatorTagInternTable>>; 119*795d594fSAndroid Build Coastguard Worker 120*795d594fSAndroid Build Coastguard Worker EXPORT InternTable(); 121*795d594fSAndroid Build Coastguard Worker 122*795d594fSAndroid Build Coastguard Worker // Interns a potentially new string in the 'strong' table. May cause thread suspension. 123*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::String> InternStrong(uint32_t utf16_length, const char* utf8_data) 124*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 125*795d594fSAndroid Build Coastguard Worker 126*795d594fSAndroid Build Coastguard Worker // Interns a potentially new string in the 'strong' table. May cause thread suspension. 127*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::String> InternStrong(const char* utf8_data) 128*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // Interns a potentially new string in the 'strong' table. May cause thread suspension. 131*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::String> InternStrong(ObjPtr<mirror::String> s) 132*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Roles::uninterruptible_); 133*795d594fSAndroid Build Coastguard Worker 134*795d594fSAndroid Build Coastguard Worker // Interns a potentially new string in the 'weak' table. May cause thread suspension. 135*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> InternWeak(const char* utf8_data) REQUIRES_SHARED(Locks::mutator_lock_) 136*795d594fSAndroid Build Coastguard Worker REQUIRES(!Roles::uninterruptible_); 137*795d594fSAndroid Build Coastguard Worker 138*795d594fSAndroid Build Coastguard Worker // Interns a potentially new string in the 'weak' table. May cause thread suspension. 139*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> InternWeak(ObjPtr<mirror::String> s) REQUIRES_SHARED(Locks::mutator_lock_) 140*795d594fSAndroid Build Coastguard Worker REQUIRES(!Roles::uninterruptible_); 141*795d594fSAndroid Build Coastguard Worker 142*795d594fSAndroid Build Coastguard Worker void SweepInternTableWeaks(IsMarkedVisitor* visitor) REQUIRES_SHARED(Locks::mutator_lock_) 143*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_); 144*795d594fSAndroid Build Coastguard Worker 145*795d594fSAndroid Build Coastguard Worker // Lookup a strong intern, returns null if not found. 146*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> LookupStrong(Thread* self, ObjPtr<mirror::String> s) 147*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) 148*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 149*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> LookupStrong(Thread* self, uint32_t utf16_length, const char* utf8_data) 150*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) 151*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 152*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> LookupStrongLocked(ObjPtr<mirror::String> s) 153*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 154*795d594fSAndroid Build Coastguard Worker 155*795d594fSAndroid Build Coastguard Worker // Lookup a weak intern, returns null if not found. 156*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> LookupWeak(Thread* self, ObjPtr<mirror::String> s) 157*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) 158*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 159*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> LookupWeakLocked(ObjPtr<mirror::String> s) 160*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 161*795d594fSAndroid Build Coastguard Worker 162*795d594fSAndroid Build Coastguard Worker // Total number of interned strings. 163*795d594fSAndroid Build Coastguard Worker EXPORT size_t Size() const REQUIRES(!Locks::intern_table_lock_); 164*795d594fSAndroid Build Coastguard Worker 165*795d594fSAndroid Build Coastguard Worker // Total number of weakly live interned strings. 166*795d594fSAndroid Build Coastguard Worker size_t StrongSize() const REQUIRES(!Locks::intern_table_lock_); 167*795d594fSAndroid Build Coastguard Worker 168*795d594fSAndroid Build Coastguard Worker // Total number of strongly live interned strings. 169*795d594fSAndroid Build Coastguard Worker size_t WeakSize() const REQUIRES(!Locks::intern_table_lock_); 170*795d594fSAndroid Build Coastguard Worker 171*795d594fSAndroid Build Coastguard Worker EXPORT void VisitRoots(RootVisitor* visitor, VisitRootFlags flags) 172*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::intern_table_lock_); 173*795d594fSAndroid Build Coastguard Worker 174*795d594fSAndroid Build Coastguard Worker // Visit all of the interns in the table. 175*795d594fSAndroid Build Coastguard Worker template <typename Visitor> 176*795d594fSAndroid Build Coastguard Worker void VisitInterns(const Visitor& visitor, 177*795d594fSAndroid Build Coastguard Worker bool visit_boot_images, 178*795d594fSAndroid Build Coastguard Worker bool visit_non_boot_images) 179*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 180*795d594fSAndroid Build Coastguard Worker 181*795d594fSAndroid Build Coastguard Worker // Count the number of intern strings in the table. 182*795d594fSAndroid Build Coastguard Worker size_t CountInterns(bool visit_boot_images, bool visit_non_boot_images) const 183*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 184*795d594fSAndroid Build Coastguard Worker 185*795d594fSAndroid Build Coastguard Worker void DumpForSigQuit(std::ostream& os) const REQUIRES(!Locks::intern_table_lock_); 186*795d594fSAndroid Build Coastguard Worker 187*795d594fSAndroid Build Coastguard Worker void BroadcastForNewInterns(); 188*795d594fSAndroid Build Coastguard Worker 189*795d594fSAndroid Build Coastguard Worker // Add all of the strings in the image's intern table into this intern table. This is required so 190*795d594fSAndroid Build Coastguard Worker // the intern table is correct. 191*795d594fSAndroid Build Coastguard Worker // The visitor arg type is UnorderedSet 192*795d594fSAndroid Build Coastguard Worker template <typename Visitor> 193*795d594fSAndroid Build Coastguard Worker void AddImageStringsToTable(gc::space::ImageSpace* image_space, 194*795d594fSAndroid Build Coastguard Worker const Visitor& visitor) 195*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::intern_table_lock_); 196*795d594fSAndroid Build Coastguard Worker 197*795d594fSAndroid Build Coastguard Worker // Add a new intern table for inserting to, previous intern tables are still there but no 198*795d594fSAndroid Build Coastguard Worker // longer inserted into and ideally unmodified. This is done to prevent dirty pages. 199*795d594fSAndroid Build Coastguard Worker void AddNewTable() 200*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!Locks::intern_table_lock_); 201*795d594fSAndroid Build Coastguard Worker 202*795d594fSAndroid Build Coastguard Worker // Change the weak root state. May broadcast to waiters. 203*795d594fSAndroid Build Coastguard Worker void ChangeWeakRootState(gc::WeakRootState new_state) 204*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_); 205*795d594fSAndroid Build Coastguard Worker 206*795d594fSAndroid Build Coastguard Worker private: 207*795d594fSAndroid Build Coastguard Worker // Table which holds pre zygote and post zygote interned strings. There is one instance for 208*795d594fSAndroid Build Coastguard Worker // weak interns and strong interns. 209*795d594fSAndroid Build Coastguard Worker class Table { 210*795d594fSAndroid Build Coastguard Worker public: 211*795d594fSAndroid Build Coastguard Worker class InternalTable { 212*795d594fSAndroid Build Coastguard Worker public: 213*795d594fSAndroid Build Coastguard Worker InternalTable() = default; InternalTable(UnorderedSet && set,bool is_boot_image)214*795d594fSAndroid Build Coastguard Worker InternalTable(UnorderedSet&& set, bool is_boot_image) 215*795d594fSAndroid Build Coastguard Worker : set_(std::move(set)), is_boot_image_(is_boot_image) {} 216*795d594fSAndroid Build Coastguard Worker Empty()217*795d594fSAndroid Build Coastguard Worker bool Empty() const { 218*795d594fSAndroid Build Coastguard Worker return set_.empty(); 219*795d594fSAndroid Build Coastguard Worker } 220*795d594fSAndroid Build Coastguard Worker Size()221*795d594fSAndroid Build Coastguard Worker size_t Size() const { 222*795d594fSAndroid Build Coastguard Worker return set_.size(); 223*795d594fSAndroid Build Coastguard Worker } 224*795d594fSAndroid Build Coastguard Worker IsBootImage()225*795d594fSAndroid Build Coastguard Worker bool IsBootImage() const { 226*795d594fSAndroid Build Coastguard Worker return is_boot_image_; 227*795d594fSAndroid Build Coastguard Worker } 228*795d594fSAndroid Build Coastguard Worker 229*795d594fSAndroid Build Coastguard Worker private: 230*795d594fSAndroid Build Coastguard Worker UnorderedSet set_; 231*795d594fSAndroid Build Coastguard Worker bool is_boot_image_ = false; 232*795d594fSAndroid Build Coastguard Worker 233*795d594fSAndroid Build Coastguard Worker friend class InternTable; 234*795d594fSAndroid Build Coastguard Worker friend class linker::ImageWriter; 235*795d594fSAndroid Build Coastguard Worker friend class Table; 236*795d594fSAndroid Build Coastguard Worker ART_FRIEND_TEST(InternTableTest, CrossHash); 237*795d594fSAndroid Build Coastguard Worker }; 238*795d594fSAndroid Build Coastguard Worker 239*795d594fSAndroid Build Coastguard Worker Table(); 240*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> Find(ObjPtr<mirror::String> s, 241*795d594fSAndroid Build Coastguard Worker uint32_t hash, 242*795d594fSAndroid Build Coastguard Worker size_t num_searched_frozen_tables = 0u) 243*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 244*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> Find(const Utf8String& string, uint32_t hash) 245*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 246*795d594fSAndroid Build Coastguard Worker void Insert(ObjPtr<mirror::String> s, uint32_t hash) 247*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 248*795d594fSAndroid Build Coastguard Worker void Remove(ObjPtr<mirror::String> s, uint32_t hash) 249*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 250*795d594fSAndroid Build Coastguard Worker void VisitRoots(RootVisitor* visitor) 251*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 252*795d594fSAndroid Build Coastguard Worker void SweepWeaks(IsMarkedVisitor* visitor) 253*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 254*795d594fSAndroid Build Coastguard Worker // Add a new intern table that will only be inserted into from now on. 255*795d594fSAndroid Build Coastguard Worker void AddNewTable() REQUIRES(Locks::intern_table_lock_); 256*795d594fSAndroid Build Coastguard Worker size_t Size() const REQUIRES(Locks::intern_table_lock_); 257*795d594fSAndroid Build Coastguard Worker // Read and add an intern table from ptr. 258*795d594fSAndroid Build Coastguard Worker // Tables read are inserted at the front of the table array. Only checks for conflicts in 259*795d594fSAndroid Build Coastguard Worker // debug builds. Returns how many bytes were read. 260*795d594fSAndroid Build Coastguard Worker // NO_THREAD_SAFETY_ANALYSIS for the visitor that may require locks. 261*795d594fSAndroid Build Coastguard Worker template <typename Visitor> 262*795d594fSAndroid Build Coastguard Worker size_t AddTableFromMemory(const uint8_t* ptr, const Visitor& visitor, bool is_boot_image) 263*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 264*795d594fSAndroid Build Coastguard Worker 265*795d594fSAndroid Build Coastguard Worker private: 266*795d594fSAndroid Build Coastguard Worker void SweepWeaks(UnorderedSet* set, IsMarkedVisitor* visitor) 267*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 268*795d594fSAndroid Build Coastguard Worker 269*795d594fSAndroid Build Coastguard Worker // Add a table to the front of the tables vector. 270*795d594fSAndroid Build Coastguard Worker void AddInternStrings(UnorderedSet&& intern_strings, bool is_boot_image) 271*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 272*795d594fSAndroid Build Coastguard Worker 273*795d594fSAndroid Build Coastguard Worker // We call AddNewTable when we create the zygote to reduce private dirty pages caused by 274*795d594fSAndroid Build Coastguard Worker // modifying the zygote intern table. The back of table is modified when strings are interned. 275*795d594fSAndroid Build Coastguard Worker dchecked_vector<InternalTable> tables_; 276*795d594fSAndroid Build Coastguard Worker 277*795d594fSAndroid Build Coastguard Worker friend class InternTable; 278*795d594fSAndroid Build Coastguard Worker friend class linker::ImageWriter; 279*795d594fSAndroid Build Coastguard Worker ART_FRIEND_TEST(InternTableTest, CrossHash); 280*795d594fSAndroid Build Coastguard Worker }; 281*795d594fSAndroid Build Coastguard Worker 282*795d594fSAndroid Build Coastguard Worker // Insert if non null, otherwise return null. Must be called holding the mutator lock. 283*795d594fSAndroid Build Coastguard Worker ObjPtr<mirror::String> Insert(ObjPtr<mirror::String> s, 284*795d594fSAndroid Build Coastguard Worker uint32_t hash, 285*795d594fSAndroid Build Coastguard Worker bool is_strong, 286*795d594fSAndroid Build Coastguard Worker size_t num_searched_strong_frozen_tables = 0u) 287*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 288*795d594fSAndroid Build Coastguard Worker 289*795d594fSAndroid Build Coastguard Worker // Add a table from memory to the strong interns. 290*795d594fSAndroid Build Coastguard Worker template <typename Visitor> 291*795d594fSAndroid Build Coastguard Worker size_t AddTableFromMemory(const uint8_t* ptr, const Visitor& visitor, bool is_boot_image) 292*795d594fSAndroid Build Coastguard Worker REQUIRES(!Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 293*795d594fSAndroid Build Coastguard Worker 294*795d594fSAndroid Build Coastguard Worker // Note: Transaction rollback calls these helper functions directly. 295*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::String> InsertStrong(ObjPtr<mirror::String> s, uint32_t hash) 296*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 297*795d594fSAndroid Build Coastguard Worker EXPORT ObjPtr<mirror::String> InsertWeak(ObjPtr<mirror::String> s, uint32_t hash) 298*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 299*795d594fSAndroid Build Coastguard Worker EXPORT void RemoveStrong(ObjPtr<mirror::String> s, uint32_t hash) 300*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 301*795d594fSAndroid Build Coastguard Worker void EXPORT RemoveWeak(ObjPtr<mirror::String> s, uint32_t hash) 302*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(Locks::intern_table_lock_); 303*795d594fSAndroid Build Coastguard Worker 304*795d594fSAndroid Build Coastguard Worker // Change the weak root state. May broadcast to waiters. 305*795d594fSAndroid Build Coastguard Worker void ChangeWeakRootStateLocked(gc::WeakRootState new_state) 306*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::intern_table_lock_); 307*795d594fSAndroid Build Coastguard Worker 308*795d594fSAndroid Build Coastguard Worker // Wait until we can read weak roots. 309*795d594fSAndroid Build Coastguard Worker void WaitUntilAccessible(Thread* self) 310*795d594fSAndroid Build Coastguard Worker REQUIRES(Locks::intern_table_lock_) REQUIRES_SHARED(Locks::mutator_lock_); 311*795d594fSAndroid Build Coastguard Worker 312*795d594fSAndroid Build Coastguard Worker bool log_new_roots_ GUARDED_BY(Locks::intern_table_lock_); 313*795d594fSAndroid Build Coastguard Worker ConditionVariable weak_intern_condition_ GUARDED_BY(Locks::intern_table_lock_); 314*795d594fSAndroid Build Coastguard Worker // Since this contains (strong) roots, they need a read barrier to 315*795d594fSAndroid Build Coastguard Worker // enable concurrent intern table (strong) root scan. Do not 316*795d594fSAndroid Build Coastguard Worker // directly access the strings in it. Use functions that contain 317*795d594fSAndroid Build Coastguard Worker // read barriers. 318*795d594fSAndroid Build Coastguard Worker Table strong_interns_ GUARDED_BY(Locks::intern_table_lock_); 319*795d594fSAndroid Build Coastguard Worker dchecked_vector<GcRoot<mirror::String>> new_strong_intern_roots_ 320*795d594fSAndroid Build Coastguard Worker GUARDED_BY(Locks::intern_table_lock_); 321*795d594fSAndroid Build Coastguard Worker // Since this contains (weak) roots, they need a read barrier. Do 322*795d594fSAndroid Build Coastguard Worker // not directly access the strings in it. Use functions that contain 323*795d594fSAndroid Build Coastguard Worker // read barriers. 324*795d594fSAndroid Build Coastguard Worker Table weak_interns_ GUARDED_BY(Locks::intern_table_lock_); 325*795d594fSAndroid Build Coastguard Worker // Weak root state, used for concurrent system weak processing and more. 326*795d594fSAndroid Build Coastguard Worker gc::WeakRootState weak_root_state_ GUARDED_BY(Locks::intern_table_lock_); 327*795d594fSAndroid Build Coastguard Worker 328*795d594fSAndroid Build Coastguard Worker friend class gc::space::ImageSpace; 329*795d594fSAndroid Build Coastguard Worker friend class linker::ImageWriter; 330*795d594fSAndroid Build Coastguard Worker friend class Transaction; 331*795d594fSAndroid Build Coastguard Worker ART_FRIEND_TEST(InternTableTest, CrossHash); 332*795d594fSAndroid Build Coastguard Worker DISALLOW_COPY_AND_ASSIGN(InternTable); 333*795d594fSAndroid Build Coastguard Worker }; 334*795d594fSAndroid Build Coastguard Worker 335*795d594fSAndroid Build Coastguard Worker } // namespace art 336*795d594fSAndroid Build Coastguard Worker 337*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_INTERN_TABLE_H_ 338