Closed Bug 612202 Opened 14 years ago Closed 14 years ago

JM: TypeInference: Faster calls on retryable functions

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED WONTFIX

People

(Reporter: bhackett1024, Unassigned)

References

(Blocks 1 open bug)

Details

A problem with trying to inline functions in JM is how to recover the stack if an inlined function throws or otherwise needs to access the stack. For a significant number of calls, this can be avoided by simply restarting the function with a stack should it fail somehow. This is OK to do as long as the function has not yet had any side effects, and a significant number of functions never have side effects, or are infallible after any side effects they do have (bug 606631 covers one pattern for these). e.g. in SS we make 120 thousand stack frames for calls to this function: function A(i,j) { return 1/((i+j)*(i+j+1)/2+i+1); } For functions which can always be restarted and which (via type inference) we do not expect to take any slow paths which require a stack or induce recompilation of the function, we can use a much simpler call ABI, and even customize it to the function itself. Still bump the stack pointer (if the callee needs scratch space) and store the return address, but leave the rest of the JSStackFrame uninitialized, don't sync the function or 'this' value (unless the callee needs them), don't sync arguments and 'this' for direct calls if they can be passed as registers instead. An ImmPtr needs to be written to the VMFrame which describes how to recover the arguments/this and restart instead of taking a slow path. A function compiled for fast calls like this can only make other fast calls or calls to natives (maybe needs knowledge of which natives have side effects), and no recursion allows a max stack depth to be computed for the outer function and stack-too-deep checks avoided. For the function 'A' above, i and j can be passed as registers and the result returned in a FP register. i+j is expected to be an integer, but if that overflows then 'A' (and possibly its callers) are recompiled taking a float result into account, and execution of 'A' restarts. Even more could be saved with proper inlining (or an inlining lite that memcpys inlined functions into the caller's generated code), but this is pretty close and it would be easier to do inlining as a followup and use the same retry mechanism.
If it can call natives, it absolutely needs to know something about the natives, because some natives examine the JS stack.
The native information can get folded into the type info already attached to the JSFunctions, which describe how the native affects types in the program (including whether the native has side effects). This will probably be a whitelist on which handlers are OK, so that Math.floor can be called in such functions but, say, eval can't.
Going to abandon this idea in favor of proper scripted call inlining (bug 639099), which will take longer for compilation but is simpler, will apply in more situations and will generate faster code.
Status: NEW → RESOLVED
Closed: 14 years ago
Resolution: --- → WONTFIX
You need to log in before you can comment on or make changes to this bug.