dictionary.hpp 7.2 KB
Newer Older
D
duke 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 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 209 210 211 212 213 214 215 216 217 218 219
/*
 * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
 * 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.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 */

class DictionaryEntry;

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

class Dictionary : public TwoOopHashtable {
  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,
                             symbolHandle name, Handle loader);

  DictionaryEntry* bucket(int i) {
    return (DictionaryEntry*)Hashtable::bucket(i);
  }

  // The following method is not MT-safe and must be done under lock.
  DictionaryEntry** bucket_addr(int i) {
    return (DictionaryEntry**)Hashtable::bucket_addr(i);
  }

  void add_entry(int index, DictionaryEntry* new_entry) {
    Hashtable::add_entry(index, (HashtableEntry*)new_entry);
  }


public:
  Dictionary(int table_size);
  Dictionary(int table_size, HashtableBucket* t, int number_of_entries);

  DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader);

  DictionaryEntry* new_entry();

  void free_entry(DictionaryEntry* entry);

  void add_klass(symbolHandle class_name, Handle class_loader,KlassHandle obj);

  klassOop find_class(int index, unsigned int hash,
                      symbolHandle name, Handle loader);

  klassOop find_shared_class(int index, unsigned int hash, symbolHandle name);

  // Compiler support
  klassOop try_get_next_class();

  // GC support

  void oops_do(OopClosure* f);
  void always_strong_classes_do(OopClosure* blk);
  void classes_do(void f(klassOop));
  void classes_do(void f(klassOop, TRAPS), TRAPS);
  void classes_do(void f(klassOop, oop));
  void classes_do(void f(klassOop, oop, TRAPS), TRAPS);

  void methods_do(void f(methodOop));


  // Classes loaded by the bootstrap loader are always strongly reachable.
  // If we're not doing class unloading, all classes are strongly reachable.
  static bool is_strongly_reachable(oop class_loader, oop klass) {
    assert (klass != NULL, "should have non-null klass");
    return (class_loader == NULL || !ClassUnloading);
  }

  // Unload (that is, break root links to) all unmarked classes and
  // loaders.  Returns "true" iff something was unloaded.
  bool do_unloading(BoolObjectClosure* is_alive);

  // Protection domains
  klassOop find(int index, unsigned int hash, symbolHandle name,
                Handle loader, Handle protection_domain, TRAPS);
  bool is_valid_protection_domain(int index, unsigned int hash,
                                  symbolHandle name, Handle class_loader,
                                  Handle protection_domain);
  void add_protection_domain(int index, unsigned int hash,
                             instanceKlassHandle klass, Handle loader,
                             Handle protection_domain, TRAPS);

  // Sharing support
  void dump(SerializeOopClosure* soc);
  void restore(SerializeOopClosure* soc);
  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.

class ProtectionDomainEntry :public CHeapObj {
  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
// { klassOop, loader, protection_domain }.

class DictionaryEntry : public HashtableEntry {
  friend class VMStructs;
 private:
  // Contains the set of approved protection domains that can access
  // this system dictionary entry.
  ProtectionDomainEntry* _pd_set;
  oop                    _loader;


 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);

  klassOop klass() const { return (klassOop)literal(); }
  klassOop* klass_addr() { return (klassOop*)literal_addr(); }

  DictionaryEntry* next() const {
    return (DictionaryEntry*)HashtableEntry::next();
  }

  DictionaryEntry** next_addr() {
    return (DictionaryEntry**)HashtableEntry::next_addr();
  }

  oop loader() const { return _loader; }
  void set_loader(oop loader) { _loader = loader; }
  oop* loader_addr() { return &_loader; }

  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();
    }
  }

  bool equals(symbolOop class_name, oop class_loader) const {
    klassOop klass = (klassOop)literal();
    return (instanceKlass::cast(klass)->name() == class_name &&
            _loader == class_loader);
  }

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