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