[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