It is a known fact that using arguments
improperly in JavaScript may result in a function not being optimisable (see here and here by the end):
function notOptimisable (a, b) {
// Optimising compiler says: Nope.
var args = [].slice.call(arguments)
}
However, none of the sources have so far managed to explain why this prevents the optimisation from happening.
It is even more mind-boggling as all I have to do is
function optimisable (a, b) {
// Optimising compiler says: I can do this!
var args = new Array(arguments.length)
, i = 0
// Copy the arguments into an actual array, very carefully...
for(i; i < args.length; ++i)
args[i] = arguments[i]
}
and voilá - I have a copy of arguments
that is an actual array and the function can be optimised:
node --trace_opt --trace_deopt script.js # Exerpt below
[marking 0x24ba2c0bf0f1 <JS Function notoptimisable (SharedFunctionInfo 0x26b62a724859)> for recompilation, reason: small function, ICs with typeinfo: 3/3 (100%), generic ICs: 0/3 (0%)]
[disabled optimization for 0x26b62a724859 <SharedFunctionInfo notoptimisable>, reason: Bad value context for arguments value]
[failed to optimize notoptimisable: Bad value context for arguments value]
[marking 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> for recompilation, reason: small function, ICs with typeinfo: 7/7 (100%), generic ICs: 0/7 (0%)]
[optimizing 0x24ba2d0041b1 <JS Function optimisable (SharedFunctionInfo 0x26b62a7247b1)> - took 0.039, 0.164, 0.051 ms]
Thus, I ask thee:
Why?
- What technical challenges prevent the optimisation from taking place?
- Why can't the v8 engine simply return a standard array of arguments, just like the second code sample shows and optimise the function?
- For extra points, why is the
arguments
only an "array-like" object from the language design perspective (i.e. it has numeric keys, but it is not a descendant of Array) and does that somehow play a role in the optimisation process?