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
|