Any reason why +PrintFlagsFinal requires unlocking experimental and diagnostic flags to print their default values?
Frederic Thevenet
fthevene at redhat.com
Mon Dec 1 10:59:50 UTC 2025
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
>>>>>
>>>>
>>>
>>
>
--
Frederic Thevenet
Senior Software Engineer - OpenJDK
Red Hat France <https://www.redhat.com>
BAF5 C2D2 0BE0 1715 5EE1 0815 2065 AD47 B326 EB92
More information about the hotspot-dev
mailing list