Redundant MethodCounters in preimage

María Arias de Reyna Dominguez mariasde at redhat.com
Thu Dec 4 09:00:35 UTC 2025


Hi!

Note that there are MethodCounters added on the assembly run that don't
have a MethodTrainingData associated. Maybe because those MethodCounters
were created during the assembly? And then they don't reflect behaviour
during training run but during assembly run? Or they are added via some
other link? I don't know. But in any case, if we don't want MethodCounters
with a low count value/with no MethodTrainingData, and we are excluding
them from the AOT, we should be consistent with that.

Example:

$ grep -r "boolean java.lang.Class.isHidden()" aot.map*
target/aot.map:0x00000008014c6340: @@ Method            104 boolean
java.lang.Class.isHidden()
target/aot.map:0x00000008014c63a8: @@ MethodCounters    64 boolean
java.lang.Class.isHidden()
target/aot.map:0x0000000803149908: @@ ConstMethod       64 boolean
java.lang.Class.isHidden()
target/aot.map.0:0x00000008015b23f0: @@ Method            104 boolean
java.lang.Class.isHidden()
target/aot.map.0:0x00000008015b2458: @@ MethodCounters    64 boolean
java.lang.Class.isHidden()
target/aot.map.0:0x00000008031d5430: @@ ConstMethod       64 boolean
java.lang.Class.isHidden()

It appears in both aot.map files (outputs of training and assembly).

Cheers!
María.


On Thu, Dec 4, 2025 at 4:55 AM Ashutosh Mehra <asmehra at redhat.com> wrote:

> Hi,
> While working on the leyden-analyzer tool Maria mentioned that
> MethodCounters for a particular method is present in the preimage generated
> by the training run but not in the final AOT Cache generated by the
> assembly phase. In fact the number of MethodCounters in the preimage is way
> more than that in the final image. For an app that Maria was using, map
> file for training phase shows:
>
> $ grep "@@ MethodCounters " t.map |wc -l 22495
>
> and the map file for assembly phase shows:
>
> $ grep "@@ MethodCounters " a.map |wc -l 8701
>
> I checked the code and realized there are two ways MethodCounters can get
> into the cache:
> 1. through Method (see Method::metaspace_pointers_do)
> 2. through MethodTrainingData
> (see MethodTrainingData::metaspace_pointers_do)
>
> The first point explains the presence of so many MethodCounters, because
> any method that gets executed would have its MethodCounters added to the
> cache.
> Interestingly the link between Method and MethodCounters is then severed
> in Method::unlink_method(). That means the Methods adopted from the
> preimage in the assembly phase do not have MethodCounters. And since we
> don't execute the application, we don't create MethodCounters for the
> Methods loaded from the preimage. Only the MethodCounters discoverable via
> MethodTrainingData seep into the AOTCache.
>
> From the above explanation it looks like not every MethodCounters added to
> the preimage is useful. Probably we should only be adding MethodCounters
> through the MethodTrainingData and not through Method. This would also
> reduce the size of the preimage a bit. In this particular case
> MethodCounters size was 1437824 bytes in preimage and 551552 bytes in the
> AOT Cache.
>
> Does this make sense?
>
> Thanks,
> - Ashutosh Mehra
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/leyden-dev/attachments/20251204/41d92c96/attachment.htm>


More information about the leyden-dev mailing list