Skip to content

Wordcode, part 2 #71316

Closed
Closed

Description

@serhiy-storchaka
BPO 27129
Nosy @rhettinger, @db3l, @vstinner, @markshannon, @berkerpeksag, @serhiy-storchaka, @efahl, @serprex, @pablogsal, @godaygo, @sweeneyde
PRs
  • bpo-27129: Use instruction offsets, not byte offsets, in bytecode and internally. #25069
  • bpo-27129: Update magic numbers and bootstrapping for GH-25069 #25172
  • Files
  • wordcode2.patch
  • word-jump-offsets.patch
  • wordcode-refactor.patch
  • wordcode-refactor2.patch
  • Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

    Show more details

    GitHub fields:

    assignee = None
    closed_at = <Date 2021-04-05.16:25:09.267>
    created_at = <Date 2016-05-26.13:13:07.796>
    labels = ['interpreter-core', 'type-feature', '3.10', 'release-blocker']
    title = 'Wordcode, part 2'
    updated_at = <Date 2021-04-05.16:25:09.265>
    user = 'https://github.com/serhiy-storchaka'

    bugs.python.org fields:

    activity = <Date 2021-04-05.16:25:09.265>
    actor = 'pablogsal'
    assignee = 'none'
    closed = True
    closed_date = <Date 2021-04-05.16:25:09.267>
    closer = 'pablogsal'
    components = ['Interpreter Core']
    creation = <Date 2016-05-26.13:13:07.796>
    creator = 'serhiy.storchaka'
    dependencies = []
    files = ['43015', '43040', '43308', '43333']
    hgrepos = []
    issue_num = 27129
    keywords = ['patch']
    message_count = 36.0
    messages = ['266431', '266435', '266446', '266447', '266489', '266490', '266556', '266604', '266611', '267880', '268132', '268142', '268143', '268145', '275771', '275773', '275780', '275781', '276044', '276049', '276055', '315266', '389707', '389991', '390017', '390024', '390025', '390082', '390085', '390088', '390099', '390151', '390152', '390157', '390178', '390242']
    nosy_count = 12.0
    nosy_names = ['rhettinger', 'db3l', 'vstinner', 'Mark.Shannon', 'python-dev', 'berker.peksag', 'serhiy.storchaka', 'eric.fahlgren', 'Demur Rumed', 'pablogsal', 'godaygo', 'Dennis Sweeney']
    pr_nums = ['25069', '25172']
    priority = 'release blocker'
    resolution = 'fixed'
    stage = 'resolved'
    status = 'closed'
    superseder = None
    type = 'enhancement'
    url = 'https://bugs.python.org/issue27129'
    versions = ['Python 3.10']

    Activity

    1. serhiy-storchaka commented on May 26, 2016

      @serhiy-storchaka
      MemberAuthor

      This is the second stage of converting to wordcode (bpo-26647).

      Proposed patch makes bytecodecode consisting of code units (16-bit words) instead of bytes. It includes following changes:

      • Changes meaning of jump offsets. They counts not bytes, but code units. This extends the range addressed by short commands (from 256 bytes to 256 words) and simplifies ceval.c.

      • Changes f_lasti, tb_lasti etc to count code units instead of bytes.

      • Changes disassembler to show addresses in code units, not bytes.

      • Refactores the code.

      These changes break compatibility (already broken by switching to 16-bit bytecode). The first one breaks compatibility with compiled bytecode and needs incrementing the magic number.

    2. vstinner commented on May 26, 2016

      @vstinner
      Member

      Changes f_lasti, tb_lasti etc to count code units instead of bytes.

      I asked Demur to not break f_lasti. I don't understand if this change
      breaks applications using f_lasti or not.

      For example, asyncio/coroutines.py uses:

                  if caller.f_code.co_code[caller.f_lasti] != _YIELD_FROM:
                      value = value[0]

      Does this code still work with your change?

      Maybe this code is already broken by wordcode, but it doesn't really
      matter since it should only be used on the exact version 3.4.0. The
      code works around a bug in Python 3.4.0, fixed in Python 3.4.1 (issue
      bpo-21209).

      Other known users of f_lasti are development tools like debuggers
      (pdb), profilers, code coverage, etc. We should check these tools.

    3. brettcannon commented on May 26, 2016

      @brettcannon
      Member

      So is avoiding changing f_lasti just to minimize breakage of tools? Aren't they going to have to update to support the wordcode changes anyway?

    4. serhiy-storchaka commented on May 26, 2016

      @serhiy-storchaka
      MemberAuthor

      The patch contains the change of Lib/asyncio/coroutines.py. This is the only change in Python code besides the dis module.

      I can keep f_lasti to be twice the number of instructions, but this will complicate the patch. The simplest way perhaps is to convert this read-only attribute to the property that multiplies internal f_lasti by 2.

    5. serprex commented on May 27, 2016

      serprexmannequin
      Mannequin

      https://github.com/search?q=f_lasti&type=Code

      Popular use of f_lasti is checking it for -1, checking the instruction at the byte offset of f_lasti, checking the argument with code[f_lasti+1] (Some bad code checking f_lasti+3 which'll break with 3.6)

      abarnert discussed how bytecode should be typed to Python code. Ideally it'd be typed as a "(instruction, arg)" tuple. He considered creating a "words" type similar to "bytes" but with 16 bit values. It's a bit niche to introduce a builtin for. So if the co_code object is remaining a bytes object then it seems intuitive to keep f_lasti as a bytes offset. Clashes with jump offsets no longer being a bytes offset even in Python code tho

      In reality most of the results on github all seem to be copying a few distinct uses. So maybe backwards compatibiltiy isn't so important

      Other search https://searchcode.com/?q=f_lasti&loc=0&loc2=10000&src=3&src=7&src=1&lan=19 doesn't produce many results either

    6. vstinner commented on May 27, 2016

      @vstinner
      Member

      if the co_code object is remaining a bytes object then it seems intuitive to keep f_lasti as a bytes offset

      Right.

      In reality most of the results on github all seem to be copying a few distinct uses. So maybe backwards compatibiltiy isn't so important

      Backwards compatibiltiy is important.

    7. serhiy-storchaka commented on May 28, 2016

      @serhiy-storchaka
      MemberAuthor

      Here is a patch that implements only the first change -- makes jump offsets be in 16-bit units, not bytes. This is minimal change, it doesn't include refactoring.

    8. rhettinger commented on May 29, 2016

      @rhettinger
      Contributor

      I don't see how this is a simplification. The additional /2 and *2 on the affected lines makes the code a little harder to reason about and it loses some of the cleanness achieved by the last patch. To me, it also increases conceptual complexity because INSTR_OFFSET() no longer gives the byte address adjustment.

    9. serhiy-storchaka commented on May 29, 2016

      @serhiy-storchaka
      MemberAuthor

      word-jump-offsets.patch doesn't simplify the code, but rather complicates it, because this is minimal patch that doesn't include the refactoring. The main benefit of this patch is that it extends the range addressed by short jump instruction. The other benefit is that the target of jump instruction is now always point at instruction boundary.

      wordcode2.patch includes refactoring and other changes:

      • Changes jump offsets. This extends addressed range and can make co_code more compact.
      • Changes co_lnotab. This can make co_lnotab more compact.
      • Changes f_lasti.
      • Changes the disassembler.
      • Refactors the C code (makes it codeunit-oriented instead of byte-oriented). Simplifies the code complicated by other changes.

      I can provide these steps by separate patches (word-jump-offsets.patch is the first of them), but every separate patch can temporary complicate the code. Three of these changes (except the disassembler changing and refactoring) break the compatibility of pyc-files and need incrementing the magic number.

    10. serhiy-storchaka commented on Jun 8, 2016

      @serhiy-storchaka
      MemberAuthor

      Here is a patch that just refactors the code. It renames OPCODE and OPCODE to _Py_OPCODE and _Py_OPCODE and moves them to code.h for reusing in other files. Introduces _Py_CODEUNIT as an alias to unsigned short (if it is 16-bit, otherwise a compile error is raised). Makes compiler and peepholer to operate with _Py_CODEUNIT units instead of bytes. Replaces or scale magic numbers with sizeof(_Py_CODEUNIT). Adds fill_nops() for filling specified region with NOPs. Decreases memory consumption for peepholer (doesn't allocate memory for unused odd addresses).

    11. rhettinger commented on Jun 10, 2016

      @rhettinger
      Contributor

      I really don't think any of this should be done at all. The current code is clean and fast (and to my eyes at least is very readable).

    12. serhiy-storchaka commented on Jun 10, 2016

      @serhiy-storchaka
      MemberAuthor

      This is not just about cleaning (to my eyes current code is not very readable, and I read it many times, perhaps more times than any other core developer in last months). There are other benefits. Changing jump offsets allows to get rid of EXTENDED_ARGs for the part of jump opcodes. Changing lnotab makes it more compact and allows the peepholer to optimize the code that it rejects now. Refactoring includes the change that decreases memory consumption of the peepholer (from 4 bytes per bytecode byte to 2 bytes per bytecode byte). Changing jump offsets together with changing f_lasti removes redundant multiplications and divisions by 2. Separate changes can complicate some parts of code, but next changes removes this complication. Only all changes together achieve maximal cleanness.

      I think that converting to wordcode is not complete without these changes. I approved the wordcode patch only having in mind following changes. It is more painless to make all changes in one Python release than break compatibility during few releases.

    13. serhiy-storchaka commented on Jun 10, 2016

      @serhiy-storchaka
      MemberAuthor

      update patch replaces yet few magic constants.

    14. 22 remaining items

    15. markshannon commented on Apr 4, 2021

      @markshannon
      Member

      New changeset c368ce7 by Dennis Sweeney in branch 'master':
      bpo-27129: Update magic numbers and bootstrapping for #69255 (GH-25172)
      c368ce7

    16. pablogsal commented on Apr 5, 2021

      @pablogsal
      Member

      Closing as this is fixed. Feel free to reopen if there is something missing

    17. transferred this issue fromon Apr 10, 2022
    18. added a commit that references this issue on Oct 7, 2022
    19. added 2 commits that reference this issue on Oct 7, 2022
    20. added 2 commits that reference this issue on Oct 7, 2022
    21. added 3 commits that reference this issue on Oct 7, 2022
    22. added a commit that references this issue on Oct 11, 2022
    23. added a commit that references this issue on Oct 22, 2022
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Metadata

    Metadata

    Assignees

    No one assigned

      Projects

      No projects

        Milestone

        No milestone

        Relationships

        None yet

        Development

        No branches or pull requests

        Issue actions