• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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   void InsertWithoutLocks(mirror::Class* klass) NO_THREAD_SAFETY_ANALYSIS;
167 
168   // Lock to guard inserting and removing.
169   mutable ReaderWriterMutex lock_;
170   // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
171   std::vector<ClassSet> classes_ GUARDED_BY(lock_);
172   // Extra strong roots that can be either dex files or dex caches. Dex files used by the class
173   // loader which may not be owned by the class loader must be held strongly live. Also dex caches
174   // are held live to prevent them being unloading once they have classes in them.
175   std::vector<GcRoot<mirror::Object>> strong_roots_ GUARDED_BY(lock_);
176 
177   friend class ImageWriter;  // for InsertWithoutLocks.
178 };
179 
180 }  // namespace art
181 
182 #endif  // ART_RUNTIME_CLASS_TABLE_H_
183