blob: 0b420352c341891702a52ee232a33262e0f73616 [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 Chartiere0671ce2015-07-28 17:23:28 -070039class ClassVisitor {
40 public:
41 virtual ~ClassVisitor() {}
42 // Return true to continue visiting.
43 virtual bool Visit(mirror::Class* klass) = 0;
44};
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070045
46// Each loader has a ClassTable
47class ClassTable {
48 public:
49 ClassTable();
50
51 // Used by image writer for checking.
52 bool Contains(mirror::Class* klass)
Mathieu Chartier00310e02015-10-17 12:46:42 -070053 REQUIRES(Locks::classlinker_classes_lock_)
54 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070055
56 // Freeze the current class tables by allocating a new table and never updating or modifying the
57 // existing table. This helps prevents dirty pages after caused by inserting after zygote fork.
58 void FreezeSnapshot()
Mathieu Chartier00310e02015-10-17 12:46:42 -070059 REQUIRES(Locks::classlinker_classes_lock_)
60 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070061
62 // Returns the number of classes in previous snapshots.
Mathieu Chartier9b1c71e2015-09-02 18:51:54 -070063 size_t NumZygoteClasses() const SHARED_REQUIRES(Locks::classlinker_classes_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070064
65 // Returns all off the classes in the lastest snapshot.
Mathieu Chartier9b1c71e2015-09-02 18:51:54 -070066 size_t NumNonZygoteClasses() const SHARED_REQUIRES(Locks::classlinker_classes_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070067
68 // Update a class in the table with the new class. Returns the existing class which was replaced.
69 mirror::Class* UpdateClass(const char* descriptor, mirror::Class* new_klass, size_t hash)
Mathieu Chartier00310e02015-10-17 12:46:42 -070070 REQUIRES(Locks::classlinker_classes_lock_)
71 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070072
Mathieu Chartiere4275c02015-08-06 15:34:15 -070073 // NO_THREAD_SAFETY_ANALYSIS for object marking requiring heap bitmap lock.
74 template<class Visitor>
75 void VisitRoots(Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -070076 NO_THREAD_SAFETY_ANALYSIS
77 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
Mathieu Chartiere4275c02015-08-06 15:34:15 -070078 template<class Visitor>
79 void VisitRoots(const Visitor& visitor)
Mathieu Chartier00310e02015-10-17 12:46:42 -070080 NO_THREAD_SAFETY_ANALYSIS
81 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070082
83 // Return false if the callback told us to exit.
Mathieu Chartiere0671ce2015-07-28 17:23:28 -070084 bool Visit(ClassVisitor* visitor)
Mathieu Chartier9b1c71e2015-09-02 18:51:54 -070085 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070086
Mathieu Chartierfbc31082016-01-24 11:59:56 -080087 // Return the first class that matches the descriptor. Returns null if there are none.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070088 mirror::Class* Lookup(const char* descriptor, size_t hash)
89 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
90
Mathieu Chartierfbc31082016-01-24 11:59:56 -080091 // Return the first class that matches the descriptor of klass. Returns null if there are none.
92 mirror::Class* LookupByDescriptor(mirror::Class* klass)
93 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
94
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070095 void Insert(mirror::Class* klass)
Mathieu Chartier00310e02015-10-17 12:46:42 -070096 REQUIRES(Locks::classlinker_classes_lock_)
97 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -070098 void InsertWithHash(mirror::Class* klass, size_t hash)
Mathieu Chartier00310e02015-10-17 12:46:42 -070099 REQUIRES(Locks::classlinker_classes_lock_)
100 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700101
102 // Returns true if the class was found and removed, false otherwise.
103 bool Remove(const char* descriptor)
Mathieu Chartier00310e02015-10-17 12:46:42 -0700104 REQUIRES(Locks::classlinker_classes_lock_)
105 SHARED_REQUIRES(Locks::mutator_lock_);
106
107 // Return true if we inserted the dex file, false if it already exists.
108 bool InsertDexFile(mirror::Object* dex_file)
109 REQUIRES(Locks::classlinker_classes_lock_)
110 SHARED_REQUIRES(Locks::mutator_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700111
Mathieu Chartier41dc8ce2015-12-04 15:07:48 -0800112 // Combines all of the tables into one class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800113 size_t WriteToMemory(uint8_t* ptr) const
Mathieu Chartier1f47b672016-01-07 16:29:01 -0800114 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800115
116 // Read a table from ptr and put it at the front of the class set.
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800117 size_t ReadFromMemory(uint8_t* ptr)
118 REQUIRES(Locks::classlinker_classes_lock_)
119 SHARED_REQUIRES(Locks::mutator_lock_);
120
Mathieu Chartierfbc31082016-01-24 11:59:56 -0800121 // Change the class loader of all the contained classes.
122 void SetClassLoader(mirror::ClassLoader* class_loader)
123 REQUIRES(Locks::classlinker_classes_lock_)
124 SHARED_REQUIRES(Locks::mutator_lock_);
125
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700126 private:
127 class ClassDescriptorHashEquals {
128 public:
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800129 // uint32_t for cross compilation.
130 uint32_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700131 // Same class loader and descriptor.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700132 bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const
133 NO_THREAD_SAFETY_ANALYSIS;;
134 // Same descriptor.
135 bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const
136 NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartier208a5cb2015-12-02 15:44:07 -0800137 // uint32_t for cross compilation.
138 uint32_t operator()(const char* descriptor) const NO_THREAD_SAFETY_ANALYSIS;
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700139 };
140 class GcRootEmptyFn {
141 public:
142 void MakeEmpty(GcRoot<mirror::Class>& item) const {
143 item = GcRoot<mirror::Class>();
144 }
145 bool IsEmpty(const GcRoot<mirror::Class>& item) const {
146 return item.IsNull();
147 }
148 };
Mathieu Chartier90ef3db2015-08-04 15:19:41 -0700149 // hash set which hashes class descriptor, and compares descriptors and class loaders. Results
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700150 // should be compared for a matching Class descriptor and class loader.
151 typedef HashSet<GcRoot<mirror::Class>, GcRootEmptyFn, ClassDescriptorHashEquals,
152 ClassDescriptorHashEquals, TrackingAllocator<GcRoot<mirror::Class>, kAllocatorTagClassTable>>
153 ClassSet;
154
155 // TODO: shard lock to have one per class loader.
Mathieu Chartier90ef3db2015-08-04 15:19:41 -0700156 // We have a vector to help prevent dirty pages after the zygote forks by calling FreezeSnapshot.
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700157 std::vector<ClassSet> classes_ GUARDED_BY(Locks::classlinker_classes_lock_);
Mathieu Chartier00310e02015-10-17 12:46:42 -0700158 // Dex files used by the class loader which may not be owned by the class loader. We keep these
159 // live so that we do not have issues closing any of the dex files.
160 std::vector<GcRoot<mirror::Object>> dex_files_ GUARDED_BY(Locks::classlinker_classes_lock_);
Mathieu Chartiercc5ebdf2015-07-27 11:19:43 -0700161};
162
163} // namespace art
164
165#endif // ART_RUNTIME_CLASS_TABLE_H_