dictionary.hpp 11.4 KB
Newer Older
D
duke 已提交
1
/*
2
 * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
D
duke 已提交
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
19 20 21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
D
duke 已提交
22 23 24
 *
 */

25 26 27 28 29 30 31 32
#ifndef SHARE_VM_CLASSFILE_DICTIONARY_HPP
#define SHARE_VM_CLASSFILE_DICTIONARY_HPP

#include "classfile/systemDictionary.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/oop.hpp"
#include "utilities/hashtable.hpp"

D
duke 已提交
33
class DictionaryEntry;
34
class PSPromotionManager;
D
duke 已提交
35 36 37 38 39

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// The data structure for the system dictionary (and the shared system
// dictionary).

40
class Dictionary : public TwoOopHashtable<Klass*, mtClass> {
D
duke 已提交
41 42 43 44 45 46 47 48
  friend class VMStructs;
private:
  // current iteration index.
  static int                    _current_class_index;
  // pointer to the current hash table entry.
  static DictionaryEntry*       _current_class_entry;

  DictionaryEntry* get_entry(int index, unsigned int hash,
49
                             Symbol* name, ClassLoaderData* loader_data);
D
duke 已提交
50 51

  DictionaryEntry* bucket(int i) {
52
    return (DictionaryEntry*)Hashtable<Klass*, mtClass>::bucket(i);
D
duke 已提交
53 54 55 56
  }

  // The following method is not MT-safe and must be done under lock.
  DictionaryEntry** bucket_addr(int i) {
57
    return (DictionaryEntry**)Hashtable<Klass*, mtClass>::bucket_addr(i);
D
duke 已提交
58 59 60
  }

  void add_entry(int index, DictionaryEntry* new_entry) {
61
    Hashtable<Klass*, mtClass>::add_entry(index, (HashtableEntry<Klass*, mtClass>*)new_entry);
D
duke 已提交
62 63 64 65
  }

public:
  Dictionary(int table_size);
Z
zgu 已提交
66
  Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
D
duke 已提交
67

68
  DictionaryEntry* new_entry(unsigned int hash, Klass* klass, ClassLoaderData* loader_data);
D
duke 已提交
69 70 71 72 73

  DictionaryEntry* new_entry();

  void free_entry(DictionaryEntry* entry);

74
  void add_klass(Symbol* class_name, ClassLoaderData* loader_data,KlassHandle obj);
D
duke 已提交
75

76 77
  Klass* find_class(int index, unsigned int hash,
                      Symbol* name, ClassLoaderData* loader_data);
D
duke 已提交
78

79
  Klass* find_shared_class(int index, unsigned int hash, Symbol* name);
D
duke 已提交
80 81

  // Compiler support
82
  Klass* try_get_next_class();
D
duke 已提交
83 84 85

  // GC support
  void oops_do(OopClosure* f);
86 87 88 89 90 91 92
  void always_strong_oops_do(OopClosure* blk);

  void always_strong_classes_do(KlassClosure* closure);

  void classes_do(void f(Klass*));
  void classes_do(void f(Klass*, TRAPS), TRAPS);
  void classes_do(void f(Klass*, ClassLoaderData*));
D
duke 已提交
93

94
  void methods_do(void f(Method*));
D
duke 已提交
95 96 97 98


  // Classes loaded by the bootstrap loader are always strongly reachable.
  // If we're not doing class unloading, all classes are strongly reachable.
99
  static bool is_strongly_reachable(ClassLoaderData* loader_data, Klass* klass) {
D
duke 已提交
100
    assert (klass != NULL, "should have non-null klass");
101
    return (loader_data->is_the_null_class_loader_data() || !ClassUnloading);
D
duke 已提交
102 103 104 105
  }

  // Unload (that is, break root links to) all unmarked classes and
  // loaders.  Returns "true" iff something was unloaded.
106
  bool do_unloading();
D
duke 已提交
107 108

  // Protection domains
109 110
  Klass* find(int index, unsigned int hash, Symbol* name,
                ClassLoaderData* loader_data, Handle protection_domain, TRAPS);
D
duke 已提交
111
  bool is_valid_protection_domain(int index, unsigned int hash,
112
                                  Symbol* name, ClassLoaderData* loader_data,
D
duke 已提交
113 114
                                  Handle protection_domain);
  void add_protection_domain(int index, unsigned int hash,
115
                             instanceKlassHandle klass, ClassLoaderData* loader_data,
D
duke 已提交
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
                             Handle protection_domain, TRAPS);

  // Sharing support
  void reorder_dictionary();


#ifndef PRODUCT
  void print();
#endif
  void verify();
};

// The following classes can be in dictionary.cpp, but we need these
// to be in header file so that SA's vmStructs can access.

Z
zgu 已提交
131
class ProtectionDomainEntry :public CHeapObj<mtClass> {
D
duke 已提交
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
  friend class VMStructs;
 public:
  ProtectionDomainEntry* _next;
  oop                    _protection_domain;

  ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
    _protection_domain = protection_domain;
    _next              = next;
  }

  ProtectionDomainEntry* next() { return _next; }
  oop protection_domain() { return _protection_domain; }
};

// An entry in the system dictionary, this describes a class as
147
// { Klass*, loader, protection_domain }.
D
duke 已提交
148

149
class DictionaryEntry : public HashtableEntry<Klass*, mtClass> {
D
duke 已提交
150 151 152 153 154
  friend class VMStructs;
 private:
  // Contains the set of approved protection domains that can access
  // this system dictionary entry.
  ProtectionDomainEntry* _pd_set;
155
  ClassLoaderData*       _loader_data;
D
duke 已提交
156 157 158 159 160 161 162

 public:
  // Tells whether a protection is in the approved set.
  bool contains_protection_domain(oop protection_domain) const;
  // Adds a protection domain to the approved set.
  void add_protection_domain(oop protection_domain);

163 164
  Klass* klass() const { return (Klass*)literal(); }
  Klass** klass_addr() { return (Klass**)literal_addr(); }
D
duke 已提交
165 166

  DictionaryEntry* next() const {
167
    return (DictionaryEntry*)HashtableEntry<Klass*, mtClass>::next();
D
duke 已提交
168 169 170
  }

  DictionaryEntry** next_addr() {
171
    return (DictionaryEntry**)HashtableEntry<Klass*, mtClass>::next_addr();
D
duke 已提交
172 173
  }

174 175
  ClassLoaderData* loader_data() const { return _loader_data; }
  void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; }
D
duke 已提交
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208

  ProtectionDomainEntry* pd_set() const { return _pd_set; }
  void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; }

  bool has_protection_domain() { return _pd_set != NULL; }

  // Tells whether the initiating class' protection can access the this _klass
  bool is_valid_protection_domain(Handle protection_domain) {
    if (!ProtectionDomainVerification) return true;
    if (!SystemDictionary::has_checkPackageAccess()) return true;

    return protection_domain() == NULL
         ? true
         : contains_protection_domain(protection_domain());
  }


  void protection_domain_set_oops_do(OopClosure* f) {
    for (ProtectionDomainEntry* current = _pd_set;
                                current != NULL;
                                current = current->_next) {
      f->do_oop(&(current->_protection_domain));
    }
  }

  void verify_protection_domain_set() {
    for (ProtectionDomainEntry* current = _pd_set;
                                current != NULL;
                                current = current->_next) {
      current->_protection_domain->verify();
    }
  }

209 210 211 212
  bool equals(Symbol* class_name, ClassLoaderData* loader_data) const {
    Klass* klass = (Klass*)literal();
    return (InstanceKlass::cast(klass)->name() == class_name &&
            _loader_data == loader_data);
D
duke 已提交
213 214 215 216 217 218 219 220 221 222 223 224
  }

  void print() {
    int count = 0;
    for (ProtectionDomainEntry* current = _pd_set;
                                current != NULL;
                                current = current->_next) {
      count++;
    }
    tty->print_cr("pd set = #%d", count);
  }
};
225

226
// Entry in a SymbolPropertyTable, mapping a single Symbol*
227
// to a managed and an unmanaged pointer.
Z
zgu 已提交
228
class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
229 230
  friend class VMStructs;
 private:
231
  intptr_t _symbol_mode;  // secondary key
232 233
  Method*   _method;
  oop       _method_type;
234 235

 public:
236
  Symbol* symbol() const            { return literal(); }
237

238 239 240
  intptr_t symbol_mode() const      { return _symbol_mode; }
  void set_symbol_mode(intptr_t m)  { _symbol_mode = m; }

241 242
  Method*        method() const     { return _method; }
  void set_method(Method* p)        { _method = p; }
243

244 245 246
  oop      method_type() const      { return _method_type; }
  oop*     method_type_addr()       { return &_method_type; }
  void set_method_type(oop p)       { _method_type = p; }
247 248

  SymbolPropertyEntry* next() const {
Z
zgu 已提交
249
    return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();
250 251 252
  }

  SymbolPropertyEntry** next_addr() {
Z
zgu 已提交
253
    return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr();
254 255 256 257
  }

  void print_on(outputStream* st) const {
    symbol()->print_value_on(st);
258
    st->print("/mode="INTX_FORMAT, symbol_mode());
259 260
    st->print(" -> ");
    bool printed = false;
261 262
    if (method() != NULL) {
      method()->print_value_on(st);
263 264
      printed = true;
    }
265
    if (method_type() != NULL) {
266
      if (printed)  st->print(" and ");
267
      st->print(INTPTR_FORMAT, method_type());
268 269 270 271 272 273 274 275 276
      printed = true;
    }
    st->print_cr(printed ? "" : "(empty)");
  }
};

// A system-internal mapping of symbols to pointers, both managed
// and unmanaged.  Used to record the auto-generation of each method
// MethodHandle.invoke(S)T, for all signatures (S)T.
Z
zgu 已提交
277
class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
278 279 280
  friend class VMStructs;
private:
  SymbolPropertyEntry* bucket(int i) {
Z
zgu 已提交
281
    return (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::bucket(i);
282 283 284 285
  }

  // The following method is not MT-safe and must be done under lock.
  SymbolPropertyEntry** bucket_addr(int i) {
Z
zgu 已提交
286
    return (SymbolPropertyEntry**) Hashtable<Symbol*, mtSymbol>::bucket_addr(i);
287 288 289 290 291 292 293 294 295
  }

  void add_entry(int index, SymbolPropertyEntry* new_entry) {
    ShouldNotReachHere();
  }
  void set_entry(int index, SymbolPropertyEntry* new_entry) {
    ShouldNotReachHere();
  }

296
  SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
Z
zgu 已提交
297
    SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol);
298 299
    // Hashtable with Symbol* literal must increment and decrement refcount.
    symbol->increment_refcount();
300
    entry->set_symbol_mode(symbol_mode);
301 302
    entry->set_method(NULL);
    entry->set_method_type(NULL);
303 304 305 306 307
    return entry;
  }

public:
  SymbolPropertyTable(int table_size);
Z
zgu 已提交
308
  SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);
309 310

  void free_entry(SymbolPropertyEntry* entry) {
311 312
    // decrement Symbol refcount here because hashtable doesn't.
    entry->literal()->decrement_refcount();
Z
zgu 已提交
313
    Hashtable<Symbol*, mtSymbol>::free_entry(entry);
314 315
  }

316
  unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
317
    // Use the regular identity_hash.
Z
zgu 已提交
318
    return Hashtable<Symbol*, mtSymbol>::compute_hash(sym) ^ symbol_mode;
319 320
  }

321
  int index_for(Symbol* name, intptr_t symbol_mode) {
322
    return hash_to_index(compute_hash(name, symbol_mode));
323 324 325
  }

  // need not be locked; no state change
326
  SymbolPropertyEntry* find_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
327 328

  // must be done under SystemDictionary_lock
329
  SymbolPropertyEntry* add_entry(int index, unsigned int hash, Symbol* name, intptr_t name_mode);
330 331 332

  // GC support
  void oops_do(OopClosure* f);
333 334

  void methods_do(void f(Method*));
335 336 337 338 339 340 341 342 343

  // Sharing support
  void reorder_dictionary();

#ifndef PRODUCT
  void print();
#endif
  void verify();
};
344
#endif // SHARE_VM_CLASSFILE_DICTIONARY_HPP