Any reason why +PrintFlagsFinal requires unlocking experimental and diagnostic flags to print their default values?

David Holmes david.holmes at oracle.com
Mon Dec 1 20:19:53 UTC 2025


On 1/12/2025 9:12 pm, Frederic Thevenet wrote:
> PS: All that to say that, yes I think simply removing the 
> `flagTable[i].is_unlocked()` check is quite possibly the way to go (I 
> hit send too soon, sorry).

Sorry, I was overlooking all the other usecases. You are quite right 
that I have reservations about changing some of those. So I stand by:

 > Well there is no obvious reason that these flags should differ in 
what kind of flags they print

but withdraw the actual suggested fix.

David
-----
> On 12/1/25 11:59, Frederic Thevenet wrote:
>>
>>
>> On 12/1/25 11:17, David Holmes wrote:
>>> On 1/12/2025 8:10 pm, Frederic Thevenet wrote:
>>>>
>>>>
>>>> On 12/1/25 10:59, David Holmes wrote:
>>>>> On 1/12/2025 7:41 pm, Frederic Thevenet wrote:
>>>>>> Thanks for filling the bug, David; I've assigned it to myself and 
>>>>>> will propose a PR for this shortly.
>>>>>>
>>>>>> Before I do, there's one point I feel might be worth clarifying in 
>>>>>> this discussion first.
>>>>>> In the current implementation, PrintFlagsFinal and 
>>>>>> PrintFlagsRanges are quite tightly intertwined, as one acts as an 
>>>>>> "upgrade" to the other (i.e. setting PrintFlagsRanges will 
>>>>>> override PrintFlagsFinal).
>>>>>> To me, it makes sense to change the behaviour for PrintFlagsRanges 
>>>>>> to also print all flags if we do it for PrintFlagsFinal, but I 
>>>>>> wanted to first ask if anyone sees a reason not to do this?
>>>>>
>>>>> I think that makes sense. Though you can then extend the same logic 
>>>>> to PrintFlagsInitial and even PrintFlagsWithComments, so the scope 
>>>>> expands. If you just want to restrict the change to PrintFlagsFinal 
>>>>> then I think the simplest thing is to just expand:
>>>>>
>>>>> void JVMFlag::printFlags(outputStream* out, bool withComments, bool 
>>>>> printRanges, bool skipDefaults) {
>>>>>
>>>>> to
>>>>>
>>>>> void JVMFlag::printFlags(outputStream* out, bool withComments, bool 
>>>>> printRanges, bool skipDefaults, bool printLocked) {
>>>>>
>>>>> and then have
>>>>>
>>>>>   // All the flags that get adjusted by VM_Version_init and os::init_2
>>>>>   // have been set so dump the flags now.
>>>>>   if (PrintFlagsFinal || PrintFlagsRanges) {
>>>>>     JVMFlag::printFlags(tty, false, PrintFlagsRanges, false, 
>>>>> PrintFlagsFinal);
>>>>>   }
>>>>
>>>> With regard to PrintFlagsInitial or PrintFlagsWithComments, it 
>>>> wasn't my primary goal to change these but I can certainly look into 
>>>> it while I'm at it if there is a consensus that it is in fact a good 
>>>> idea.
>>>> Anyone care to  comment?
>>>
>>> Well there is no obvious reason that these flags should differ in 
>>> what kind of flags they print - they only differ in what data gets 
>>> printed for each flag.
>>>
>>> Maybe it is simpler and more consistent to just delete the
>>>
>>>  flagTable[i].is_unlocked()
>>>
>>> check.
>>
>> Well yes indeed, but then aren't we right back at my initial proposal, 
>> which we were worried might be too far-reaching? (Or maybe it was just 
>> me who misunderstood your first answer?)
>>
>> Right now I can list 6 call sites for the underlying 
>> JVMFlag::printFlags methods:
>> - For handling PrintFlagsFinal and  PrintFlagsRanges in init.cpp [0]
>> - For -XprintFlags in arguments.cpp [1]
>> - For PrintFlagsInitial  in arguments.cpp [2]
>> - For PrintFlagsWithComments in arguments.cpp [3]
>> - For printing flags in hs_err reports in vmError.cpp [4]
>> - For handling PrintVMFlagsDCmd in diagnosticCommand.cpp [5]
>>
>> As per our current discussion, we probably want the first fourto 
>> exhibit the same behaviour, for the sake of coherency.
>> Then, as mentioned before, I believe calling  JVMFlag::printFlags with 
>> skipDefaults to true would not be affected by removing the unlocked 
>> check at all (so printing flags in hs_err would not change).
>> Finally, when it comes to the implementation of the PrintVMFlagsDCmd 
>> diagnostic command, it already offers two modes controlled by the 
>> consumer, one for only showing set flags and one for showing "all" 
>> flags: I feel that also showing locked flags in this case would not be 
>> a bad thing.
>>
>> [0] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> runtime/init.cpp#L210
>> [1] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> runtime/arguments.cpp#L2528C18-L2528C19
>> [2] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> runtime/arguments.cpp#L3467
>> [3] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> runtime/arguments.cpp#L3473
>> [4] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> utilities/vmError.cpp#L1277
>> [5] https://github.com/openjdk/jdk/ 
>> blob/5bd7db034aaf8aa6780945e02a7f9a35e16b036e/src/hotspot/share/ 
>> services/diagnosticCommand.cpp#L256
>>
>>>
>>> David
>>>>>
>>>>> David
>>>>>> Cheers
>>>>>> Frederic
>>>>>>
>>>>>> On 12/1/25 10:21, David Holmes wrote:
>>>>>>> Okay I have filed:
>>>>>>>
>>>>>>> JDK-8372802: PrintFlagsFinal should also print locked flags
>>>>>>>
>>>>>>> but note there is no commitment for anyone to actually perform 
>>>>>>> the work.
>>>>>>>
>>>>>>> David
>>>>>>>
>>>>>>> On 28/11/2025 3:19 pm, Thomas Stüfe wrote:
>>>>>>>> I am very much in favor of printing all flags, for the reasons 
>>>>>>>> Frederic has given. When one supports many different releases, 
>>>>>>>> it is a huge timesaver not to have to look up flags but see them 
>>>>>>>> right there in the customer logs. The ability of PrintFlagsFinal 
>>>>>>>> to give me all flags, including default values, after they are 
>>>>>>>> resolved to their final values, is also very useful during 
>>>>>>>> development.
>>>>>>>>
>>>>>>>> For simplicity, I would prefer just to change the behavior of 
>>>>>>>> PrintFlagsFinal to do that, but I could live with a new 
>>>>>>>> PrintAllFlagsFinal.
>>>>>>>>
>>>>>>>> Number of normal flags: 513, incl. diagnostic: 777, incl. 
>>>>>>>> experimental&diagnostic: 933. (Jdk 25). So, it's a bit more. I 
>>>>>>>> am not bothered by this, since this list never fits onto a 
>>>>>>>> single screen anyway. People grep. But if others prefer an extra 
>>>>>>>> flag, sure, let's have one.
>>>>>>>>
>>>>>>>>
>>>>>>>> On Thu, Nov 27, 2025 at 3:05 AM David Holmes 
>>>>>>>> <david.holmes at oracle.com <mailto:david.holmes at oracle.com>> wrote:
>>>>>>>>
>>>>>>>>     On 27/11/2025 12:53 am, Frederic Thevenet wrote:
>>>>>>>>      > Hi,
>>>>>>>>      >
>>>>>>>>      > Currently, using +PrintFlagsFinal prints out all JVM 
>>>>>>>> flags and their
>>>>>>>>      > values, even if they were not modified from their 
>>>>>>>> default, except
>>>>>>>>     for
>>>>>>>>      > 'locked' flags, i.e. Experimental and Diagnotic flags. In 
>>>>>>>> order
>>>>>>>>     to have
>>>>>>>>      > those printed out as well, one must first 'unlock' them 
>>>>>>>> (with
>>>>>>>>      > +UnlockExperimentalVMOptions, for instance).
>>>>>>>>
>>>>>>>>     I think this was simply a pragmatic decision to avoid 
>>>>>>>> overwhelming the
>>>>>>>>     user with information that should not be relevant.
>>>>>>>>      > Now, is their a strong reason for not always displaying 
>>>>>>>> the default
>>>>>>>>      > values for those in scenarios were there is no concerns 
>>>>>>>> that the
>>>>>>>>     output
>>>>>>>>      > might be too large (that is when calling upon
>>>>>>>>     'JVMFlag::printFlags' with
>>>>>>>>      > 'skipDefaults' set to false, like PrintFlagsFinal does)?
>>>>>>>>      >
>>>>>>>>      > The reason for this question is that when chasing a bug 
>>>>>>>> in scenarios
>>>>>>>>      > where one can only rely on logs or output provided by 
>>>>>>>> tools that
>>>>>>>>     uses
>>>>>>>>      > +PrintFlagsFinal, getting the default values *in the 
>>>>>>>> conditions that
>>>>>>>>      > those logs where produced* can be tricky as it depends on 
>>>>>>>> the exact
>>>>>>>>      > version of the JDK that was running, and some values can be
>>>>>>>>     changed by
>>>>>>>>      > ergonomics.
>>>>>>>>
>>>>>>>>     Ouch. I think that would be a poor design choice for 
>>>>>>>> diagnostic, and
>>>>>>>>     especially experimental flags!
>>>>>>>>
>>>>>>>>
>>>>>>>> Not every experimental/diagnostic flag is a boolean that 
>>>>>>>> defaults to false and controls an opt-in feature. We have non- 
>>>>>>>> boolean experimental flags and boolean flags that default to 
>>>>>>>> true. It is not unthinkable that those are changed during VM start.
>>>>>>>>
>>>>>>>>
>>>>>>>>      > If you need to know the default for experimental flags -- 
>>>>>>>> which
>>>>>>>>     given
>>>>>>>>      > their nature can and do change often -- your choices are to
>>>>>>>>     either ask
>>>>>>>>      > for these logs to be generated again using
>>>>>>>>     +UnlockExperimentalVMOptions
>>>>>>>>      > (even if there is no intention of changing an 
>>>>>>>> experimental flag)
>>>>>>>>     or to
>>>>>>>>      > go on a time consuming deep dive into the code base for 
>>>>>>>> the exact
>>>>>>>>      > version of the JDK that was used. Neither is ideal.
>>>>>>>>
>>>>>>>>     True, but for experimental flags in particular, unless you 
>>>>>>>> are deep
>>>>>>>>     diving into the code how can you know whether a particular 
>>>>>>>> flag and its
>>>>>>>>     value are relevant to your debugging in the first place?
>>>>>>>>
>>>>>>>>
>>>>>>>> I think the point here is reducing analyst strain. It's not that 
>>>>>>>> it is impossible to get the information otherwise, but that 
>>>>>>>> it's convenient and stress-reducing to have one sure way to look 
>>>>>>>> up all resolved flag values for a customer's JVM run. Folks who 
>>>>>>>> have to work with many cases involving different JVM versions 
>>>>>>>> would value this.
>>>>>>>>
>>>>>>>> BTW, we do print default values for non-experimental non- 
>>>>>>>> diagnostic flags, too. The same reasoning applies here: if 
>>>>>>>> its not changed, you could look up the default value.
>>>>>>>>
>>>>>>>>
>>>>>>>>     That said, I don't see any harm in providing a way to print 
>>>>>>>> all flags,
>>>>>>>>     though whether by default or by a new -XX:PrintAllFlagsFinal 
>>>>>>>> flag, I'm
>>>>>>>>     not sure.
>>>>>>>>
>>>>>>>>
>>>>>>>> Wonderful, let's do that then.
>>>>>>>>
>>>>>>>> Cheers, Thomas
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
> 



More information about the hotspot-dev mailing list