< prev index next >

src/hotspot/share/classfile/protectionDomainCache.cpp

Concurrent class unloading

30 #include "memory/resourceArea.hpp"                                                                                                   
31 #include "oops/oop.inline.hpp"                                                                                                       
32 #include "oops/weakHandle.inline.hpp"                                                                                                
33 #include "utilities/hashtable.inline.hpp"                                                                                            
34 
35 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) {                                                    
36   // Identity hash can safepoint, so keep protection domain in a Handle.                                                             
37   return (unsigned int)(protection_domain->identity_hash());                                                                         
38 }                                                                                                                                    
39 
40 int ProtectionDomainCacheTable::index_for(Handle protection_domain) {                                                                
41   return hash_to_index(compute_hash(protection_domain));                                                                             
42 }                                                                                                                                    
43 
44 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)                                                               
45   : Hashtable<ClassLoaderWeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))                                        
46 {                                                                                                                                    
47 }                                                                                                                                    
48 
49 void ProtectionDomainCacheTable::unlink() {                                                                                          
50   assert(SafepointSynchronize::is_at_safepoint(), "must be");                                                                        
51   for (int i = 0; i < table_size(); ++i) {                                                                                           
52     ProtectionDomainCacheEntry** p = bucket_addr(i);                                                                                 
53     ProtectionDomainCacheEntry* entry = bucket(i);                                                                                   
54     while (entry != NULL) {                                                                                                          
55       oop pd = entry->object_no_keepalive();                                                                                         
56       if (pd != NULL) {                                                                                                              
57         p = entry->next_addr();                                                                                                      
58       } else {                                                                                                                       
59         LogTarget(Debug, protectiondomain) lt;                                                                                       
60         if (lt.is_enabled()) {                                                                                                       
61           LogStream ls(lt);                                                                                                          
62           ls.print_cr("protection domain unlinked at %d", i);                                                                        
63         }                                                                                                                            
64         entry->literal().release();                                                                                                  
65         *p = entry->next();                                                                                                          
66         free_entry(entry);                                                                                                           
67       }                                                                                                                              
68       entry = *p;                                                                                                                    
69     }                                                                                                                                

30 #include "memory/resourceArea.hpp"
31 #include "oops/oop.inline.hpp"
32 #include "oops/weakHandle.inline.hpp"
33 #include "utilities/hashtable.inline.hpp"
34 
35 unsigned int ProtectionDomainCacheTable::compute_hash(Handle protection_domain) {
36   // Identity hash can safepoint, so keep protection domain in a Handle.
37   return (unsigned int)(protection_domain->identity_hash());
38 }
39 
40 int ProtectionDomainCacheTable::index_for(Handle protection_domain) {
41   return hash_to_index(compute_hash(protection_domain));
42 }
43 
44 ProtectionDomainCacheTable::ProtectionDomainCacheTable(int table_size)
45   : Hashtable<ClassLoaderWeakHandle, mtClass>(table_size, sizeof(ProtectionDomainCacheEntry))
46 {
47 }
48 
49 void ProtectionDomainCacheTable::unlink() {
50   MutexLockerEx m(SystemDictionary_lock->owned_by_self() ? NULL : SystemDictionary_lock);
51   for (int i = 0; i < table_size(); ++i) {
52     ProtectionDomainCacheEntry** p = bucket_addr(i);
53     ProtectionDomainCacheEntry* entry = bucket(i);
54     while (entry != NULL) {
55       oop pd = entry->object_no_keepalive();
56       if (pd != NULL) {
57         p = entry->next_addr();
58       } else {
59         LogTarget(Debug, protectiondomain) lt;
60         if (lt.is_enabled()) {
61           LogStream ls(lt);
62           ls.print_cr("protection domain unlinked at %d", i);
63         }
64         entry->literal().release();
65         *p = entry->next();
66         free_entry(entry);
67       }
68       entry = *p;
69     }

93 oop ProtectionDomainEntry::object() {                                                                                                
94   return _pd_cache->object();                                                                                                        
95 }                                                                                                                                    
96 
97 // The object_no_keepalive() call peeks at the phantomly reachable oop without                                                       
98 // keeping it alive. This is okay to do in the VM thread state if it is not                                                          
99 // leaked out to become strongly reachable.                                                                                          
100 oop ProtectionDomainCacheEntry::object_no_keepalive() {                                                                              
101   return literal().peek();                                                                                                           
102 }                                                                                                                                    
103 
104 oop ProtectionDomainEntry::object_no_keepalive() {                                                                                   
105   return _pd_cache->object_no_keepalive();                                                                                           
106 }                                                                                                                                    
107 
108 void ProtectionDomainCacheEntry::verify() {                                                                                          
109   guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop");                              
110 }                                                                                                                                    
111 
112 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) {                                              
                                                                                                                                     
113   unsigned int hash = compute_hash(protection_domain);                                                                               
114   int index = hash_to_index(hash);                                                                                                   
115 
116   ProtectionDomainCacheEntry* entry = find_entry(index, protection_domain);                                                          
117   if (entry == NULL) {                                                                                                               
118     entry = add_entry(index, hash, protection_domain);                                                                               
119   }                                                                                                                                  
120   // keep entry alive                                                                                                                
121   (void)entry->object();                                                                                                             
122   return entry;                                                                                                                      
123 }                                                                                                                                    
124 
125 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::find_entry(int index, Handle protection_domain) {                            
126   for (ProtectionDomainCacheEntry* e = bucket(index); e != NULL; e = e->next()) {                                                    
127     if (oopDesc::equals(e->object_no_keepalive(), protection_domain())) {                                                            
128       return e;                                                                                                                      
129     }                                                                                                                                
130   }                                                                                                                                  
131 

93 oop ProtectionDomainEntry::object() {
94   return _pd_cache->object();
95 }
96 
97 // The object_no_keepalive() call peeks at the phantomly reachable oop without
98 // keeping it alive. This is okay to do in the VM thread state if it is not
99 // leaked out to become strongly reachable.
100 oop ProtectionDomainCacheEntry::object_no_keepalive() {
101   return literal().peek();
102 }
103 
104 oop ProtectionDomainEntry::object_no_keepalive() {
105   return _pd_cache->object_no_keepalive();
106 }
107 
108 void ProtectionDomainCacheEntry::verify() {
109   guarantee(object_no_keepalive() == NULL || oopDesc::is_oop(object_no_keepalive()), "must be an oop");
110 }
111 
112 ProtectionDomainCacheEntry* ProtectionDomainCacheTable::get(Handle protection_domain) {
113   MutexLockerEx m(SystemDictionary_lock->owned_by_self() ? NULL : SystemDictionary_lock);
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 
< prev index next >