Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Exclude function-rooted traces from global_State->lasttrace
The variable global_State.lasttrace records the trace that is "to blame" by the profiler when the bytecode interpreter is running. This had previously been defined as the trace that most recently exited to the interpreter. Now it is restricted to exclude function-rooted traces and instead to always blame the most recently exited loop-rooted tace. This is based on the assumption that calling function-rooted traces is usually a consequence of running interpreted rather than the root cause. First a looping trace fails to compile (e.g. "fallback to interpreter" side-exit) and then the interpreter may execute a series of function-rooted traces before it enters a loop again. This makes the profiler information more actionable in common cases. The profiler will count time spent in the interpreter to the trace that most likely needs to be changed if you want to eliminate that interpreter time. Here is an example program: function save(x) saved = x end for i = 1, 1e4 do for i = 1, 1e3 do save(i) end for i = 1, 1e3 do save(function() end) end end This code runs in the interpreter because it includes an NYI i.e. creation of a closure with 'function() end'. This causes the second loop to run interpreted, which causes save(x) to get hot and be compiled. Previously RaptorJIT would have blamed the VM time on the trace for 'function save(x)' since that is the most recently executed trace when the profiler wakes up. However, with this change the profiler will assume that the function-rooted trace is a consequence of running interpreted rather than the root cause and so it will instead "blame" the exit from the first loop -- which is good because this is the point in the source code where we will find the root cause for ending up running interpreted (we will see the relevant trace aborts there.)
- Loading branch information