354
355 dynamic_info->open_as_output();
356 ArchiveHeapInfo no_heap_for_dynamic_dump;
357 ArchiveBuilder::write_archive(dynamic_info, &no_heap_for_dynamic_dump);
358
359 address base = _requested_dynamic_archive_bottom;
360 address top = _requested_dynamic_archive_top;
361 size_t file_size = pointer_delta(top, base, sizeof(char));
362
363 log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT
364 " [" UINT32_FORMAT " bytes header, %zu bytes total]",
365 p2i(base), p2i(top), _header->header_size(), file_size);
366
367 log_info(cds, dynamic)("%d klasses; %d symbols", klasses()->length(), symbols()->length());
368 }
369
370 void DynamicArchiveBuilder::gather_array_klasses() {
371 for (int i = 0; i < klasses()->length(); i++) {
372 if (klasses()->at(i)->is_objArray_klass()) {
373 ObjArrayKlass* oak = ObjArrayKlass::cast(klasses()->at(i));
374 Klass* elem = oak->element_klass();
375 if (AOTMetaspace::in_aot_cache_static_region(elem)) {
376 // Only capture the array klass whose element_klass is in the static archive.
377 // During run time, setup (see DynamicArchive::setup_array_klasses()) is needed
378 // so that the element_klass can find its array klasses from the dynamic archive.
379 DynamicArchive::append_array_klass(oak);
380 } else {
381 // The element_klass and its array klasses are in the same archive.
382 assert(!AOTMetaspace::in_aot_cache_static_region(oak),
383 "we should not gather klasses that are already in the static archive");
384 }
385 }
386 }
387 log_debug(aot)("Total array klasses gathered for dynamic archive: %d", DynamicArchive::num_array_klasses());
388 }
389
390 class VM_PopulateDynamicDumpSharedSpace: public VM_Heap_Sync_Operation {
391 DynamicArchiveBuilder _builder;
392 public:
393 VM_PopulateDynamicDumpSharedSpace(const char* archive_name)
423
424 void DynamicArchive::dump_array_klasses() {
425 assert(CDSConfig::is_dumping_dynamic_archive(), "sanity");
426 if (_array_klasses != nullptr) {
427 ArchiveBuilder* builder = ArchiveBuilder::current();
428 int num_array_klasses = _array_klasses->length();
429 _dynamic_archive_array_klasses =
430 ArchiveBuilder::new_ro_array<ObjArrayKlass*>(num_array_klasses);
431 for (int i = 0; i < num_array_klasses; i++) {
432 builder->write_pointer_in_buffer(_dynamic_archive_array_klasses->adr_at(i), _array_klasses->at(i));
433 }
434 }
435 }
436
437 void DynamicArchive::setup_array_klasses() {
438 if (_dynamic_archive_array_klasses != nullptr) {
439 for (int i = 0; i < _dynamic_archive_array_klasses->length(); i++) {
440 ObjArrayKlass* oak = _dynamic_archive_array_klasses->at(i);
441 Klass* elm = oak->element_klass();
442 assert(AOTMetaspace::in_aot_cache_static_region((void*)elm), "must be");
443
444 if (elm->is_instance_klass()) {
445 assert(InstanceKlass::cast(elm)->array_klasses() == nullptr, "must be");
446 InstanceKlass::cast(elm)->set_array_klasses(oak);
447 } else {
448 assert(elm->is_array_klass(), "sanity");
449 assert(ArrayKlass::cast(elm)->higher_dimension() == nullptr, "must be");
450 ArrayKlass::cast(elm)->set_higher_dimension(oak);
451 }
452 }
453 log_debug(aot)("Total array klasses read from dynamic archive: %d", _dynamic_archive_array_klasses->length());
454 }
455 }
456
457 void DynamicArchive::make_array_klasses_shareable() {
458 if (_array_klasses != nullptr) {
459 int num_array_klasses = _array_klasses->length();
460 for (int i = 0; i < num_array_klasses; i++) {
461 ObjArrayKlass* k = ArchiveBuilder::current()->get_buffered_addr(_array_klasses->at(i));
462 k->remove_unshareable_info();
463 }
464 }
465 }
466
467 void DynamicArchive::post_dump() {
468 if (_array_klasses != nullptr) {
469 delete _array_klasses;
470 _array_klasses = nullptr;
|
354
355 dynamic_info->open_as_output();
356 ArchiveHeapInfo no_heap_for_dynamic_dump;
357 ArchiveBuilder::write_archive(dynamic_info, &no_heap_for_dynamic_dump);
358
359 address base = _requested_dynamic_archive_bottom;
360 address top = _requested_dynamic_archive_top;
361 size_t file_size = pointer_delta(top, base, sizeof(char));
362
363 log_info(cds, dynamic)("Written dynamic archive " PTR_FORMAT " - " PTR_FORMAT
364 " [" UINT32_FORMAT " bytes header, %zu bytes total]",
365 p2i(base), p2i(top), _header->header_size(), file_size);
366
367 log_info(cds, dynamic)("%d klasses; %d symbols", klasses()->length(), symbols()->length());
368 }
369
370 void DynamicArchiveBuilder::gather_array_klasses() {
371 for (int i = 0; i < klasses()->length(); i++) {
372 if (klasses()->at(i)->is_objArray_klass()) {
373 ObjArrayKlass* oak = ObjArrayKlass::cast(klasses()->at(i));
374 if (oak->is_refined_objArray_klass()) {
375 oak = ObjArrayKlass::cast(oak->super());
376 }
377 Klass* elem = oak->element_klass();
378 if (AOTMetaspace::in_aot_cache_static_region(elem)) {
379 // Only capture the array klass whose element_klass is in the static archive.
380 // During run time, setup (see DynamicArchive::setup_array_klasses()) is needed
381 // so that the element_klass can find its array klasses from the dynamic archive.
382 DynamicArchive::append_array_klass(oak);
383 } else {
384 // The element_klass and its array klasses are in the same archive.
385 assert(!AOTMetaspace::in_aot_cache_static_region(oak),
386 "we should not gather klasses that are already in the static archive");
387 }
388 }
389 }
390 log_debug(aot)("Total array klasses gathered for dynamic archive: %d", DynamicArchive::num_array_klasses());
391 }
392
393 class VM_PopulateDynamicDumpSharedSpace: public VM_Heap_Sync_Operation {
394 DynamicArchiveBuilder _builder;
395 public:
396 VM_PopulateDynamicDumpSharedSpace(const char* archive_name)
426
427 void DynamicArchive::dump_array_klasses() {
428 assert(CDSConfig::is_dumping_dynamic_archive(), "sanity");
429 if (_array_klasses != nullptr) {
430 ArchiveBuilder* builder = ArchiveBuilder::current();
431 int num_array_klasses = _array_klasses->length();
432 _dynamic_archive_array_klasses =
433 ArchiveBuilder::new_ro_array<ObjArrayKlass*>(num_array_klasses);
434 for (int i = 0; i < num_array_klasses; i++) {
435 builder->write_pointer_in_buffer(_dynamic_archive_array_klasses->adr_at(i), _array_klasses->at(i));
436 }
437 }
438 }
439
440 void DynamicArchive::setup_array_klasses() {
441 if (_dynamic_archive_array_klasses != nullptr) {
442 for (int i = 0; i < _dynamic_archive_array_klasses->length(); i++) {
443 ObjArrayKlass* oak = _dynamic_archive_array_klasses->at(i);
444 Klass* elm = oak->element_klass();
445 assert(AOTMetaspace::in_aot_cache_static_region((void*)elm), "must be");
446 // Higher dimension may have been set when doing setup on ObjArrayKlass
447 if (!oak->is_refined_objArray_klass()) {
448 if (elm->is_instance_klass()) {
449 assert(InstanceKlass::cast(elm)->array_klasses() == nullptr, "must be");
450 InstanceKlass::cast(elm)->set_array_klasses(oak);
451 } else {
452 assert(elm->is_array_klass(), "sanity");
453 assert(ArrayKlass::cast(elm)->higher_dimension() == nullptr, "must be");
454 ArrayKlass::cast(elm)->set_higher_dimension(oak);
455 }
456 }
457 }
458 log_debug(aot)("Total array klasses read from dynamic archive: %d", _dynamic_archive_array_klasses->length());
459 }
460 }
461
462 void DynamicArchive::make_array_klasses_shareable() {
463 if (_array_klasses != nullptr) {
464 int num_array_klasses = _array_klasses->length();
465 for (int i = 0; i < num_array_klasses; i++) {
466 ObjArrayKlass* k = ArchiveBuilder::current()->get_buffered_addr(_array_klasses->at(i));
467 k->remove_unshareable_info();
468 }
469 }
470 }
471
472 void DynamicArchive::post_dump() {
473 if (_array_klasses != nullptr) {
474 delete _array_klasses;
475 _array_klasses = nullptr;
|