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