blob: 558c144013d98c79405846e80b8ec739b1f8003e [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"
28#include "dex_file.h"
29#include "gc_root.h"
Mathieu Chartierbc5a7952016-10-17 15:46:31 -070030#include "obj_ptr.h"
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070031#include "object_callbacks.h"
32#include "runtime.h"
33
34namespace art {
35
Vladimir Markoaad75c62016-10-03 08:46:48 +000036class OatFile;
37
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070038namespace mirror {
39 class ClassLoader;
40} // namespace mirror
41
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070042// Each loader has a ClassTable
43class ClassTable {
44 public:
Mathieu Chartier88027bd2016-03-02 16:08:31 -080045 class ClassDescriptorHashEquals {
46 public:
47 // uint32_t for cross compilation.
48 uint32_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS;
49 // Same class loader and descriptor.
50 bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const
Mathieu Chartier6beced42016-11-15 15:51:31 -080051 NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartier88027bd2016-03-02 16:08:31 -080052 // Same descriptor.
53 bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const
54 NO_THREAD_SAFETY_ANALYSIS;
55 // uint32_t for cross compilation.
56 uint32_t operator()(const char* descriptor) const NO_THREAD_SAFETY_ANALYSIS;
57 };
58 class GcRootEmptyFn {
59 public:
60 void MakeEmpty(GcRoot<mirror::Class>& item) const {
61 item = GcRoot<mirror::Class>();
62 }
63 bool IsEmpty(const GcRoot<mirror::Class>& item) const {
64 return item.IsNull();
65 }
66 };
67 // hash set which hashes class descriptor, and compares descriptors and class loaders. Results
68 // should be compared for a matching Class descriptor and class loader.
69 typedef HashSet<GcRoot<mirror::Class>, GcRootEmptyFn, ClassDescriptorHashEquals,
70 ClassDescriptorHashEquals, TrackingAllocator<GcRoot<mirror::Class>, kAllocatorTagClassTable>>
71 ClassSet;
72
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070073 ClassTable();
74
75 // Used by image writer for checking.
Mathieu Chartier28357fa2016-10-18 16:27:40 -070076 bool Contains(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070077 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070078 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070079
80 // Freeze the current class tables by allocating a new table and never updating or modifying the
81 // existing table. This helps prevents dirty pages after caused by inserting after zygote fork.
82 void FreezeSnapshot()
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070083 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070084 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070085
86 // Returns the number of classes in previous snapshots.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070087 size_t NumZygoteClasses() const REQUIRES(!lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070088
89 // Returns all off the classes in the lastest snapshot.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070090 size_t NumNonZygoteClasses() const REQUIRES(!lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070091
92 // Update a class in the table with the new class. Returns the existing class which was replaced.
93 mirror::Class* UpdateClass(const char* descriptor, mirror::Class* new_klass, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070094 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -070095 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070096
Mathieu Chartiere4275c02015-08-06 15:34:15 -070097 // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock.
98 template<class Visitor>
99 void VisitRoots(Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700100 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700101 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700102 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700103
Mathieu Chartiere4275c02015-08-06 15:34:15 -0700104 template<class Visitor>
105 void VisitRoots(const Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700106 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700107 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700108 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700109
Mathieu Chartier1aa8ec22016-02-01 10:34:47 -0800110 // Stops visit if the visitor returns false.
111 template <typename Visitor>
112 bool Visit(Visitor& visitor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700113 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700114 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700115
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800116 // Return the first class that matches the descriptor. Returns null if there are none.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700117 mirror::Class* Lookup(const char* descriptor, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700118 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700119 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700120
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800121 // Return the first class that matches the descriptor of klass. Returns null if there are none.
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700122 mirror::Class* LookupByDescriptor(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700123 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700124 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800125
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700126 void Insert(ObjPtr<mirror::Class> klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700127 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700128 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700129
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700130 void InsertWithHash(ObjPtr<mirror::Class> klass, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700131 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700132 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700133
134 // Returns true if the class was found and removed, false otherwise.
135 bool Remove(const char* descriptor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700136 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700137 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier00310e02015-10-17 12:46:42 -0700138
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700139 // Return true if we inserted the strong root, false if it already exists.
Mathieu Chartierbc5a7952016-10-17 15:46:31 -0700140 bool InsertStrongRoot(ObjPtr<mirror::Object> obj)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700141 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700142 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700143
Vladimir Marko1bc4b172016-10-24 16:53:39 +0000144 // Return true if we inserted the oat file, false if it already exists.
145 bool InsertOatFile(const OatFile* oat_file)
146 REQUIRES(!lock_)
147 REQUIRES_SHARED(Locks::mutator_lock_);
148
Mathieu Chartier41dc8ce2015-12-04 15:07:48 -0800149 // Combines all of the tables into one class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800150 size_t WriteToMemory(uint8_t* ptr) const
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700151 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700152 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800153
154 // Read a table from ptr and put it at the front of the class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800155 size_t ReadFromMemory(uint8_t* ptr)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700156 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700157 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800158
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800159 // Add a class set to the front of classes.
160 void AddClassSet(ClassSet&& set)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700161 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700162 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700163
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700164 // Clear strong roots (other than classes themselves).
165 void ClearStrongRoots()
166 REQUIRES(!lock_)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700167 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700168
Mathieu Chartier92091bd2016-05-10 18:13:20 -0700169 ReaderWriterMutex& GetLock() {
170 return lock_;
171 }
172
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800173 private:
Mathieu Chartier28357fa2016-10-18 16:27:40 -0700174 void InsertWithoutLocks(ObjPtr<mirror::Class> klass) NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartier496577f2016-09-20 15:33:31 -0700175
Vladimir Marko1bc4b172016-10-24 16:53:39 +0000176 // Return true if we inserted the oat file, false if it already exists.
177 bool InsertOatFileLocked(const OatFile* oat_file)
178 REQUIRES(lock_)
179 REQUIRES_SHARED(Locks::mutator_lock_);
180
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700181 // Lock to guard inserting and removing.
182 mutable ReaderWriterMutex lock_;
Mathieu Chartier90ef3db2015-08-04 15:19:41 -0700183 // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700184 std::vector<ClassSet> classes_ GUARDED_BY(lock_);
Mathieu Chartierc9dbb1d2016-06-03 17:47:32 -0700185 // Extra strong roots that can be either dex files or dex caches. Dex files used by the class
186 // loader which may not be owned by the class loader must be held strongly live. Also dex caches
187 // are held live to prevent them being unloading once they have classes in them.
188 std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_);
Vladimir Markoaad75c62016-10-03 08:46:48 +0000189 // Keep track of oat files with GC roots associated with dex caches in `strong_roots_`.
190 std::vector<const OatFile*> oat_files_ GUARDED_BY(lock_);
Mathieu Chartier496577f2016-09-20 15:33:31 -0700191
192 friend class ImageWriter; // for InsertWithoutLocks.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700193};
194
195} // namespace art
196
197#endif // ART_RUNTIME_CLASS_TABLE_H_