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.
171 // freeing each entry.
172 for (int i = 0; i < table_size(); ++i) {
173 for (PackageEntry* p = bucket(i); p != NULL;) {
174 PackageEntry* to_remove = p;
175 // read next before freeing.
176 p = p->next();
177
178 // Clean out the C heap allocated qualified exports list first before freeing the entry
179 to_remove->delete_qualified_exports();
180 to_remove->name()->decrement_refcount();
181
182 // Unlink from the Hashtable prior to freeing
183 unlink_entry(to_remove);
184 FREE_C_HEAP_ARRAY(char, to_remove);
185 }
186 }
187 assert(number_of_entries() == 0, "should have removed all entries");
188 assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list");
189 }
190
191 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
192 assert(Module_lock->owned_by_self(), "should have the Module_lock");
193 PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
194
195 JFR_ONLY(INIT_ID(entry);)
196
197 // Initialize fields specific to a PackageEntry
198 entry->init();
199 entry->name()->increment_refcount();
200 entry->set_module(module);
201 return entry;
202 }
203
204 void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) {
205 assert(Module_lock->owned_by_self(), "should have the Module_lock");
206 Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
207 }
208
209 // Create package entry in loader's package entry table. Assume Module lock
210 // was taken by caller.
256 }
257
258 // Called when a define module for java.base is being processed.
259 // Verify the packages loaded thus far are in java.base's package list.
260 void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) {
261 assert_lock_strong(Module_lock);
262 for (int i = 0; i < table_size(); i++) {
263 for (PackageEntry* entry = bucket(i);
264 entry != NULL;
265 entry = entry->next()) {
266 ModuleEntry* m = entry->module();
267 Symbol* module_name = (m == NULL ? NULL : m->name());
268 if (module_name != NULL &&
269 (module_name->fast_compare(vmSymbols::java_base()) == 0) &&
270 !pkg_list->contains(entry->name())) {
271 ResourceMark rm;
272 vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization", entry->name()->as_C_string());
273 }
274 }
275 }
276
277 }
278
279 // iteration of qualified exports
280 void PackageEntry::package_exports_do(ModuleClosure* f) {
281 assert_locked_or_safepoint(Module_lock);
282 assert(f != NULL, "invariant");
283
284 if (has_qual_exports_list()) {
285 int qe_len = _qualified_exports->length();
286
287 for (int i = 0; i < qe_len; ++i) {
288 f->do_module(_qualified_exports->at(i));
289 }
290 }
291 }
292
293 bool PackageEntry::exported_pending_delete() const {
294 assert_locked_or_safepoint(Module_lock);
295 return (is_unqual_exported() && _qualified_exports != NULL);
296 }
|
1 /*
2 * Copyright (c) 2016, 2020, 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/archiveUtils.hpp"
30 #include "memory/metaspaceShared.hpp"
31 #include "memory/resourceArea.hpp"
32 #include "oops/array.hpp"
33 #include "oops/symbol.hpp"
34 #include "runtime/handles.inline.hpp"
35 #include "utilities/events.hpp"
36 #include "utilities/growableArray.hpp"
37 #include "utilities/hashtable.inline.hpp"
38 #include "utilities/ostream.hpp"
39 #include "utilities/quickSort.hpp"
40 #include "utilities/resourceHash.hpp"
41
42 // Returns true if this package specifies m as a qualified export, including through an unnamed export
43 bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
44 assert(Module_lock->owned_by_self(), "should have the Module_lock");
45 assert(m != NULL, "No module to lookup in this package's qualified exports list");
46 if (is_exported_allUnnamed() && !m->is_named()) {
47 return true;
48 } else if (!has_qual_exports_list()) {
49 return false;
50 } else {
51 return _qualified_exports->contains(m);
52 }
53 }
54
55 // Add a module to the package's qualified export list.
56 void PackageEntry::add_qexport(ModuleEntry* m) {
57 assert(Module_lock->owned_by_self(), "should have the Module_lock");
58 if (!has_qual_exports_list()) {
59 // Lazily create a package's qualified exports list.
60 // Initial size is small, do not anticipate export lists to be large.
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 #if INCLUDE_CDS_JAVA_HEAP
197 typedef ResourceHashtable<
198 const PackageEntry*,
199 PackageEntry*,
200 primitive_hash<const PackageEntry*>,
201 primitive_equals<const PackageEntry*>,
202 557, // prime number
203 ResourceObj::C_HEAP> ArchivedPackageEntries;
204 static ArchivedPackageEntries* _archived_packages_entries = NULL;
205
206 PackageEntry* PackageEntry::allocate_archived_entry() const {
207 assert(!in_unnamed_module(), "unnamed packages/modules are not archived");
208 PackageEntry* archived_entry = (PackageEntry*)MetaspaceShared::read_write_space_alloc(sizeof(PackageEntry));
209 memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry));
210
211 if (_archived_packages_entries == NULL) {
212 _archived_packages_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedPackageEntries();
213 }
214 assert(_archived_packages_entries->get(this) == NULL, "Each PackageEntry must not be shared across PackageEntryTables");
215 _archived_packages_entries->put(this, archived_entry);
216
217 return archived_entry;
218 }
219
220 PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) {
221 PackageEntry** ptr = _archived_packages_entries->get(orig_entry);
222 assert(ptr != NULL && *ptr != NULL, "must have been allocated");
223 return *ptr;
224 }
225
226 void PackageEntry::init_as_archived_entry() {
227 Array<ModuleEntry*>* archived_qualified_exports = ModuleEntry::write_archived_entry_array(_qualified_exports);
228
229 set_next(NULL);
230 set_literal(MetaspaceShared::get_relocated_symbol(literal()));
231 set_hash(0x0); // re-init at runtime
232 _module = ModuleEntry::get_archived_entry(_module);
233 _qualified_exports = (GrowableArray<ModuleEntry*>*)archived_qualified_exports;
234 _defined_by_cds_in_class_path = 0;
235
236 ArchivePtrMarker::mark_pointer((address*)literal_addr());
237 ArchivePtrMarker::mark_pointer((address*)&_module);
238 ArchivePtrMarker::mark_pointer((address*)&_qualified_exports);
239 }
240
241 void PackageEntry::load_from_archive() {
242 _qualified_exports = ModuleEntry::read_archived_entry_array((Array<ModuleEntry*>*)_qualified_exports);
243 JFR_ONLY(INIT_ID(this);)
244 }
245
246 static int compare_package_by_name(PackageEntry* a, PackageEntry* b) {
247 return a->name()->fast_compare(b->name());
248 }
249
250 Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
251 // First count the packages in named modules
252 int n, i;
253 for (n = 0, i = 0; i < table_size(); ++i) {
254 for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
255 if (p->module()->name() != NULL) {
256 n++;
257 }
258 }
259 }
260
261 Array<PackageEntry*>* archived_packages = MetaspaceShared::new_rw_array<PackageEntry*>(n);
262 for (n = 0, i = 0; i < table_size(); ++i) {
263 for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) {
264 if (p->module()->name() != NULL) {
265 // We don't archive unnamed modules, or packages in unnamed modules. They will be
266 // created on-demand at runtime as classes in such packages are loaded.
267 archived_packages->at_put(n++, p);
268 }
269 }
270 }
271 if (n > 1) {
272 QuickSort::sort(archived_packages->data(), n, (_sort_Fn)compare_package_by_name, true);
273 }
274 for (i = 0; i < n; i++) {
275 archived_packages->at_put(i, archived_packages->at(i)->allocate_archived_entry());
276 ArchivePtrMarker::mark_pointer((address*)archived_packages->adr_at(i));
277 }
278 return archived_packages;
279 }
280
281 void PackageEntryTable::init_archived_entries(Array<PackageEntry*>* archived_packages) {
282 for (int i = 0; i < archived_packages->length(); i++) {
283 PackageEntry* archived_entry = archived_packages->at(i);
284 archived_entry->init_as_archived_entry();
285 }
286 }
287
288 void PackageEntryTable::load_archived_entries(Array<PackageEntry*>* archived_packages) {
289 assert(UseSharedSpaces, "runtime only");
290
291 for (int i = 0; i < archived_packages->length(); i++) {
292 PackageEntry* archived_entry = archived_packages->at(i);
293 archived_entry->load_from_archive();
294
295 unsigned int hash = compute_hash(archived_entry->name());
296 archived_entry->set_hash(hash);
297 add_entry(hash_to_index(hash), archived_entry);
298 }
299 }
300
301 #endif // INCLUDE_CDS_JAVA_HEAP
302
303 PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) {
304 assert(Module_lock->owned_by_self(), "should have the Module_lock");
305 PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name);
306
307 JFR_ONLY(INIT_ID(entry);)
308
309 // Initialize fields specific to a PackageEntry
310 entry->init();
311 entry->name()->increment_refcount();
312 entry->set_module(module);
313 return entry;
314 }
315
316 void PackageEntryTable::add_entry(int index, PackageEntry* new_entry) {
317 assert(Module_lock->owned_by_self(), "should have the Module_lock");
318 Hashtable<Symbol*, mtModule>::add_entry(index, (HashtableEntry<Symbol*, mtModule>*)new_entry);
319 }
320
321 // Create package entry in loader's package entry table. Assume Module lock
322 // was taken by caller.
368 }
369
370 // Called when a define module for java.base is being processed.
371 // Verify the packages loaded thus far are in java.base's package list.
372 void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) {
373 assert_lock_strong(Module_lock);
374 for (int i = 0; i < table_size(); i++) {
375 for (PackageEntry* entry = bucket(i);
376 entry != NULL;
377 entry = entry->next()) {
378 ModuleEntry* m = entry->module();
379 Symbol* module_name = (m == NULL ? NULL : m->name());
380 if (module_name != NULL &&
381 (module_name->fast_compare(vmSymbols::java_base()) == 0) &&
382 !pkg_list->contains(entry->name())) {
383 ResourceMark rm;
384 vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization", entry->name()->as_C_string());
385 }
386 }
387 }
388 }
389
390 // iteration of qualified exports
391 void PackageEntry::package_exports_do(ModuleClosure* f) {
392 assert_locked_or_safepoint(Module_lock);
393 assert(f != NULL, "invariant");
394
395 if (has_qual_exports_list()) {
396 int qe_len = _qualified_exports->length();
397
398 for (int i = 0; i < qe_len; ++i) {
399 f->do_module(_qualified_exports->at(i));
400 }
401 }
402 }
403
404 bool PackageEntry::exported_pending_delete() const {
405 assert_locked_or_safepoint(Module_lock);
406 return (is_unqual_exported() && _qualified_exports != NULL);
407 }
|