27 #include "classfile/systemDictionary.hpp" 28 #include "logging/log.hpp" 29 #include "logging/logStream.hpp" 30 #include "memory/iterator.hpp" 31 #include "memory/resourceArea.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "oops/weakHandle.inline.hpp" 34 #include "utilities/hashtable.inline.hpp" 35 36 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) { 37 // Identity hash can safepoint, so keep protection domain in a Handle. 38 return (unsigned int)(protection_domain->identity_hash()); 39 } 40 41 int ProtectionDomainCacheTable::index_for(Handle protection_domain) { 42 return hash_to_index(compute_hash(protection_domain)); 43 } 44 45 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size) 46 : Hashtable<ClassLoaderWeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry)) 47 { 48 } 49 50 void ProtectionDomainCacheTable::unlink() { 51 assert(SafepointSynchronize::is_at_safepoint(), "must be"); 52 for (int i = 0; i < table_size(); ++i) { 53 ProtectionDomainCacheEntry** p = bucket_addr(i); 54 ProtectionDomainCacheEntry* entry = bucket(i); 55 while (entry != NULL) { 56 oop pd = entry->object_no_keepalive(); 57 if (pd != NULL) { 58 p = entry->next_addr(); 59 } else { 60 LogTarget(Debug, protectiondomain) lt; 61 if (lt.is_enabled()) { 62 LogStream ls(lt); 63 ls.print_cr("protection domain unlinked at %d", i); 64 } 65 entry->literal().release(); 66 *p = entry->next(); 67 free_entry(entry); 68 } 69 entry = *p; 70 } 71 } 72 } 73 74 void ProtectionDomainCacheTable::print_on(outputStream* st) const { 75 st->print_cr("Protection domain cache table (table_size=%d, classes=%d)", 76 table_size(), number_of_entries()); 77 for (int index = 0; index < table_size(); index++) { 78 for (ProtectionDomainCacheEntry* probe = bucket(index); 79 probe != NULL; 80 probe = probe->next()) { 81 st->print_cr("%4d: protection_domain: " PTR_FORMAT, index, p2i(probe->object_no_keepalive())); 82 } 83 } 84 } 85 86 void ProtectionDomainCacheTable::verify() { 87 verify_table<ProtectionDomainCacheEntry>("Protection Domain Table"); 88 } 89 90 oop ProtectionDomainCacheEntry::object() { 91 return literal().resolve(); 92 } 93 94 oop ProtectionDomainEntry::object() { 107 } 108 109 void ProtectionDomainCacheEntry::verify() { 110 guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop"); 111 } 112 113 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) { 114 unsigned int hash = compute_hash(protection_domain); 115 int index = hash_to_index(hash); 116 117 ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain); 118 if (entry == NULL) { 119 entry = add_entry(index, hash, protection_domain); 120 } 121 // keep entry alive 122 (void)entry->object(); 123 return entry; 124 } 125 126 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) { 127 for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) { 128 if (oopDesc::equals(e->object_no_keepalive(), protection_domain())) { 129 return e; 130 } 131 } 132 133 return NULL; 134 } 135 136 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, Handle protection_domain) { 137 assert_locked_or_safepoint(SystemDictionary_lock); 138 assert(index == index_for(protection_domain), "incorrect index?"); 139 assert(find_entry(index, protection_domain) == NULL, "no double entry"); 140 141 ClassLoaderWeakHandle w = ClassLoaderWeakHandle::create(protection_domain); 142 ProtectionDomainCacheEntry* p = new_entry(hash, w); 143 Hashtable<ClassLoaderWeakHandle, mtClass>::add_entry(index, p); 144 return p; 145 } | 27 #include "classfile/systemDictionary.hpp" 28 #include "logging/log.hpp" 29 #include "logging/logStream.hpp" 30 #include "memory/iterator.hpp" 31 #include "memory/resourceArea.hpp" 32 #include "oops/oop.inline.hpp" 33 #include "oops/weakHandle.inline.hpp" 34 #include "utilities/hashtable.inline.hpp" 35 36 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) { 37 // Identity hash can safepoint, so keep protection domain in a Handle. 38 return (unsigned int)(protection_domain->identity_hash()); 39 } 40 41 int ProtectionDomainCacheTable::index_for(Handle protection_domain) { 42 return hash_to_index(compute_hash(protection_domain)); 43 } 44 45 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size) 46 : Hashtable<ClassLoaderWeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry)) 47 { _dead_entries = false; 48 _total_oops_removed = 0; 49 } 50 51 void ProtectionDomainCacheTable::trigger_cleanup() { 52 MutexLockerEx ml(Service_lock, Mutex::_no_safepoint_check_flag); 53 _dead_entries = true; 54 Service_lock->notify_all(); 55 } 56 57 void ProtectionDomainCacheTable::unlink() { 58 MutexLocker ml(SystemDictionary_lock); 59 int oops_removed = 0; 60 for (int i = 0; i < table_size(); ++i) { 61 ProtectionDomainCacheEntry** p = bucket_addr(i); 62 ProtectionDomainCacheEntry* entry = bucket(i); 63 while (entry != NULL) { 64 oop pd = entry->object_no_keepalive(); 65 if (pd != NULL) { 66 p = entry->next_addr(); 67 } else { 68 oops_removed++; 69 LogTarget(Debug, protectiondomain, table) lt; 70 if (lt.is_enabled()) { 71 LogStream ls(lt); 72 ls.print_cr("protection domain unlinked at %d", i); 73 } 74 entry->literal().release(); 75 *p = entry->next(); 76 free_entry(entry); 77 } 78 entry = *p; 79 } 80 } 81 _total_oops_removed += oops_removed; 82 _dead_entries = false; 83 } 84 85 void ProtectionDomainCacheTable::print_on(outputStream* st) const { 86 assert_locked_or_safepoint(SystemDictionary_lock); 87 st->print_cr("Protection domain cache table (table_size=%d, classes=%d)", 88 table_size(), number_of_entries()); 89 for (int index = 0; index < table_size(); index++) { 90 for (ProtectionDomainCacheEntry* probe = bucket(index); 91 probe != NULL; 92 probe = probe->next()) { 93 st->print_cr("%4d: protection_domain: " PTR_FORMAT, index, p2i(probe->object_no_keepalive())); 94 } 95 } 96 } 97 98 void ProtectionDomainCacheTable::verify() { 99 verify_table<ProtectionDomainCacheEntry>("Protection Domain Table"); 100 } 101 102 oop ProtectionDomainCacheEntry::object() { 103 return literal().resolve(); 104 } 105 106 oop ProtectionDomainEntry::object() { 119 } 120 121 void ProtectionDomainCacheEntry::verify() { 122 guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop"); 123 } 124 125 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) { 126 unsigned int hash = compute_hash(protection_domain); 127 int index = hash_to_index(hash); 128 129 ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain); 130 if (entry == NULL) { 131 entry = add_entry(index, hash, protection_domain); 132 } 133 // keep entry alive 134 (void)entry->object(); 135 return entry; 136 } 137 138 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) { 139 assert_locked_or_safepoint(SystemDictionary_lock); 140 for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) { 141 if (oopDesc::equals(e->object_no_keepalive(), protection_domain())) { 142 return e; 143 } 144 } 145 146 return NULL; 147 } 148 149 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::add_entry(int index, unsigned int hash, Handle protection_domain) { 150 assert_locked_or_safepoint(SystemDictionary_lock); 151 assert(index == index_for(protection_domain), "incorrect index?"); 152 assert(find_entry(index, protection_domain) == NULL, "no double entry"); 153 154 LogTarget(Debug, protectiondomain, table) lt; 155 if (lt.is_enabled()) { 156 LogStream ls(lt); 157 ls.print("protection domain added "); 158 protection_domain->print_value_on(&ls); 159 ls.cr(); 160 } 161 ClassLoaderWeakHandle w = ClassLoaderWeakHandle::create(protection_domain); 162 ProtectionDomainCacheEntry* p = new_entry(hash, w); 163 Hashtable<ClassLoaderWeakHandle, mtClass>::add_entry(index, p); 164 return p; 165 } |