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. 142 class 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). 185 class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> { 186 friend class VMStructs; 187 private: 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, Handle 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(Handle protection_domain); 204 205 int index_for(Handle protection_domain); 206 ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, Handle protection_domain); 207 ProtectionDomainCacheEntry* find_entry(int index, Handle protection_domain); 208 209 public: 210 211 ProtectionDomainCacheTable(int table_size); 212 213 ProtectionDomainCacheEntry* get(Handle 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 230 class 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; } 287 DictionaryEntry** next_addr() { 288 return (DictionaryEntry**)HashtableEntry<InstanceKlass*, 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 InstanceKlass* klass = (InstanceKlass*)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) { | 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. 142 class 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 ProtectionDomainCacheEntry* next() { 153 return (ProtectionDomainCacheEntry*)HashtableEntry<oop, mtClass>::next(); 154 } 155 156 ProtectionDomainCacheEntry** next_addr() { 157 return (ProtectionDomainCacheEntry**)HashtableEntry<oop, mtClass>::next_addr(); 158 } 159 160 void oops_do(OopClosure* f) { 161 f->do_oop(literal_addr()); 162 } 163 164 void print() PRODUCT_RETURN; 165 void verify(); 166 }; 167 168 // The ProtectionDomainCacheTable contains all protection domain oops. The system 169 // dictionary entries reference its entries instead of having references to oops 170 // directly. 171 // This is used to speed up system dictionary iteration: the oops in the 172 // protection domain are the only ones referring the Java heap. So when there is 173 // need to update these, instead of going over every entry of the system dictionary, 174 // we only need to iterate over this set. 175 // The amount of different protection domains used is typically magnitudes smaller 176 // than the number of system dictionary entries (loaded classes). 177 class ProtectionDomainCacheTable : public Hashtable<oop, mtClass> { 178 friend class VMStructs; 179 private: 180 ProtectionDomainCacheEntry* bucket(int i) { 181 return (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::bucket(i); 182 } 183 184 // The following method is not MT-safe and must be done under lock. 185 ProtectionDomainCacheEntry** bucket_addr(int i) { 186 return (ProtectionDomainCacheEntry**) Hashtable<oop, mtClass>::bucket_addr(i); 187 } 188 189 ProtectionDomainCacheEntry* new_entry(unsigned int hash, Handle protection_domain) { 190 ProtectionDomainCacheEntry* entry = (ProtectionDomainCacheEntry*) Hashtable<oop, mtClass>::new_entry(hash, protection_domain()); 191 return entry; 192 } 193 194 static unsigned int compute_hash(Handle protection_domain); 195 196 int index_for(Handle protection_domain); 197 ProtectionDomainCacheEntry* add_entry(int index, unsigned int hash, Handle protection_domain); 198 ProtectionDomainCacheEntry* find_entry(int index, Handle protection_domain); 199 200 public: 201 202 ProtectionDomainCacheTable(int table_size); 203 204 ProtectionDomainCacheEntry* get(Handle protection_domain); 205 void free(ProtectionDomainCacheEntry* entry); 206 207 void unlink(BoolObjectClosure* cl); 208 209 // GC support 210 void oops_do(OopClosure* f); 211 212 static uint bucket_size(); 213 214 void print() PRODUCT_RETURN; 215 void verify(); 216 }; 217 218 219 class ProtectionDomainEntry :public CHeapObj<mtClass> { 220 friend class VMStructs; 221 public: 222 ProtectionDomainEntry* _next; 223 ProtectionDomainCacheEntry* _pd_cache; 224 225 ProtectionDomainEntry(ProtectionDomainCacheEntry* pd_cache, ProtectionDomainEntry* next) { 226 _pd_cache = pd_cache; 227 _next = next; 228 } 229 230 ProtectionDomainEntry* next() { return _next; } 276 DictionaryEntry** next_addr() { 277 return (DictionaryEntry**)HashtableEntry<InstanceKlass*, mtClass>::next_addr(); 278 } 279 280 ClassLoaderData* loader_data() const { return _loader_data; } 281 void set_loader_data(ClassLoaderData* loader_data) { _loader_data = loader_data; } 282 283 ProtectionDomainEntry* pd_set() const { return _pd_set; } 284 void set_pd_set(ProtectionDomainEntry* pd_set) { _pd_set = pd_set; } 285 286 bool has_protection_domain() { return _pd_set != NULL; } 287 288 // Tells whether the initiating class' protection can access the this _klass 289 bool is_valid_protection_domain(Handle protection_domain) { 290 if (!ProtectionDomainVerification) return true; 291 if (!SystemDictionary::has_checkPackageAccess()) return true; 292 293 return protection_domain() == NULL 294 ? true 295 : contains_protection_domain(protection_domain()); 296 } 297 298 void verify_protection_domain_set() { 299 for (ProtectionDomainEntry* current = _pd_set; 300 current != NULL; 301 current = current->_next) { 302 current->_pd_cache->protection_domain()->verify(); 303 } 304 } 305 306 bool equals(const Symbol* class_name, ClassLoaderData* loader_data) const { 307 InstanceKlass* klass = (InstanceKlass*)literal(); 308 return (klass->name() == class_name && _loader_data == loader_data); 309 } 310 311 void print_count(outputStream *st) { 312 int count = 0; 313 for (ProtectionDomainEntry* current = _pd_set; 314 current != NULL; 315 current = current->_next) { |