blob: 686381d35cb472184e9c13d7ca6976ed77b1933c [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"
30#include "object_callbacks.h"
31#include "runtime.h"
32
33namespace art {
34
35namespace mirror {
36 class ClassLoader;
37} // namespace mirror
38
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070039// Each loader has a ClassTable
40class ClassTable {
41 public:
Mathieu Chartier88027bd2016-03-02 16:08:31 -080042 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:
57 void MakeEmpty(GcRoot<mirror::Class>& item) const {
58 item = GcRoot<mirror::Class>();
59 }
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
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070070 ClassTable();
71
72 // Used by image writer for checking.
73 bool Contains(mirror::Class* klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070074 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -070075 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070076
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()
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070080 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -070081 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070082
83 // Returns the number of classes in previous snapshots.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070084 size_t NumZygoteClasses() const REQUIRES(!lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070085
86 // Returns all off the classes in the lastest snapshot.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070087 size_t NumNonZygoteClasses() const REQUIRES(!lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070088
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)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070091 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -070092 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070093
Mathieu Chartiere4275c02015-08-06 15:34:15 -070094 // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock.
95 template<class Visitor>
96 void VisitRoots(Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -070097 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -070098 REQUIRES(!lock_)
99 SHARED_REQUIRES(Locks::mutator_lock_);
100
Mathieu Chartiere4275c02015-08-06 15:34:15 -0700101 template<class Visitor>
102 void VisitRoots(const Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700103 NO_THREAD_SAFETY_ANALYSIS
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700104 REQUIRES(!lock_)
105 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700106
Mathieu Chartier1aa8ec22016-02-01 10:34:47 -0800107 // Stops visit if the visitor returns false.
108 template <typename Visitor>
109 bool Visit(Visitor& visitor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700110 REQUIRES(!lock_)
111 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700112
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800113 // Return the first class that matches the descriptor. Returns null if there are none.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700114 mirror::Class* Lookup(const char* descriptor, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700115 REQUIRES(!lock_)
116 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700117
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800118 // Return the first class that matches the descriptor of klass. Returns null if there are none.
119 mirror::Class* LookupByDescriptor(mirror::Class* klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700120 REQUIRES(!lock_)
121 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800122
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700123 void Insert(mirror::Class* klass)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700124 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700125 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700126
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700127 void InsertWithHash(mirror::Class* klass, size_t hash)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700128 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700129 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700130
131 // Returns true if the class was found and removed, false otherwise.
132 bool Remove(const char* descriptor)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700133 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700134 SHARED_REQUIRES(Locks::mutator_lock_);
135
136 // Return true if we inserted the dex file, false if it already exists.
137 bool InsertDexFile(mirror::Object* dex_file)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700138 REQUIRES(!lock_)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700139 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700140
Mathieu Chartier41dc8ce2015-12-04 15:07:48 -0800141 // Combines all of the tables into one class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800142 size_t WriteToMemory(uint8_t* ptr) const
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700143 REQUIRES(!lock_)
144 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800145
146 // Read a table from ptr and put it at the front of the class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800147 size_t ReadFromMemory(uint8_t* ptr)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700148 REQUIRES(!lock_)
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800149 SHARED_REQUIRES(Locks::mutator_lock_);
150
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800151 // Add a class set to the front of classes.
152 void AddClassSet(ClassSet&& set)
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700153 REQUIRES(!lock_)
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800154 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700155
Mathieu Chartier92091bd2016-05-10 18:13:20 -0700156 ReaderWriterMutex& GetLock() {
157 return lock_;
158 }
159
Mathieu Chartier88027bd2016-03-02 16:08:31 -0800160 private:
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700161 // Lock to guard inserting and removing.
162 mutable ReaderWriterMutex lock_;
Mathieu Chartier90ef3db2015-08-04 15:19:41 -0700163 // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700164 std::vector<ClassSet> classes_ GUARDED_BY(lock_);
Mathieu Chartier00310e02015-10-17 12:46:42 -0700165 // Dex files used by the class loader which may not be owned by the class loader. We keep these
166 // live so that we do not have issues closing any of the dex files.
Mathieu Chartier1609e3a2016-04-05 14:36:57 -0700167 std::vector<GcRoot<mirror::Object>> dex_files_ GUARDED_BY(lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700168};
169
170} // namespace art
171
172#endif // ART_RUNTIME_CLASS_TABLE_H_