JDK-8298600 : Prerequisites for JDK-8296344: Remove dependency on G1 for writing the CDS archive heap
  • Type: Enhancement
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 21
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2022-12-12
  • Updated: 2023-01-10
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 21
21Unresolved
Related Reports
Relates :  
Sub Tasks
JDK-8297914 :  
JDK-8298601 :  
JDK-8298610 :  
JDK-8298612 :  
Description
In order to implement  JDK-8296344 (Remove dependency on G1 for writing the CDS archive heap), the following need to be implemented first:

[1] Do not use "archived oops" in heap archiving APIs:

Currently, we execute HeapShared::archive_objects() while we are inside the safepoint of VM_PopulateDumpSharedSpace.  HeapShared::archive_objects() allocates an archived_oop for every oop to be archived. In some cases, we pass the archived_oop through "archiving APIs" to other modules for further manipulation. For example, java_lang_Class::process_archived_mirror() would zero out some fields inside the archived_oop. See JDK-8297914.

The problem with passing archived_oop to these APIs is that the callers often use the archive_oop as a real oop. I.e., they call functions such as oopDesc::obj_field_put(), which (indirectly) asserts that the archive_oop is an actual object in the Java heap.

As a result, the existing implementation requires the collector to implement a special allocator to create oops inside a safepoint. This has resulted in complex code in G1 that's fragile -- E.g., the allocation may fail or may be suboptimal when the G1 heap is fragmented by huge objects.

The goal of JDK-8296344 is to get rid of the special allocator (G1CollectedHeap::archive_mem_allocate). Instead, the heap image is built inside of a malloc'ed buffer that's outside of the heap. Even though the code uses the 'oop' type when it manipulates the copies, it avoids all operations that require a valid heap object check.

Consequently, all existing APIs that accept or return an archived_oop need to be rewritten to remove such usage.

[2] Avoid hand-assembling archived objects

Historically, archived objects of the java.lang.String and java.lang.Class types were hand-assembled. E.g., we archive the String object and its value array separately. However, now that we can recursively archive reachable objects, we can get rid of the hand-assembling code. This also avoid problems in [1].

The following RFEs need to be done before  JDK-8296344, in the following order:

JDK-8298601 - Refactor archiving of java.lang.Module objects
                       [1] 

JDK-8297914 - Remove java_lang_Class::process_archived_mirror()
                       [1] [2]
    
JDK-8298610 - Refactor archiving of ConstantPool::resolved_references()
                       [1] 
    
JDK-8298612 - Refactor archiving of java String objects
                       [1] [2]