25
#include "precompiled.hpp"
26
#include "cds/archiveBuilder.hpp"
27
#include "cds/archiveUtils.hpp"
28
#include "cds/cdsConfig.hpp"
29
#include "classfile/classLoaderData.hpp"
30
#include "classfile/moduleEntry.hpp"
31
#include "classfile/packageEntry.hpp"
32
#include "classfile/vmSymbols.hpp"
33
#include "logging/log.hpp"
34
#include "memory/resourceArea.hpp"
35
#include "oops/array.hpp"
36
#include "oops/symbol.hpp"
37
#include "runtime/java.hpp"
38
#include "runtime/handles.inline.hpp"
39
#include "utilities/events.hpp"
40
#include "utilities/growableArray.hpp"
41
#include "utilities/ostream.hpp"
42
#include "utilities/quickSort.hpp"
43
#include "utilities/resourceHash.hpp"
45
PackageEntry::PackageEntry(Symbol* name, ModuleEntry* module) :
50
_must_walk_exports(false),
51
_qualified_exports(nullptr),
52
_defined_by_cds_in_class_path(0)
55
_name->increment_refcount();
57
JFR_ONLY(INIT_ID(this);)
60
PackageEntry::~PackageEntry() {
61
delete_qualified_exports();
62
_name->decrement_refcount();
66
bool PackageEntry::is_qexported_to(ModuleEntry* m) const {
67
assert(Module_lock->owned_by_self(), "should have the Module_lock");
68
assert(m != nullptr, "No module to lookup in this package's qualified exports list");
69
if (is_exported_allUnnamed() && !m->is_named()) {
71
} else if (!has_qual_exports_list()) {
74
return _qualified_exports->contains(m);
79
void PackageEntry::add_qexport(ModuleEntry* m) {
80
assert(Module_lock->owned_by_self(), "should have the Module_lock");
81
if (!has_qual_exports_list()) {
84
_qualified_exports = new (mtModule) GrowableArray<ModuleEntry*>(QUAL_EXP_SIZE, mtModule);
89
set_export_walk_required(m->loader_data());
92
_qualified_exports->append_if_missing(m);
100
void PackageEntry::set_export_walk_required(ClassLoaderData* m_loader_data) {
101
assert_locked_or_safepoint(Module_lock);
102
ModuleEntry* this_pkg_mod = module();
103
if (!_must_walk_exports &&
104
(this_pkg_mod == nullptr || this_pkg_mod->loader_data() != m_loader_data) &&
105
!m_loader_data->is_builtin_class_loader_data()) {
106
_must_walk_exports = true;
107
if (log_is_enabled(Trace, module)) {
109
assert(name() != nullptr, "PackageEntry without a valid name");
110
log_trace(module)("PackageEntry::set_export_walk_required(): package %s defined in module %s, exports list must be walked",
111
name()->as_C_string(),
112
(this_pkg_mod == nullptr || this_pkg_mod->name() == nullptr) ?
113
UNNAMED_MODULE : this_pkg_mod->name()->as_C_string());
119
void PackageEntry::set_exported(ModuleEntry* m) {
120
assert(Module_lock->owned_by_self(), "should have the Module_lock");
121
if (is_unqual_exported()) {
130
set_unqual_exported();
139
void PackageEntry::set_is_exported_allUnnamed() {
140
assert(!module()->is_open(), "should have been checked already");
141
assert(Module_lock->owned_by_self(), "should have the Module_lock");
142
if (!is_unqual_exported()) {
143
_export_flags = PKG_EXP_ALLUNNAMED;
151
void PackageEntry::purge_qualified_exports() {
152
assert_locked_or_safepoint(Module_lock);
153
if (_must_walk_exports &&
154
_qualified_exports != nullptr &&
155
!_qualified_exports->is_empty()) {
159
_must_walk_exports = false;
161
if (log_is_enabled(Trace, module)) {
163
assert(name() != nullptr, "PackageEntry without a valid name");
164
ModuleEntry* pkg_mod = module();
165
log_trace(module)("PackageEntry::purge_qualified_exports(): package %s defined in module %s, exports list being walked",
166
name()->as_C_string(),
167
(pkg_mod == nullptr || pkg_mod->name() == nullptr) ? UNNAMED_MODULE : pkg_mod->name()->as_C_string());
171
int len = _qualified_exports->length();
172
for (int idx = len - 1; idx >= 0; idx--) {
173
ModuleEntry* module_idx = _qualified_exports->at(idx);
174
ClassLoaderData* cld_idx = module_idx->loader_data();
175
if (cld_idx->is_unloading()) {
176
_qualified_exports->delete_at(idx);
179
set_export_walk_required(cld_idx);
185
void PackageEntry::delete_qualified_exports() {
186
if (_qualified_exports != nullptr) {
187
delete _qualified_exports;
189
_qualified_exports = nullptr;
192
PackageEntryTable::PackageEntryTable() { }
194
PackageEntryTable::~PackageEntryTable() {
195
class PackageEntryTableDeleter : public StackObj {
197
bool do_entry(const SymbolHandle& name, PackageEntry*& entry) {
198
if (log_is_enabled(Info, module, unload) || log_is_enabled(Debug, module)) {
200
const char* str = name->as_C_string();
201
log_info(module, unload)("unloading package %s", str);
202
log_debug(module)("PackageEntry: deleting package: %s", str);
209
PackageEntryTableDeleter deleter;
210
_table.unlink(&deleter);
211
assert(_table.number_of_entries() == 0, "should have removed all entries");
214
#if INCLUDE_CDS_JAVA_HEAP
215
typedef ResourceHashtable<
219
AnyObj::C_HEAP> ArchivedPackageEntries;
220
static ArchivedPackageEntries* _archived_packages_entries = nullptr;
222
PackageEntry* PackageEntry::allocate_archived_entry() const {
223
assert(!in_unnamed_module(), "unnamed packages/modules are not archived");
224
PackageEntry* archived_entry = (PackageEntry*)ArchiveBuilder::rw_region_alloc(sizeof(PackageEntry));
225
memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry));
227
if (_archived_packages_entries == nullptr) {
228
_archived_packages_entries = new (mtClass)ArchivedPackageEntries();
230
assert(_archived_packages_entries->get(this) == nullptr, "Each PackageEntry must not be shared across PackageEntryTables");
231
_archived_packages_entries->put(this, archived_entry);
233
return archived_entry;
236
PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) {
237
PackageEntry** ptr = _archived_packages_entries->get(orig_entry);
238
if (ptr != nullptr) {
245
void PackageEntry::iterate_symbols(MetaspaceClosure* closure) {
246
closure->push(&_name);
249
void PackageEntry::init_as_archived_entry() {
250
Array<ModuleEntry*>* archived_qualified_exports = ModuleEntry::write_growable_array(_qualified_exports);
252
_name = ArchiveBuilder::get_buffered_symbol(_name);
253
_module = ModuleEntry::get_archived_entry(_module);
254
_qualified_exports = (GrowableArray<ModuleEntry*>*)archived_qualified_exports;
255
_defined_by_cds_in_class_path = 0;
256
JFR_ONLY(set_trace_id(0);)
258
ArchivePtrMarker::mark_pointer((address*)&_name);
259
ArchivePtrMarker::mark_pointer((address*)&_module);
260
ArchivePtrMarker::mark_pointer((address*)&_qualified_exports);
263
void PackageEntry::load_from_archive() {
264
_qualified_exports = ModuleEntry::restore_growable_array((Array<ModuleEntry*>*)_qualified_exports);
265
JFR_ONLY(INIT_ID(this);)
268
static int compare_package_by_name(PackageEntry* a, PackageEntry* b) {
269
assert(a == b || a->name() != b->name(), "no duplicated names");
270
return a->name()->fast_compare(b->name());
273
void PackageEntryTable::iterate_symbols(MetaspaceClosure* closure) {
274
auto syms = [&] (const SymbolHandle& key, PackageEntry*& p) {
275
p->iterate_symbols(closure);
277
_table.iterate_all(syms);
280
Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() {
283
auto count = [&] (const SymbolHandle& key, PackageEntry*& p) {
284
if (p->module()->is_named()) {
288
_table.iterate_all(count);
290
Array<PackageEntry*>* archived_packages = ArchiveBuilder::new_rw_array<PackageEntry*>(n);
293
auto grab = [&] (const SymbolHandle& key, PackageEntry*& p) {
294
if (p->module()->is_named()) {
297
archived_packages->at_put(n++, p);
300
_table.iterate_all(grab);
304
QuickSort::sort(archived_packages->data(), n, compare_package_by_name);
306
for (int i = 0; i < n; i++) {
307
archived_packages->at_put(i, archived_packages->at(i)->allocate_archived_entry());
308
ArchivePtrMarker::mark_pointer((address*)archived_packages->adr_at(i));
310
return archived_packages;
313
void PackageEntryTable::init_archived_entries(Array<PackageEntry*>* archived_packages) {
314
for (int i = 0; i < archived_packages->length(); i++) {
315
PackageEntry* archived_entry = archived_packages->at(i);
316
archived_entry->init_as_archived_entry();
320
void PackageEntryTable::load_archived_entries(Array<PackageEntry*>* archived_packages) {
321
assert(CDSConfig::is_using_archive(), "runtime only");
323
for (int i = 0; i < archived_packages->length(); i++) {
324
PackageEntry* archived_entry = archived_packages->at(i);
325
archived_entry->load_from_archive();
326
_table.put(archived_entry->name(), archived_entry);
334
void PackageEntryTable::locked_create_entry(Symbol* name, ModuleEntry* module) {
335
assert(Module_lock->owned_by_self(), "should have the Module_lock");
336
assert(locked_lookup_only(name) == nullptr, "Package entry already exists");
337
PackageEntry* entry = new PackageEntry(name, module);
338
bool created = _table.put(name, entry);
339
assert(created, "must be");
344
PackageEntry* PackageEntryTable::locked_create_entry_if_absent(Symbol* name, ModuleEntry* module) {
345
assert(Module_lock->owned_by_self(), "should have the Module_lock");
348
PackageEntry* entry = new PackageEntry(name, module);
349
PackageEntry** old_entry = _table.put_if_absent(name, entry, &created);
358
PackageEntry* PackageEntryTable::create_entry_if_absent(Symbol* name, ModuleEntry* module) {
359
MutexLocker ml(Module_lock);
360
return locked_create_entry_if_absent(name, module);
363
PackageEntry* PackageEntryTable::lookup_only(Symbol* name) {
364
assert(!Module_lock->owned_by_self(), "should not have the Module_lock - use locked_lookup_only");
365
MutexLocker ml(Module_lock);
366
return locked_lookup_only(name);
369
PackageEntry* PackageEntryTable::locked_lookup_only(Symbol* name) {
370
assert(Module_lock->owned_by_self(), "should have the Module_lock");
371
PackageEntry** entry = _table.get(name);
372
return entry == nullptr ? nullptr : *entry;
377
void PackageEntryTable::verify_javabase_packages(GrowableArray<Symbol*> *pkg_list) {
378
assert_lock_strong(Module_lock);
379
auto verifier = [&] (const SymbolHandle& name, PackageEntry*& entry) {
380
ModuleEntry* m = entry->module();
381
Symbol* module_name = (m == nullptr ? nullptr : m->name());
382
if (module_name != nullptr &&
383
(module_name->fast_compare(vmSymbols::java_base()) == 0) &&
384
!pkg_list->contains(entry->name())) {
386
vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization",
387
entry->name()->as_C_string());
390
_table.iterate_all(verifier);
394
void PackageEntry::package_exports_do(ModuleClosure* f) {
395
assert_locked_or_safepoint(Module_lock);
396
assert(f != nullptr, "invariant");
398
if (has_qual_exports_list()) {
399
int qe_len = _qualified_exports->length();
401
for (int i = 0; i < qe_len; ++i) {
402
f->do_module(_qualified_exports->at(i));
407
bool PackageEntry::exported_pending_delete() const {
408
assert_locked_or_safepoint(Module_lock);
409
return (is_unqual_exported() && _qualified_exports != nullptr);
413
void PackageEntryTable::purge_all_package_exports() {
414
assert_locked_or_safepoint(Module_lock);
415
auto purge = [&] (const SymbolHandle& name, PackageEntry*& entry) {
416
if (entry->exported_pending_delete()) {
419
entry->delete_qualified_exports();
420
} else if (entry->is_qual_exported()) {
421
entry->purge_qualified_exports();
424
_table.iterate_all(purge);
427
void PackageEntryTable::packages_do(void f(PackageEntry*)) {
428
auto doit = [&] (const SymbolHandle&name, PackageEntry*& entry) {
431
assert_locked_or_safepoint(Module_lock);
432
_table.iterate_all(doit);
436
GrowableArray<PackageEntry*>* PackageEntryTable::get_system_packages() {
437
GrowableArray<PackageEntry*>* loaded_class_pkgs = new GrowableArray<PackageEntry*>(50);
438
auto grab = [&] (const SymbolHandle& name, PackageEntry*& entry) {
439
if (entry->has_loaded_class()) {
440
loaded_class_pkgs->append(entry);
444
MutexLocker ml(Module_lock);
445
_table.iterate_all(grab);
447
return loaded_class_pkgs;
450
void PackageEntryTable::print(outputStream* st) {
451
auto printer = [&] (const SymbolHandle& name, PackageEntry*& entry) {
454
st->print_cr("Package Entry Table (table_size=%d, entries=%d)",
455
_table.table_size(), _table.number_of_entries());
456
_table.iterate_all(printer);
462
void PackageEntry::print(outputStream* st) {
464
st->print_cr("package entry " PTR_FORMAT " name %s module %s classpath_index "
465
INT32_FORMAT " is_exported_unqualified %d is_exported_allUnnamed %d ",
466
p2i(this), name()->as_C_string(),
467
(module()->is_named() ? module()->name()->as_C_string() : UNNAMED_MODULE),
468
_classpath_index, _export_flags == PKG_EXP_UNQUALIFIED,
469
_export_flags == PKG_EXP_ALLUNNAMED);