Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/classfile/dictionary.hpp
40950 views
1
/*
2
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*
23
*/
24
25
#ifndef SHARE_CLASSFILE_DICTIONARY_HPP
26
#define SHARE_CLASSFILE_DICTIONARY_HPP
27
28
#include "oops/instanceKlass.hpp"
29
#include "oops/oop.hpp"
30
#include "oops/oopHandle.hpp"
31
#include "utilities/hashtable.hpp"
32
#include "utilities/ostream.hpp"
33
34
class DictionaryEntry;
35
class ProtectionDomainEntry;
36
template <typename T> class GrowableArray;
37
38
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
39
// The data structure for the class loader data dictionaries.
40
41
class Dictionary : public Hashtable<InstanceKlass*, mtClass> {
42
friend class VMStructs;
43
44
static bool _some_dictionary_needs_resizing;
45
bool _resizable;
46
bool _needs_resizing;
47
void check_if_needs_resize();
48
49
ClassLoaderData* _loader_data; // backpointer to owning loader
50
ClassLoaderData* loader_data() const { return _loader_data; }
51
52
DictionaryEntry* get_entry(int index, unsigned int hash, Symbol* name);
53
54
public:
55
Dictionary(ClassLoaderData* loader_data, int table_size, bool resizable = false);
56
Dictionary(ClassLoaderData* loader_data, int table_size, HashtableBucket<mtClass>* t, int number_of_entries, bool resizable = false);
57
~Dictionary();
58
59
static bool does_any_dictionary_needs_resizing();
60
bool resize_if_needed();
61
62
void add_klass(unsigned int hash, Symbol* class_name, InstanceKlass* obj);
63
64
InstanceKlass* find_class(unsigned int hash, Symbol* name);
65
66
void classes_do(void f(InstanceKlass*));
67
void classes_do(void f(InstanceKlass*, TRAPS), TRAPS);
68
void all_entries_do(KlassClosure* closure);
69
void classes_do(MetaspaceClosure* it);
70
71
void clean_cached_protection_domains(GrowableArray<ProtectionDomainEntry*>* delete_list);
72
73
// Protection domains
74
InstanceKlass* find(unsigned int hash, Symbol* name, Handle protection_domain);
75
void validate_protection_domain(unsigned int name_hash,
76
InstanceKlass* klass,
77
Handle class_loader,
78
Handle protection_domain,
79
TRAPS);
80
81
void print_on(outputStream* st) const;
82
void verify();
83
84
private:
85
DictionaryEntry* new_entry(unsigned int hash, InstanceKlass* klass);
86
87
DictionaryEntry* bucket(int i) const {
88
return (DictionaryEntry*)Hashtable<InstanceKlass*, mtClass>::bucket(i);
89
}
90
91
// The following method is not MT-safe and must be done under lock.
92
DictionaryEntry** bucket_addr(int i) {
93
return (DictionaryEntry**)Hashtable<InstanceKlass*, mtClass>::bucket_addr(i);
94
}
95
96
void free_entry(DictionaryEntry* entry);
97
98
bool is_valid_protection_domain(unsigned int hash,
99
Symbol* name,
100
Handle protection_domain);
101
void add_protection_domain(int index, unsigned int hash,
102
InstanceKlass* klass,
103
Handle protection_domain);
104
};
105
106
// An entry in the class loader data dictionaries, this describes a class as
107
// { InstanceKlass*, protection_domain }.
108
109
class DictionaryEntry : public HashtableEntry<InstanceKlass*, mtClass> {
110
friend class VMStructs;
111
private:
112
// Contains the set of approved protection domains that can access
113
// this dictionary entry.
114
//
115
// [Note that C.protection_domain(), which is stored in the java.lang.Class
116
// mirror of C, is NOT the same as PD]
117
//
118
// If an entry for PD exists in the list, it means that
119
// it is okay for a caller class to reference the class in this dictionary entry.
120
//
121
// The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
122
// It is essentially a cache to avoid repeated Java up-calls to
123
// ClassLoader.checkPackageAccess().
124
//
125
ProtectionDomainEntry* volatile _pd_set;
126
127
public:
128
// Tells whether a protection is in the approved set.
129
bool contains_protection_domain(oop protection_domain) const;
130
// Adds a protection domain to the approved set.
131
void add_protection_domain(ClassLoaderData* loader_data, Handle protection_domain);
132
133
InstanceKlass* instance_klass() const { return literal(); }
134
InstanceKlass** klass_addr() { return (InstanceKlass**)literal_addr(); }
135
136
DictionaryEntry* next() const {
137
return (DictionaryEntry*)HashtableEntry<InstanceKlass*, mtClass>::next();
138
}
139
140
DictionaryEntry** next_addr() {
141
return (DictionaryEntry**)HashtableEntry<InstanceKlass*, mtClass>::next_addr();
142
}
143
144
ProtectionDomainEntry* pd_set_acquire() const { return Atomic::load_acquire(&_pd_set); }
145
void release_set_pd_set(ProtectionDomainEntry* entry) { Atomic::release_store(&_pd_set, entry); }
146
147
// Tells whether the initiating class' protection domain can access the klass in this entry
148
inline bool is_valid_protection_domain(Handle protection_domain);
149
void verify_protection_domain_set();
150
151
void print_count(outputStream *st);
152
void verify();
153
};
154
155
// Entry in a SymbolPropertyTable, mapping a single Symbol*
156
// to a managed and an unmanaged pointer.
157
class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
158
friend class VMStructs;
159
private:
160
intptr_t _symbol_mode; // secondary key
161
Method* _method;
162
OopHandle _method_type;
163
164
public:
165
Symbol* symbol() const { return literal(); }
166
167
intptr_t symbol_mode() const { return _symbol_mode; }
168
void set_symbol_mode(intptr_t m) { _symbol_mode = m; }
169
170
Method* method() const { return _method; }
171
void set_method(Method* p) { _method = p; }
172
173
oop method_type() const;
174
void set_method_type(oop p);
175
176
// We need to clear the OopHandle because these hashtable entries are not constructed properly.
177
void clear_method_type() { _method_type = OopHandle(); }
178
179
void free_entry();
180
181
SymbolPropertyEntry* next() const {
182
return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();
183
}
184
185
SymbolPropertyEntry** next_addr() {
186
return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr();
187
}
188
189
void print_entry(outputStream* st) const;
190
};
191
192
// A system-internal mapping of symbols to pointers, both managed
193
// and unmanaged. Used to record the auto-generation of each method
194
// MethodHandle.invoke(S)T, for all signatures (S)T.
195
class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
196
friend class VMStructs;
197
private:
198
// The following method is not MT-safe and must be done under lock.
199
SymbolPropertyEntry** bucket_addr(int i) {
200
return (SymbolPropertyEntry**) Hashtable<Symbol*, mtSymbol>::bucket_addr(i);
201
}
202
203
void add_entry(int index, SymbolPropertyEntry* new_entry) {
204
ShouldNotReachHere();
205
}
206
void set_entry(int index, SymbolPropertyEntry* new_entry) {
207
ShouldNotReachHere();
208
}
209
210
SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
211
SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol);
212
// Hashtable with Symbol* literal must increment and decrement refcount.
213
symbol->increment_refcount();
214
entry->set_symbol_mode(symbol_mode);
215
entry->set_method(NULL);
216
entry->clear_method_type();
217
return entry;
218
}
219
220
public:
221
SymbolPropertyTable(int table_size);
222
SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);
223
224
void free_entry(SymbolPropertyEntry* entry);
225
226
unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
227
// Use the regular identity_hash.
228
return Hashtable<Symbol*, mtSymbol>::compute_hash(sym) ^ symbol_mode;
229
}
230
231
int index_for(Symbol* name, intptr_t symbol_mode) {
232
return hash_to_index(compute_hash(name, symbol_mode));
233
}
234
235
// need not be locked; no state change
236
SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
237
238
// must be done under SystemDictionary_lock
239
SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
240
241
void methods_do(void f(Method*));
242
243
void verify();
244
245
SymbolPropertyEntry* bucket(int i) {
246
return (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::bucket(i);
247
}
248
};
249
#endif // SHARE_CLASSFILE_DICTIONARY_HPP
250
251