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