375 } 376 377 size_t field_delta = pointer_delta( 378 p, _orig_referencing_obj, sizeof(char)); 379 T* new_p = (T*)(address(_archived_referencing_obj) + field_delta); 380 oop archived = MetaspaceShared::find_archived_heap_object(obj); 381 if (archived != NULL) { 382 // There is an archived copy existing, update reference to point 383 // to the archived copy 384 RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); 385 log.print( 386 "--- found existing archived copy, store archived " PTR_FORMAT " in " PTR_FORMAT, 387 p2i(archived), p2i(new_p)); 388 return; 389 } 390 391 int l = _level + 1; 392 Thread* THREAD = Thread::current(); 393 // Archive the current oop before iterating through its references 394 archived = MetaspaceShared::archive_heap_object(obj, THREAD); 395 assert(MetaspaceShared::is_archive_object(archived), "must be archived"); 396 log.print("=== archiving oop " PTR_FORMAT " ==> " PTR_FORMAT, 397 p2i(obj), p2i(archived)); 398 399 // Following the references in the current oop and archive any 400 // encountered objects during the process 401 WalkOopAndArchiveClosure walker(l, _subgraph_info, obj, archived); 402 obj->oop_iterate(&walker); 403 404 // Update the reference in the archived copy of the referencing object 405 RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); 406 log.print("=== store archived " PTR_FORMAT " in " PTR_FORMAT, 407 p2i(archived), p2i(new_p)); 408 409 // Add the klass to the list of classes that need to be loaded before 410 // module system initialization 411 Klass *orig_k = obj->klass(); 412 Klass *relocated_k = archived->klass(); 413 _subgraph_info->add_subgraph_object_klass(orig_k, relocated_k); 414 } 463 oop archived_m = MetaspaceShared::find_archived_heap_object(m); 464 if (CompressedOops::is_null(archived_m)) { 465 return; 466 } 467 468 if (field_type == T_OBJECT) { 469 // obtain k's subGraph Info 470 KlassSubGraphInfo* subgraph_info = get_subgraph_info(k); 471 472 // get the object referenced by the field 473 oop f = m->obj_field(field_offset); 474 if (!CompressedOops::is_null(f)) { 475 LogTarget(Debug, cds, heap) log; 476 LogStream ls(log); 477 outputStream* out = &ls; 478 log.print("Start from: "); 479 f->print_on(out); 480 481 // get the archived copy of the field referenced object 482 oop af = MetaspaceShared::archive_heap_object(f, THREAD); 483 if (!MetaspaceShared::is_archive_object(f)) { 484 WalkOopAndArchiveClosure walker(1, subgraph_info, f, af); 485 f->oop_iterate(&walker); 486 } 487 488 // The field value is not preserved in the archived mirror. 489 // Record the field as a new subGraph entry point. The recorded 490 // information is restored from the archive at runtime. 491 subgraph_info->add_subgraph_entry_field(field_offset, af); 492 Klass *relocated_k = af->klass(); 493 Klass *orig_k = f->klass(); 494 subgraph_info->add_subgraph_object_klass(orig_k, relocated_k); 495 } else { 496 // The field contains null, we still need to record the entry point, 497 // so it can be restored at runtime. 498 subgraph_info->add_subgraph_entry_field(field_offset, NULL); 499 } 500 } else { 501 ShouldNotReachHere(); 502 } 503 } 504 505 #define do_module_object_graph(archive_object_graph_do) \ 506 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \ 507 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \ 508 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK); \ 509 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedConfiguration_offset(), T_OBJECT, CHECK); \ 510 archive_object_graph_do(SystemDictionary::ImmutableCollections_ListN_klass(), java_util_ImmutableCollections_ListN::EMPTY_LIST_offset(), T_OBJECT, CHECK); \ 511 archive_object_graph_do(SystemDictionary::ImmutableCollections_MapN_klass(), java_util_ImmutableCollections_MapN::EMPTY_MAP_offset(), T_OBJECT, CHECK); \ 512 archive_object_graph_do(SystemDictionary::ImmutableCollections_SetN_klass(), java_util_ImmutableCollections_SetN::EMPTY_SET_offset(), T_OBJECT, CHECK); \ 513 archive_object_graph_do(SystemDictionary::Integer_IntegerCache_klass(), java_lang_Integer_IntegerCache::archivedCache_offset(), T_OBJECT, CHECK); \ 514 archive_object_graph_do(SystemDictionary::Configuration_klass(), java_lang_module_Configuration::EMPTY_CONFIGURATION_offset(), T_OBJECT, CHECK) | 375 } 376 377 size_t field_delta = pointer_delta( 378 p, _orig_referencing_obj, sizeof(char)); 379 T* new_p = (T*)(address(_archived_referencing_obj) + field_delta); 380 oop archived = MetaspaceShared::find_archived_heap_object(obj); 381 if (archived != NULL) { 382 // There is an archived copy existing, update reference to point 383 // to the archived copy 384 RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); 385 log.print( 386 "--- found existing archived copy, store archived " PTR_FORMAT " in " PTR_FORMAT, 387 p2i(archived), p2i(new_p)); 388 return; 389 } 390 391 int l = _level + 1; 392 Thread* THREAD = Thread::current(); 393 // Archive the current oop before iterating through its references 394 archived = MetaspaceShared::archive_heap_object(obj, THREAD); 395 if (archived == NULL) { 396 ResourceMark rm; 397 tty->print("Failed to archive %s object (" 398 PTR_FORMAT "), size[" SIZE_FORMAT "] in sub-graph", 399 obj->klass()->external_name(), p2i(obj), (size_t)obj->size()); 400 obj->print_on(tty); 401 vm_exit(1); 402 } 403 assert(MetaspaceShared::is_archive_object(archived), "must be archived"); 404 log.print("=== archiving oop " PTR_FORMAT " ==> " PTR_FORMAT, 405 p2i(obj), p2i(archived)); 406 407 // Following the references in the current oop and archive any 408 // encountered objects during the process 409 WalkOopAndArchiveClosure walker(l, _subgraph_info, obj, archived); 410 obj->oop_iterate(&walker); 411 412 // Update the reference in the archived copy of the referencing object 413 RawAccess<IS_NOT_NULL>::oop_store(new_p, archived); 414 log.print("=== store archived " PTR_FORMAT " in " PTR_FORMAT, 415 p2i(archived), p2i(new_p)); 416 417 // Add the klass to the list of classes that need to be loaded before 418 // module system initialization 419 Klass *orig_k = obj->klass(); 420 Klass *relocated_k = archived->klass(); 421 _subgraph_info->add_subgraph_object_klass(orig_k, relocated_k); 422 } 471 oop archived_m = MetaspaceShared::find_archived_heap_object(m); 472 if (CompressedOops::is_null(archived_m)) { 473 return; 474 } 475 476 if (field_type == T_OBJECT) { 477 // obtain k's subGraph Info 478 KlassSubGraphInfo* subgraph_info = get_subgraph_info(k); 479 480 // get the object referenced by the field 481 oop f = m->obj_field(field_offset); 482 if (!CompressedOops::is_null(f)) { 483 LogTarget(Debug, cds, heap) log; 484 LogStream ls(log); 485 outputStream* out = &ls; 486 log.print("Start from: "); 487 f->print_on(out); 488 489 // get the archived copy of the field referenced object 490 oop af = MetaspaceShared::archive_heap_object(f, THREAD); 491 if (af == NULL) { 492 // Skip archiving the sub-graph referenced from the current entry field. 493 ResourceMark rm; 494 log_info(cds, heap)( 495 "Cannot archive the sub-graph referenced from %s object (" 496 PTR_FORMAT ") size[" SIZE_FORMAT "], skipped.", 497 f->klass()->external_name(), p2i(f), (size_t)f->size()); 498 return; 499 } 500 if (!MetaspaceShared::is_archive_object(f)) { 501 WalkOopAndArchiveClosure walker(1, subgraph_info, f, af); 502 f->oop_iterate(&walker); 503 } 504 505 // The field value is not preserved in the archived mirror. 506 // Record the field as a new subGraph entry point. The recorded 507 // information is restored from the archive at runtime. 508 subgraph_info->add_subgraph_entry_field(field_offset, af); 509 Klass *relocated_k = af->klass(); 510 Klass *orig_k = f->klass(); 511 subgraph_info->add_subgraph_object_klass(orig_k, relocated_k); 512 ResourceMark rm; 513 log_info(cds, heap)( 514 "Archived the sub-graph referenced from %s object " PTR_FORMAT, 515 f->klass()->external_name(), p2i(f)); 516 } else { 517 // The field contains null, we still need to record the entry point, 518 // so it can be restored at runtime. 519 subgraph_info->add_subgraph_entry_field(field_offset, NULL); 520 } 521 } else { 522 ShouldNotReachHere(); 523 } 524 } 525 526 #define do_module_object_graph(archive_object_graph_do) \ 527 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedSystemModules_offset(), T_OBJECT, CHECK); \ 528 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedModuleFinder_offset(), T_OBJECT, CHECK); \ 529 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedMainModule_offset(), T_OBJECT, CHECK); \ 530 archive_object_graph_do(SystemDictionary::ArchivedModuleGraph_klass(), jdk_internal_module_ArchivedModuleGraph::archivedConfiguration_offset(), T_OBJECT, CHECK); \ 531 archive_object_graph_do(SystemDictionary::ImmutableCollections_ListN_klass(), java_util_ImmutableCollections_ListN::EMPTY_LIST_offset(), T_OBJECT, CHECK); \ 532 archive_object_graph_do(SystemDictionary::ImmutableCollections_MapN_klass(), java_util_ImmutableCollections_MapN::EMPTY_MAP_offset(), T_OBJECT, CHECK); \ 533 archive_object_graph_do(SystemDictionary::ImmutableCollections_SetN_klass(), java_util_ImmutableCollections_SetN::EMPTY_SET_offset(), T_OBJECT, CHECK); \ 534 archive_object_graph_do(SystemDictionary::Integer_IntegerCache_klass(), java_lang_Integer_IntegerCache::archivedCache_offset(), T_OBJECT, CHECK); \ 535 archive_object_graph_do(SystemDictionary::Configuration_klass(), java_lang_module_Configuration::EMPTY_CONFIGURATION_offset(), T_OBJECT, CHECK) |