diff --git a/src/hotspot/share/classfile/moduleEntry.cpp b/src/hotspot/share/classfile/moduleEntry.cpp index 78478d282c5..e7f05bedb29 100644 --- a/src/hotspot/share/classfile/moduleEntry.cpp +++ b/src/hotspot/share/classfile/moduleEntry.cpp @@ -149,7 +149,7 @@ bool ModuleEntry::can_read(ModuleEntry* m) const { if (!has_reads_list()) { return false; } else { - return _reads->contains(m); + return reads()->contains(m); } } @@ -164,9 +164,10 @@ void ModuleEntry::add_read(ModuleEntry* m) { if (m == nullptr) { set_can_read_all_unnamed(); } else { - if (_reads == nullptr) { + if (reads() == nullptr) { // Lazily create a module's reads list - _reads = new (mtModule) GrowableArray(MODULE_READS_SIZE, mtModule); + GrowableArray* new_reads = new (mtModule) GrowableArray(MODULE_READS_SIZE, mtModule); + set_reads(new_reads); } // Determine, based on this newly established read edge to module m, @@ -174,7 +175,7 @@ void ModuleEntry::add_read(ModuleEntry* m) { set_read_walk_required(m->loader_data()); // Establish readability to module m - _reads->append_if_missing(m); + reads()->append_if_missing(m); } } @@ -208,7 +209,7 @@ void ModuleEntry::set_is_open(bool is_open) { // module will return false. bool ModuleEntry::has_reads_list() const { assert_locked_or_safepoint(Module_lock); - return ((_reads != nullptr) && !_reads->is_empty()); + return ((reads() != nullptr) && !reads()->is_empty()); } // Purge dead module entries out of reads list. @@ -227,12 +228,12 @@ void ModuleEntry::purge_reads() { } // Go backwards because this removes entries that are dead. - int len = _reads->length(); + int len = reads()->length(); for (int idx = len - 1; idx >= 0; idx--) { - ModuleEntry* module_idx = _reads->at(idx); + ModuleEntry* module_idx = reads()->at(idx); ClassLoaderData* cld_idx = module_idx->loader_data(); if (cld_idx->is_unloading()) { - _reads->delete_at(idx); + reads()->delete_at(idx); } else { // Update the need to walk this module's reads based on live modules set_read_walk_required(cld_idx); @@ -246,15 +247,15 @@ void ModuleEntry::module_reads_do(ModuleClosure* f) { assert(f != nullptr, "invariant"); if (has_reads_list()) { - int reads_len = _reads->length(); - for (int i = 0; i < reads_len; ++i) { - f->do_module(_reads->at(i)); + int reads_len = reads()->length(); + for (ModuleEntry* m : *reads()) { + f->do_module(m); } } } void ModuleEntry::delete_reads() { - delete _reads; + delete reads(); _reads = nullptr; } @@ -272,7 +273,8 @@ ModuleEntry::ModuleEntry(Handle module_handle, _has_default_read_edges(false), _must_walk_reads(false), _is_open(is_open), - _is_patched(false) { + _is_patched(false) + DEBUG_ONLY(COMMA _reads_is_archived(false)) { // Initialize fields specific to a ModuleEntry if (_name == nullptr) { @@ -466,7 +468,7 @@ void ModuleEntry::iterate_symbols(MetaspaceClosure* closure) { } void ModuleEntry::init_as_archived_entry() { - Array* archived_reads = write_growable_array(_reads); + set_archived_reads(write_growable_array(reads())); _loader_data = nullptr; // re-init at runtime _shared_path_index = FileMapInfo::get_module_shared_path_index(_location); @@ -474,7 +476,6 @@ void ModuleEntry::init_as_archived_entry() { _name = ArchiveBuilder::get_buffered_symbol(_name); ArchivePtrMarker::mark_pointer((address*)&_name); } - _reads = (GrowableArray*)archived_reads; if (_version != nullptr) { _version = ArchiveBuilder::get_buffered_symbol(_version); } @@ -515,7 +516,7 @@ void ModuleEntry::verify_archived_module_entries() { void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) { assert(CDSConfig::is_using_archive(), "runtime only"); set_loader_data(loader_data); - _reads = restore_growable_array((Array*)_reads); + set_reads(restore_growable_array(archived_reads())); JFR_ONLY(INIT_ID(this);) } diff --git a/src/hotspot/share/classfile/moduleEntry.hpp b/src/hotspot/share/classfile/moduleEntry.hpp index 62a0ba2a0b7..48adc41eddc 100644 --- a/src/hotspot/share/classfile/moduleEntry.hpp +++ b/src/hotspot/share/classfile/moduleEntry.hpp @@ -68,7 +68,11 @@ private: // for shared classes from this module Symbol* _name; // name of this module ClassLoaderData* _loader_data; - GrowableArray* _reads; // list of modules that are readable by this module + + union { + GrowableArray* _reads; // list of modules that are readable by this module + Array* _archived_reads; // List of readable modules stored in the CDS archive + }; Symbol* _version; // module version number Symbol* _location; // module location CDS_ONLY(int _shared_path_index;) // >=0 if classes in this module are in CDS archive @@ -77,6 +81,7 @@ private: bool _must_walk_reads; // walk module's reads list at GC safepoints to purge out dead modules bool _is_open; // whether the packages in the module are all unqualifiedly exported bool _is_patched; // whether the module is patched via --patch-module + DEBUG_ONLY(bool _reads_is_archived); CDS_JAVA_HEAP_ONLY(int _archived_module_index;) JFR_ONLY(DEFINE_TRACE_ID_FIELD;) @@ -115,6 +120,22 @@ public: bool can_read(ModuleEntry* m) const; bool has_reads_list() const; + GrowableArray* reads() const { + assert(!_reads_is_archived, "sanity"); + return _reads; + } + void set_reads(GrowableArray* r) { + _reads = r; + DEBUG_ONLY(_reads_is_archived = false); + } + Array* archived_reads() const { + assert(_reads_is_archived, "sanity"); + return _archived_reads; + } + void set_archived_reads(Array* r) { + _archived_reads = r; + DEBUG_ONLY(_reads_is_archived = true); + } void add_read(ModuleEntry* m); void set_read_walk_required(ClassLoaderData* m_loader_data);