Ever considered inlining 'hot' functions?
Hi all, I might be completely wrong, my understanding of our JIT or JIT in general might be flawed as well. I have been reading some papers on SELF93s type based optimizations and related papers and started to wonder.
From my understanding our JIT is generating code on the method level (a whole method), did you ever consider inlining small functions? E.g. where the number of bytecode is < 2 * the size of an activation record?
is that already done? was it tried? does it make sense? z.
On Sep 21, 2010, at 10:05 AM, Holger Freyther wrote:
Hi all,
I might be completely wrong, my understanding of our JIT or JIT in general might be flawed as well. I have been reading some papers on SELF93s type based optimizations and related papers and started to wonder.
From my understanding our JIT is generating code on the method level (a whole method), did you ever consider inlining small functions? E.g. where the number of bytecode is < 2 * the size of an activation record?
is that already done? was it tried? does it make sense?
It does make sense to inline hot functions. However, because of the highly dynamic nature of JavaScript, it is challenging to do this with full correctness. In particular, you need to either prove that the call will always be to the same function, or test to verify that it is the same. And you have to be prepared to recompile if your assumption fails. We actually do some level of "still the same function" testing in the fast path for calls. It is possible to apply similar techniques to inlining, but more challenging and with a greater penalty for missing. Regards, Maciej
In addition to what Maciej said you also have to ensure correct behaviour when someone does something akin to: function f() { return g(); } function g() { return g.caller; } or function g() { return arguments.callee; } or function g() { return g.arguments; } etc In the general case this would require being able to convert from inlined code to a 'correct' call stack at some arbitrary point --Oliver On Sep 21, 2010, at 10:05 AM, Holger Freyther wrote:
Hi all,
I might be completely wrong, my understanding of our JIT or JIT in general might be flawed as well. I have been reading some papers on SELF93s type based optimizations and related papers and started to wonder.
From my understanding our JIT is generating code on the method level (a whole method), did you ever consider inlining small functions? E.g. where the number of bytecode is < 2 * the size of an activation record?
is that already done? was it tried? does it make sense?
z. _______________________________________________ squirrelfish-dev mailing list squirrelfish-dev@lists.webkit.org http://lists.webkit.org/mailman/listinfo.cgi/squirrelfish-dev
On 09/22/2010 02:09 AM, Oliver Hunt wrote:
In the general case this would require being able to convert from inlined code to a 'correct' call stack at some arbitrary point
argh, I had hoped that such things would be only necessary when we have a debugger attached. This mean besides what maciej had said, we will need to remember that this range of instructions belongs to a inlined call and be able to generate the virtual call record. Can one write to arguments, callee and such? I wonder (and will try to measure based on sunspider and other test content) how many functions occur like function f(x) { return x +2; } or even fully constant. Is there any classification of the complexity of functions at parse time?
On Sep 21, 2010, at 11:37 AM, Holger Freyther wrote:
On 09/22/2010 02:09 AM, Oliver Hunt wrote:
In the general case this would require being able to convert from inlined code to a 'correct' call stack at some arbitrary point
argh, I had hoped that such things would be only necessary when we have a debugger attached. This mean besides what maciej had said, we will need to remember that this range of instructions belongs to a inlined call and be able to generate the virtual call record.
Can one write to arguments, callee and such?
arguments can be shadowed or individual arguments can be modified. You can statically detect when a function might use "arguments" and just avoid inlining it; the big problems are arguments.caller and func.arguments, since those can be done by functions called by the inlined function, so it's hard (maybe impossible) to statically prove they won't happen. There is a subset of functions that you can prove makes no calls, so in that case, inlining would be safe without excessive magic. But this would exclude property access for instance, since getters and setters can turn any property access into a call. So only functions that stick to simple arithmetic could be inlined.
I wonder (and will try to measure based on sunspider and other test content) how many functions occur like function f(x) { return x +2; } or even fully constant. Is there any classification of the complexity of functions at parse time?
I wonder how ES5 strict mode affects the challenge of doing inlining correctly. Regards, Maciej
On Sep 21, 2010, at 12:57 PM, Maciej Stachowiak wrote:
On Sep 21, 2010, at 11:37 AM, Holger Freyther wrote:
On 09/22/2010 02:09 AM, Oliver Hunt wrote:
In the general case this would require being able to convert from inlined code to a 'correct' call stack at some arbitrary point
argh, I had hoped that such things would be only necessary when we have a debugger attached. This mean besides what maciej had said, we will need to remember that this range of instructions belongs to a inlined call and be able to generate the virtual call record.
Can one write to arguments, callee and such?
arguments can be shadowed or individual arguments can be modified. You can statically detect when a function might use "arguments" and just avoid inlining it; the big problems are arguments.caller and func.arguments, since those can be done by functions called by the inlined function, so it's hard (maybe impossible) to statically prove they won't happen.
There is a subset of functions that you can prove makes no calls, so in that case, inlining would be safe without excessive magic. But this would exclude property access for instance, since getters and setters can turn any property access into a call. So only functions that stick to simple arithmetic could be inlined.
I wonder (and will try to measure based on sunspider and other test content) how many functions occur like function f(x) { return x +2; } or even fully constant. Is there any classification of the complexity of functions at parse time?
I wonder how ES5 strict mode affects the challenge of doing inlining correctly.
In strict mode arguments aren't live, arguments.callee, function.caller and function.arguments throw for any strict function.
Regards, Maciej
On Sep 21, 2010, at 1:02 PM, Oliver Hunt wrote:
On Sep 21, 2010, at 12:57 PM, Maciej Stachowiak wrote:
On Sep 21, 2010, at 11:37 AM, Holger Freyther wrote:
I wonder (and will try to measure based on sunspider and other test content) how many functions occur like function f(x) { return x +2; } or even fully constant. Is there any classification of the complexity of functions at parse time?
I wonder how ES5 strict mode affects the challenge of doing inlining correctly.
In strict mode arguments aren't live, arguments.callee, function.caller and function.arguments throw for any strict function.
That should make it practical to inline a wider range of functions if they are declared strict. Regards, Maciej
participants (3)
-
Holger Freyther
-
Maciej Stachowiak
-
Oliver Hunt