On Wed, 7 Jan 2026 12:58:43 GMT, Leo Korinth <[email protected]> wrote:

>> This change moves almost all of the ConcurrentMark initialisation from its 
>> constructor to the method `G1ConcurrentMark::fully_initialize()`.  Thus, 
>> creation time of the VM can be slightly improved by postponing creation of 
>> ConcurrentMark. Most time is saved postponing creation of statistics buffers 
>> and threads.
>> 
>> It is not obvious that this is the best solution. I have earlier 
>> experimented with lazily allocating statistics buffers _only_. One could 
>> also initialise a little bit more eagerly (for example the concurrent mark 
>> thread) and maybe get a slightly cleaner change. However IMO it seems better 
>> to not have ConcurrentMark "half initiated" with a created mark thread, but 
>> un-initialised worker threads.
>> 
>> This change is depending on the integration of 
>> https://bugs.openjdk.org/browse/JDK-8373253.
>> 
>> I will be out for vacation, and will be back after new year (and will not 
>> answer questions during that time), but I thought I get the pull request out 
>> now so that you can have a look.
>
> Leo Korinth has updated the pull request with a new target base due to a 
> merge or a rebase. The pull request now contains 564 commits:
> 
>  - Merge branch '8373253' into 8367993
>  - Merge branch 'master' into _8373253
>  - Merge branch 'master' into _8367993
>  - 8366058: Outdated comment in WinCAPISeedGenerator
>    
>    Reviewed-by: mullan
>  - 8357258: x86: Improve receiver type profiling reliability
>    
>    Reviewed-by: kvn, vlivanov
>  - 8373704: Improve "SocketException: Protocol family unavailable" message
>    
>    Reviewed-by: lucy, jpai
>  - 8373722: [TESTBUG] 
> compiler/vectorapi/TestVectorOperationsWithPartialSize.java fails 
> intermittently
>    
>    Reviewed-by: jiefu, jbhateja, erfang, qamai
>  - 8343809: Add requires tag to mark tests that are incompatible with 
> exploded image
>    
>    Reviewed-by: alanb, dholmes
>  - 8374465: Spurious dot in documentation for JVMTI ClassLoad
>    
>    Reviewed-by: kbarrett
>  - 8374317: Change GCM IV size to 12 bytes when encrypting/decrypting TLS 
> session ticket
>    
>    Reviewed-by: djelinski, mpowers, ascarpino
>  - ... and 554 more: https://git.openjdk.org/jdk/compare/2aa8aa4b...28ccbb68

Thanks for looking into this Leo. 

Overall I think it looks good, just some small questions and suggestions.

src/hotspot/share/gc/g1/g1CollectedHeap.cpp line 1637:

> 1635: 
> 1636: bool G1CollectedHeap::concurrent_mark_is_terminating() const {
> 1637:   assert(_cm != nullptr, "thread must exist in order to check if mark 
> is terminating");

I think it would make sense to add `&& _cm->is_fully_initialized()` to really 
make sure the thread has been created.

src/hotspot/share/gc/g1/g1CollectedHeap.cpp line 2427:

> 2425:   if (_cm->is_fully_initialized()) {
> 2426:     tc->do_thread(_cm->cm_thread());
> 2427:   }

Since the _cm_thread is now in `G1ConcurrentMark` this should be handled in 
`G1ConcurrentMark::threads_do()`

src/hotspot/share/gc/g1/g1CollectedHeap.cpp line 2549:

> 2547: void G1CollectedHeap::start_concurrent_cycle(bool 
> concurrent_operation_is_full_mark) {
> 2548:   assert(!_cm->in_progress(), "Can not start concurrent operation while 
> in progress");
> 2549:   assert(_cm->is_fully_initialized(), "sanity");

Not sure this sanity assert is needed `_cm->in_progress()` will always return 
`false` if not fully initialized, so the above assert will cover this. If we 
still want it, I think it should be moved above the `in_progress()` assert.

src/hotspot/share/gc/g1/g1PeriodicGCTask.cpp line 46:

> 44:     return false;
> 45:   }
> 46: 

Why is this needed? The initial young collection will make sure concurrent 
marking gets initialized, right?

src/hotspot/share/gc/g1/g1Policy.cpp line 744:

> 742:   if (!_g1h->concurrent_mark()->is_fully_initialized()) {
> 743:     return false;
> 744:   }

Is this needed? The `in_progress()` check below makes sure to only check the 
cm_thread when fully initialized.

src/hotspot/share/gc/g1/g1YoungCollector.cpp line 1127:

> 1125: 
> 1126: void G1YoungCollector::collect() {
> 1127:   _g1h->_cm->fully_initialize();

I think it would make more sense to do this in 
`G1CollectedHeap::do_collection_pause_at_safepoint()`. There we check if we 
should start concurrent mark, so maybe the initialization could be done only if 
we are about to start concurrent mark. If we can do the initialization after 
the actual young collection, then we could maybe even move the initialization 
into `G1CollectedHeap::start_concurrent_cycle(...)`

-------------

Changes requested by sjohanss (Reviewer).

PR Review: https://git.openjdk.org/jdk/pull/28723#pullrequestreview-3639436840
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2672366755
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2675276733
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2675291347
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2675313622
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2675328503
PR Review Comment: https://git.openjdk.org/jdk/pull/28723#discussion_r2675249630

Reply via email to