123 // Remove dead module entries within the package's exported list. Note that |
123 // Remove dead module entries within the package's exported list. Note that |
124 // if all of the modules on the _qualified_exports get purged the list does not |
124 // if all of the modules on the _qualified_exports get purged the list does not |
125 // get deleted. This prevents the package from illegally transitioning from |
125 // get deleted. This prevents the package from illegally transitioning from |
126 // exported to non-exported. |
126 // exported to non-exported. |
127 void PackageEntry::purge_qualified_exports() { |
127 void PackageEntry::purge_qualified_exports() { |
128 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
128 assert_locked_or_safepoint(Module_lock); |
129 if (_must_walk_exports && |
129 if (_must_walk_exports && |
130 _qualified_exports != NULL && |
130 _qualified_exports != NULL && |
131 !_qualified_exports->is_empty()) { |
131 !_qualified_exports->is_empty()) { |
132 ModuleEntry* pkg_module = module(); |
132 ModuleEntry* pkg_module = module(); |
133 |
133 |
226 return entry; |
225 return entry; |
227 } |
226 } |
228 } |
227 } |
229 |
228 |
230 PackageEntry* PackageEntryTable::lookup(Symbol* name, ModuleEntry* module) { |
229 PackageEntry* PackageEntryTable::lookup(Symbol* name, ModuleEntry* module) { |
|
230 MutexLocker ml(Module_lock); |
231 PackageEntry* p = lookup_only(name); |
231 PackageEntry* p = lookup_only(name); |
232 if (p != NULL) { |
232 if (p != NULL) { |
233 return p; |
233 return p; |
234 } else { |
234 } else { |
235 // If not found, add to table. Grab the PackageEntryTable lock first. |
235 assert(module != NULL, "module should never be null"); |
236 MutexLocker ml(Module_lock); |
236 PackageEntry* entry = new_entry(compute_hash(name), name, module); |
237 |
237 add_entry(index_for(name), entry); |
238 // Since look-up was done lock-free, we need to check if another thread beat |
238 return entry; |
239 // us in the race to insert the package. |
|
240 PackageEntry* test = lookup_only(name); |
|
241 if (test != NULL) { |
|
242 // A race occurred and another thread introduced the package. |
|
243 return test; |
|
244 } else { |
|
245 assert(module != NULL, "module should never be null"); |
|
246 PackageEntry* entry = new_entry(compute_hash(name), name, module); |
|
247 add_entry(index_for(name), entry); |
|
248 return entry; |
|
249 } |
|
250 } |
239 } |
251 } |
240 } |
252 |
241 |
253 PackageEntry* PackageEntryTable::lookup_only(Symbol* name) { |
242 PackageEntry* PackageEntryTable::lookup_only(Symbol* name) { |
|
243 MutexLockerEx ml(Module_lock->owned_by_self() ? NULL : Module_lock); |
254 int index = index_for(name); |
244 int index = index_for(name); |
255 for (PackageEntry* p = bucket(index); p != NULL; p = p->next()) { |
245 for (PackageEntry* p = bucket(index); p != NULL; p = p->next()) { |
256 if (p->name()->fast_compare(name) == 0) { |
246 if (p->name()->fast_compare(name) == 0) { |
257 return p; |
247 return p; |
258 } |
248 } |
294 } |
284 } |
295 } |
285 } |
296 } |
286 } |
297 |
287 |
298 bool PackageEntry::exported_pending_delete() const { |
288 bool PackageEntry::exported_pending_delete() const { |
299 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
289 assert_locked_or_safepoint(Module_lock); |
300 return (is_unqual_exported() && _qualified_exports != NULL); |
290 return (is_unqual_exported() && _qualified_exports != NULL); |
301 } |
291 } |
302 |
292 |
303 // Remove dead entries from all packages' exported list |
293 // Remove dead entries from all packages' exported list |
304 void PackageEntryTable::purge_all_package_exports() { |
294 void PackageEntryTable::purge_all_package_exports() { |