< prev index next >

src/hotspot/share/classfile/packageEntry.cpp

Print this page

*** 1,7 **** /* ! * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 24,40 **** --- 24,45 ---- #include "precompiled.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/packageEntry.hpp" #include "logging/log.hpp" + #include "memory/archiveUtils.hpp" + #include "memory/metaspaceShared.hpp" #include "memory/resourceArea.hpp" + #include "oops/array.hpp" #include "oops/symbol.hpp" #include "runtime/handles.inline.hpp" #include "utilities/events.hpp" #include "utilities/growableArray.hpp" #include "utilities/hashtable.inline.hpp" #include "utilities/ostream.hpp" + #include "utilities/quickSort.hpp" + #include "utilities/resourceHash.hpp" // Returns true if this package specifies m as a qualified export, including through an unnamed export bool PackageEntry::is_qexported_to(ModuleEntry* m) const { assert(Module_lock->owned_by_self(), "should have the Module_lock"); assert(m != NULL, "No module to lookup in this package's qualified exports list");
*** 186,195 **** --- 191,307 ---- } assert(number_of_entries() == 0, "should have removed all entries"); assert(new_entry_free_list() == NULL, "entry present on PackageEntryTable's free list"); } + #if INCLUDE_CDS_JAVA_HEAP + typedef ResourceHashtable< + const PackageEntry*, + PackageEntry*, + primitive_hash<const PackageEntry*>, + primitive_equals<const PackageEntry*>, + 557, // prime number + ResourceObj::C_HEAP> ArchivedPackageEntries; + static ArchivedPackageEntries* _archived_packages_entries = NULL; + + PackageEntry* PackageEntry::allocate_archived_entry() const { + assert(!in_unnamed_module(), "unnamed packages/modules are not archived"); + PackageEntry* archived_entry = (PackageEntry*)MetaspaceShared::read_write_space_alloc(sizeof(PackageEntry)); + memcpy((void*)archived_entry, (void*)this, sizeof(PackageEntry)); + + if (_archived_packages_entries == NULL) { + _archived_packages_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedPackageEntries(); + } + assert(_archived_packages_entries->get(this) == NULL, "Each PackageEntry must not be shared across PackageEntryTables"); + _archived_packages_entries->put(this, archived_entry); + + return archived_entry; + } + + PackageEntry* PackageEntry::get_archived_entry(PackageEntry* orig_entry) { + PackageEntry** ptr = _archived_packages_entries->get(orig_entry); + assert(ptr != NULL && *ptr != NULL, "must have been allocated"); + return *ptr; + } + + void PackageEntry::init_as_archived_entry() { + Array<ModuleEntry*>* archived_qualified_exports = ModuleEntry::write_archived_entry_array(_qualified_exports); + + set_next(NULL); + set_literal(MetaspaceShared::get_relocated_symbol(literal())); + set_hash(0x0); // re-init at runtime + _module = ModuleEntry::get_archived_entry(_module); + _qualified_exports = (GrowableArray<ModuleEntry*>*)archived_qualified_exports; + _defined_by_cds_in_class_path = 0; + + ArchivePtrMarker::mark_pointer((address*)literal_addr()); + ArchivePtrMarker::mark_pointer((address*)&_module); + ArchivePtrMarker::mark_pointer((address*)&_qualified_exports); + } + + void PackageEntry::load_from_archive() { + _qualified_exports = ModuleEntry::read_archived_entry_array((Array<ModuleEntry*>*)_qualified_exports); + JFR_ONLY(INIT_ID(this);) + } + + static int compare_package_by_name(PackageEntry* a, PackageEntry* b) { + return a->name()->fast_compare(b->name()); + } + + Array<PackageEntry*>* PackageEntryTable::allocate_archived_entries() { + // First count the packages in named modules + int n, i; + for (n = 0, i = 0; i < table_size(); ++i) { + for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) { + if (p->module()->name() != NULL) { + n++; + } + } + } + + Array<PackageEntry*>* archived_packages = MetaspaceShared::new_rw_array<PackageEntry*>(n); + for (n = 0, i = 0; i < table_size(); ++i) { + for (PackageEntry* p = bucket(i); p != NULL; p = p->next()) { + if (p->module()->name() != NULL) { + // We don't archive unnamed modules, or packages in unnamed modules. They will be + // created on-demand at runtime as classes in such packages are loaded. + archived_packages->at_put(n++, p); + } + } + } + if (n > 1) { + QuickSort::sort(archived_packages->data(), n, (_sort_Fn)compare_package_by_name, true); + } + for (i = 0; i < n; i++) { + archived_packages->at_put(i, archived_packages->at(i)->allocate_archived_entry()); + ArchivePtrMarker::mark_pointer((address*)archived_packages->adr_at(i)); + } + return archived_packages; + } + + void PackageEntryTable::init_archived_entries(Array<PackageEntry*>* archived_packages) { + for (int i = 0; i < archived_packages->length(); i++) { + PackageEntry* archived_entry = archived_packages->at(i); + archived_entry->init_as_archived_entry(); + } + } + + void PackageEntryTable::load_archived_entries(Array<PackageEntry*>* archived_packages) { + assert(UseSharedSpaces, "runtime only"); + + for (int i = 0; i < archived_packages->length(); i++) { + PackageEntry* archived_entry = archived_packages->at(i); + archived_entry->load_from_archive(); + + unsigned int hash = compute_hash(archived_entry->name()); + archived_entry->set_hash(hash); + add_entry(hash_to_index(hash), archived_entry); + } + } + + #endif // INCLUDE_CDS_JAVA_HEAP + PackageEntry* PackageEntryTable::new_entry(unsigned int hash, Symbol* name, ModuleEntry* module) { assert(Module_lock->owned_by_self(), "should have the Module_lock"); PackageEntry* entry = (PackageEntry*)Hashtable<Symbol*, mtModule>::allocate_new_entry(hash, name); JFR_ONLY(INIT_ID(entry);)
*** 271,281 **** ResourceMark rm; vm_exit_during_initialization("A non-" JAVA_BASE_NAME " package was loaded prior to module system initialization", entry->name()->as_C_string()); } } } - } // iteration of qualified exports void PackageEntry::package_exports_do(ModuleClosure* f) { assert_locked_or_safepoint(Module_lock); --- 383,392 ----
< prev index next >