[jsc-dev] Revisiting inlining and bytecode size
Keith Miller
keith_miller at apple.com
Mon May 22 08:20:18 PDT 2017
Hi Yusuke!
I had thought about this problem a while ago and it always seemed to me that we should, at least, change our inlining heuristic to
use the average DFG/FTL assembly size of the function from previous compilations when choosing to inline or not. Something like:
double inliningCost()
{
if (compilationTier == FTL && haveAssemblySizeAverage(FTL))
return inliningScaleFactor(FTL) * assemblySizeAverage(FTL);
if (haveAssemblySizeAverage(DFG))
return inliningScaleFactor(DFG) * assemblySizeAverage(DFG);
return inliningScaleFactor(Bytecode) * bytecodeSize();
}
Another idea I had, possibly in addition to the using the average assembly size per function, would be to keep a running
average of the assembly size for each bytecode. Then when computing the inlining cost of a function, if we don’t have a
more accurate number from previous compilations, use the sum of the per bytecode assembly size averages.
Thoughts?
Cheers,
Keith
> On May 21, 2017, at 8:05 AM, Yusuke SUZUKI <utatane.tea at gmail.com> wrote:
>
> Hi, JSC folks!
>
> Recently I found that JSC does not work well in some microbenchmarks.
> https://arewefastyet.com/#machine=29&view=single&suite=six-speed&subtest=for-of-object-es6 <https://arewefastyet.com/#machine=29&view=single&suite=six-speed&subtest=for-of-object-es6>
>
> It shows that the critical function is not inlined.
> However, seeing the actual code, I think the target function is rather very small and we should inline that function in this case.
> The focused function is "next" in the following code.
>
> var data = {'a': 'b', 'c': 'd'};
> data[Symbol.iterator] = function() {
> var array = Object.keys(data),
> nextIndex = 0;
>
> return {
> next: function() {
> return nextIndex < array.length ?
> {value: data[array[nextIndex++]], done: false} :
> {done: true};
> }
> };
> };
>
> function fn() {
> var ret = '';
> for (var value of data) {
> ret += value;
> }
> return ret;
> }
>
> assertEqual(fn(), 'bd');
> test(fn);
>
> In the above code, next() function looks up multiple closure variables. nextIndex, array, and data.
> In that case, our bytecode compiler emits resolve_scope and get_from_scope.
> The problem is that the bytecode size of the resolve_scope and get_from_scope is quite big... It has much metadata to optimize them well.
>
> I think this size of these bytecodes does not reflect the actual cost of inlining. It has much size. But actual operation in DFG / FTL is quite, *quite* small.
>
> So here, I would like to start discussion about whether the bytecode size is good for cost calcucation for inlining. How do you think of accumulating number of operations instead of instruction size?
>
> BTW, get_by_id / put_by_id / etc. property operations also have massive sizes. It tends to become larger over years (for metadata). But we did not change inlining threshold.
>
> Best regards,
> Yusuke Suzuki
>
> _______________________________________________
> jsc-dev mailing list
> jsc-dev at lists.webkit.org
> https://lists.webkit.org/mailman/listinfo/jsc-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/jsc-dev/attachments/20170522/d97ae3e7/attachment.html>
More information about the jsc-dev
mailing list