|
1 /* |
|
2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. |
|
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
|
4 * |
|
5 * This code is free software; you can redistribute it and/or modify it |
|
6 * under the terms of the GNU General Public License version 2 only, as |
|
7 * published by the Free Software Foundation. |
|
8 * |
|
9 * This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 * version 2 for more details (a copy is included in the LICENSE file that |
|
13 * accompanied this code). |
|
14 * |
|
15 * You should have received a copy of the GNU General Public License version |
|
16 * 2 along with this work; if not, write to the Free Software Foundation, |
|
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 * |
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
|
20 * or visit www.oracle.com if you need additional information or have any |
|
21 * questions. |
|
22 * |
|
23 */ |
|
24 |
|
25 #include "precompiled.hpp" |
|
26 #include "classfile/moduleEntry.hpp" |
|
27 #include "classfile/packageEntry.hpp" |
|
28 #include "logging/log.hpp" |
|
29 #include "memory/resourceArea.hpp" |
|
30 #include "oops/symbol.hpp" |
|
31 #include "runtime/handles.inline.hpp" |
|
32 #include "trace/traceMacros.hpp" |
|
33 #include "utilities/events.hpp" |
|
34 #include "utilities/growableArray.hpp" |
|
35 #include "utilities/hashtable.inline.hpp" |
|
36 #include "utilities/ostream.hpp" |
|
37 |
|
38 // Returns true if this package specifies m as a qualified export, including through an unnamed export |
|
39 bool PackageEntry::is_qexported_to(ModuleEntry* m) const { |
|
40 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
|
41 assert(m != NULL, "No module to lookup in this package's qualified exports list"); |
|
42 if (is_exported_allUnnamed() && !m->is_named()) { |
|
43 return true; |
|
44 } else if (!has_qual_exports_list()) { |
|
45 return false; |
|
46 } else { |
|
47 return _qualified_exports->contains(m); |
|
48 } |
|
49 } |
|
50 |
|
51 // Add a module to the package's qualified export list. |
|
52 void PackageEntry::add_qexport(ModuleEntry* m) { |
|
53 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
|
54 if (!has_qual_exports_list()) { |
|
55 // Lazily create a package's qualified exports list. |
|
56 // Initial size is small, do not anticipate export lists to be large. |
|
57 _qualified_exports = new (ResourceObj::C_HEAP, mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, true); |
|
58 } |
|
59 |
|
60 // Determine, based on this newly established export to module m, |
|
61 // if this package's export list should be walked at a GC safepoint. |
|
62 set_export_walk_required(m->loader_data()); |
|
63 |
|
64 // Establish exportability to module m |
|
65 _qualified_exports->append_if_missing(m); |
|
66 } |
|
67 |
|
68 // If the module's loader, that an export is being established to, is |
|
69 // not the same loader as this module's and is not one of the 3 builtin |
|
70 // class loaders, then this package's export list must be walked at GC |
|
71 // safepoint. Modules have the same life cycle as their defining class |
|
72 // loaders and should be removed if dead. |
|
73 void PackageEntry::set_export_walk_required(ClassLoaderData* m_loader_data) { |
|
74 assert_locked_or_safepoint(Module_lock); |
|
75 ModuleEntry* this_pkg_mod = module(); |
|
76 if (!_must_walk_exports && |
|
77 (this_pkg_mod == NULL || this_pkg_mod->loader_data() != m_loader_data) && |
|
78 !m_loader_data->is_builtin_class_loader_data()) { |
|
79 _must_walk_exports = true; |
|
80 if (log_is_enabled(Trace, module)) { |
|
81 ResourceMark rm; |
|
82 assert(name() != NULL, "PackageEntry without a valid name"); |
|
83 log_trace(module)("PackageEntry::set_export_walk_required(): package %s defined in module %s, exports list must be walked", |
|
84 name()->as_C_string(), |
|
85 (this_pkg_mod == NULL || this_pkg_mod->name() == NULL) ? |
|
86 UNNAMED_MODULE : this_pkg_mod->name()->as_C_string()); |
|
87 } |
|
88 } |
|
89 } |
|
90 |
|
91 // Set the package's exported states based on the value of the ModuleEntry. |
|
92 void PackageEntry::set_exported(ModuleEntry* m) { |
|
93 MutexLocker m1(Module_lock); |
|
94 if (is_unqual_exported()) { |
|
95 // An exception could be thrown, but choose to simply ignore. |
|
96 // Illegal to convert an unqualified exported package to be qualifiedly exported |
|
97 return; |
|
98 } |
|
99 |
|
100 if (m == NULL) { |
|
101 // NULL indicates the package is being unqualifiedly exported. Clean up |
|
102 // the qualified list at the next safepoint. |
|
103 set_unqual_exported(); |
|
104 } else { |
|
105 // Add the exported module |
|
106 add_qexport(m); |
|
107 } |
|
108 } |
|
109 |
|
110 // Set the package as exported to all unnamed modules unless the package is |
|
111 // already unqualifiedly exported. |
|
112 void PackageEntry::set_is_exported_allUnnamed() { |
|
113 if (module()->is_open()) { |
|
114 // No-op for open modules since all packages are unqualifiedly exported |
|
115 return; |
|
116 } |
|
117 |
|
118 MutexLocker m1(Module_lock); |
|
119 if (!is_unqual_exported()) { |
|
120 _export_flags = PKG_EXP_ALLUNNAMED; |
|
121 } |
|
122 } |
|
123 |
|
124 // Remove dead module entries within the package's exported list. Note that |
|
125 // if all of the modules on the _qualified_exports get purged the list does not |
|
126 // get deleted. This prevents the package from illegally transitioning from |
|
127 // exported to non-exported. |
|
128 void PackageEntry::purge_qualified_exports() { |
|
129 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
130 if (_must_walk_exports && |
|
131 _qualified_exports != NULL && |
|
132 !_qualified_exports->is_empty()) { |
|
133 ModuleEntry* pkg_module = module(); |
|
134 |
|
135 // This package's _must_walk_exports flag will be reset based |
|
136 // on the remaining live modules on the exports list. |
|
137 _must_walk_exports = false; |
|
138 |
|
139 if (log_is_enabled(Trace, module)) { |
|
140 ResourceMark rm; |
|
141 assert(name() != NULL, "PackageEntry without a valid name"); |
|
142 ModuleEntry* pkg_mod = module(); |
|
143 log_trace(module)("PackageEntry::purge_qualified_exports(): package %s defined in module %s, exports list being walked", |
|
144 name()->as_C_string(), |
|
145 (pkg_mod == NULL || pkg_mod->name() == NULL) ? UNNAMED_MODULE : pkg_mod->name()->as_C_string()); |
|
146 } |
|
147 |
|
148 // Go backwards because this removes entries that are dead. |
|
149 int len = _qualified_exports->length(); |
|
150 for (int idx = len - 1; idx >= 0; idx--) { |
|
151 ModuleEntry* module_idx = _qualified_exports->at(idx); |
|
152 ClassLoaderData* cld_idx = module_idx->loader_data(); |
|
153 if (cld_idx->is_unloading()) { |
|
154 _qualified_exports->delete_at(idx); |
|
155 } else { |
|
156 // Update the need to walk this package's exports based on live modules |
|
157 set_export_walk_required(cld_idx); |
|
158 } |
|
159 } |
|
160 } |
|
161 } |
|
162 |
|
163 void PackageEntry::delete_qualified_exports() { |
|
164 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
165 if (_qualified_exports != NULL) { |
|
166 delete _qualified_exports; |
|
167 } |
|
168 _qualified_exports = NULL; |
|
169 } |
|
170 |
|
171 PackageEntryTable::PackageEntryTable(int table_size) |
|
172 : Hashtable<Symbol*, mtModule>(table_size, sizeof(PackageEntry)) |
|
173 { |
|
174 } |
|
175 |
|
176 PackageEntryTable::~PackageEntryTable() { |
|
177 // Walk through all buckets and all entries in each bucket, |
|
178 // freeing each entry. |
|
179 for (int i = 0; i < table_size(); ++i) { |
|
180 for (PackageEntry* p = bucket(i); p != NULL;) { |
|
181 PackageEntry* to_remove = p; |
|
182 // read next before freeing. |
|
183 p = p->next(); |
|
184 |
|
185 // Clean out the C heap allocated qualified exports list first before freeing the entry |
|
186 to_remove->delete_qualified_exports(); |
|
187 to_remove->name()->decrement_refcount(); |
|
188 |
|
189 // Unlink from the Hashtable prior to freeing |
|
190 unlink_entry(to_remove); |
|
191 FREE_C_HEAP_ARRAY(char, to_remove); |
|
192 } |
|
193 } |
|
194 assert(number_of_entries() == 0, "should have removed all entries"); |
|
195 assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list"); |
|
196 free_buckets(); |
|
197 } |
|
198 |
|
199 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) { |
|
200 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
|
201 PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name); |
|
202 |
|
203 TRACE_INIT_ID(entry); |
|
204 |
|
205 // Initialize fields specific to a PackageEntry |
|
206 entry->init(); |
|
207 entry->name()->increment_refcount(); |
|
208 entry->set_module(module); |
|
209 return entry; |
|
210 } |
|
211 |
|
212 void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) { |
|
213 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
|
214 Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry); |
|
215 } |
|
216 |
|
217 // Create package in loader's package entry table and return the entry. |
|
218 // If entry already exists, return null. Assume Module lock was taken by caller. |
|
219 PackageEntry* PackageEntryTable::locked_create_entry_or_null(Symbol* name, ModuleEntry* module) { |
|
220 assert(Module_lock->owned_by_self(), "should have the Module_lock"); |
|
221 // Check if package already exists. Return NULL if it does. |
|
222 if (lookup_only(name) != NULL) { |
|
223 return NULL; |
|
224 } else { |
|
225 PackageEntry* entry = new_entry(compute_hash(name), name, module); |
|
226 add_entry(index_for(name), entry); |
|
227 return entry; |
|
228 } |
|
229 } |
|
230 |
|
231 PackageEntry* PackageEntryTable::lookup(Symbol* name, ModuleEntry* module) { |
|
232 PackageEntry* p = lookup_only(name); |
|
233 if (p != NULL) { |
|
234 return p; |
|
235 } else { |
|
236 // If not found, add to table. Grab the PackageEntryTable lock first. |
|
237 MutexLocker ml(Module_lock); |
|
238 |
|
239 // Since look-up was done lock-free, we need to check if another thread beat |
|
240 // us in the race to insert the package. |
|
241 PackageEntry* test = lookup_only(name); |
|
242 if (test != NULL) { |
|
243 // A race occurred and another thread introduced the package. |
|
244 return test; |
|
245 } else { |
|
246 assert(module != NULL, "module should never be null"); |
|
247 PackageEntry* entry = new_entry(compute_hash(name), name, module); |
|
248 add_entry(index_for(name), entry); |
|
249 return entry; |
|
250 } |
|
251 } |
|
252 } |
|
253 |
|
254 PackageEntry* PackageEntryTable::lookup_only(Symbol* name) { |
|
255 int index = index_for(name); |
|
256 for (PackageEntry* p = bucket(index); p != NULL; p = p->next()) { |
|
257 if (p->name()->fast_compare(name) == 0) { |
|
258 return p; |
|
259 } |
|
260 } |
|
261 return NULL; |
|
262 } |
|
263 |
|
264 // Called when a define module for java.base is being processed. |
|
265 // Verify the packages loaded thus far are in java.base's package list. |
|
266 void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) { |
|
267 assert_lock_strong(Module_lock); |
|
268 for (int i = 0; i < table_size(); i++) { |
|
269 for (PackageEntry* entry = bucket(i); |
|
270 entry != NULL; |
|
271 entry = entry->next()) { |
|
272 ModuleEntry* m = entry->module(); |
|
273 Symbol* module_name = (m == NULL ? NULL : m->name()); |
|
274 if (module_name != NULL && |
|
275 (module_name->fast_compare(vmSymbols::java_base()) == 0) && |
|
276 !pkg_list->contains(entry->name())) { |
|
277 ResourceMark rm; |
|
278 vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization", entry->name()->as_C_string()); |
|
279 } |
|
280 } |
|
281 } |
|
282 |
|
283 } |
|
284 |
|
285 // iteration of qualified exports |
|
286 void PackageEntry::package_exports_do(ModuleClosure* const f) { |
|
287 assert_locked_or_safepoint(Module_lock); |
|
288 assert(f != NULL, "invariant"); |
|
289 |
|
290 if (has_qual_exports_list()) { |
|
291 int qe_len = _qualified_exports->length(); |
|
292 |
|
293 for (int i = 0; i < qe_len; ++i) { |
|
294 f->do_module(_qualified_exports->at(i)); |
|
295 } |
|
296 } |
|
297 } |
|
298 |
|
299 bool PackageEntry::exported_pending_delete() const { |
|
300 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
301 return (is_unqual_exported() && _qualified_exports != NULL); |
|
302 } |
|
303 |
|
304 // Remove dead entries from all packages' exported list |
|
305 void PackageEntryTable::purge_all_package_exports() { |
|
306 assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint"); |
|
307 for (int i = 0; i < table_size(); i++) { |
|
308 for (PackageEntry* entry = bucket(i); |
|
309 entry != NULL; |
|
310 entry = entry->next()) { |
|
311 if (entry->exported_pending_delete()) { |
|
312 // exported list is pending deletion due to a transition |
|
313 // from qualified to unqualified |
|
314 entry->delete_qualified_exports(); |
|
315 } else if (entry->is_qual_exported()) { |
|
316 entry->purge_qualified_exports(); |
|
317 } |
|
318 } |
|
319 } |
|
320 } |
|
321 |
|
322 void PackageEntryTable::print(outputStream* st) { |
|
323 st->print_cr("Package Entry Table (table_size=%d, entries=%d)", |
|
324 table_size(), number_of_entries()); |
|
325 for (int i = 0; i < table_size(); i++) { |
|
326 for (PackageEntry* probe = bucket(i); |
|
327 probe != NULL; |
|
328 probe = probe->next()) { |
|
329 probe->print(st); |
|
330 } |
|
331 } |
|
332 } |
|
333 |
|
334 // This function may be called from debuggers so access private fields directly |
|
335 // to prevent triggering locking-related asserts that could result from calling |
|
336 // getter methods. |
|
337 void PackageEntry::print(outputStream* st) { |
|
338 ResourceMark rm; |
|
339 st->print_cr("package entry " PTR_FORMAT " name %s module %s classpath_index " |
|
340 INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d " "next " PTR_FORMAT, |
|
341 p2i(this), name()->as_C_string(), |
|
342 (module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE), |
|
343 _classpath_index, _export_flags == PKG_EXP_UNQUALIFIED, |
|
344 _export_flags == PKG_EXP_ALLUNNAMED, p2i(next())); |
|
345 } |
|
346 |
|
347 void PackageEntryTable::verify() { |
|
348 verify_table<PackageEntry>("Package Entry Table"); |
|
349 } |
|
350 |
|
351 void PackageEntry::verify() { |
|
352 guarantee(name() != NULL, "A package entry must have a corresponding symbol name."); |
|
353 } |