msg41295 - (view) |
Author: Armin Rigo (arigo) *  |
Date: 2002-10-01 23:26 |
Psyco-friendly patch #3. Allows the C profile and trace functions (called upon function entry, line tracing, function exit, and exception) to alter some fields of the current PyFrameObject to influence the execution of the main loop. This is currently impossible because all the relevant fields are copied into local variables of eval_frame(), shadowing any subsequence change in the frame object. This is designed for what I plan to do with Psyco, but could also be used by advanced debuggers to allow the execution point to be modified by the user. Besides, the patch is just a matter of swapping a few lines in eval_frame(), introducing almost no extra complexity. In ceval.c:eval_frame(): The calls to call_trace(...PyTrace_CALL...) at the beginning of the code have been moved above the initialization of the local variables, allowing the trace functions to fiddle with the frame object before the main loop sees it. There is also a bug fix here: if the profile or trace functions raise an error at this point, eval_frame() used to quit without restoring tstate->frame and tstate->recursion_depth. [XXX should have been a bug report on its own] Finally, the call_trace() on SET_LINENO has been slightly modified to allow the trace function to move the execution point elsewhere. This is done by saving a few local variables are saved to and restored from the frame object around the call_trace(). The variables are the current instruction pointer (which was already saved in f->f_lasti, but is now restored from f->f_lasti too), and the current stack_pointer. Compatibility: f->f_stacktop normally remains NULL for the whole execution of the frame. This patch sets it to a non-NULL value for the duration of the call to the line-by-line trace function. I expect this not to cause any incompatibility because f->f_stacktop is not visible from Python code. I do not expect extension modules to rely on this detail. Note however that this has an influence on the GC, which only visits the stack if f->f_stacktop is set. Again, I assume this is not an issue -- it cannot even cause dead cycles to be detected earlier by the GC because as long as we are in the call_trace() call, we have a live reference to f. Performance: when tracing is on, SET_LINENO is now marginally slower. I guess this is not considered as an issue given the debugging nature of tracing. In Python 2.3, line tracing is currently *much* heavier and nobody seems to complain ;-) |
|
|
msg41296 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-10-02 12:23 |
Logged In: YES user_id=6656 What about the blockstack? Are you just relying on trace functions not moving f_lasti unwisely? Agree about the bug. Do you have a test case for it? Otherwise I'll cook one up. |
|
|
msg41297 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-10-02 13:14 |
Logged In: YES user_id=6656 Never mind, the bug offended me so much that I fixed it both on the trunk and the 22-maint branch. Python/ceval.c revisions 2.337 and 2.301.4.5 Lib/test/test_trace.py revisions 1.4 and 1.4.2.1 (probably a 2.1 bugix candidate, if any cares...) |
|
|
msg41298 - (view) |
Author: Armin Rigo (arigo) *  |
Date: 2002-10-02 20:33 |
Logged In: YES user_id=4771 The trace function can change f_lasti if it knows what it does and if it accordingly changes all other fields too, like f_stacktop, f_blockstack and f_iblock. In fact, f_lasti and f_stacktop are the only fields of the frame objects that are currently cached in local variables (with the exception of what concerns the f_code object itself) so that this patch is enough to let the trace function actually move the execution point elsewhere. This would be quite useful in Psyco, if the rest of the function has been emulated and we then want the main loop to exit with the proper value: just move f_lasti just before the RETURN_VALUE opcode, clean up the stack and block stack, and push the already-computed result value where RETURN_VALUE will find it. Psyco could also execute just a part of the function and give it back to Python at some later position. A "clean hack". |
|
|
msg41299 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-10-03 08:50 |
Logged In: YES user_id=6656 Fair enough. Let's see what Guido thinks. |
|
|
msg41300 - (view) |
Author: Guido van Rossum (gvanrossum) *  |
Date: 2002-10-06 20:44 |
Logged In: YES user_id=6380 I'd like to get this into 2.2.2, but the patch doesn't apply cleanly (courtesy of MWH fixing the beg reported herein :-). Armin, can you upload a fixed patch? Or if MWH reads this, can you check this and the other two in? |
|
|
msg41301 - (view) |
Author: Armin Rigo (arigo) *  |
Date: 2002-10-07 00:28 |
Logged In: YES user_id=4771 Here you are! |
|
|
msg41302 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-10-07 09:38 |
Logged In: YES user_id=6656 OK done, in ceval.c revision 2.301.4.6. |
|
|
msg41303 - (view) |
Author: Armin Rigo (arigo) *  |
Date: 2002-10-07 15:35 |
Logged In: YES user_id=4771 Uploaded patch for 2.3. I had to change the order of some things in the main loop -- namely, call maybe_call_trace_line () before the next opcode/oparg is loaded. To do so I had to simplify the signature of maybe_call_trace_line(): I removed its first argument, 'opcode', which wasn't used any more anyway. I carefully checked that I didn't broke anything, and 'test_trace' says so, but you may as well double-check the patch. |
|
|
msg41304 - (view) |
Author: Michael Hudson (mwh)  |
Date: 2002-11-08 12:56 |
Logged In: YES user_id=6656 I got lazy and checked in all the psyco patches at once: Include/pystate.h revision 2.21 Modules/pyexpat.c revision 2.76 Python/ceval.c revision 2.340 Python/pystate.c revision 2.22 |
|
|
msg41305 - (view) |
Author: Richie Hindle (richiehindle) |
Date: 2002-12-17 17:47 |
Logged In: YES user_id=85414 Armin said: "This [...] could also be used by advanced debuggers to allow the execution point to be modified by the user." I've implemented an extension of this idea as patch 643835, just checked in by mwh. Debuggers (including those written in pure Python) can now write to f_lineno to modify the exeuction point. pdb now has a 'jump' command that does this. |
|
|