380
381 if (length == 0) {
382 return SECONDARY_SUPERS_BITMAP_EMPTY;
383 }
384
385 if (length == 1) {
386 int hash_slot = secondaries->at(0)->hash_slot();
387 return uintx(1) << hash_slot;
388 }
389
390 // Invariant: _secondary_supers.length >= population_count(_secondary_supers_bitmap)
391
392 // Don't attempt to hash a table that's completely full, because in
393 // the case of an absent interface linear probing would not
394 // terminate.
395 if (length >= SECONDARY_SUPERS_TABLE_SIZE) {
396 return SECONDARY_SUPERS_BITMAP_FULL;
397 }
398
399 {
400 PerfTraceTime ptt(ClassLoader::perf_secondary_hash_time());
401
402 ResourceMark rm;
403 uintx bitmap = SECONDARY_SUPERS_BITMAP_EMPTY;
404 auto hashed_secondaries = new GrowableArray<Klass*>(SECONDARY_SUPERS_TABLE_SIZE,
405 SECONDARY_SUPERS_TABLE_SIZE, nullptr);
406
407 for (int j = 0; j < length; j++) {
408 Klass* k = secondaries->at(j);
409 hash_insert(k, hashed_secondaries, bitmap);
410 }
411
412 // Pack the hashed secondaries array by copying it into the
413 // secondaries array, sans nulls, if modification is allowed.
414 // Otherwise, validate the order.
415 int i = 0;
416 for (int slot = 0; slot < SECONDARY_SUPERS_TABLE_SIZE; slot++) {
417 bool has_element = ((bitmap >> slot) & 1) != 0;
418 assert(has_element == (hashed_secondaries->at(slot) != nullptr), "");
419 if (has_element) {
420 Klass* k = hashed_secondaries->at(slot);
811 set_is_shared();
812
813 // FIXME: validation in Klass::hash_secondary_supers() may fail for shared klasses.
814 // Even though the bitmaps always match, the canonical order of elements in the table
815 // is not guaranteed to stay the same (see tie breaker during Robin Hood hashing in Klass::hash_insert).
816 //assert(compute_secondary_supers_bitmap(secondary_supers()) == _secondary_supers_bitmap, "broken table");
817 }
818
819 void Klass::remove_java_mirror() {
820 assert(CDSConfig::is_dumping_archive(), "sanity");
821 if (log_is_enabled(Trace, cds, unshareable)) {
822 ResourceMark rm;
823 log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
824 }
825
826 #if INCLUDE_CDS_JAVA_HEAP
827 _archived_mirror_index = -1;
828 if (CDSConfig::is_dumping_heap()) {
829 Klass* src_k = ArchiveBuilder::current()->get_source_addr(this);
830 oop orig_mirror = src_k->java_mirror();
831 oop scratch_mirror = HeapShared::scratch_java_mirror(orig_mirror);
832 if (scratch_mirror != nullptr) {
833 _archived_mirror_index = HeapShared::append_root(scratch_mirror);
834 }
835 }
836 #endif
837
838 // Just null out the mirror. The class_loader_data() no longer exists.
839 clear_java_mirror_handle();
840 }
841
842 void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
843 assert(is_klass(), "ensure C++ vtable is restored");
844 assert(is_shared(), "must be set");
845 assert(secondary_supers()->length() >= (int)population_count(_secondary_supers_bitmap), "must be");
846 JFR_ONLY(RESTORE_ID(this);)
847 if (log_is_enabled(Trace, cds, unshareable)) {
848 ResourceMark rm(THREAD);
849 oop class_loader = loader_data->class_loader();
850 log_trace(cds, unshareable)("restore: %s with class loader: %s", external_name(),
851 class_loader != nullptr ? class_loader->klass()->external_name() : "boot");
852 }
853
|
380
381 if (length == 0) {
382 return SECONDARY_SUPERS_BITMAP_EMPTY;
383 }
384
385 if (length == 1) {
386 int hash_slot = secondaries->at(0)->hash_slot();
387 return uintx(1) << hash_slot;
388 }
389
390 // Invariant: _secondary_supers.length >= population_count(_secondary_supers_bitmap)
391
392 // Don't attempt to hash a table that's completely full, because in
393 // the case of an absent interface linear probing would not
394 // terminate.
395 if (length >= SECONDARY_SUPERS_TABLE_SIZE) {
396 return SECONDARY_SUPERS_BITMAP_FULL;
397 }
398
399 {
400 //PerfTraceTime ptt(ClassLoader::perf_secondary_hash_time()); // Leyden FIXME
401
402 ResourceMark rm;
403 uintx bitmap = SECONDARY_SUPERS_BITMAP_EMPTY;
404 auto hashed_secondaries = new GrowableArray<Klass*>(SECONDARY_SUPERS_TABLE_SIZE,
405 SECONDARY_SUPERS_TABLE_SIZE, nullptr);
406
407 for (int j = 0; j < length; j++) {
408 Klass* k = secondaries->at(j);
409 hash_insert(k, hashed_secondaries, bitmap);
410 }
411
412 // Pack the hashed secondaries array by copying it into the
413 // secondaries array, sans nulls, if modification is allowed.
414 // Otherwise, validate the order.
415 int i = 0;
416 for (int slot = 0; slot < SECONDARY_SUPERS_TABLE_SIZE; slot++) {
417 bool has_element = ((bitmap >> slot) & 1) != 0;
418 assert(has_element == (hashed_secondaries->at(slot) != nullptr), "");
419 if (has_element) {
420 Klass* k = hashed_secondaries->at(slot);
811 set_is_shared();
812
813 // FIXME: validation in Klass::hash_secondary_supers() may fail for shared klasses.
814 // Even though the bitmaps always match, the canonical order of elements in the table
815 // is not guaranteed to stay the same (see tie breaker during Robin Hood hashing in Klass::hash_insert).
816 //assert(compute_secondary_supers_bitmap(secondary_supers()) == _secondary_supers_bitmap, "broken table");
817 }
818
819 void Klass::remove_java_mirror() {
820 assert(CDSConfig::is_dumping_archive(), "sanity");
821 if (log_is_enabled(Trace, cds, unshareable)) {
822 ResourceMark rm;
823 log_trace(cds, unshareable)("remove java_mirror: %s", external_name());
824 }
825
826 #if INCLUDE_CDS_JAVA_HEAP
827 _archived_mirror_index = -1;
828 if (CDSConfig::is_dumping_heap()) {
829 Klass* src_k = ArchiveBuilder::current()->get_source_addr(this);
830 oop orig_mirror = src_k->java_mirror();
831 if (orig_mirror == nullptr) {
832 assert(CDSConfig::is_dumping_final_static_archive(), "sanity");
833 assert(is_instance_klass(), "sanity");
834 assert(InstanceKlass::cast(this)->is_shared_unregistered_class(), "sanity");
835 } else {
836 oop scratch_mirror = HeapShared::scratch_java_mirror(orig_mirror);
837 if (scratch_mirror != nullptr) {
838 _archived_mirror_index = HeapShared::append_root(scratch_mirror);
839 }
840 }
841 }
842 #endif
843
844 // Just null out the mirror. The class_loader_data() no longer exists.
845 clear_java_mirror_handle();
846 }
847
848 void Klass::restore_unshareable_info(ClassLoaderData* loader_data, Handle protection_domain, TRAPS) {
849 assert(is_klass(), "ensure C++ vtable is restored");
850 assert(is_shared(), "must be set");
851 assert(secondary_supers()->length() >= (int)population_count(_secondary_supers_bitmap), "must be");
852 JFR_ONLY(RESTORE_ID(this);)
853 if (log_is_enabled(Trace, cds, unshareable)) {
854 ResourceMark rm(THREAD);
855 oop class_loader = loader_data->class_loader();
856 log_trace(cds, unshareable)("restore: %s with class loader: %s", external_name(),
857 class_loader != nullptr ? class_loader->klass()->external_name() : "boot");
858 }
859
|