Mercurial > cpython-lru_cache-weakref
comparison Objects/codeobject.c @ 54297:dddf424bd669 legacy-trunk
Issue #6042:
lnotab-based tracing is very complicated and isn't documented very well. There
were at least 3 comment blocks purporting to document co_lnotab, and none did a
very good job. This patch unifies them into Objects/lnotab_notes.txt which
tries to completely capture the current state of affairs.
I also discovered that we've attached 2 layers of patches to the basic tracing
scheme. The first layer avoids jumping to instructions that don't start a line,
to avoid problems in if statements and while loops. The second layer
discovered that jumps backward do need to trace at instructions that don't
start a line, so it added extra lnotab entries for 'while' and 'for' loops, and
added a special case for backward jumps within the same line. I replaced these
patches by just treating forward and backward jumps differently.
| author | Jeffrey Yasskin <jyasskin@gmail.com> |
|---|---|
| date | Sat, 23 May 2009 23:23:01 +0000 |
| parents | a171048daf76 |
| children | 22f589a8e3ab |
comparison
equal
deleted
inserted
replaced
| 54296:d9ce3e740676 | 54297:dddf424bd669 |
|---|---|
| 505 0, /* tp_init */ | 505 0, /* tp_init */ |
| 506 0, /* tp_alloc */ | 506 0, /* tp_alloc */ |
| 507 code_new, /* tp_new */ | 507 code_new, /* tp_new */ |
| 508 }; | 508 }; |
| 509 | 509 |
| 510 /* All about c_lnotab. | 510 /* Use co_lnotab to compute the line number from a bytecode index, addrq. See |
| 511 | 511 lnotab_notes.txt for the details of the lnotab representation. |
| 512 c_lnotab is an array of unsigned bytes disguised as a Python string. In -O | |
| 513 mode, SET_LINENO opcodes aren't generated, and bytecode offsets are mapped | |
| 514 to source code line #s (when needed for tracebacks) via c_lnotab instead. | |
| 515 The array is conceptually a list of | |
| 516 (bytecode offset increment, line number increment) | |
| 517 pairs. The details are important and delicate, best illustrated by example: | |
| 518 | |
| 519 byte code offset source code line number | |
| 520 0 1 | |
| 521 6 2 | |
| 522 50 7 | |
| 523 350 307 | |
| 524 361 308 | |
| 525 | |
| 526 The first trick is that these numbers aren't stored, only the increments | |
| 527 from one row to the next (this doesn't really work, but it's a start): | |
| 528 | |
| 529 0, 1, 6, 1, 44, 5, 300, 300, 11, 1 | |
| 530 | |
| 531 The second trick is that an unsigned byte can't hold negative values, or | |
| 532 values larger than 255, so (a) there's a deep assumption that byte code | |
| 533 offsets and their corresponding line #s both increase monotonically, and (b) | |
| 534 if at least one column jumps by more than 255 from one row to the next, more | |
| 535 than one pair is written to the table. In case #b, there's no way to know | |
| 536 from looking at the table later how many were written. That's the delicate | |
| 537 part. A user of c_lnotab desiring to find the source line number | |
| 538 corresponding to a bytecode address A should do something like this | |
| 539 | |
| 540 lineno = addr = 0 | |
| 541 for addr_incr, line_incr in c_lnotab: | |
| 542 addr += addr_incr | |
| 543 if addr > A: | |
| 544 return lineno | |
| 545 lineno += line_incr | |
| 546 | |
| 547 In order for this to work, when the addr field increments by more than 255, | |
| 548 the line # increment in each pair generated must be 0 until the remaining addr | |
| 549 increment is < 256. So, in the example above, com_set_lineno should not (as | |
| 550 was actually done until 2.2) expand 300, 300 to 255, 255, 45, 45, but to | |
| 551 255, 0, 45, 255, 0, 45. | |
| 552 */ | 512 */ |
| 553 | 513 |
| 554 int | 514 int |
| 555 PyCode_Addr2Line(PyCodeObject *co, int addrq) | 515 PyCode_Addr2Line(PyCodeObject *co, int addrq) |
| 556 { | 516 { |
| 565 line += *p++; | 525 line += *p++; |
| 566 } | 526 } |
| 567 return line; | 527 return line; |
| 568 } | 528 } |
| 569 | 529 |
| 570 /* | 530 /* Update *bounds to describe the first and one-past-the-last instructions in |
| 571 Check whether the current instruction is at the start of a line. | 531 the same line as lasti. Return the number of that line. */ |
| 572 | 532 int |
| 573 */ | 533 _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) |
| 574 | |
| 575 /* The theory of SET_LINENO-less tracing. | |
| 576 | |
| 577 In a nutshell, we use the co_lnotab field of the code object | |
| 578 to tell when execution has moved onto a different line. | |
| 579 | |
| 580 As mentioned above, the basic idea is so set things up so | |
| 581 that | |
| 582 | |
| 583 *instr_lb <= frame->f_lasti < *instr_ub | |
| 584 | |
| 585 is true so long as execution does not change lines. | |
| 586 | |
| 587 This is all fairly simple. Digging the information out of | |
| 588 co_lnotab takes some work, but is conceptually clear. | |
| 589 | |
| 590 Somewhat harder to explain is why we don't *always* call the | |
| 591 line trace function when the above test fails. | |
| 592 | |
| 593 Consider this code: | |
| 594 | |
| 595 1: def f(a): | |
| 596 2: if a: | |
| 597 3: print 1 | |
| 598 4: else: | |
| 599 5: print 2 | |
| 600 | |
| 601 which compiles to this: | |
| 602 | |
| 603 2 0 LOAD_FAST 0 (a) | |
| 604 3 JUMP_IF_FALSE 9 (to 15) | |
| 605 6 POP_TOP | |
| 606 | |
| 607 3 7 LOAD_CONST 1 (1) | |
| 608 10 PRINT_ITEM | |
| 609 11 PRINT_NEWLINE | |
| 610 12 JUMP_FORWARD 6 (to 21) | |
| 611 >> 15 POP_TOP | |
| 612 | |
| 613 5 16 LOAD_CONST 2 (2) | |
| 614 19 PRINT_ITEM | |
| 615 20 PRINT_NEWLINE | |
| 616 >> 21 LOAD_CONST 0 (None) | |
| 617 24 RETURN_VALUE | |
| 618 | |
| 619 If 'a' is false, execution will jump to instruction at offset | |
| 620 15 and the co_lnotab will claim that execution has moved to | |
| 621 line 3. This is at best misleading. In this case we could | |
| 622 associate the POP_TOP with line 4, but that doesn't make | |
| 623 sense in all cases (I think). | |
| 624 | |
| 625 What we do is only call the line trace function if the co_lnotab | |
| 626 indicates we have jumped to the *start* of a line, i.e. if the | |
| 627 current instruction offset matches the offset given for the | |
| 628 start of a line by the co_lnotab. | |
| 629 | |
| 630 This also takes care of the situation where 'a' is true. | |
| 631 Execution will jump from instruction offset 12 to offset 21. | |
| 632 Then the co_lnotab would imply that execution has moved to line | |
| 633 5, which is again misleading. | |
| 634 | |
| 635 Why do we set f_lineno when tracing? Well, consider the code | |
| 636 above when 'a' is true. If stepping through this with 'n' in | |
| 637 pdb, you would stop at line 1 with a "call" type event, then | |
| 638 line events on lines 2 and 3, then a "return" type event -- but | |
| 639 you would be shown line 5 during this event. This is a change | |
| 640 from the behaviour in 2.2 and before, and I've found it | |
| 641 confusing in practice. By setting and using f_lineno when | |
| 642 tracing, one can report a line number different from that | |
| 643 suggested by f_lasti on this one occasion where it's desirable. | |
| 644 */ | |
| 645 | |
| 646 | |
| 647 int | |
| 648 PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds) | |
| 649 { | 534 { |
| 650 int size, addr, line; | 535 int size, addr, line; |
| 651 unsigned char* p; | 536 unsigned char* p; |
| 652 | 537 |
| 653 p = (unsigned char*)PyString_AS_STRING(co->co_lnotab); | 538 p = (unsigned char*)PyString_AS_STRING(co->co_lnotab); |
| 660 /* possible optimization: if f->f_lasti == instr_ub | 545 /* possible optimization: if f->f_lasti == instr_ub |
| 661 (likely to be a common case) then we already know | 546 (likely to be a common case) then we already know |
| 662 instr_lb -- if we stored the matching value of p | 547 instr_lb -- if we stored the matching value of p |
| 663 somwhere we could skip the first while loop. */ | 548 somwhere we could skip the first while loop. */ |
| 664 | 549 |
| 665 /* see comments in compile.c for the description of | 550 /* See lnotab_notes.txt for the description of |
| 666 co_lnotab. A point to remember: increments to p | 551 co_lnotab. A point to remember: increments to p |
| 667 should come in pairs -- although we don't care about | 552 come in (addr, line) pairs. */ |
| 668 the line increments here, treating them as byte | |
| 669 increments gets confusing, to say the least. */ | |
| 670 | 553 |
| 671 bounds->ap_lower = 0; | 554 bounds->ap_lower = 0; |
| 672 while (size > 0) { | 555 while (size > 0) { |
| 673 if (addr + *p > lasti) | 556 if (addr + *p > lasti) |
| 674 break; | 557 break; |
| 677 bounds->ap_lower = addr; | 560 bounds->ap_lower = addr; |
| 678 line += *p++; | 561 line += *p++; |
| 679 --size; | 562 --size; |
| 680 } | 563 } |
| 681 | 564 |
| 682 /* If lasti and addr don't match exactly, we don't want to | |
| 683 change the lineno slot on the frame or execute a trace | |
| 684 function. Return -1 instead. | |
| 685 */ | |
| 686 if (addr != lasti) | |
| 687 line = -1; | |
| 688 | |
| 689 if (size > 0) { | 565 if (size > 0) { |
| 690 while (--size >= 0) { | 566 while (--size >= 0) { |
| 691 addr += *p++; | 567 addr += *p++; |
| 692 if (*p++) | 568 if (*p++) |
| 693 break; | 569 break; |
