<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
{font-family:"Cambria Math";
panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
{font-family:Calibri;
panose-1:2 15 5 2 2 2 4 3 2 4;}
@font-face
{font-family:"Helvetica Neue";
panose-1:2 0 5 3 0 0 0 2 0 4;}
@font-face
{font-family:Consolas;
panose-1:2 11 6 9 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
{margin:0cm;
font-size:10.0pt;
font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
{mso-style-priority:99;
color:blue;
text-decoration:underline;}
span.EmailStyle19
{mso-style-type:personal-reply;
font-family:"Calibri",sans-serif;
color:windowtext;}
p.p1, li.p1, div.p1
{mso-style-name:p1;
margin:0cm;
font-size:10.0pt;
font-family:"Helvetica Neue";}
p.p2, li.p2, div.p2
{mso-style-name:p2;
margin:0cm;
font-size:10.0pt;
font-family:"Helvetica Neue";}
span.apple-converted-space
{mso-style-name:apple-converted-space;}
.MsoChpDefault
{mso-style-type:export-only;
font-size:10.0pt;
mso-ligatures:none;}
@page WordSection1
{size:612.0pt 792.0pt;
margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
{page:WordSection1;}
--></style>
</head>
<body lang="en-CZ" link="blue" vlink="purple" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I’ve added to the PR a new benchmark:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><a href="https://github.com/openjdk/jdk/pull/13671/commits/958174edf6d794096846c879ca81cd2e6a1546f8">https://github.com/openjdk/jdk/pull/13671/commits/958174edf6d794096846c879ca81cd2e6a1546f8</a><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">It measures repeated transformations rebuilding method bodies (down to the symbols expansion) from already expanded model.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I’ve added shared and unshared CP alternatives (for curiosity), however the unshared is closer to simulation of building from symbols.
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">Here are results from the actual code base:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="p1"><span style="font-family:Consolas">Benchmark<span class="apple-converted-space">
</span>Mode<span class="apple-converted-space"> </span>Cnt<span class="apple-converted-space">
</span>Score <span class="apple-converted-space"> </span>Error<span class="apple-converted-space">
</span>Units<o:p></o:p></span></p>
<p class="p1"><span style="font-family:Consolas">RebuildMethodBodies.shared<span class="apple-converted-space">
</span>thrpt<span class="apple-converted-space"> </span>4<span class="apple-converted-space">
</span>10258.597 ± 383.699<span class="apple-converted-space"> </span>ops/s<o:p></o:p></span></p>
<p class="p1"><span style="font-family:Consolas">RebuildMethodBodies.unshared<span class="apple-converted-space">
</span>thrpt<span class="apple-converted-space"> </span>4 <span class="apple-converted-space">
</span>7224.543 ± 256.800<span class="apple-converted-space"> </span>ops/s<o:p></o:p></span></p>
<p class="p2"><o:p> </o:p></p>
<p class="p2"><span lang="EN-US">And here is visible approx. 22%improvement in both:<o:p></o:p></span></p>
<p class="p2"><o:p> </o:p></p>
<p class="p1"><span style="font-family:Consolas">Benchmark<span class="apple-converted-space">
</span>Mode<span class="apple-converted-space"> </span>Cnt<span class="apple-converted-space">
</span>Score<span class="apple-converted-space"> </span>Error<span class="apple-converted-space">
</span>Units<o:p></o:p></span></p>
<p class="p1"><span style="font-family:Consolas">RebuildMethodBodies.shared<span class="apple-converted-space">
</span>thrpt<span class="apple-converted-space"> </span>4<span class="apple-converted-space">
</span>12498.597 ± 309.585<span class="apple-converted-space"> </span>ops/s<o:p></o:p></span></p>
<p class="p1"><span style="font-family:Consolas">RebuildMethodBodies.unshared<span class="apple-converted-space">
</span>thrpt<span class="apple-converted-space"> </span>4 <span class="apple-converted-space">
</span>8807.229 ±<span class="apple-converted-space"> </span>167.247<span class="apple-converted-space">
</span>ops/s<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-size:11.0pt;mso-fareast-language:EN-US">I’m looking forward to the numbers after Constants API improvements (cached internal names in ClassDesc and ClassDescs of parameters cached in MethodTypeDescs).<o:p></o:p></span></p>
<div style="border:none;border-top:solid #B5C4DF 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal" style="margin-bottom:12.0pt"><b><span style="font-size:12.0pt;color:black">From:
</span></b><span style="font-size:12.0pt;color:black">liangchenblue@gmail.com <liangchenblue@gmail.com><br>
<b>Date: </b>Wednesday, 26 April 2023 18:07<br>
<b>To: </b>Brian Goetz <brian.goetz@oracle.com><br>
<b>Cc: </b>Adam Sotona <adam.sotona@oracle.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
<b>Subject: </b>[External] : Re: Caching symbolic descriptors for the constant pool<o:p></o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:11.0pt">I've been using Write/jdkTree as a reference, for it has an asm<br>
baseline that can calibrate between runs and most JDK usages are<br>
write-oriented. If we can run AdaptNull/SHARED_3 with an ASM_1 as a<br>
baseline, it would be more convincing as well.<br>
<br>
On Wed, Apr 26, 2023 at 10:47 AM Brian Goetz <brian.goetz@oracle.com> wrote:<br>
><br>
> Right, that was mostly aimed at other folks who are contributing -- "this is the most useful general-purpose bench IMO".<br>
><br>
> On 4/26/2023 11:45 AM, Adam Sotona wrote:<br>
><br>
> Unfortunately AdaptNull/SHARED_3 does not include symbols conversions and building performance (the use case of ProxyGenerator).<br>
><br>
> I’ll try to add a benchmark focused on building from symbols.<br>
><br>
><br>
><br>
> From: Brian Goetz <brian.goetz@oracle.com><br>
> Date: Wednesday, 26 April 2023 17:19<br>
> To: Adam Sotona <adam.sotona@oracle.com>, liangchenblue@gmail.com <liangchenblue@gmail.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
> Subject: Re: Caching symbolic descriptors for the constant pool<br>
><br>
> BTW, I have found the AdaptNull/SHARED_3 benchmark to extremely useful for detecting *overall* regressions/improvements. (Obviously targeted benchmarks are more useful for targeted problems like this one, but if people are going to run one bench before and
after a change, it should be this one.)<br>
><br>
> On 4/26/2023 11:12 AM, Adam Sotona wrote:<br>
><br>
> FYI: Here is draft of pull request with initial batch of performance improvements (no API change):<br>
><br>
> <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/pull/13671__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7s6KvQHT$">
https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/13671__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7s6KvQHT$</a>
<br>
><br>
><br>
><br>
> It is branched from PR13478 due to its significant changes in StackMapGenerator.<br>
><br>
><br>
><br>
> Here are some first measurable improvements:<br>
><br>
><br>
><br>
> Benchmark Mode Cnt Score Error Units<br>
><br>
> GenerateStackMaps.benchmark thrpt 10 407931.202 ± 13101.023 ops/s<br>
><br>
><br>
><br>
> improved by approx 15% to:<br>
><br>
><br>
><br>
> GenerateStackMaps.benchmark thrpt 10 470826.720 ± 3569.194 ops/s<br>
><br>
><br>
><br>
> Adam<br>
><br>
><br>
><br>
><br>
><br>
> From: classfile-api-dev <classfile-api-dev-retn@openjdk.org> on behalf of Adam Sotona <adam.sotona@oracle.com><br>
> Date: Tuesday, 25 April 2023 16:25<br>
> To: Brian Goetz <brian.goetz@oracle.com>, liangchenblue@gmail.com <liangchenblue@gmail.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
> Subject: Re: Caching symbolic descriptors for the constant pool<br>
><br>
> I think it perfectly fits to the performance improvements I’m working on.<br>
><br>
> The “caching” here means to 1:1 store symbol with PoolEntry after the first request or when the entry has been created from the symbol.<br>
><br>
> There is no risk of any growing global caches.<br>
><br>
><br>
><br>
> If the Constants API will also “cache” internal class name in ClassDesc and ClassDescs of the MethodTypeDesc parameters and return type.<br>
><br>
><br>
><br>
> Then we can achieve paths with minimal or no conversions, for example:<br>
><br>
> ClassDesc -> MethodTypeDesc -> CodeBuilder -> PoolEntry -> InvokeInstruction -> StackMapGenerator -> ClassHierarchyResolver -> ClassDesc -> internal class name -> StackMapGenerator.Type -> PoolEntry -> BufWriterImpl -> internal class name<br>
><br>
><br>
><br>
> From: classfile-api-dev <classfile-api-dev-retn@openjdk.org> on behalf of Brian Goetz <brian.goetz@oracle.com><br>
> Date: Tuesday, 25 April 2023 16:12<br>
> To: liangchenblue@gmail.com <liangchenblue@gmail.com>, classfile-api-dev <classfile-api-dev@openjdk.org><br>
> Subject: Re: Caching symbolic descriptors for the constant pool<br>
><br>
> For caching symbols in the Class API, this is fine but we should wait a<br>
> bit. Doing caching raises the question of where the cache lives and how<br>
> long it lives; we had some discussions recently about caching for class<br>
> hierarchy info, and concluded that we had reached the limits of what we<br>
> can do with static entry points. By refactoring the main entry points<br>
> (build/parse) to instance methods on a user-controlled "classfile<br>
> context" object, we create a logical place and lifetime for caches, of<br>
> which we now have two examples.<br>
><br>
> Adam currently has a queue of patches he is trying to shepherd in, after<br>
> which we will look at refactoring the CHA functionality, after which we<br>
> will look at refactoring the "front door", and then that should leave a<br>
> natural place to slot in caching of symbolic constants.<br>
><br>
> On 4/24/2023 7:18 PM, - wrote:<br>
> > First, thanks for the feedback on my cache proposal a few days ago!<br>
> > I've prepared two patches under 8306697<br>
> > <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/pull/13598and__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7qSkfBvJ$">
https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/13598and__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7qSkfBvJ$</a> 8306698<br>
> > <a href="https://urldefense.com/v3/__https:/github.com/openjdk/jdk/pull/13599__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7qddDVgO$">
https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/13599__;!!ACWV5N9M2RV99hQ!IVDau8WQpIsrL_JQ_jJprNpo673-bfPT7Cw0QgrmYLh24m0fmxkAKgMzPtCwY9g0uUa3mmUKVVL2trDA7qddDVgO$</a> , which will hopefully make<br>
> > the Constant API more useful with classfiles.<br>
> ><br>
> > I wish to cache symbolic descriptors in classfile API itself. One of<br>
> > the prime candidates identified by Adam in his migration of<br>
> > java.lang.invoke to classfile API is ClassEntry.asSymbol, which from<br>
> > my search, appears to be frequently used in stack map generation. In<br>
> > addition, a MethodTypeDesc is passed to stack map generator<br>
> > constructor via ofDescriptor (which has slow parsing even after Adam's<br>
> > optimization), but the parsing can totally be averted if we can reuse<br>
> > the MethodTypeDesc passed in withMethod(). Thus, I wish to add<br>
> > accessors like typeSymbol() and cachedTypeSymbol() for MethodInfo to<br>
> > speed up StackMapGenerator initialization.<br>
> ><br>
> > In addition, the stack map generator has a custom bitset-based tool to<br>
> > split a descriptor on the fly (See<br>
> > StackMapGenerator.processInvokeInstructions). I believe they can<br>
> > benefit from reusing a parsed MethodTypeDesc as well, especially if<br>
> > the invoke instructions were originally built with MethodTypeDesc.<br>
> ><br>
> > Chen Liang<br>
><br>
><br>
><br>
><o:p></o:p></span></p>
</div>
</div>
</body>
</html>