< prev index next > src/hotspot/share/classfile/moduleEntry.cpp
Print this page
#include "cds/heapShared.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/moduleEntry.hpp"
+ #include "classfile/modules.hpp"
#include "classfile/systemDictionary.hpp"
#include "jni.h"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/resourceArea.hpp"
}
// This function is used to archive ModuleEntry::_reads and PackageEntry::_qualified_exports.
// GrowableArray cannot be directly archived, as it needs to be expandable at runtime.
// Write it out as an Array, and convert it back to GrowableArray at runtime.
! Array<ModuleEntry*>* ModuleEntry::write_growable_array(GrowableArray<ModuleEntry*>* array) {
Array<ModuleEntry*>* archived_array = nullptr;
int length = (array == nullptr) ? 0 : array->length();
if (length > 0) {
archived_array = ArchiveBuilder::new_ro_array<ModuleEntry*>(length);
for (int i = 0; i < length; i++) {
ModuleEntry* archived_entry = get_archived_entry(array->at(i));
archived_array->at_put(i, archived_entry);
}
// This function is used to archive ModuleEntry::_reads and PackageEntry::_qualified_exports.
// GrowableArray cannot be directly archived, as it needs to be expandable at runtime.
// Write it out as an Array, and convert it back to GrowableArray at runtime.
! Array<ModuleEntry*>* ModuleEntry::write_growable_array(ModuleEntry* module, GrowableArray<ModuleEntry*>* array) {
Array<ModuleEntry*>* archived_array = nullptr;
int length = (array == nullptr) ? 0 : array->length();
+ if (module->is_named()) {
+ if (Modules::is_dynamic_proxy_module(module)) {
+ // This is a dynamically generated module. Its opens and exports will be
+ // restored at runtime in the Java code. See comments in ArchivedData::restore().
+ return nullptr;
+ }
+ }
if (length > 0) {
archived_array = ArchiveBuilder::new_ro_array<ModuleEntry*>(length);
for (int i = 0; i < length; i++) {
ModuleEntry* archived_entry = get_archived_entry(array->at(i));
archived_array->at_put(i, archived_entry);
closure->push(&_version);
closure->push(&_location);
}
void ModuleEntry::init_as_archived_entry() {
! set_archived_reads(write_growable_array(reads()));
_loader_data = nullptr; // re-init at runtime
_shared_path_index = FileMapInfo::get_module_shared_path_index(_location);
if (name() != nullptr) {
_name = ArchiveBuilder::get_buffered_symbol(_name);
closure->push(&_version);
closure->push(&_location);
}
void ModuleEntry::init_as_archived_entry() {
! set_archived_reads(write_growable_array(this, reads()));
_loader_data = nullptr; // re-init at runtime
_shared_path_index = FileMapInfo::get_module_shared_path_index(_location);
if (name() != nullptr) {
_name = ArchiveBuilder::get_buffered_symbol(_name);
assert(_archived_module_index == -1, "must be set exactly once");
assert(root_oop_index >= 0, "sanity");
_archived_module_index = root_oop_index;
! assert(shared_protection_domain() == nullptr, "never set during -Xshare:dump");
// Clear handles and restore at run time. Handles cannot be archived.
OopHandle null_handle;
_module = null_handle;
// For verify_archived_module_entries()
assert(_archived_module_index == -1, "must be set exactly once");
assert(root_oop_index >= 0, "sanity");
_archived_module_index = root_oop_index;
! if (CDSConfig::is_dumping_final_static_archive()) {
+ OopHandle null_handle;
+ _shared_pd = null_handle;
+ } else {
+ assert(shared_protection_domain() == nullptr, "never set during -Xshare:dump");
+ }
// Clear handles and restore at run time. Handles cannot be archived.
OopHandle null_handle;
_module = null_handle;
// For verify_archived_module_entries()
_num_archived_module_entries, _num_inited_module_entries);
}
#endif // PRODUCT
void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
! assert(CDSConfig::is_using_archive(), "runtime only");
set_loader_data(loader_data);
set_reads(restore_growable_array(archived_reads()));
JFR_ONLY(INIT_ID(this);)
}
void ModuleEntry::restore_archived_oops(ClassLoaderData* loader_data) {
! assert(CDSConfig::is_using_archive(), "runtime only");
Handle module_handle(Thread::current(), HeapShared::get_root(_archived_module_index, /*clear=*/true));
assert(module_handle.not_null(), "huh");
set_module(loader_data->add_handle(module_handle));
// This was cleared to zero during dump time -- we didn't save the value
_num_archived_module_entries, _num_inited_module_entries);
}
#endif // PRODUCT
void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
! assert(CDSConfig::is_using_full_module_graph(), "runtime only");
set_loader_data(loader_data);
set_reads(restore_growable_array(archived_reads()));
JFR_ONLY(INIT_ID(this);)
}
void ModuleEntry::restore_archived_oops(ClassLoaderData* loader_data) {
! assert(CDSConfig::is_using_full_module_graph(), "runtime only");
Handle module_handle(Thread::current(), HeapShared::get_root(_archived_module_index, /*clear=*/true));
assert(module_handle.not_null(), "huh");
set_module(loader_data->add_handle(module_handle));
// This was cleared to zero during dump time -- we didn't save the value
print(&ls);
}
}
void ModuleEntry::clear_archived_oops() {
! assert(CDSConfig::is_using_archive(), "runtime only");
HeapShared::clear_root(_archived_module_index);
}
static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
assert(a == b || a->name() != b->name(), "no duplicated names");
print(&ls);
}
}
void ModuleEntry::clear_archived_oops() {
! assert(CDSConfig::is_using_archive() && !CDSConfig::is_using_full_module_graph(), "runtime only");
HeapShared::clear_root(_archived_module_index);
}
static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
assert(a == b || a->name() != b->name(), "no duplicated names");
}
}
void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
Array<ModuleEntry*>* archived_modules) {
! assert(CDSConfig::is_using_archive(), "runtime only");
for (int i = 0; i < archived_modules->length(); i++) {
ModuleEntry* archived_entry = archived_modules->at(i);
archived_entry->load_from_archive(loader_data);
_table.put(archived_entry->name(), archived_entry);
}
}
void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
! assert(CDSConfig::is_using_archive(), "runtime only");
for (int i = 0; i < archived_modules->length(); i++) {
ModuleEntry* archived_entry = archived_modules->at(i);
archived_entry->restore_archived_oops(loader_data);
}
}
}
}
void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
Array<ModuleEntry*>* archived_modules) {
! assert(CDSConfig::is_using_full_module_graph(), "runtime only");
for (int i = 0; i < archived_modules->length(); i++) {
ModuleEntry* archived_entry = archived_modules->at(i);
archived_entry->load_from_archive(loader_data);
_table.put(archived_entry->name(), archived_entry);
}
}
void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
! assert(CDSConfig::is_using_full_module_graph(), "runtime only");
for (int i = 0; i < archived_modules->length(); i++) {
ModuleEntry* archived_entry = archived_modules->at(i);
archived_entry->restore_archived_oops(loader_data);
}
}
< prev index next >