src/share/vm/classfile/dictionary.hpp

changeset 5865
aa6f2ea19d8f
parent 5784
190899198332
parent 5862
82af7d7a0128
child 6680
78bbf4d43a14
     1.1 --- a/src/share/vm/classfile/dictionary.hpp	Thu Oct 10 13:25:51 2013 -0700
     1.2 +++ b/src/share/vm/classfile/dictionary.hpp	Fri Oct 11 08:27:21 2013 -0700
     1.3 @@ -27,11 +27,14 @@
     1.4  
     1.5  #include "classfile/systemDictionary.hpp"
     1.6  #include "oops/instanceKlass.hpp"
     1.7 -#include "oops/oop.hpp"
     1.8 +#include "oops/oop.inline.hpp"
     1.9  #include "utilities/hashtable.hpp"
    1.10  
    1.11  class DictionaryEntry;
    1.12  class PSPromotionManager;
    1.13 +class ProtectionDomainCacheTable;
    1.14 +class ProtectionDomainCacheEntry;
    1.15 +class BoolObjectClosure;
    1.16  
    1.17  //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    1.18  // The data structure for the system dictionary (and the shared system
    1.19 @@ -45,6 +48,8 @@
    1.20    // pointer to the current hash table entry.
    1.21    static DictionaryEntry*       _current_class_entry;
    1.22  
    1.23 +  ProtectionDomainCacheTable*   _pd_cache_table;
    1.24 +
    1.25    DictionaryEntry* get_entry(int index, unsigned int hash,
    1.26                               Symbol* name, ClassLoaderData* loader_data);
    1.27  
    1.28 @@ -93,6 +98,7 @@
    1.29  
    1.30    void methods_do(void f(Method*));
    1.31  
    1.32 +  void unlink(BoolObjectClosure* is_alive);
    1.33  
    1.34    // Classes loaded by the bootstrap loader are always strongly reachable.
    1.35    // If we're not doing class unloading, all classes are strongly reachable.
    1.36 @@ -118,6 +124,7 @@
    1.37    // Sharing support
    1.38    void reorder_dictionary();
    1.39  
    1.40 +  ProtectionDomainCacheEntry* cache_get(oop protection_domain);
    1.41  
    1.42  #ifndef PRODUCT
    1.43    void print();
    1.44 @@ -126,21 +133,112 @@
    1.45  };
    1.46  
    1.47  // The following classes can be in dictionary.cpp, but we need these
    1.48 -// to be in header file so that SA's vmStructs can access.
    1.49 +// to be in header file so that SA's vmStructs can access them.
    1.50 +class ProtectionDomainCacheEntry : public HashtableEntry<oop, mtClass> {
    1.51 +  friend class VMStructs;
    1.52 + private:
    1.53 +  // Flag indicating whether this protection domain entry is strongly reachable.
    1.54 +  // Used during iterating over the system dictionary to remember oops that need
    1.55 +  // to be updated.
    1.56 +  bool _strongly_reachable;
    1.57 + public:
    1.58 +  oop protection_domain() { return literal(); }
    1.59 +
    1.60 +  void init() {
    1.61 +    _strongly_reachable = false;
    1.62 +  }
    1.63 +
    1.64 +  ProtectionDomainCacheEntry* next() {
    1.65 +    return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next();
    1.66 +  }
    1.67 +
    1.68 +  ProtectionDomainCacheEntry** next_addr() {
    1.69 +    return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr();
    1.70 +  }
    1.71 +
    1.72 +  void oops_do(OopClosure* f) {
    1.73 +    f->do_oop(literal_addr());
    1.74 +  }
    1.75 +
    1.76 +  void set_strongly_reachable()   { _strongly_reachable = true; }
    1.77 +  bool is_strongly_reachable()    { return _strongly_reachable; }
    1.78 +  void reset_strongly_reachable() { _strongly_reachable = false; }
    1.79 +
    1.80 +  void print() PRODUCT_RETURN;
    1.81 +  void verify();
    1.82 +};
    1.83 +
    1.84 +// The ProtectionDomainCacheTable contains all protection domain oops. The system
    1.85 +// dictionary entries reference its entries instead of having references to oops
    1.86 +// directly.
    1.87 +// This is used to speed up system dictionary iteration: the oops in the
    1.88 +// protection domain are the only ones referring the Java heap. So when there is
    1.89 +// need to update these, instead of going over every entry of the system dictionary,
    1.90 +// we only need to iterate over this set.
    1.91 +// The amount of different protection domains used is typically magnitudes smaller
    1.92 +// than the number of system dictionary entries (loaded classes).
    1.93 +class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> {
    1.94 +  friend class VMStructs;
    1.95 +private:
    1.96 +  ProtectionDomainCacheEntry* bucket(int i) {
    1.97 +    return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i);
    1.98 +  }
    1.99 +
   1.100 +  // The following method is not MT-safe and must be done under lock.
   1.101 +  ProtectionDomainCacheEntry** bucket_addr(int i) {
   1.102 +    return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i);
   1.103 +  }
   1.104 +
   1.105 +  ProtectionDomainCacheEntry* new_entry(unsigned int hash, oop protection_domain) {
   1.106 +    ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain);
   1.107 +    entry->init();
   1.108 +    return entry;
   1.109 +  }
   1.110 +
   1.111 +  static unsigned int compute_hash(oop protection_domain) {
   1.112 +    return (unsigned int)(protection_domain->identity_hash());
   1.113 +  }
   1.114 +
   1.115 +  int index_for(oop protection_domain) {
   1.116 +    return hash_to_index(compute_hash(protection_domain));
   1.117 +  }
   1.118 +
   1.119 +  ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, oop protection_domain);
   1.120 +  ProtectionDomainCacheEntry* find_entry(int index, oop protection_domain);
   1.121 +
   1.122 +public:
   1.123 +
   1.124 +  ProtectionDomainCacheTable(int table_size);
   1.125 +
   1.126 +  ProtectionDomainCacheEntry* get(oop protection_domain);
   1.127 +  void free(ProtectionDomainCacheEntry* entry);
   1.128 +
   1.129 +  void unlink(BoolObjectClosure* cl);
   1.130 +
   1.131 +  // GC support
   1.132 +  void oops_do(OopClosure* f);
   1.133 +  void always_strong_oops_do(OopClosure* f);
   1.134 +
   1.135 +  static uint bucket_size();
   1.136 +
   1.137 +  void print() PRODUCT_RETURN;
   1.138 +  void verify();
   1.139 +};
   1.140 +
   1.141  
   1.142  class ProtectionDomainEntry :public CHeapObj<mtClass> {
   1.143    friend class VMStructs;
   1.144   public:
   1.145    ProtectionDomainEntry* _next;
   1.146 -  oop                    _protection_domain;
   1.147 +  ProtectionDomainCacheEntry* _pd_cache;
   1.148  
   1.149 -  ProtectionDomainEntry(oop protection_domain, ProtectionDomainEntry* next) {
   1.150 -    _protection_domain = protection_domain;
   1.151 -    _next              = next;
   1.152 +  ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) {
   1.153 +    _pd_cache = pd_cache;
   1.154 +    _next     = next;
   1.155    }
   1.156  
   1.157    ProtectionDomainEntry* next() { return _next; }
   1.158 -  oop protection_domain() { return _protection_domain; }
   1.159 +  oop protection_domain() { return _pd_cache->protection_domain(); }
   1.160  };
   1.161  
   1.162  // An entry in the system dictionary, this describes a class as
   1.163 @@ -151,6 +249,24 @@
   1.164   private:
   1.165    // Contains the set of approved protection domains that can access
   1.166    // this system dictionary entry.
   1.167 +  //
   1.168 +  // This protection domain set is a set of tuples:
   1.169 +  //
   1.170 +  // (InstanceKlass C, initiating class loader ICL, Protection Domain PD)
   1.171 +  //
   1.172 +  // [Note that C.protection_domain(), which is stored in the java.lang.Class
   1.173 +  // mirror of C, is NOT the same as PD]
   1.174 +  //
   1.175 +  // If such an entry (C, ICL, PD) exists in the table, it means that
   1.176 +  // it is okay for a class Foo to reference C, where
   1.177 +  //
   1.178 +  //    Foo.protection_domain() == PD, and
   1.179 +  //    Foo's defining class loader == ICL
   1.180 +  //
   1.181 +  // The usage of the PD set can be seen in SystemDictionary::validate_protection_domain()
   1.182 +  // It is essentially a cache to avoid repeated Java up-calls to
   1.183 +  // ClassLoader.checkPackageAccess().
   1.184 +  //
   1.185    ProtectionDomainEntry* _pd_set;
   1.186    ClassLoaderData*       _loader_data;
   1.187  
   1.188 @@ -158,7 +274,7 @@
   1.189    // Tells whether a protection is in the approved set.
   1.190    bool contains_protection_domain(oop protection_domain) const;
   1.191    // Adds a protection domain to the approved set.
   1.192 -  void add_protection_domain(oop protection_domain);
   1.193 +  void add_protection_domain(Dictionary* dict, oop protection_domain);
   1.194  
   1.195    Klass* klass() const { return (Klass*)literal(); }
   1.196    Klass** klass_addr() { return (Klass**)literal_addr(); }
   1.197 @@ -189,12 +305,11 @@
   1.198           : contains_protection_domain(protection_domain());
   1.199    }
   1.200  
   1.201 -
   1.202 -  void protection_domain_set_oops_do(OopClosure* f) {
   1.203 +  void set_strongly_reachable() {
   1.204      for (ProtectionDomainEntry* current = _pd_set;
   1.205                                  current != NULL;
   1.206                                  current = current->_next) {
   1.207 -      f->do_oop(&(current->_protection_domain));
   1.208 +      current->_pd_cache->set_strongly_reachable();
   1.209      }
   1.210    }
   1.211  
   1.212 @@ -202,7 +317,7 @@
   1.213      for (ProtectionDomainEntry* current = _pd_set;
   1.214                                  current != NULL;
   1.215                                  current = current->_next) {
   1.216 -      current->_protection_domain->verify();
   1.217 +      current->_pd_cache->protection_domain()->verify();
   1.218      }
   1.219    }
   1.220  

mercurial