blob: af25131ab4296efbe7dc135171227ef38b9b1459 [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
39typedef bool (ClassVisitor)(mirror::Class* c, void* arg);
40
41// Each loader has a ClassTable
42class ClassTable {
43 public:
44 ClassTable();
45
46 // Used by image writer for checking.
47 bool Contains(mirror::Class* klass)
48 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
49
50 // Freeze the current class tables by allocating a new table and never updating or modifying the
51 // existing table. This helps prevents dirty pages after caused by inserting after zygote fork.
52 void FreezeSnapshot()
53 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
54
55 // Returns the number of classes in previous snapshots.
56 size_t NumZygoteClasses() const REQUIRES(Locks::classlinker_classes_lock_);
57
58 // Returns all off the classes in the lastest snapshot.
59 size_t NumNonZygoteClasses() const REQUIRES(Locks::classlinker_classes_lock_);
60
61 // Update a class in the table with the new class. Returns the existing class which was replaced.
62 mirror::Class* UpdateClass(const char* descriptor, mirror::Class* new_klass, size_t hash)
63 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
64
65 void VisitRoots(RootVisitor* visitor, VisitRootFlags flags)
66 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
67
68 // Return false if the callback told us to exit.
69 bool Visit(ClassVisitor* visitor, void* arg)
70 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
71
72 mirror::Class* Lookup(const char* descriptor, size_t hash)
73 SHARED_REQUIRES(Locks::classlinker_classes_lock_, Locks::mutator_lock_);
74
75 void Insert(mirror::Class* klass)
76 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
77 void InsertWithHash(mirror::Class* klass, size_t hash)
78 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
79
80 // Returns true if the class was found and removed, false otherwise.
81 bool Remove(const char* descriptor)
82 REQUIRES(Locks::classlinker_classes_lock_) SHARED_REQUIRES(Locks::mutator_lock_);
83
84 private:
85 class ClassDescriptorHashEquals {
86 public:
87 // Same class loader and descriptor.
88 std::size_t operator()(const GcRoot<mirror::Class>& root) const NO_THREAD_SAFETY_ANALYSIS;
89 bool operator()(const GcRoot<mirror::Class>& a, const GcRoot<mirror::Class>& b) const
90 NO_THREAD_SAFETY_ANALYSIS;;
91 // Same descriptor.
92 bool operator()(const GcRoot<mirror::Class>& a, const char* descriptor) const
93 NO_THREAD_SAFETY_ANALYSIS;
94 std::size_t operator()(const char* descriptor) const NO_THREAD_SAFETY_ANALYSIS;
95 };
96 class GcRootEmptyFn {
97 public:
98 void MakeEmpty(GcRoot<mirror::Class>& item) const {
99 item = GcRoot<mirror::Class>();
100 }
101 bool IsEmpty(const GcRoot<mirror::Class>& item) const {
102 return item.IsNull();
103 }
104 };
105 // hash set which hashes class descriptor, and compares descriptors nad class loaders. Results
106 // should be compared for a matching Class descriptor and class loader.
107 typedef HashSet<GcRoot<mirror::Class>, GcRootEmptyFn, ClassDescriptorHashEquals,
108 ClassDescriptorHashEquals, TrackingAllocator<GcRoot<mirror::Class>, kAllocatorTagClassTable>>
109 ClassSet;
110
111 // TODO: shard lock to have one per class loader.
112 std::vector<ClassSet> classes_ GUARDED_BY(Locks::classlinker_classes_lock_);
113};
114
115} // namespace art
116
117#endif // ART_RUNTIME_CLASS_TABLE_H_