26 #include "jni.h"
27 #include "classfile/classLoader.hpp"
28 #include "classfile/classLoaderData.inline.hpp"
29 #include "classfile/javaClasses.inline.hpp"
30 #include "classfile/moduleEntry.hpp"
31 #include "logging/log.hpp"
32 #include "memory/archiveUtils.hpp"
33 #include "memory/filemap.hpp"
34 #include "memory/heapShared.hpp"
35 #include "memory/metaspaceShared.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "memory/universe.hpp"
38 #include "oops/oopHandle.inline.hpp"
39 #include "oops/symbol.hpp"
40 #include "runtime/handles.inline.hpp"
41 #include "runtime/safepoint.hpp"
42 #include "utilities/events.hpp"
43 #include "utilities/growableArray.hpp"
44 #include "utilities/hashtable.inline.hpp"
45 #include "utilities/ostream.hpp"
46 #include "utilities/resourceHash.hpp"
47
48 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
49
50 oop ModuleEntry::module() const { return _module.resolve(); }
51
52 void ModuleEntry::set_location(Symbol* location) {
53 if (_location != NULL) {
54 // _location symbol's refcounts are managed by ModuleEntry,
55 // must decrement the old one before updating.
56 _location->decrement_refcount();
57 }
58
59 _location = location;
60
61 if (location != NULL) {
62 location->increment_refcount();
63 CDS_ONLY(if (UseSharedSpaces) {
64 _shared_path_index = FileMapInfo::get_module_shared_path_index(location);
65 });
380 assert(is_named(), "unnamed packages/modules are not archived");
381 ModuleEntry* archived_entry = (ModuleEntry*)MetaspaceShared::read_write_space_alloc(sizeof(ModuleEntry));
382 memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry));
383
384 if (_archive_modules_entries == NULL) {
385 _archive_modules_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedModuleEntries();
386 }
387 assert(_archive_modules_entries->get(this) == NULL, "Each ModuleEntry must not be shared across ModuleEntryTables");
388 _archive_modules_entries->put(this, archived_entry);
389
390 return archived_entry;
391 }
392
393 ModuleEntry* ModuleEntry::get_archived_entry(ModuleEntry* orig_entry) {
394 ModuleEntry** ptr = _archive_modules_entries->get(orig_entry);
395 assert(ptr != NULL && *ptr != NULL, "must have been allocated");
396 return *ptr;
397 }
398
399 // GrowableArrays cannot be directly archived, as they need to be expandable at runtime.
400 // Write it out as an Array, and conver it back to GrowableArray at runtime.
401 Array<ModuleEntry*>* ModuleEntry::write_archived_entry_array(GrowableArray<ModuleEntry*>* array) {
402 Array<ModuleEntry*>* archived_array = NULL;
403 int length = (array == NULL) ? 0 : array->length();
404 if (length > 0) {
405 archived_array = MetaspaceShared::new_ro_array<ModuleEntry*>(length);
406 for (int i = 0; i < length; i++) {
407 ModuleEntry* archived_entry = get_archived_entry(array->at(i));
408 archived_array->at_put(i, archived_entry);
409 ArchivePtrMarker::mark_pointer((address*)archived_array->adr_at(i));
410 }
411 }
412
413 return archived_array;
414 }
415
416 GrowableArray<ModuleEntry*>* ModuleEntry::read_archived_entry_array(Array<ModuleEntry*>* archived_array) {
417 GrowableArray<ModuleEntry*>* array = NULL;
418 int length = (archived_array == NULL) ? 0 : archived_array->length();
419 if (length > 0) {
420 array = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(length, mtModule);
468 void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
469 set_loader_data(loader_data);
470 _reads = read_archived_entry_array((Array<ModuleEntry*>*)_reads);
471 JFR_ONLY(INIT_ID(this);)
472 }
473
474 void ModuleEntry::restore_archive_oops(ClassLoaderData* loader_data) {
475 Handle module_handle(Thread::current(), HeapShared::materialize_archived_object(_archived_module_narrow_oop));
476 assert(module_handle.not_null(), "huh");
477 set_module(loader_data->add_handle(module_handle));
478
479 // This was cleared to zero during dump time -- we didn't save the value
480 // because it may be affected by archive relocation.
481 java_lang_Module::set_module_entry(module_handle(), this);
482
483 if (loader_data->class_loader() != NULL) {
484 java_lang_Module::set_loader(module_handle(), loader_data->class_loader());
485 }
486 }
487
488 static int compare_module_by_name(ModuleEntry** a, ModuleEntry** b) {
489 return a[0]->name()->fast_compare(b[0]->name());
490 }
491
492 Array<ModuleEntry*>* ModuleEntryTable::allocate_archived_entries() {
493 Array<ModuleEntry*>* archived_modules = MetaspaceShared::new_rw_array<ModuleEntry*>(number_of_entries());
494 int n = 0;
495 for (int i = 0; i < table_size(); ++i) {
496 for (ModuleEntry* m = bucket(i); m != NULL; m = m->next()) {
497 archived_modules->at_put(n++, m);
498 }
499 }
500 if (n > 0) {
501 // Always allocate in the same order to produce deterministic archive.
502 qsort(archived_modules->adr_at(0), n, sizeof(ModuleEntry*), (_sort_Fn)compare_module_by_name);
503 for (int i = 0; i < n; i++) {
504 archived_modules->at_put(i, archived_modules->at(i)->allocate_archived_entry());
505 ArchivePtrMarker::mark_pointer((address*)archived_modules->adr_at(i));
506 }
507 }
508 return archived_modules;
509 }
510
511 void ModuleEntryTable::init_archived_entries(Array<ModuleEntry*>* archived_modules) {
512 assert(DumpSharedSpaces, "dump time only");
513 for (int i = 0; i < archived_modules->length(); i++) {
514 ModuleEntry* archived_entry = archived_modules->at(i);
515 archived_entry->init_as_archived_entry();
516 }
517 }
518
519 void ModuleEntryTable::init_archived_oops(Array<ModuleEntry*>* archived_modules) {
520 assert(DumpSharedSpaces, "dump time only");
521 for (int i = 0; i < archived_modules->length(); i++) {
522 ModuleEntry* archived_entry = archived_modules->at(i);
523 archived_entry->init_archived_oops();
524 }
525 }
526
527 void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
528 Array<ModuleEntry*>* archived_modules) {
529 assert(UseSharedSpaces, "runtime only");
530
531 MutexLocker m1(Module_lock);
532 for (int i = 0; i < archived_modules->length(); i++) {
533 ModuleEntry* archived_entry = archived_modules->at(i);
534 archived_entry->load_from_archive(loader_data);
535
536 unsigned int hash = compute_hash(archived_entry->name());
537 archived_entry->set_hash(hash);
538 add_entry(hash_to_index(hash), archived_entry);
539 }
540 }
541
542 void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
543 assert(UseSharedSpaces, "runtime only");
544 for (int i = 0; i < archived_modules->length(); i++) {
545 ModuleEntry* archived_entry = archived_modules->at(i);
546 archived_entry->restore_archive_oops(loader_data);
547 }
548 }
549 #endif // INCLUDE_CDS_JAVA_HEAP
550
551 ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle,
|
26 #include "jni.h"
27 #include "classfile/classLoader.hpp"
28 #include "classfile/classLoaderData.inline.hpp"
29 #include "classfile/javaClasses.inline.hpp"
30 #include "classfile/moduleEntry.hpp"
31 #include "logging/log.hpp"
32 #include "memory/archiveUtils.hpp"
33 #include "memory/filemap.hpp"
34 #include "memory/heapShared.hpp"
35 #include "memory/metaspaceShared.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "memory/universe.hpp"
38 #include "oops/oopHandle.inline.hpp"
39 #include "oops/symbol.hpp"
40 #include "runtime/handles.inline.hpp"
41 #include "runtime/safepoint.hpp"
42 #include "utilities/events.hpp"
43 #include "utilities/growableArray.hpp"
44 #include "utilities/hashtable.inline.hpp"
45 #include "utilities/ostream.hpp"
46 #include "utilities/quickSort.hpp"
47 #include "utilities/resourceHash.hpp"
48
49 ModuleEntry* ModuleEntryTable::_javabase_module = NULL;
50
51 oop ModuleEntry::module() const { return _module.resolve(); }
52
53 void ModuleEntry::set_location(Symbol* location) {
54 if (_location != NULL) {
55 // _location symbol's refcounts are managed by ModuleEntry,
56 // must decrement the old one before updating.
57 _location->decrement_refcount();
58 }
59
60 _location = location;
61
62 if (location != NULL) {
63 location->increment_refcount();
64 CDS_ONLY(if (UseSharedSpaces) {
65 _shared_path_index = FileMapInfo::get_module_shared_path_index(location);
66 });
381 assert(is_named(), "unnamed packages/modules are not archived");
382 ModuleEntry* archived_entry = (ModuleEntry*)MetaspaceShared::read_write_space_alloc(sizeof(ModuleEntry));
383 memcpy((void*)archived_entry, (void*)this, sizeof(ModuleEntry));
384
385 if (_archive_modules_entries == NULL) {
386 _archive_modules_entries = new (ResourceObj::C_HEAP, mtClass)ArchivedModuleEntries();
387 }
388 assert(_archive_modules_entries->get(this) == NULL, "Each ModuleEntry must not be shared across ModuleEntryTables");
389 _archive_modules_entries->put(this, archived_entry);
390
391 return archived_entry;
392 }
393
394 ModuleEntry* ModuleEntry::get_archived_entry(ModuleEntry* orig_entry) {
395 ModuleEntry** ptr = _archive_modules_entries->get(orig_entry);
396 assert(ptr != NULL && *ptr != NULL, "must have been allocated");
397 return *ptr;
398 }
399
400 // GrowableArrays cannot be directly archived, as they need to be expandable at runtime.
401 // Write it out as an Array, and convert it back to GrowableArray at runtime.
402 Array<ModuleEntry*>* ModuleEntry::write_archived_entry_array(GrowableArray<ModuleEntry*>* array) {
403 Array<ModuleEntry*>* archived_array = NULL;
404 int length = (array == NULL) ? 0 : array->length();
405 if (length > 0) {
406 archived_array = MetaspaceShared::new_ro_array<ModuleEntry*>(length);
407 for (int i = 0; i < length; i++) {
408 ModuleEntry* archived_entry = get_archived_entry(array->at(i));
409 archived_array->at_put(i, archived_entry);
410 ArchivePtrMarker::mark_pointer((address*)archived_array->adr_at(i));
411 }
412 }
413
414 return archived_array;
415 }
416
417 GrowableArray<ModuleEntry*>* ModuleEntry::read_archived_entry_array(Array<ModuleEntry*>* archived_array) {
418 GrowableArray<ModuleEntry*>* array = NULL;
419 int length = (archived_array == NULL) ? 0 : archived_array->length();
420 if (length > 0) {
421 array = new (ResourceObj::C_HEAP, mtModule)GrowableArray<ModuleEntry*>(length, mtModule);
469 void ModuleEntry::load_from_archive(ClassLoaderData* loader_data) {
470 set_loader_data(loader_data);
471 _reads = read_archived_entry_array((Array<ModuleEntry*>*)_reads);
472 JFR_ONLY(INIT_ID(this);)
473 }
474
475 void ModuleEntry::restore_archive_oops(ClassLoaderData* loader_data) {
476 Handle module_handle(Thread::current(), HeapShared::materialize_archived_object(_archived_module_narrow_oop));
477 assert(module_handle.not_null(), "huh");
478 set_module(loader_data->add_handle(module_handle));
479
480 // This was cleared to zero during dump time -- we didn't save the value
481 // because it may be affected by archive relocation.
482 java_lang_Module::set_module_entry(module_handle(), this);
483
484 if (loader_data->class_loader() != NULL) {
485 java_lang_Module::set_loader(module_handle(), loader_data->class_loader());
486 }
487 }
488
489 static int compare_module_by_name(ModuleEntry* a, ModuleEntry* b) {
490 return a->name()->fast_compare(b->name());
491 }
492
493 Array<ModuleEntry*>* ModuleEntryTable::allocate_archived_entries() {
494 Array<ModuleEntry*>* archived_modules = MetaspaceShared::new_rw_array<ModuleEntry*>(number_of_entries());
495 int n = 0;
496 for (int i = 0; i < table_size(); ++i) {
497 for (ModuleEntry* m = bucket(i); m != NULL; m = m->next()) {
498 archived_modules->at_put(n++, m);
499 }
500 }
501 if (n > 1) {
502 // Always allocate in the same order to produce deterministic archive.
503 QuickSort::sort(archived_modules->data(), n, (_sort_Fn)compare_module_by_name, true);
504 }
505 for (int i = 0; i < n; i++) {
506 archived_modules->at_put(i, archived_modules->at(i)->allocate_archived_entry());
507 ArchivePtrMarker::mark_pointer((address*)archived_modules->adr_at(i));
508 }
509 return archived_modules;
510 }
511
512 void ModuleEntryTable::init_archived_entries(Array<ModuleEntry*>* archived_modules) {
513 assert(DumpSharedSpaces, "dump time only");
514 for (int i = 0; i < archived_modules->length(); i++) {
515 ModuleEntry* archived_entry = archived_modules->at(i);
516 archived_entry->init_as_archived_entry();
517 }
518 }
519
520 void ModuleEntryTable::init_archived_oops(Array<ModuleEntry*>* archived_modules) {
521 assert(DumpSharedSpaces, "dump time only");
522 for (int i = 0; i < archived_modules->length(); i++) {
523 ModuleEntry* archived_entry = archived_modules->at(i);
524 archived_entry->init_archived_oops();
525 }
526 }
527
528 void ModuleEntryTable::load_archived_entries(ClassLoaderData* loader_data,
529 Array<ModuleEntry*>* archived_modules) {
530 assert(UseSharedSpaces, "runtime only");
531
532 for (int i = 0; i < archived_modules->length(); i++) {
533 ModuleEntry* archived_entry = archived_modules->at(i);
534 archived_entry->load_from_archive(loader_data);
535
536 unsigned int hash = compute_hash(archived_entry->name());
537 archived_entry->set_hash(hash);
538 add_entry(hash_to_index(hash), archived_entry);
539 }
540 }
541
542 void ModuleEntryTable::restore_archived_oops(ClassLoaderData* loader_data, Array<ModuleEntry*>* archived_modules) {
543 assert(UseSharedSpaces, "runtime only");
544 for (int i = 0; i < archived_modules->length(); i++) {
545 ModuleEntry* archived_entry = archived_modules->at(i);
546 archived_entry->restore_archive_oops(loader_data);
547 }
548 }
549 #endif // INCLUDE_CDS_JAVA_HEAP
550
551 ModuleEntry* ModuleEntryTable::new_entry(unsigned int hash, Handle module_handle,
|