1 /* 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" 30 #include "object_callbacks.h" 31 #include "runtime.h" 32 33 namespace art { 34 35 namespace mirror { 36 class ClassLoader; 37 } // namespace mirror 38 39 // Each loader has a ClassTable 40 class ClassTable { 41 public: 42 class ClassDescriptorHashEquals { 43 public: 44 // uint32_t for cross compilation. 45 uint32_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS; 46 // Same class loader and descriptor. 47 bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const 48 NO_THREAD_SAFETY_ANALYSIS;; 49 // Same descriptor. 50 bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const 51 NO_THREAD_SAFETY_ANALYSIS; 52 // uint32_t for cross compilation. 53 uint32_t operator()(const char* descriptor) const NO_THREAD_SAFETY_ANALYSIS; 54 }; 55 class GcRootEmptyFn { 56 public: MakeEmpty(GcRoot<mirror::Class> & item)57 void MakeEmpty(GcRoot<mirror::Class>& item) const { 58 item = GcRoot<mirror::Class>(); 59 } IsEmpty(const GcRoot<mirror::Class> & item)60 bool IsEmpty(const GcRoot<mirror::Class>& item) const { 61 return item.IsNull(); 62 } 63 }; 64 // hash set which hashes class descriptor, and compares descriptors and class loaders. Results 65 // should be compared for a matching Class descriptor and class loader. 66 typedef HashSet<GcRoot<mirror::Class>, GcRootEmptyFn, ClassDescriptorHashEquals, 67 ClassDescriptorHashEquals, TrackingAllocator<GcRoot<mirror::Class>, kAllocatorTagClassTable>> 68 ClassSet; 69 70 ClassTable(); 71 72 // Used by image writer for checking. 73 bool Contains(mirror::Class* klass) 74 REQUIRES(!lock_) 75 SHARED_REQUIRES(Locks::mutator_lock_); 76 77 // Freeze the current class tables by allocating a new table and never updating or modifying the 78 // existing table. This helps prevents dirty pages after caused by inserting after zygote fork. 79 void FreezeSnapshot() 80 REQUIRES(!lock_) 81 SHARED_REQUIRES(Locks::mutator_lock_); 82 83 // Returns the number of classes in previous snapshots. 84 size_t NumZygoteClasses() const REQUIRES(!lock_); 85 86 // Returns all off the classes in the lastest snapshot. 87 size_t NumNonZygoteClasses() const REQUIRES(!lock_); 88 89 // Update a class in the table with the new class. Returns the existing class which was replaced. 90 mirror::Class* UpdateClass(const char* descriptor, mirror::Class* new_klass, size_t hash) 91 REQUIRES(!lock_) 92 SHARED_REQUIRES(Locks::mutator_lock_); 93 94 // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock. 95 template<class Visitor> 96 void VisitRoots(Visitor& visitor) 97 NO_THREAD_SAFETY_ANALYSIS 98 REQUIRES(!lock_) 99 SHARED_REQUIRES(Locks::mutator_lock_); 100 101 template<class Visitor> 102 void VisitRoots(const Visitor& visitor) 103 NO_THREAD_SAFETY_ANALYSIS 104 REQUIRES(!lock_) 105 SHARED_REQUIRES(Locks::mutator_lock_); 106 107 // Stops visit if the visitor returns false. 108 template <typename Visitor> 109 bool Visit(Visitor& visitor) 110 REQUIRES(!lock_) 111 SHARED_REQUIRES(Locks::mutator_lock_); 112 113 // Return the first class that matches the descriptor. Returns null if there are none. 114 mirror::Class* Lookup(const char* descriptor, size_t hash) 115 REQUIRES(!lock_) 116 SHARED_REQUIRES(Locks::mutator_lock_); 117 118 // Return the first class that matches the descriptor of klass. Returns null if there are none. 119 mirror::Class* LookupByDescriptor(mirror::Class* klass) 120 REQUIRES(!lock_) 121 SHARED_REQUIRES(Locks::mutator_lock_); 122 123 void Insert(mirror::Class* klass) 124 REQUIRES(!lock_) 125 SHARED_REQUIRES(Locks::mutator_lock_); 126 127 void InsertWithHash(mirror::Class* klass, size_t hash) 128 REQUIRES(!lock_) 129 SHARED_REQUIRES(Locks::mutator_lock_); 130 131 // Returns true if the class was found and removed, false otherwise. 132 bool Remove(const char* descriptor) 133 REQUIRES(!lock_) 134 SHARED_REQUIRES(Locks::mutator_lock_); 135 136 // Return true if we inserted the strong root, false if it already exists. 137 bool InsertStrongRoot(mirror::Object* obj) 138 REQUIRES(!lock_) 139 SHARED_REQUIRES(Locks::mutator_lock_); 140 141 // Combines all of the tables into one class set. 142 size_t WriteToMemory(uint8_t* ptr) const 143 REQUIRES(!lock_) 144 SHARED_REQUIRES(Locks::mutator_lock_); 145 146 // Read a table from ptr and put it at the front of the class set. 147 size_t ReadFromMemory(uint8_t* ptr) 148 REQUIRES(!lock_) 149 SHARED_REQUIRES(Locks::mutator_lock_); 150 151 // Add a class set to the front of classes. 152 void AddClassSet(ClassSet&& set) 153 REQUIRES(!lock_) 154 SHARED_REQUIRES(Locks::mutator_lock_); 155 156 // Clear strong roots (other than classes themselves). 157 void ClearStrongRoots() 158 REQUIRES(!lock_) 159 SHARED_REQUIRES(Locks::mutator_lock_); 160 GetLock()161 ReaderWriterMutex& GetLock() { 162 return lock_; 163 } 164 165 private: 166 // Lock to guard inserting and removing. 167 mutable ReaderWriterMutex lock_; 168 // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot. 169 std::vector<ClassSet> classes_ GUARDED_BY(lock_); 170 // Extra strong roots that can be either dex files or dex caches. Dex files used by the class 171 // loader which may not be owned by the class loader must be held strongly live. Also dex caches 172 // are held live to prevent them being unloading once they have classes in them. 173 std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_); 174 }; 175 176 } // namespace art 177 178 #endif // ART_RUNTIME_CLASS_TABLE_H_ 179