-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
IAF: Where can a trace end? Why? #103
Comments
I faced the same question some time ago, and here is what I learned after a very quick investigation:
There are some corner cases, though:
So answering your first question: No, looks like there is no option to finish recording on an arbitrary byte code. Just in case: To figure things out, I was simply trying to understand the code around rec_stop in lj_record.c |
Thanks for the notes @igelhaus! Do you think it is important to the design that traces only end on these particular points? I noticed an assertion in trace_stop() that will abort if a trace would end on a bytecode other than FORL/LOOP/ITERL/FUNCF/RET/RET0/RET1/JMP/CALLM/CALL/ITERC and I am wondering how important this is i.e. are the other cases truly invalid or simply unexpected. Seems to me like a trace should be able to end at any point. The JIT can exit to a side-trace at any point and the end of the trace is just another exit, right? Seems to me like this would be desirable too e.g. if your trace has 100 instructions and you hit an NYI/ILOOP/IFUNC then it is probably best to accept the trace and bail out to the interpreter as late as possible. That would about the situation of "blacklisting contagion" where one NYI can propagate through the whole program. |
Technically a "true" trace exit and a side trace exit are handled with more
or less the same code (I mean, side exits do hot-counting etc., but I do
not remember any crucial differences here), so I see no design limitations.
I can only guess, but probably recording stops at some fixed points to
minimise unexpected negative performance impact. Assume you are trying to
compile a loop and you have assembled a trace from N byte code instructions
with (N+1)-th being both a NYI and a last one in the loop body. An
arbitrary exit to the interpreter adds a switch between the interpreter and
the compiled code on each iteration, which is not as lightweight, which, in
turn, can eat up all performance gain achieved with JITting N instructions
(especially when N is considerably small).
But back to your example, it is still tempting to be able to JIT 100
instructions of some scalar code before, say, a NYI that appears
unconditionally in the control flow. Looks like the trace stitching feature
(briefly mentioned on http://wiki.luajit.org/NYI) addresses this issue to
some point.
2017-09-10 13:16 GMT+03:00 Luke Gorrie <notifications@github.com>:
… Thanks for the notes @igelhaus <https://github.com/igelhaus>!
Do you think it is important to the design that traces only end on these
particular points? I noticed an assertion in trace_stop()
<https://github.com/raptorjit/raptorjit/blob/master/src/lj_trace.c#L438>
that will abort if a trace would end on a bytecode other than
FORL/LOOP/ITERL/FUNCF/RET/RET0/RET1/JMP/CALLM/CALL/ITERC and I am
wondering how important this is i.e. are the other cases truly invalid or
simply unexpected.
Seems to me like a trace should be able to end at any point. The JIT can
exit to a side-trace at any point and the end of the trace is just another
exit, right? Seems to me like this would be desirable too e.g. if your
trace has 100 instructions and you hit an NYI/ILOOP/IFUNC then it is
probably best to accept the trace and bail out to the interpreter as late
as possible. That would about the situation of "blacklisting contagion"
where one NYI can propagate through the whole program.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#103 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AGWzvvVJ6CwESb58DBj33fs7z6aRC_KDks5sg7bygaJpZM4PR8on>
.
--
Med vennlig hilsen,
Anton Soldatov
|
Here is an Infrequently Answered Question:
Can a trace end on any bytecode at all? Or are there restrictions about e.g. what is the final bytecode, what is the point of control flow, etc?
This seems relevant to understanding how much flexibility the JIT has in selecting traces. For example, if we encounter an uncompilable bytecode like an NYI or a blacklisted function, do we have the option to successfully end the current trace and then transition to the interpreter? Or do we have to abort because this is not a valid end point for a trace for some reason?
cc @javierguerragiraldez
The text was updated successfully, but these errors were encountered: