8198888: Reduce string allocation churn inInvokerBytecodeGenerator

Claes Redestad claes.redestad at oracle.com
Thu Mar 1 19:05:29 UTC 2018

Hi Bernd,

to dispel your concerns about keeping references to classes then 
InvokerBytecodeGenerators are shortlived and go out of scope after 
they've been used to generate an invoker (or LF) class, so the impl. 
here should be safe from a class leak perspective. A static cache is 
tempting, but would then of course require the use of weak (or soft) 
references and a concurrent collection, which might make it cost more 
than it'd save us.

It does seem the typical answer for the number of entries that get put 
into each generator's cache is exactly one, so a single entry cache 
isn't an unreasonable alternative here.


On 2018-03-01 19:39, Bernd Eckenfels wrote:
> +        if (nameMap == null) {
> +            nameMap = new HashMap<>(2);
> What is the typical size the map ends up with? If it stays this small linearly searching an Array (or „last value“) may be faster.
> If the map typically grows more than a few entries having some more initial buckets will decrease collissions and avoid resizes. Especially considering the fact that HashMap is a rather fat object, it does not hurt to start with a bigger initial table. Does the lazy initialisation actually help anything?
> Single entry alternative
> ----------------
> Object lastClass; String lastName;
> If (lastClass == c)
>    return lastName;
> lastClass = c;
> lastName = c.getName().replace(‘.‘, ‘/‘);
> return lastName;
> (or make it a x Slot Version…):
> -------------------
> Object tab_obj = new tab_obj[8];
> String tab_val = new String[8];
> for(int i=0; i < tab_obj.length; i++)
> {
>    If (tab_obj[i] == c);
>      return tab_val[i];
> }
> i = (i+1 % tab_obj.length);
> tab_obj[i] = c;
> return (tab_val[i] = c.getName().replace());
> (not sure about the concurrent semantics and having this static may actually help)
> Gruss
> Bernd

More information about the core-libs-dev mailing list