Currently two different mechanisms exist for using archived heap regions stored in a CDS archive.
First mechanism mmaps the archived heap regions in the address space reserved for the heap. This mechanism is used only by G1 gc policy. This mechanism may need to relocate the pointers if the mapped address is different from the dump time address of the archived heap regions. The APIs are for this mechanism are G1 specific.
Second mechanism, used by non-G1 gc policies like serial and parallel, rely on allocating a chunk of heap memory and then reading the contents of archived heap regions in the memory chunk. This mechanism requires the contents to be relocated.
Presence of two different mechanisms has multiple drawbacks. It leads to unnecessary coupling between CDS and GC implementation. It makes the code difficult to reason about, and reduces maintainability. Extending the support to new GC policies like Shenandoah and ZGC is also challenging.
With some effort it should be possible to use same mechanism for all GC policies. Key is to design the GC APIs in such a way that they serve the requirement of CDS code without leaking internal details of the GC.
----
For easier review and integration this work is split into multiple sub-tasks:
1. Move the logic to determine location of the archive heap from CDS to G1 GC into the API alloc_archive_regions().
This also involves changing the API from
bool alloc_archive_regions(MemRegion range);
to
HeapWord* alloc_archive_regions(size_t word_size);
With the new API CDS would only pass the size of the archive space. G1 would internally do the calculation to determine the location and return that back.
This would make alloc_archive_regions() similar to the other API (allocate_loaded_archive_space) used by non-G1 collectors for loading the archive space.
2. Add/update the GC APIs that would work for all collectors.
Under this task common GC APIs to be used by CDS would be added. These APIs would be implemented by all collectors.
The new APIs would be:
HeapWord* alloc_archive_space(size_t word_size)
This would eventually replace allocate_loaded_archive_space() and the G1's alloc_archive_regions().
void fixup_archive_space(MemRegion range)
This would replace complete_loaded_archive_space() and G1's populate_archive_regions_bot_part().
void handle_archive_space_failure(MemRegion range)
This would replace ArchiveHeapLoader::fill_failed_loaded_heap() and G1's dealloc_archive_regions().
At this stage CDS code would also be updated to use Universe::heap() instead of G1CollectedHeap::heap() when calling the GC APIs for mapping the archive space.
CollectedHeap::reserved() would be added to return the reserved heap region so that the calls to G1CollectedHeap::heap()->reserved() can be replaced with Universe::heap()->reserved(). Currently only ZGC does not seem to set CollectedHeap::_reserved which can be addressed later when support for archive objects needs to be added for ZGC.
As the other collectors are not updated to use alloc_archive_space() yet, the allocate_loaded_archive_space() would continue to exist in the code base.
3. Update Serial, Parallel and Epsilon collectors to use new APIs.
As mentioned above non-G1 collectors would then be updated to add the new APIs, and the CDS code would need some updates to enable the use of new APIs for non-G1 collectors.
4. Cleanup - remove unused code if any.
First mechanism mmaps the archived heap regions in the address space reserved for the heap. This mechanism is used only by G1 gc policy. This mechanism may need to relocate the pointers if the mapped address is different from the dump time address of the archived heap regions. The APIs are for this mechanism are G1 specific.
Second mechanism, used by non-G1 gc policies like serial and parallel, rely on allocating a chunk of heap memory and then reading the contents of archived heap regions in the memory chunk. This mechanism requires the contents to be relocated.
Presence of two different mechanisms has multiple drawbacks. It leads to unnecessary coupling between CDS and GC implementation. It makes the code difficult to reason about, and reduces maintainability. Extending the support to new GC policies like Shenandoah and ZGC is also challenging.
With some effort it should be possible to use same mechanism for all GC policies. Key is to design the GC APIs in such a way that they serve the requirement of CDS code without leaking internal details of the GC.
----
For easier review and integration this work is split into multiple sub-tasks:
1. Move the logic to determine location of the archive heap from CDS to G1 GC into the API alloc_archive_regions().
This also involves changing the API from
bool alloc_archive_regions(MemRegion range);
to
HeapWord* alloc_archive_regions(size_t word_size);
With the new API CDS would only pass the size of the archive space. G1 would internally do the calculation to determine the location and return that back.
This would make alloc_archive_regions() similar to the other API (allocate_loaded_archive_space) used by non-G1 collectors for loading the archive space.
2. Add/update the GC APIs that would work for all collectors.
Under this task common GC APIs to be used by CDS would be added. These APIs would be implemented by all collectors.
The new APIs would be:
HeapWord* alloc_archive_space(size_t word_size)
This would eventually replace allocate_loaded_archive_space() and the G1's alloc_archive_regions().
void fixup_archive_space(MemRegion range)
This would replace complete_loaded_archive_space() and G1's populate_archive_regions_bot_part().
void handle_archive_space_failure(MemRegion range)
This would replace ArchiveHeapLoader::fill_failed_loaded_heap() and G1's dealloc_archive_regions().
At this stage CDS code would also be updated to use Universe::heap() instead of G1CollectedHeap::heap() when calling the GC APIs for mapping the archive space.
CollectedHeap::reserved() would be added to return the reserved heap region so that the calls to G1CollectedHeap::heap()->reserved() can be replaced with Universe::heap()->reserved(). Currently only ZGC does not seem to set CollectedHeap::_reserved which can be addressed later when support for archive objects needs to be added for ZGC.
As the other collectors are not updated to use alloc_archive_space() yet, the allocate_loaded_archive_space() would continue to exist in the code base.
3. Update Serial, Parallel and Epsilon collectors to use new APIs.
As mentioned above non-G1 collectors would then be updated to add the new APIs, and the CDS code would need some updates to enable the use of new APIs for non-G1 collectors.
4. Cleanup - remove unused code if any.
- is blocked by
-
JDK-8298048 Combine CDS archive heap into a single block
- Resolved
- relates to
-
JDK-8297313 Refactor APIs for calculating address of CDS archive heap regions
- Resolved
-
JDK-8311604 Simplify NOCOOPS requested addresses for archived heap objects
- Resolved
-
JDK-8296344 Remove dependency on G1 for writing the CDS archive heap
- Resolved
-
JDK-8310823 CDS archived object streaming
- Closed
- links to
-
Review openjdk/jdk/10970
(1 links to)