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 "cds/aotClassLocation.hpp"
26 #include "cds/archiveBuilder.hpp"
27 #include "cds/archiveUtils.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "classfile/classLoader.hpp"
31 #include "classfile/classLoaderData.inline.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/moduleEntry.hpp"
34 #include "classfile/systemDictionary.hpp"
35 #include "jni.h"
36 #include "logging/log.hpp"
37 #include "logging/logStream.hpp"
38 #include "memory/resourceArea.hpp"
39 #include "memory/universe.hpp"
40 #include "oops/oopHandle.inline.hpp"
41 #include "oops/symbol.hpp"
42 #include "runtime/handles.inline.hpp"
43 #include "runtime/safepoint.hpp"
44 #include "utilities/events.hpp"
45 #include "utilities/growableArray.hpp"
46 #include "utilities/ostream.hpp"
47 #include "utilities/quickSort.hpp"
48 #include "utilities/resourceHash.hpp"
49
50 ModuleEntry* ModuleEntryTable::_javabase_module = nullptr;
51
52 oop ModuleEntry::module() const { return _module.resolve(); }
53
433 ls.print("Stored in archive: ");
434 archived_entry->print(&ls);
435 }
436 return archived_entry;
437 }
438
439 bool ModuleEntry::has_been_archived() {
440 assert(!ArchiveBuilder::current()->is_in_buffer_space(this), "must be called on original ModuleEntry");
441 return _archive_modules_entries->contains(this);
442 }
443
444 ModuleEntry* ModuleEntry::get_archived_entry(ModuleEntry* orig_entry) {
445 ModuleEntry** ptr = _archive_modules_entries->get(orig_entry);
446 assert(ptr != nullptr && *ptr != nullptr, "must have been allocated");
447 return *ptr;
448 }
449
450 // This function is used to archive ModuleEntry::_reads and PackageEntry::_qualified_exports.
451 // GrowableArray cannot be directly archived, as it needs to be expandable at runtime.
452 // Write it out as an Array, and convert it back to GrowableArray at runtime.
453 Array<ModuleEntry*>* ModuleEntry::write_growable_array(GrowableArray<ModuleEntry*>* array) {
454 Array<ModuleEntry*>* archived_array = nullptr;
455 int length = (array == nullptr) ? 0 : array->length();
456 if (length > 0) {
457 archived_array = ArchiveBuilder::new_ro_array<ModuleEntry*>(length);
458 for (int i = 0; i < length; i++) {
459 ModuleEntry* archived_entry = get_archived_entry(array->at(i));
460 archived_array->at_put(i, archived_entry);
461 ArchivePtrMarker::mark_pointer((address*)archived_array->adr_at(i));
462 }
463 }
464
465 return archived_array;
466 }
467
468 GrowableArray<ModuleEntry*>* ModuleEntry::restore_growable_array(Array<ModuleEntry*>* archived_array) {
469 GrowableArray<ModuleEntry*>* array = nullptr;
470 int length = (archived_array == nullptr) ? 0 : archived_array->length();
471 if (length > 0) {
472 array = new (mtModule) GrowableArray<ModuleEntry*>(length, mtModule);
473 for (int i = 0; i < length; i++) {
474 ModuleEntry* archived_entry = archived_array->at(i);
475 array->append(archived_entry);
476 }
477 }
478
479 return array;
480 }
481
482 void ModuleEntry::iterate_symbols(MetaspaceClosure* closure) {
483 closure->push(&_name);
484 closure->push(&_version);
485 closure->push(&_location);
486 }
487
488 void ModuleEntry::init_as_archived_entry() {
489 set_archived_reads(write_growable_array(reads()));
490
491 _loader_data = nullptr; // re-init at runtime
492 _shared_path_index = AOTClassLocationConfig::dumptime()->get_module_shared_path_index(_location);
493 if (name() != nullptr) {
494 _name = ArchiveBuilder::get_buffered_symbol(_name);
495 ArchivePtrMarker::mark_pointer((address*)&_name);
496 }
497 if (_version != nullptr) {
498 _version = ArchiveBuilder::get_buffered_symbol(_version);
499 }
500 if (_location != nullptr) {
501 _location = ArchiveBuilder::get_buffered_symbol(_location);
502 }
503 JFR_ONLY(set_trace_id(0);) // re-init at runtime
504
505 ArchivePtrMarker::mark_pointer((address*)&_reads);
506 ArchivePtrMarker::mark_pointer((address*)&_version);
507 ArchivePtrMarker::mark_pointer((address*)&_location);
508 }
509
510 #ifndef PRODUCT
511 void ModuleEntry::verify_archived_module_entries() {
512 assert(_num_archived_module_entries == _num_inited_module_entries,
513 "%d ModuleEntries have been archived but %d of them have been properly initialized with archived java.lang.Module objects",
514 _num_archived_module_entries, _num_inited_module_entries);
515 }
516 #endif // PRODUCT
517
518 void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
519 assert(CDSConfig::is_using_archive(), "runtime only");
520 set_loader_data(loader_data);
521 set_reads(restore_growable_array(archived_reads()));
522 JFR_ONLY(INIT_ID(this);)
523 }
524
525 void ModuleEntry::restore_archived_oops(ClassLoaderData* loader_data) {
526 assert(CDSConfig::is_using_archive(), "runtime only");
527 Handle module_handle(Thread::current(), HeapShared::get_root(_archived_module_index, /*clear=*/true));
528 assert(module_handle.not_null(), "huh");
529 set_module(loader_data->add_handle(module_handle));
530
531 // This was cleared to zero during dump time -- we didn't save the value
532 // because it may be affected by archive relocation.
533 java_lang_Module::set_module_entry(module_handle(), this);
534
535 assert(java_lang_Module::loader(module_handle()) == loader_data->class_loader(),
536 "must be set in dump time");
537
538 if (log_is_enabled(Info, cds, module)) {
539 ResourceMark rm;
540 LogStream ls(Log(cds, module)::info());
541 ls.print("Restored from archive: ");
542 print(&ls);
543 }
544 }
545
546 void ModuleEntry::clear_archived_oops() {
547 assert(CDSConfig::is_using_archive(), "runtime only");
548 HeapShared::clear_root(_archived_module_index);
549 }
550
551 static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
552 assert(a == b || a->name() != b->name(), "no duplicated names");
553 return a->name()->fast_compare(b->name());
554 }
555
556 void ModuleEntryTable::iterate_symbols(MetaspaceClosure* closure) {
557 auto syms = [&] (const SymbolHandle& key, ModuleEntry*& m) {
558 m->iterate_symbols(closure);
559 };
560 _table.iterate_all(syms);
561 }
562
563 Array<ModuleEntry*>* ModuleEntryTable::allocate_archived_entries() {
564 Array<ModuleEntry*>* archived_modules = ArchiveBuilder::new_rw_array<ModuleEntry*>(_table.number_of_entries());
565 int n = 0;
566 auto grab = [&] (const SymbolHandle& key, ModuleEntry*& m) {
567 archived_modules->at_put(n++, m);
572 // Always allocate in the same order to produce deterministic archive.
573 QuickSort::sort(archived_modules->data(), n, compare_module_by_name);
574 }
575 for (int i = 0; i < n; i++) {
576 archived_modules->at_put(i, archived_modules->at(i)->allocate_archived_entry());
577 ArchivePtrMarker::mark_pointer((address*)archived_modules->adr_at(i));
578 }
579 return archived_modules;
580 }
581
582 void ModuleEntryTable::init_archived_entries(Array<ModuleEntry*>* archived_modules) {
583 assert(CDSConfig::is_dumping_full_module_graph(), "sanity");
584 for (int i = 0; i < archived_modules->length(); i++) {
585 ModuleEntry* archived_entry = archived_modules->at(i);
586 archived_entry->init_as_archived_entry();
587 }
588 }
589
590 void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
591 Array<ModuleEntry*>* archived_modules) {
592 assert(CDSConfig::is_using_archive(), "runtime only");
593
594 for (int i = 0; i < archived_modules->length(); i++) {
595 ModuleEntry* archived_entry = archived_modules->at(i);
596 archived_entry->load_from_archive(loader_data);
597 _table.put(archived_entry->name(), archived_entry);
598 }
599 }
600
601 void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
602 assert(CDSConfig::is_using_archive(), "runtime only");
603 for (int i = 0; i < archived_modules->length(); i++) {
604 ModuleEntry* archived_entry = archived_modules->at(i);
605 archived_entry->restore_archived_oops(loader_data);
606 }
607 }
608 #endif // INCLUDE_CDS_JAVA_HEAP
609
610 // Create an entry in the class loader's module_entry_table. It is the
611 // caller's responsibility to ensure that the entry has not already been
612 // created.
613 ModuleEntry* ModuleEntryTable::locked_create_entry(Handle module_handle,
614 bool is_open,
615 Symbol* module_name,
616 Symbol* module_version,
617 Symbol* module_location,
618 ClassLoaderData* loader_data) {
619 assert(module_name != nullptr, "ModuleEntryTable locked_create_entry should never be called for unnamed module.");
620 assert(Module_lock->owned_by_self(), "should have the Module_lock");
621 assert(lookup_only(module_name) == nullptr, "Module already exists");
622 ModuleEntry* entry = new ModuleEntry(module_handle, is_open, module_name,
|
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 "cds/aotClassLocation.hpp"
26 #include "cds/archiveBuilder.hpp"
27 #include "cds/archiveUtils.hpp"
28 #include "cds/cdsConfig.hpp"
29 #include "cds/heapShared.hpp"
30 #include "classfile/classLoader.hpp"
31 #include "classfile/classLoaderData.inline.hpp"
32 #include "classfile/javaClasses.inline.hpp"
33 #include "classfile/moduleEntry.hpp"
34 #include "classfile/modules.hpp"
35 #include "classfile/systemDictionary.hpp"
36 #include "jni.h"
37 #include "logging/log.hpp"
38 #include "logging/logStream.hpp"
39 #include "memory/resourceArea.hpp"
40 #include "memory/universe.hpp"
41 #include "oops/oopHandle.inline.hpp"
42 #include "oops/symbol.hpp"
43 #include "runtime/handles.inline.hpp"
44 #include "runtime/safepoint.hpp"
45 #include "utilities/events.hpp"
46 #include "utilities/growableArray.hpp"
47 #include "utilities/ostream.hpp"
48 #include "utilities/quickSort.hpp"
49 #include "utilities/resourceHash.hpp"
50
51 ModuleEntry* ModuleEntryTable::_javabase_module = nullptr;
52
53 oop ModuleEntry::module() const { return _module.resolve(); }
54
434 ls.print("Stored in archive: ");
435 archived_entry->print(&ls);
436 }
437 return archived_entry;
438 }
439
440 bool ModuleEntry::has_been_archived() {
441 assert(!ArchiveBuilder::current()->is_in_buffer_space(this), "must be called on original ModuleEntry");
442 return _archive_modules_entries->contains(this);
443 }
444
445 ModuleEntry* ModuleEntry::get_archived_entry(ModuleEntry* orig_entry) {
446 ModuleEntry** ptr = _archive_modules_entries->get(orig_entry);
447 assert(ptr != nullptr && *ptr != nullptr, "must have been allocated");
448 return *ptr;
449 }
450
451 // This function is used to archive ModuleEntry::_reads and PackageEntry::_qualified_exports.
452 // GrowableArray cannot be directly archived, as it needs to be expandable at runtime.
453 // Write it out as an Array, and convert it back to GrowableArray at runtime.
454 Array<ModuleEntry*>* ModuleEntry::write_growable_array(ModuleEntry* module, GrowableArray<ModuleEntry*>* array) {
455 Array<ModuleEntry*>* archived_array = nullptr;
456 int length = (array == nullptr) ? 0 : array->length();
457 if (module->is_named()) {
458 if (Modules::is_dynamic_proxy_module(module)) {
459 // This is a dynamically generated module. Its opens and exports will be
460 // restored at runtime in the Java code. See comments in ArchivedData::restore().
461 return nullptr;
462 }
463 }
464 if (length > 0) {
465 archived_array = ArchiveBuilder::new_ro_array<ModuleEntry*>(length);
466 for (int i = 0; i < length; i++) {
467 ModuleEntry* archived_entry = get_archived_entry(array->at(i));
468 archived_array->at_put(i, archived_entry);
469 ArchivePtrMarker::mark_pointer((address*)archived_array->adr_at(i));
470 }
471 }
472
473 return archived_array;
474 }
475
476 GrowableArray<ModuleEntry*>* ModuleEntry::restore_growable_array(Array<ModuleEntry*>* archived_array) {
477 GrowableArray<ModuleEntry*>* array = nullptr;
478 int length = (archived_array == nullptr) ? 0 : archived_array->length();
479 if (length > 0) {
480 array = new (mtModule) GrowableArray<ModuleEntry*>(length, mtModule);
481 for (int i = 0; i < length; i++) {
482 ModuleEntry* archived_entry = archived_array->at(i);
483 array->append(archived_entry);
484 }
485 }
486
487 return array;
488 }
489
490 void ModuleEntry::iterate_symbols(MetaspaceClosure* closure) {
491 closure->push(&_name);
492 closure->push(&_version);
493 closure->push(&_location);
494 }
495
496 void ModuleEntry::init_as_archived_entry() {
497 set_archived_reads(write_growable_array(this, reads()));
498
499 _loader_data = nullptr; // re-init at runtime
500 _shared_path_index = AOTClassLocationConfig::dumptime()->get_module_shared_path_index(_location);
501 if (name() != nullptr) {
502 _name = ArchiveBuilder::get_buffered_symbol(_name);
503 ArchivePtrMarker::mark_pointer((address*)&_name);
504 }
505 if (_version != nullptr) {
506 _version = ArchiveBuilder::get_buffered_symbol(_version);
507 }
508 if (_location != nullptr) {
509 _location = ArchiveBuilder::get_buffered_symbol(_location);
510 }
511 JFR_ONLY(set_trace_id(0);) // re-init at runtime
512
513 ArchivePtrMarker::mark_pointer((address*)&_reads);
514 ArchivePtrMarker::mark_pointer((address*)&_version);
515 ArchivePtrMarker::mark_pointer((address*)&_location);
516 }
517
518 #ifndef PRODUCT
519 void ModuleEntry::verify_archived_module_entries() {
520 assert(_num_archived_module_entries == _num_inited_module_entries,
521 "%d ModuleEntries have been archived but %d of them have been properly initialized with archived java.lang.Module objects",
522 _num_archived_module_entries, _num_inited_module_entries);
523 }
524 #endif // PRODUCT
525
526 void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
527 assert(CDSConfig::is_using_full_module_graph(), "runtime only");
528 set_loader_data(loader_data);
529 set_reads(restore_growable_array(archived_reads()));
530 JFR_ONLY(INIT_ID(this);)
531 }
532
533 void ModuleEntry::restore_archived_oops(ClassLoaderData* loader_data) {
534 assert(CDSConfig::is_using_full_module_graph(), "runtime only");
535 Handle module_handle(Thread::current(), HeapShared::get_root(_archived_module_index, /*clear=*/true));
536 assert(module_handle.not_null(), "huh");
537 set_module(loader_data->add_handle(module_handle));
538
539 // This was cleared to zero during dump time -- we didn't save the value
540 // because it may be affected by archive relocation.
541 java_lang_Module::set_module_entry(module_handle(), this);
542
543 assert(java_lang_Module::loader(module_handle()) == loader_data->class_loader(),
544 "must be set in dump time");
545
546 if (log_is_enabled(Info, cds, module)) {
547 ResourceMark rm;
548 LogStream ls(Log(cds, module)::info());
549 ls.print("Restored from archive: ");
550 print(&ls);
551 }
552 }
553
554 void ModuleEntry::clear_archived_oops() {
555 assert(CDSConfig::is_using_archive() && !CDSConfig::is_using_full_module_graph(), "runtime only");
556 HeapShared::clear_root(_archived_module_index);
557 }
558
559 static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
560 assert(a == b || a->name() != b->name(), "no duplicated names");
561 return a->name()->fast_compare(b->name());
562 }
563
564 void ModuleEntryTable::iterate_symbols(MetaspaceClosure* closure) {
565 auto syms = [&] (const SymbolHandle& key, ModuleEntry*& m) {
566 m->iterate_symbols(closure);
567 };
568 _table.iterate_all(syms);
569 }
570
571 Array<ModuleEntry*>* ModuleEntryTable::allocate_archived_entries() {
572 Array<ModuleEntry*>* archived_modules = ArchiveBuilder::new_rw_array<ModuleEntry*>(_table.number_of_entries());
573 int n = 0;
574 auto grab = [&] (const SymbolHandle& key, ModuleEntry*& m) {
575 archived_modules->at_put(n++, m);
580 // Always allocate in the same order to produce deterministic archive.
581 QuickSort::sort(archived_modules->data(), n, compare_module_by_name);
582 }
583 for (int i = 0; i < n; i++) {
584 archived_modules->at_put(i, archived_modules->at(i)->allocate_archived_entry());
585 ArchivePtrMarker::mark_pointer((address*)archived_modules->adr_at(i));
586 }
587 return archived_modules;
588 }
589
590 void ModuleEntryTable::init_archived_entries(Array<ModuleEntry*>* archived_modules) {
591 assert(CDSConfig::is_dumping_full_module_graph(), "sanity");
592 for (int i = 0; i < archived_modules->length(); i++) {
593 ModuleEntry* archived_entry = archived_modules->at(i);
594 archived_entry->init_as_archived_entry();
595 }
596 }
597
598 void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
599 Array<ModuleEntry*>* archived_modules) {
600 assert(CDSConfig::is_using_full_module_graph(), "runtime only");
601
602 for (int i = 0; i < archived_modules->length(); i++) {
603 ModuleEntry* archived_entry = archived_modules->at(i);
604 archived_entry->load_from_archive(loader_data);
605 _table.put(archived_entry->name(), archived_entry);
606 }
607 }
608
609 void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
610 assert(CDSConfig::is_using_full_module_graph(), "runtime only");
611 for (int i = 0; i < archived_modules->length(); i++) {
612 ModuleEntry* archived_entry = archived_modules->at(i);
613 archived_entry->restore_archived_oops(loader_data);
614 }
615 }
616 #endif // INCLUDE_CDS_JAVA_HEAP
617
618 // Create an entry in the class loader's module_entry_table. It is the
619 // caller's responsibility to ensure that the entry has not already been
620 // created.
621 ModuleEntry* ModuleEntryTable::locked_create_entry(Handle module_handle,
622 bool is_open,
623 Symbol* module_name,
624 Symbol* module_version,
625 Symbol* module_location,
626 ClassLoaderData* loader_data) {
627 assert(module_name != nullptr, "ModuleEntryTable locked_create_entry should never be called for unnamed module.");
628 assert(Module_lock->owned_by_self(), "should have the Module_lock");
629 assert(lookup_only(module_name) == nullptr, "Module already exists");
630 ModuleEntry* entry = new ModuleEntry(module_handle, is_open, module_name,
|