comparison src/share/vm/classfile/dictionary.cpp @ 13639:644db104e2f0

8164207: Checking missing load-acquire in relation to _pd_set in dictionary.cpp Summary: Use load_acquire for accessing DictionaryEntry::_pd_set since it's accessed outside the SystemDictionary_lock Reviewed-by: zgu, twisti, dholmes, adinn
author coleenp
date Wed, 30 Aug 2017 19:18:22 -0400
parents 731370f39fcd
children 7df86c5f8b5d
comparison
equal deleted inserted replaced
53:3f51d8879c7e 54:081dbb41481a
83 } 83 }
84 84
85 85
86 void Dictionary::free_entry(DictionaryEntry* entry) { 86 void Dictionary::free_entry(DictionaryEntry* entry) {
87 // avoid recursion when deleting linked list 87 // avoid recursion when deleting linked list
88 // pd_set is accessed during a safepoint.
88 while (entry->pd_set() != NULL) { 89 while (entry->pd_set() != NULL) {
89 ProtectionDomainEntry* to_delete = entry->pd_set(); 90 ProtectionDomainEntry* to_delete = entry->pd_set();
90 entry->set_pd_set(to_delete->next()); 91 entry->set_pd_set(to_delete->next());
91 delete to_delete; 92 delete to_delete;
92 } 93 }
99 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const { 100 bool DictionaryEntry::contains_protection_domain(oop protection_domain) const {
100 #ifdef ASSERT 101 #ifdef ASSERT
101 if (protection_domain == instance_klass()->protection_domain()) { 102 if (protection_domain == instance_klass()->protection_domain()) {
102 // Ensure this doesn't show up in the pd_set (invariant) 103 // Ensure this doesn't show up in the pd_set (invariant)
103 bool in_pd_set = false; 104 bool in_pd_set = false;
104 for (ProtectionDomainEntry* current = _pd_set; 105 for (ProtectionDomainEntry* current = pd_set_acquire();
105 current != NULL; 106 current != NULL;
106 current = current->next()) { 107 current = current->next()) {
107 if (current->protection_domain() == protection_domain) { 108 if (current->protection_domain() == protection_domain) {
108 in_pd_set = true; 109 in_pd_set = true;
109 break; 110 break;
119 if (protection_domain == instance_klass()->protection_domain()) { 120 if (protection_domain == instance_klass()->protection_domain()) {
120 // Succeeds trivially 121 // Succeeds trivially
121 return true; 122 return true;
122 } 123 }
123 124
124 for (ProtectionDomainEntry* current = _pd_set; 125 for (ProtectionDomainEntry* current = pd_set_acquire();
125 current != NULL; 126 current != NULL;
126 current = current->next()) { 127 current = current->next()) {
127 if (current->protection_domain() == protection_domain) return true; 128 if (current->protection_domain() == protection_domain) return true;
128 } 129 }
129 return false; 130 return false;
133 void DictionaryEntry::add_protection_domain(Dictionary* dict, Handle protection_domain) { 134 void DictionaryEntry::add_protection_domain(Dictionary* dict, Handle protection_domain) {
134 assert_locked_or_safepoint(SystemDictionary_lock); 135 assert_locked_or_safepoint(SystemDictionary_lock);
135 if (!contains_protection_domain(protection_domain())) { 136 if (!contains_protection_domain(protection_domain())) {
136 ProtectionDomainCacheEntry* entry = SystemDictionary::cache_get(protection_domain); 137 ProtectionDomainCacheEntry* entry = SystemDictionary::cache_get(protection_domain);
137 ProtectionDomainEntry* new_head = 138 ProtectionDomainEntry* new_head =
138 new ProtectionDomainEntry(entry, _pd_set); 139 new ProtectionDomainEntry(entry, pd_set());
139 // Warning: Preserve store ordering. The SystemDictionary is read 140 // Warning: Preserve store ordering. The SystemDictionary is read
140 // without locks. The new ProtectionDomainEntry must be 141 // without locks. The new ProtectionDomainEntry must be
141 // complete before other threads can be allowed to see it 142 // complete before other threads can be allowed to see it
142 // via a store to _pd_set. 143 // via a store to _pd_set.
143 OrderAccess::release_store_ptr(&_pd_set, new_head); 144 release_set_pd_set(new_head);
144 } 145 }
145 LogTarget(Trace, protectiondomain) lt; 146 LogTarget(Trace, protectiondomain) lt;
146 if (lt.is_enabled()) { 147 if (lt.is_enabled()) {
147 LogStream ls(lt); 148 LogStream ls(lt);
148 print_count(&ls); 149 print_count(&ls);