1/*
2 * Copyright (c) 2003, 2016, 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_VM_CLASSFILE_DICTIONARY_HPP
26#define SHARE_VM_CLASSFILE_DICTIONARY_HPP
27
28#include "classfile/systemDictionary.hpp"
29#include "oops/instanceKlass.hpp"
30#include "oops/oop.hpp"
31#include "utilities/hashtable.hpp"
32#include "utilities/ostream.hpp"
33
34class DictionaryEntry;
35class PSPromotionManager;
36class ProtectionDomainCacheTable;
37class ProtectionDomainCacheEntry;
38class BoolObjectClosure;
39
40//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
41// The data structure for the system dictionary (and the shared system
42// dictionary).
43
44class Dictionary : public TwoOopHashtable<Klass*, mtClass> {
45  friend class VMStructs;
46private:
47  // current iteration index.
48  static int                    _current_class_index;
49  // pointer to the current hash table entry.
50  static DictionaryEntry*       _current_class_entry;
51
52  ProtectionDomainCacheTable*   _pd_cache_table;
53
54  DictionaryEntry* get_entry(int index, unsigned int hash,
55                             Symbol* name, ClassLoaderData* loader_data);
56
57protected:
58  DictionaryEntry* bucket(int i) const {
59    return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i);
60  }
61
62  // The following method is not MT-safe and must be done under lock.
63  DictionaryEntry** bucket_addr(int i) {
64    return (DictionaryEntry**)Hashtable<Klass*, mtClass>::bucket_addr(i);
65  }
66
67  void add_entry(int index, DictionaryEntry* new_entry) {
68    Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry);
69  }
70
71  static size_t entry_size();
72public:
73  Dictionary(int table_size);
74  Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
75
76  DictionaryEntry* new_entry(unsigned int hash, Klass* klass, ClassLoaderData* loader_data);
77
78  DictionaryEntry* new_entry();
79
80  void free_entry(DictionaryEntry* entry);
81
82  void add_klass(Symbol* class_name, ClassLoaderData* loader_data,KlassHandle obj);
83
84  Klass* find_class(int index, unsigned int hash,
85                      Symbol* name, ClassLoaderData* loader_data);
86
87  Klass* find_shared_class(int index, unsigned int hash, Symbol* name);
88
89  // Compiler support
90  Klass* try_get_next_class();
91
92  // GC support
93  void oops_do(OopClosure* f);
94  void always_strong_oops_do(OopClosure* blk);
95  void roots_oops_do(OopClosure* strong, OopClosure* weak);
96
97  void always_strong_classes_do(KlassClosure* closure);
98
99  void classes_do(void f(Klass*));
100  void classes_do(void f(Klass*, TRAPS), TRAPS);
101  void classes_do(void f(Klass*, ClassLoaderData*));
102
103  void methods_do(void f(Method*));
104
105  void unlink(BoolObjectClosure* is_alive);
106  void remove_classes_in_error_state();
107
108  // Classes loaded by the bootstrap loader are always strongly reachable.
109  // If we're not doing class unloading, all classes are strongly reachable.
110  static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) {
111    assert (klass != NULL, "should have non-null klass");
112    return (loader_data->is_the_null_class_loader_data() || !ClassUnloading);
113  }
114
115  // Unload (that is, break root links to) all unmarked classes and loaders.
116  void do_unloading();
117
118  // Protection domains
119  Klass* find(int index, unsigned int hash, Symbol* name,
120                ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
121  bool is_valid_protection_domain(int index, unsigned int hash,
122                                  Symbol* name, ClassLoaderData* loader_data,
123                                  Handle protection_domain);
124  void add_protection_domain(int index, unsigned int hash,
125                             instanceKlassHandle klass, ClassLoaderData* loader_data,
126                             Handle protection_domain, TRAPS);
127
128  // Sharing support
129  void reorder_dictionary();
130
131  ProtectionDomainCacheEntry* cache_get(oop protection_domain);
132
133  void print(bool details = true);
134#ifdef ASSERT
135  void printPerformanceInfoDetails();
136#endif // ASSERT
137  void verify();
138};
139
140// The following classes can be in dictionary.cpp, but we need these
141// to be in header file so that SA's vmStructs can access them.
142class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
143  friend class VMStructs;
144 private:
145  // Flag indicating whether this protection domain entry is strongly reachable.
146  // Used during iterating over the system dictionary to remember oops that need
147  // to be updated.
148  bool _strongly_reachable;
149 public:
150  oop protection_domain() { return literal(); }
151
152  void init() {
153    _strongly_reachable = false;
154  }
155
156  ProtectionDomainCacheEntry* next() {
157    return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next();
158  }
159
160  ProtectionDomainCacheEntry** next_addr() {
161    return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr();
162  }
163
164  void oops_do(OopClosure* f) {
165    f->do_oop(literal_addr());
166  }
167
168  void set_strongly_reachable()   { _strongly_reachable = true; }
169  bool is_strongly_reachable()    { return _strongly_reachable; }
170  void reset_strongly_reachable() { _strongly_reachable = false; }
171
172  void print() PRODUCT_RETURN;
173  void verify();
174};
175
176// The ProtectionDomainCacheTable contains all protection domain oops. The system
177// dictionary entries reference its entries instead of having references to oops
178// directly.
179// This is used to speed up system dictionary iteration: the oops in the
180// protection domain are the only ones referring the Java heap. So when there is
181// need to update these, instead of going over every entry of the system dictionary,
182// we only need to iterate over this set.
183// The amount of different protection domains used is typically magnitudes smaller
184// than the number of system dictionary entries (loaded classes).
185class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> {
186  friend class VMStructs;
187private:
188  ProtectionDomainCacheEntry* bucket(int i) {
189    return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i);
190  }
191
192  // The following method is not MT-safe and must be done under lock.
193  ProtectionDomainCacheEntry** bucket_addr(int i) {
194    return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
195  }
196
197  ProtectionDomainCacheEntry* new_entry(unsigned int hash, oop protection_domain) {
198    ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain);
199    entry->init();
200    return entry;
201  }
202
203  static unsigned int compute_hash(oop protection_domain);
204
205  int index_for(oop protection_domain);
206  ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, oop protection_domain);
207  ProtectionDomainCacheEntry* find_entry(int index, oop protection_domain);
208
209public:
210
211  ProtectionDomainCacheTable(int table_size);
212
213  ProtectionDomainCacheEntry* get(oop protection_domain);
214  void free(ProtectionDomainCacheEntry* entry);
215
216  void unlink(BoolObjectClosure* cl);
217
218  // GC support
219  void oops_do(OopClosure* f);
220  void always_strong_oops_do(OopClosure* f);
221  void roots_oops_do(OopClosure* strong, OopClosure* weak);
222
223  static uint bucket_size();
224
225  void print() PRODUCT_RETURN;
226  void verify();
227};
228
229
230class ProtectionDomainEntry :public CHeapObj<mtClass> {
231  friend class VMStructs;
232 public:
233  ProtectionDomainEntry* _next;
234  ProtectionDomainCacheEntry* _pd_cache;
235
236  ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) {
237    _pd_cache = pd_cache;
238    _next     = next;
239  }
240
241  ProtectionDomainEntry* next() { return _next; }
242  oop protection_domain() { return _pd_cache->protection_domain(); }
243};
244
245// An entry in the system dictionary, this describes a class as
246// { Klass*, loader, protection_domain }.
247
248class DictionaryEntry : public HashtableEntry<Klass*, mtClass> {
249  friend class VMStructs;
250 private:
251  // Contains the set of approved protection domains that can access
252  // this system dictionary entry.
253  //
254  // This protection domain set is a set of tuples:
255  //
256  // (InstanceKlass C, initiating class loader ICL, Protection Domain PD)
257  //
258  // [Note that C.protection_domain(), which is stored in the java.lang.Class
259  // mirror of C, is NOT the same as PD]
260  //
261  // If such an entry (C, ICL, PD) exists in the table, it means that
262  // it is okay for a class Foo to reference C, where
263  //
264  //    Foo.protection_domain() == PD, and
265  //    Foo's defining class loader == ICL
266  //
267  // The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
268  // It is essentially a cache to avoid repeated Java up-calls to
269  // ClassLoader.checkPackageAccess().
270  //
271  ProtectionDomainEntry* _pd_set;
272  ClassLoaderData*       _loader_data;
273
274 public:
275  // Tells whether a protection is in the approved set.
276  bool contains_protection_domain(oop protection_domain) const;
277  // Adds a protection domain to the approved set.
278  void add_protection_domain(Dictionary* dict, oop protection_domain);
279
280  Klass* klass() const { return (Klass*)literal(); }
281  Klass** klass_addr() { return (Klass**)literal_addr(); }
282
283  DictionaryEntry* next() const {
284    return (DictionaryEntry*)HashtableEntry<Klass*, mtClass>::next();
285  }
286
287  DictionaryEntry** next_addr() {
288    return (DictionaryEntry**)HashtableEntry<Klass*, mtClass>::next_addr();
289  }
290
291  ClassLoaderData* loader_data() const { return _loader_data; }
292  void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
293
294  ProtectionDomainEntry* pd_set() const { return _pd_set; }
295  void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }
296
297  bool has_protection_domain() { return _pd_set != NULL; }
298
299  // Tells whether the initiating class' protection can access the this _klass
300  bool is_valid_protection_domain(Handle protection_domain) {
301    if (!ProtectionDomainVerification) return true;
302    if (!SystemDictionary::has_checkPackageAccess()) return true;
303
304    return protection_domain() == NULL
305         ? true
306         : contains_protection_domain(protection_domain());
307  }
308
309  void set_strongly_reachable() {
310    for (ProtectionDomainEntry* current = _pd_set;
311                                current != NULL;
312                                current = current->_next) {
313      current->_pd_cache->set_strongly_reachable();
314    }
315  }
316
317  void verify_protection_domain_set() {
318    for (ProtectionDomainEntry* current = _pd_set;
319                                current != NULL;
320                                current = current->_next) {
321      current->_pd_cache->protection_domain()->verify();
322    }
323  }
324
325  bool equals(const Symbol* class_name, ClassLoaderData* loader_data) const {
326    Klass* klass = (Klass*)literal();
327    return (klass->name() == class_name && _loader_data == loader_data);
328  }
329
330  void print_count(outputStream *st) {
331    int count = 0;
332    for (ProtectionDomainEntry* current = _pd_set;
333                                current != NULL;
334                                current = current->_next) {
335      count++;
336    }
337    st->print_cr("pd set count = #%d", count);
338  }
339};
340
341// Entry in a SymbolPropertyTable, mapping a single Symbol*
342// to a managed and an unmanaged pointer.
343class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
344  friend class VMStructs;
345 private:
346  intptr_t _symbol_mode;  // secondary key
347  Method*   _method;
348  oop       _method_type;
349
350 public:
351  Symbol* symbol() const            { return literal(); }
352
353  intptr_t symbol_mode() const      { return _symbol_mode; }
354  void set_symbol_mode(intptr_t m)  { _symbol_mode = m; }
355
356  Method*        method() const     { return _method; }
357  void set_method(Method* p)        { _method = p; }
358
359  oop      method_type() const      { return _method_type; }
360  oop*     method_type_addr()       { return &_method_type; }
361  void set_method_type(oop p)       { _method_type = p; }
362
363  SymbolPropertyEntry* next() const {
364    return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();
365  }
366
367  SymbolPropertyEntry** next_addr() {
368    return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr();
369  }
370
371  void print_on(outputStream* st) const {
372    symbol()->print_value_on(st);
373    st->print("/mode=" INTX_FORMAT, symbol_mode());
374    st->print(" -> ");
375    bool printed = false;
376    if (method() != NULL) {
377      method()->print_value_on(st);
378      printed = true;
379    }
380    if (method_type() != NULL) {
381      if (printed)  st->print(" and ");
382      st->print(INTPTR_FORMAT, p2i((void *)method_type()));
383      printed = true;
384    }
385    st->print_cr(printed ? "" : "(empty)");
386  }
387};
388
389// A system-internal mapping of symbols to pointers, both managed
390// and unmanaged.  Used to record the auto-generation of each method
391// MethodHandle.invoke(S)T, for all signatures (S)T.
392class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
393  friend class VMStructs;
394private:
395  SymbolPropertyEntry* bucket(int i) {
396    return (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::bucket(i);
397  }
398
399  // The following method is not MT-safe and must be done under lock.
400  SymbolPropertyEntry** bucket_addr(int i) {
401    return (SymbolPropertyEntry**) Hashtable<Symbol*, mtSymbol>::bucket_addr(i);
402  }
403
404  void add_entry(int index, SymbolPropertyEntry* new_entry) {
405    ShouldNotReachHere();
406  }
407  void set_entry(int index, SymbolPropertyEntry* new_entry) {
408    ShouldNotReachHere();
409  }
410
411  SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
412    SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol);
413    // Hashtable with Symbol* literal must increment and decrement refcount.
414    symbol->increment_refcount();
415    entry->set_symbol_mode(symbol_mode);
416    entry->set_method(NULL);
417    entry->set_method_type(NULL);
418    return entry;
419  }
420
421public:
422  SymbolPropertyTable(int table_size);
423  SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);
424
425  void free_entry(SymbolPropertyEntry* entry) {
426    // decrement Symbol refcount here because hashtable doesn't.
427    entry->literal()->decrement_refcount();
428    Hashtable<Symbol*, mtSymbol>::free_entry(entry);
429  }
430
431  unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
432    // Use the regular identity_hash.
433    return Hashtable<Symbol*, mtSymbol>::compute_hash(sym) ^ symbol_mode;
434  }
435
436  int index_for(Symbol* name, intptr_t symbol_mode) {
437    return hash_to_index(compute_hash(name, symbol_mode));
438  }
439
440  // need not be locked; no state change
441  SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
442
443  // must be done under SystemDictionary_lock
444  SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
445
446  // GC support
447  void oops_do(OopClosure* f);
448
449  void methods_do(void f(Method*));
450
451  // Sharing support
452  void reorder_dictionary();
453
454#ifndef PRODUCT
455  void print();
456#endif
457  void verify();
458};
459#endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP
460