This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add a line-start table to the code object.
Type: behavior Stage:
Components: Interpreter Core Versions: Python 3.11
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Mark.Shannon, brandtbucher, iritkatriel
Priority: normal Keywords:

Created on 2022-02-21 12:59 by Mark.Shannon, last changed 2022-04-11 14:59 by admin.

Messages (3)
msg413651 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2022-02-21 12:59
Computing whether an instruction is the first on a line (for tracing) in the interpreter is complicated and slow. Doing it in the compiler should be simpler and has no runtime cost.

Currently we decide if the current instruction is the first on a line, by using the `co_lines` table, but if the previous instruction executed was a jump from the same line over a block of instructions with different line number(s) then we can get this wrong.

This doesn't seem to a problem now, but could be with either: 
Specialization of FOR_ITER inlining generators, or
Compiler improvements leading to different code layout.


The table is only one bit per instruction, so shouldn't be a problem in terms of space.
msg415263 - (view) Author: Irit Katriel (iritkatriel) * (Python committer) Date: 2022-03-15 16:26
I can see the linestarts used in trace.py to figure out coverage. But for this duplications don't make a difference (they are deduped in _find_lines_from_code anyway), right? 

Where else are they used, such that the current scheme may not work?
msg415264 - (view) Author: Mark Shannon (Mark.Shannon) * (Python committer) Date: 2022-03-15 16:51
sys.settrace line events cannot use the co_lines table. They need additional state, as we don't want to trace the same line twice (unless there is a backwards jump).

Using the start of a entry in `co_lines` doesn't work when some entries have no line number.
E.g.
list(co.co_lines):

(0, 2, 1)
(2, 4, None)
(4, 6, 1)

The instruction @ byte offset 4 starts an entry for line 1, but does not start line 1.
History
Date User Action Args
2022-04-11 14:59:56adminsetgithub: 90973
2022-03-16 18:01:25brandtbuchersetnosy: + brandtbucher
2022-03-15 16:51:14Mark.Shannonsetmessages: + msg415264
2022-03-15 16:26:47iritkatrielsetmessages: + msg415263
2022-02-21 12:59:12Mark.Shannoncreate