blob: 375954ac1800436ac07a60de643811468954ecf7 [file] [log] [blame]
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_CLASS_TABLE_H_
18#define ART_RUNTIME_CLASS_TABLE_H_
19
20#include <string>
21#include <utility>
22#include <vector>
23
24#include "base/allocator.h"
25#include "base/hash_set.h"
26#include "base/macros.h"
27#include "base/mutex.h"
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070028#include "gc_root.h"
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070029#include "obj_ptr.h"
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070030
31namespace art {
32
Vladimir Markoaad75c62016-10-03 08:46:48 +000033class OatFile;
34
Vladimir Marko74527972016-11-29 15:57:32 +000035namespace linker {
36class ImageWriter;
37} // namespace linker
38
39namespace linker {
40class OatWriter;
41} // namespace linker
42
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070043namespace mirror {
Igor Murashkin2ffb7032017-11-08 13:35:21 -080044class Class;
45class ClassLoader;
46class Object;
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070047} // namespace mirror
48
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070049// Each loader has a ClassTable
50class ClassTable {
51 public:
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080052 class TableSlot {
53 public:
54 TableSlot() : data_(0u) {}
55
Orion Hodson88591fe2018-03-06 13:35:43 +000056 TableSlot(const TableSlot& copy) : data_(copy.data_.load(std::memory_order_relaxed)) {}
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080057
58 explicit TableSlot(ObjPtr<mirror::Class> klass);
59
60 TableSlot(ObjPtr<mirror::Class> klass, uint32_t descriptor_hash);
61
62 TableSlot& operator=(const TableSlot& copy) {
Orion Hodson88591fe2018-03-06 13:35:43 +000063 data_.store(copy.data_.load(std::memory_order_relaxed), std::memory_order_relaxed);
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080064 return *this;
65 }
66
Vladimir Markoc6934e32019-04-10 11:40:01 +010067 bool IsNull() const REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080068
69 uint32_t Hash() const {
Orion Hodson88591fe2018-03-06 13:35:43 +000070 return MaskHash(data_.load(std::memory_order_relaxed));
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080071 }
72
73 static uint32_t MaskHash(uint32_t hash) {
74 return hash & kHashMask;
75 }
76
77 bool MaskedHashEquals(uint32_t other) const {
78 return MaskHash(other) == Hash();
79 }
80
Mathieu Chartierdb70ce52016-12-12 11:06:59 -080081 static uint32_t HashDescriptor(ObjPtr<mirror::Class> klass)
82 REQUIRES_SHARED(Locks::mutator_lock_);
83
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080084 template<ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
Vladimir Marko1fe58392019-04-10 16:14:56 +010085 ObjPtr<mirror::Class> Read() const REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -080086
87 // NO_THREAD_SAFETY_ANALYSIS since the visitor may require heap bitmap lock.
88 template<typename Visitor>
89 void VisitRoot(const Visitor& visitor) const NO_THREAD_SAFETY_ANALYSIS;
90
91 private:
92 // Extract a raw pointer from an address.
93 static ObjPtr<mirror::Class> ExtractPtr(uint32_t data)
94 REQUIRES_SHARED(Locks::mutator_lock_);
95
96 static uint32_t Encode(ObjPtr<mirror::Class> klass, uint32_t hash_bits)
97 REQUIRES_SHARED(Locks::mutator_lock_);
98
99 // Data contains the class pointer GcRoot as well as the low bits of the descriptor hash.
100 mutable Atomic<uint32_t> data_;
101 static const uint32_t kHashMask = kObjectAlignment - 1;
102 };
103
104 using DescriptorHashPair = std::pair<const char*, uint32_t>;
105
Vladimir Markoeae6a712021-02-05 13:33:28 +0000106 class ClassDescriptorHash {
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800107 public:
108 // uint32_t for cross compilation.
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800109 uint32_t operator()(const TableSlot& slot) const NO_THREAD_SAFETY_ANALYSIS;
Vladimir Markoeae6a712021-02-05 13:33:28 +0000110 // uint32_t for cross compilation.
111 uint32_t operator()(const DescriptorHashPair& pair) const NO_THREAD_SAFETY_ANALYSIS;
112 };
113
114 class ClassDescriptorEquals {
115 public:
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800116 // Same class loader and descriptor.
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800117 bool operator()(const TableSlot& a, const TableSlot& b) const
Mathieu Chartier6beced42016-11-15 15:51:31 -0800118 NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800119 // Same descriptor.
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800120 bool operator()(const TableSlot& a, const DescriptorHashPair& b) const
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800121 NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800122 };
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800123
124 class TableSlotEmptyFn {
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800125 public:
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800126 void MakeEmpty(TableSlot& item) const NO_THREAD_SAFETY_ANALYSIS {
127 item = TableSlot();
128 DCHECK(IsEmpty(item));
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800129 }
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800130 bool IsEmpty(const TableSlot& item) const NO_THREAD_SAFETY_ANALYSIS {
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800131 return item.IsNull();
132 }
133 };
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800134
135 // Hash set that hashes class descriptor, and compares descriptors and class loaders. Results
136 // should be compared for a matching class descriptor and class loader.
137 typedef HashSet<TableSlot,
138 TableSlotEmptyFn,
Vladimir Markoeae6a712021-02-05 13:33:28 +0000139 ClassDescriptorHash,
140 ClassDescriptorEquals,
Mathieu Chartier58c3f6a2016-12-01 14:21:11 -0800141 TrackingAllocator<TableSlot, kAllocatorTagClassTable>> ClassSet;
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800142
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700143 ClassTable();
144
145 // Used by image writer for checking.
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700146 bool Contains(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700147 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700148 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700149
150 // Freeze the current class tables by allocating a new table and never updating or modifying the
151 // existing table. This helps prevents dirty pages after caused by inserting after zygote fork.
152 void FreezeSnapshot()
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700153 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700154 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700155
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000156 // Returns the number of classes in previous snapshots defined by `defining_loader`.
Vladimir Markoc5798bf2016-12-09 10:20:54 +0000157 size_t NumZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
158 REQUIRES(!lock_)
159 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700160
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000161 // Returns all off the classes in the lastest snapshot defined by `defining_loader`.
Vladimir Markoc5798bf2016-12-09 10:20:54 +0000162 size_t NumNonZygoteClasses(ObjPtr<mirror::ClassLoader> defining_loader) const
163 REQUIRES(!lock_)
164 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700165
Vladimir Marko8d6768d2017-03-14 10:13:21 +0000166 // Returns the number of classes in previous snapshots no matter the defining loader.
167 size_t NumReferencedZygoteClasses() const
168 REQUIRES(!lock_)
169 REQUIRES_SHARED(Locks::mutator_lock_);
170
171 // Returns all off the classes in the lastest snapshot no matter the defining loader.
172 size_t NumReferencedNonZygoteClasses() const
173 REQUIRES(!lock_)
174 REQUIRES_SHARED(Locks::mutator_lock_);
175
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700176 // Update a class in the table with the new class. Returns the existing class which was replaced.
Vladimir Marko1fe58392019-04-10 16:14:56 +0100177 ObjPtr<mirror::Class> UpdateClass(const char* descriptor,
178 ObjPtr<mirror::Class> new_klass,
179 size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700180 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700181 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700182
Mathieu Chartiere4275c02015-08-06 15:34:15 -0700183 // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock.
184 template<class Visitor>
185 void VisitRoots(Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700186 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700187 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700188 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700189
Mathieu Chartiere4275c02015-08-06 15:34:15 -0700190 template<class Visitor>
191 void VisitRoots(const Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700192 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700193 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700194 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700195
Mathieu Chartier1aa8ec22016-02-01 10:34:47 -0800196 // Stops visit if the visitor returns false.
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300197 template <typename Visitor, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
Mathieu Chartier1aa8ec22016-02-01 10:34:47 -0800198 bool Visit(Visitor& visitor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700199 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700200 REQUIRES_SHARED(Locks::mutator_lock_);
Alexey Grebenkinbe4c2bd2018-02-01 19:09:59 +0300201 template <typename Visitor, ReadBarrierOption kReadBarrierOption = kWithReadBarrier>
Mathieu Chartierdb70ce52016-12-12 11:06:59 -0800202 bool Visit(const Visitor& visitor)
203 REQUIRES(!lock_)
204 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700205
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800206 // Return the first class that matches the descriptor. Returns null if there are none.
Vladimir Marko1fe58392019-04-10 16:14:56 +0100207 ObjPtr<mirror::Class> Lookup(const char* descriptor, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700208 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700209 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700210
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800211 // Return the first class that matches the descriptor of klass. Returns null if there are none.
Vladimir Marko1fe58392019-04-10 16:14:56 +0100212 ObjPtr<mirror::Class> LookupByDescriptor(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700213 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700214 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800215
Vladimir Markocd556b02017-02-03 11:47:34 +0000216 // Try to insert a class and return the inserted class if successful. If another class
217 // with the same descriptor is already in the table, return the existing entry.
218 ObjPtr<mirror::Class> TryInsert(ObjPtr<mirror::Class> klass)
219 REQUIRES(!lock_)
220 REQUIRES_SHARED(Locks::mutator_lock_);
221
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700222 void Insert(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700223 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700224 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700225
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700226 void InsertWithHash(ObjPtr<mirror::Class> klass, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700227 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700228 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700229
230 // Returns true if the class was found and removed, false otherwise.
231 bool Remove(const char* descriptor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700232 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700233 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier00310e02015-10-17 12:46:42 -0700234
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700235 // Return true if we inserted the strong root, false if it already exists.
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700236 bool InsertStrongRoot(ObjPtr<mirror::Object> obj)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700237 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700238 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700239
Vladimir Marko1bc4b172016-10-24 16:53:39 +0000240 // Return true if we inserted the oat file, false if it already exists.
241 bool InsertOatFile(const OatFile* oat_file)
242 REQUIRES(!lock_)
243 REQUIRES_SHARED(Locks::mutator_lock_);
244
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800245 // Read a table from ptr and put it at the front of the class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800246 size_t ReadFromMemory(uint8_t* ptr)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700247 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700248 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800249
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800250 // Add a class set to the front of classes.
251 void AddClassSet(ClassSet&& set)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700252 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700253 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700254
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700255 // Clear strong roots (other than classes themselves).
256 void ClearStrongRoots()
257 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700258 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700259
Mathieu Chartier72041a02017-07-14 18:23:25 -0700260 // Filter strong roots (other than classes themselves).
261 template <typename Filter>
262 void RemoveStrongRoots(const Filter& filter)
263 REQUIRES(!lock_)
264 REQUIRES_SHARED(Locks::mutator_lock_);
265
Mathieu Chartier92091bd2016-05-10 18:13:20 -0700266 ReaderWriterMutex& GetLock() {
267 return lock_;
268 }
269
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800270 private:
Vladimir Markoc5798bf2016-12-09 10:20:54 +0000271 size_t CountDefiningLoaderClasses(ObjPtr<mirror::ClassLoader> defining_loader,
272 const ClassSet& set) const
273 REQUIRES(lock_)
274 REQUIRES_SHARED(Locks::mutator_lock_);
275
Vladimir Marko1bc4b172016-10-24 16:53:39 +0000276 // Return true if we inserted the oat file, false if it already exists.
277 bool InsertOatFileLocked(const OatFile* oat_file)
278 REQUIRES(lock_)
279 REQUIRES_SHARED(Locks::mutator_lock_);
280
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700281 // Lock to guard inserting and removing.
282 mutable ReaderWriterMutex lock_;
Mathieu Chartier90ef3db2015-08-04 15:19:41 -0700283 // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700284 std::vector<ClassSet> classes_ GUARDED_BY(lock_);
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700285 // Extra strong roots that can be either dex files or dex caches. Dex files used by the class
286 // loader which may not be owned by the class loader must be held strongly live. Also dex caches
287 // are held live to prevent them being unloading once they have classes in them.
288 std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_);
Vladimir Markoaad75c62016-10-03 08:46:48 +0000289 // Keep track of oat files with GC roots associated with dex caches in `strong_roots_`.
290 std::vector<const OatFile*> oat_files_ GUARDED_BY(lock_);
Mathieu Chartier496577f2016-09-20 15:33:31 -0700291
Vladimir Marko74527972016-11-29 15:57:32 +0000292 friend class linker::ImageWriter; // for InsertWithoutLocks.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700293};
294
295} // namespace art
296
297#endif // ART_RUNTIME_CLASS_TABLE_H_