xref: /aosp_15_r20/art/runtime/class_table.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2015 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_CLASS_TABLE_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_CLASS_TABLE_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include <string>
21*795d594fSAndroid Build Coastguard Worker #include <utility>
22*795d594fSAndroid Build Coastguard Worker #include <vector>
23*795d594fSAndroid Build Coastguard Worker 
24*795d594fSAndroid Build Coastguard Worker #include "base/gc_visited_arena_pool.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/hash_set.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/mutex.h"
28*795d594fSAndroid Build Coastguard Worker #include "gc_root.h"
29*795d594fSAndroid Build Coastguard Worker #include "obj_ptr.h"
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker class OatFile;
34*795d594fSAndroid Build Coastguard Worker 
35*795d594fSAndroid Build Coastguard Worker namespace linker {
36*795d594fSAndroid Build Coastguard Worker class ImageWriter;
37*795d594fSAndroid Build Coastguard Worker }  // namespace linker
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker namespace linker {
40*795d594fSAndroid Build Coastguard Worker class OatWriter;
41*795d594fSAndroid Build Coastguard Worker }  // namespace linker
42*795d594fSAndroid Build Coastguard Worker 
43*795d594fSAndroid Build Coastguard Worker namespace mirror {
44*795d594fSAndroid Build Coastguard Worker class Class;
45*795d594fSAndroid Build Coastguard Worker class ClassLoader;
46*795d594fSAndroid Build Coastguard Worker class Object;
47*795d594fSAndroid Build Coastguard Worker }  // namespace mirror
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker // Each loader has a ClassTable
50*795d594fSAndroid Build Coastguard Worker class ClassTable {
51*795d594fSAndroid Build Coastguard Worker  public:
52*795d594fSAndroid Build Coastguard Worker   class TableSlot {
53*795d594fSAndroid Build Coastguard Worker    public:
TableSlot()54*795d594fSAndroid Build Coastguard Worker     TableSlot() : data_(0u) {}
55*795d594fSAndroid Build Coastguard Worker 
TableSlot(const TableSlot & copy)56*795d594fSAndroid Build Coastguard Worker     TableSlot(const TableSlot& copy) : data_(copy.data_.load(std::memory_order_relaxed)) {}
57*795d594fSAndroid Build Coastguard Worker 
58*795d594fSAndroid Build Coastguard Worker     explicit TableSlot(ObjPtr<mirror::Class> klass);
59*795d594fSAndroid Build Coastguard Worker 
60*795d594fSAndroid Build Coastguard Worker     TableSlot(ObjPtr<mirror::Class> klass, uint32_t descriptor_hash);
61*795d594fSAndroid Build Coastguard Worker     TableSlot(uint32_t ptr, uint32_t descriptor_hash);
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker     TableSlot& operator=(const TableSlot& copy) {
64*795d594fSAndroid Build Coastguard Worker       data_.store(copy.data_.load(std::memory_order_relaxed), std::memory_order_relaxed);
65*795d594fSAndroid Build Coastguard Worker       return *this;
66*795d594fSAndroid Build Coastguard Worker     }
67*795d594fSAndroid Build Coastguard Worker 
Data()68*795d594fSAndroid Build Coastguard Worker     uint32_t Data() const {
69*795d594fSAndroid Build Coastguard Worker       return data_.load(std::memory_order_relaxed);
70*795d594fSAndroid Build Coastguard Worker     }
71*795d594fSAndroid Build Coastguard Worker 
72*795d594fSAndroid Build Coastguard Worker     bool IsNull() const REQUIRES_SHARED(Locks::mutator_lock_);
73*795d594fSAndroid Build Coastguard Worker 
Hash()74*795d594fSAndroid Build Coastguard Worker     uint32_t Hash() const {
75*795d594fSAndroid Build Coastguard Worker       return MaskHash(data_.load(std::memory_order_relaxed));
76*795d594fSAndroid Build Coastguard Worker     }
77*795d594fSAndroid Build Coastguard Worker 
NonHashData()78*795d594fSAndroid Build Coastguard Worker     uint32_t NonHashData() const {
79*795d594fSAndroid Build Coastguard Worker       return RemoveHash(Data());
80*795d594fSAndroid Build Coastguard Worker     }
81*795d594fSAndroid Build Coastguard Worker 
RemoveHash(uint32_t hash)82*795d594fSAndroid Build Coastguard Worker     static uint32_t RemoveHash(uint32_t hash) {
83*795d594fSAndroid Build Coastguard Worker       return hash & ~kHashMask;
84*795d594fSAndroid Build Coastguard Worker     }
85*795d594fSAndroid Build Coastguard Worker 
MaskHash(uint32_t hash)86*795d594fSAndroid Build Coastguard Worker     static uint32_t MaskHash(uint32_t hash) {
87*795d594fSAndroid Build Coastguard Worker       return hash & kHashMask;
88*795d594fSAndroid Build Coastguard Worker     }
89*795d594fSAndroid Build Coastguard Worker 
MaskedHashEquals(uint32_t other)90*795d594fSAndroid Build Coastguard Worker     bool MaskedHashEquals(uint32_t other) const {
91*795d594fSAndroid Build Coastguard Worker       return MaskHash(other) == Hash();
92*795d594fSAndroid Build Coastguard Worker     }
93*795d594fSAndroid Build Coastguard Worker 
94*795d594fSAndroid Build Coastguard Worker     template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
95*795d594fSAndroid Build Coastguard Worker     ObjPtr<mirror::Class> Read() const REQUIRES_SHARED(Locks::mutator_lock_);
96*795d594fSAndroid Build Coastguard Worker 
97*795d594fSAndroid Build Coastguard Worker     // NO_THREAD_SAFETY_ANALYSIS since the visitor may require heap bitmap lock.
98*795d594fSAndroid Build Coastguard Worker     template<typename Visitor>
99*795d594fSAndroid Build Coastguard Worker     void VisitRoot(const Visitor& visitor) const NO_THREAD_SAFETY_ANALYSIS;
100*795d594fSAndroid Build Coastguard Worker 
101*795d594fSAndroid Build Coastguard Worker     template<typename Visitor>
102*795d594fSAndroid Build Coastguard Worker     class ClassAndRootVisitor;
103*795d594fSAndroid Build Coastguard Worker 
104*795d594fSAndroid Build Coastguard Worker    private:
105*795d594fSAndroid Build Coastguard Worker     // Extract a raw pointer from an address.
106*795d594fSAndroid Build Coastguard Worker     static ObjPtr<mirror::Class> ExtractPtr(uint32_t data)
107*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(Locks::mutator_lock_);
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker     static uint32_t Encode(ObjPtr<mirror::Class> klass, uint32_t hash_bits)
110*795d594fSAndroid Build Coastguard Worker         REQUIRES_SHARED(Locks::mutator_lock_);
111*795d594fSAndroid Build Coastguard Worker 
112*795d594fSAndroid Build Coastguard Worker     // Data contains the class pointer GcRoot as well as the low bits of the descriptor hash.
113*795d594fSAndroid Build Coastguard Worker     mutable Atomic<uint32_t> data_;
114*795d594fSAndroid Build Coastguard Worker     static constexpr uint32_t kHashMask = kObjectAlignment - 1;
115*795d594fSAndroid Build Coastguard Worker   };
116*795d594fSAndroid Build Coastguard Worker 
117*795d594fSAndroid Build Coastguard Worker   using DescriptorHashPair = std::pair<std::string_view, uint32_t>;
118*795d594fSAndroid Build Coastguard Worker 
119*795d594fSAndroid Build Coastguard Worker   class ClassDescriptorHash {
120*795d594fSAndroid Build Coastguard Worker    public:
121*795d594fSAndroid Build Coastguard Worker     // uint32_t for cross compilation.
122*795d594fSAndroid Build Coastguard Worker     // NO_THREAD_SAFETY_ANALYSIS: Used from unannotated `HashSet<>` functions.
123*795d594fSAndroid Build Coastguard Worker     uint32_t operator()(const TableSlot& slot) const NO_THREAD_SAFETY_ANALYSIS;
124*795d594fSAndroid Build Coastguard Worker     // uint32_t for cross compilation.
125*795d594fSAndroid Build Coastguard Worker     uint32_t operator()(const DescriptorHashPair& pair) const;
126*795d594fSAndroid Build Coastguard Worker   };
127*795d594fSAndroid Build Coastguard Worker 
128*795d594fSAndroid Build Coastguard Worker   class ClassDescriptorEquals {
129*795d594fSAndroid Build Coastguard Worker    public:
130*795d594fSAndroid Build Coastguard Worker     // Same class loader and descriptor.
131*795d594fSAndroid Build Coastguard Worker     bool operator()(const TableSlot& a, const TableSlot& b) const
132*795d594fSAndroid Build Coastguard Worker         NO_THREAD_SAFETY_ANALYSIS;
133*795d594fSAndroid Build Coastguard Worker     // Same descriptor.
134*795d594fSAndroid Build Coastguard Worker     bool operator()(const TableSlot& a, const DescriptorHashPair& b) const
135*795d594fSAndroid Build Coastguard Worker         NO_THREAD_SAFETY_ANALYSIS;
136*795d594fSAndroid Build Coastguard Worker   };
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   class TableSlotEmptyFn {
139*795d594fSAndroid Build Coastguard Worker    public:
MakeEmpty(TableSlot & item)140*795d594fSAndroid Build Coastguard Worker     void MakeEmpty(TableSlot& item) const NO_THREAD_SAFETY_ANALYSIS {
141*795d594fSAndroid Build Coastguard Worker       item = TableSlot();
142*795d594fSAndroid Build Coastguard Worker       DCHECK(IsEmpty(item));
143*795d594fSAndroid Build Coastguard Worker     }
IsEmpty(const TableSlot & item)144*795d594fSAndroid Build Coastguard Worker     bool IsEmpty(const TableSlot& item) const NO_THREAD_SAFETY_ANALYSIS {
145*795d594fSAndroid Build Coastguard Worker       return item.IsNull();
146*795d594fSAndroid Build Coastguard Worker     }
147*795d594fSAndroid Build Coastguard Worker   };
148*795d594fSAndroid Build Coastguard Worker 
149*795d594fSAndroid Build Coastguard Worker   // Hash set that hashes class descriptor, and compares descriptors and class loaders. Results
150*795d594fSAndroid Build Coastguard Worker   // should be compared for a matching class descriptor and class loader.
151*795d594fSAndroid Build Coastguard Worker   using ClassSet = HashSet<TableSlot,
152*795d594fSAndroid Build Coastguard Worker                            TableSlotEmptyFn,
153*795d594fSAndroid Build Coastguard Worker                            ClassDescriptorHash,
154*795d594fSAndroid Build Coastguard Worker                            ClassDescriptorEquals,
155*795d594fSAndroid Build Coastguard Worker                            GcRootArenaAllocator<TableSlot, kAllocatorTagClassTable>>;
156*795d594fSAndroid Build Coastguard Worker 
157*795d594fSAndroid Build Coastguard Worker   EXPORT ClassTable();
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   // Freeze the current class tables by allocating a new table and never updating or modifying the
160*795d594fSAndroid Build Coastguard Worker   // existing table. This helps prevents dirty pages after caused by inserting after zygote fork.
161*795d594fSAndroid Build Coastguard Worker   void FreezeSnapshot()
162*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
163*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
164*795d594fSAndroid Build Coastguard Worker 
165*795d594fSAndroid Build Coastguard Worker   // Returns the number of classes in previous snapshots defined by `defining_loader`.
166*795d594fSAndroid Build Coastguard Worker   size_t NumZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
167*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
168*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker   // Returns all off the classes in the lastest snapshot defined by `defining_loader`.
171*795d594fSAndroid Build Coastguard Worker   size_t NumNonZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
172*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
173*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
174*795d594fSAndroid Build Coastguard Worker 
175*795d594fSAndroid Build Coastguard Worker   // Returns the number of classes in previous snapshots no matter the defining loader.
176*795d594fSAndroid Build Coastguard Worker   EXPORT size_t NumReferencedZygoteClasses() const
177*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
178*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
179*795d594fSAndroid Build Coastguard Worker 
180*795d594fSAndroid Build Coastguard Worker   // Returns all off the classes in the lastest snapshot no matter the defining loader.
181*795d594fSAndroid Build Coastguard Worker   size_t NumReferencedNonZygoteClasses() const
182*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
183*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   // Returns the number of class-sets in the class table.
186*795d594fSAndroid Build Coastguard Worker   size_t Size() const
187*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
188*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
189*795d594fSAndroid Build Coastguard Worker 
190*795d594fSAndroid Build Coastguard Worker   // Update a class in the table with the new class. Returns the existing class which was replaced.
191*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> UpdateClass(ObjPtr<mirror::Class> new_klass, size_t hash)
192*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
193*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
194*795d594fSAndroid Build Coastguard Worker 
195*795d594fSAndroid Build Coastguard Worker   // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock.
196*795d594fSAndroid Build Coastguard Worker   template <class Visitor>
197*795d594fSAndroid Build Coastguard Worker   void VisitRoots(Visitor& visitor, bool skip_classes = false) NO_THREAD_SAFETY_ANALYSIS
198*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_) REQUIRES_SHARED(Locks::mutator_lock_);
199*795d594fSAndroid Build Coastguard Worker 
200*795d594fSAndroid Build Coastguard Worker   template <class Visitor>
201*795d594fSAndroid Build Coastguard Worker   void VisitRoots(const Visitor& visitor, bool skip_classes = false) NO_THREAD_SAFETY_ANALYSIS
202*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_) REQUIRES_SHARED(Locks::mutator_lock_);
203*795d594fSAndroid Build Coastguard Worker 
204*795d594fSAndroid Build Coastguard Worker   template<class Visitor>
205*795d594fSAndroid Build Coastguard Worker   void VisitClassesAndRoots(Visitor& visitor)
206*795d594fSAndroid Build Coastguard Worker       NO_THREAD_SAFETY_ANALYSIS
207*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
208*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
209*795d594fSAndroid Build Coastguard Worker 
210*795d594fSAndroid Build Coastguard Worker   // Visit classes in those class-sets which satisfy 'cond'.
211*795d594fSAndroid Build Coastguard Worker   template <class Condition, class Visitor>
212*795d594fSAndroid Build Coastguard Worker   void VisitClassesIfConditionMet(Condition& cond, Visitor& visitor) REQUIRES(!lock_)
213*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
214*795d594fSAndroid Build Coastguard Worker   // Stops visit if the visitor returns false.
215*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
216*795d594fSAndroid Build Coastguard Worker   bool Visit(Visitor& visitor)
217*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
218*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
219*795d594fSAndroid Build Coastguard Worker   template <ReadBarrierOption kReadBarrierOption = kWithReadBarrier, typename Visitor>
220*795d594fSAndroid Build Coastguard Worker   bool Visit(const Visitor& visitor)
221*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
222*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker   // Return the first class that matches the descriptor. Returns null if there are none.
225*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> Lookup(std::string_view descriptor, size_t hash)
226*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
227*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker   // Return the first class that matches the descriptor of klass. Returns null if there are none.
230*795d594fSAndroid Build Coastguard Worker   // Used for tests and debug-build checks.
231*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> LookupByDescriptor(ObjPtr<mirror::Class> klass)
232*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
233*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker   void Insert(ObjPtr<mirror::Class> klass)
236*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
237*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker   void InsertWithHash(ObjPtr<mirror::Class> klass, size_t hash)
240*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
241*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker   // Return true if we inserted the strong root, false if it already exists.
244*795d594fSAndroid Build Coastguard Worker   bool InsertStrongRoot(ObjPtr<mirror::Object> obj)
245*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
246*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
247*795d594fSAndroid Build Coastguard Worker 
248*795d594fSAndroid Build Coastguard Worker   // Return true if we inserted the oat file, false if it already exists.
249*795d594fSAndroid Build Coastguard Worker   bool InsertOatFile(const OatFile* oat_file)
250*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
251*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker   // Read a table from ptr and put it at the front of the class set.
254*795d594fSAndroid Build Coastguard Worker   EXPORT size_t ReadFromMemory(uint8_t* ptr)
255*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
256*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
257*795d594fSAndroid Build Coastguard Worker 
258*795d594fSAndroid Build Coastguard Worker   // Add a class set to the front of classes.
259*795d594fSAndroid Build Coastguard Worker   void AddClassSet(ClassSet&& set)
260*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
261*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker   // Clear strong roots (other than classes themselves).
264*795d594fSAndroid Build Coastguard Worker   void ClearStrongRoots()
265*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
266*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
267*795d594fSAndroid Build Coastguard Worker 
268*795d594fSAndroid Build Coastguard Worker   // Filter strong roots (other than classes themselves).
269*795d594fSAndroid Build Coastguard Worker   template <typename Filter>
270*795d594fSAndroid Build Coastguard Worker   void RemoveStrongRoots(const Filter& filter)
271*795d594fSAndroid Build Coastguard Worker       REQUIRES(!lock_)
272*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
273*795d594fSAndroid Build Coastguard Worker 
GetLock()274*795d594fSAndroid Build Coastguard Worker   ReaderWriterMutex& GetLock() {
275*795d594fSAndroid Build Coastguard Worker     return lock_;
276*795d594fSAndroid Build Coastguard Worker   }
277*795d594fSAndroid Build Coastguard Worker 
278*795d594fSAndroid Build Coastguard Worker  private:
279*795d594fSAndroid Build Coastguard Worker   size_t CountDefiningLoaderClasses(ObjPtr<mirror::ClassLoader> defining_loader,
280*795d594fSAndroid Build Coastguard Worker                                     const ClassSet& set) const
281*795d594fSAndroid Build Coastguard Worker       REQUIRES(lock_)
282*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
283*795d594fSAndroid Build Coastguard Worker 
284*795d594fSAndroid Build Coastguard Worker   // Return true if we inserted the oat file, false if it already exists.
285*795d594fSAndroid Build Coastguard Worker   bool InsertOatFileLocked(const OatFile* oat_file)
286*795d594fSAndroid Build Coastguard Worker       REQUIRES(lock_)
287*795d594fSAndroid Build Coastguard Worker       REQUIRES_SHARED(Locks::mutator_lock_);
288*795d594fSAndroid Build Coastguard Worker 
289*795d594fSAndroid Build Coastguard Worker   // Lock to guard inserting and removing.
290*795d594fSAndroid Build Coastguard Worker   mutable ReaderWriterMutex lock_;
291*795d594fSAndroid Build Coastguard Worker   // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
292*795d594fSAndroid Build Coastguard Worker   std::vector<ClassSet> classes_ GUARDED_BY(lock_);
293*795d594fSAndroid Build Coastguard Worker   // Extra strong roots that can be either dex files or dex caches. Dex files used by the class
294*795d594fSAndroid Build Coastguard Worker   // loader which may not be owned by the class loader must be held strongly live. Also dex caches
295*795d594fSAndroid Build Coastguard Worker   // are held live to prevent them being unloading once they have classes in them.
296*795d594fSAndroid Build Coastguard Worker   std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_);
297*795d594fSAndroid Build Coastguard Worker   // Keep track of oat files with GC roots associated with dex caches in `strong_roots_`.
298*795d594fSAndroid Build Coastguard Worker   std::vector<const OatFile*> oat_files_ GUARDED_BY(lock_);
299*795d594fSAndroid Build Coastguard Worker 
300*795d594fSAndroid Build Coastguard Worker   friend class linker::ImageWriter;  // for InsertWithoutLocks.
301*795d594fSAndroid Build Coastguard Worker };
302*795d594fSAndroid Build Coastguard Worker 
303*795d594fSAndroid Build Coastguard Worker }  // namespace art
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker #endif  // ART_RUNTIME_CLASS_TABLE_H_
306