8000 gh-90997: bpo-46841: Disassembly of quickened code by penguin-wwy · Pull Request #32099 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-90997: bpo-46841: Disassembly of quickened code #32099

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 16 commits into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Move deoptmap to dis module
  • Loading branch information
penguin-wwy committed Apr 1, 2022
commit 2a4bb97b66ad9527b60a11e5b22fdf332cc120fe
22 changes: 17 additions & 5 deletions Lib/dis.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from opcode import *
from opcode import __all__ as _opcodes_all
from opcode import _nb_ops, _inline_cache_entries
from opcode import _nb_ops, _inline_cache_entries, _specializations, _specialized_instructions

__all__ = ["code_info", "dis", "disassemble", "distb", "disco",
"findlinestarts", "findlabels", "show_code",
Expand All @@ -34,6 +34,18 @@

CACHE = opmap["CACHE"]

_all_opname = list(opname)
_all_opmap = dict(opmap)
_empty_slot = [slot for slot, name in enumerate(_all_opname) if name.startswith("<")]
for spec_op, specialized in zip(_empty_slot, _specialized_instructions):
# fill opname and opmap
_all_opname[spec_op] = specialized
_all_opmap[specialized] = spec_op

deoptmap = {
specialized: base for base, family in _specializations.items() for specialized in family
}

def _try_compile(source, name):
"""Attempts to compile the given source, first as an expression and
then as a statement if the first approach fails.
Expand Down Expand Up @@ -163,11 +175,11 @@ def _get_code_object(x):
type(x).__name__)

def _deoptop(op):
name = opname[op]
return opmap[deoptmap[name]] if name in deoptmap else op
name = _all_opname[op]
return _all_opmap[deoptmap[name]] if name in deoptmap else op

def _get_code_array(co, adaptive):
return co._co_code_adaptive.tobytes() if adaptive else co.co_code
return co._co_code_adaptive if adaptive else co.co_code

def code_info(x):
"""Formatted details of methods, functions, or code."""
Expand Down Expand Up @@ -476,7 +488,7 @@ def _get_instructions_bytes(code, varname_from_oparg=None,
if arg & (1<<i))
elif deop == BINARY_OP:
_, argrepr = _nb_ops[arg]
yield Instruction(opname[op], op,
yield Instruction(_all_opname[op], op,
arg, argval, argrepr,
offset, starts_line, is_jump_target, positions)

Expand Down
13 changes: 1 addition & 12 deletions Lib/opcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

__all__ = ["cmp_op", "hasconst", "hasname", "hasjrel", "hasjabs",
"haslocal", "hascompare", "hasfree", "opname", "opmap",
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs", "deoptmap"]
"HAVE_ARGUMENT", "EXTENDED_ARG", "hasnargs"]

# It's a chicken-and-egg I'm afraid:
# We're imported before _opcode's made.
Expand Down Expand Up @@ -336,17 +336,6 @@ def jabs_op(name, op, entries=0):
_specialized_instructions = [
opcode for family in _specializations.values() for opcode in family
]

_empty_slot = [slot for slot, name in enumerate(opname) if name.startswith("<")]
for spec_op, specialized in zip(_empty_slot, _specialized_instructions):
# fill opname and opmap
opname[spec_op] = specialized
opmap[specialized] = spec_op

deoptmap = {
specialized: base for base, family in _specializations.items() for specialized in family
}

_specialization_stats = [
"success",
"failure",
Expand Down
5 changes: 5 additions & 0 deletions Python/makeopcodetargets.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ def write_contents(f):
targets[255] = "TARGET_DO_TRACING"
for opname, op in opcode.opmap.items():
targets[op] = "TARGET_%s" % opname
next_op = 1
for opname in opcode._specialized_instructions:
while targets[next_op] != '_unknown_opcode':
next_op += 1
targets[next_op] = "TARGET_%s" % opname
f.write("static void *opcode_targets[256] = {\n")
f.write(",\n".join([" &&%s" % s for s in targets]))
f.write("\n};\n")
Expand Down
19 changes: 14 additions & 5 deletions Tools/scripts/generate_opcode_h.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,17 +57,23 @@ def main(opcode_py, outfile='Include/opcode.h'):
hasconst = opcode['hasconst']
hasjrel = opcode['hasjrel']
hasjabs = opcode['hasjabs']
deoptmap = opcode['deoptmap']
used = [ False ] * 256
next_op = 1
for name, op in opmap.items():
used[op] = True
with open(outfile, 'w') as fobj:
fobj.write(header)
for name in opname:
if name in opmap and name not in deoptmap:
if name in opmap:
fobj.write(DEFINE.format(name, opmap[name]))
if name == 'POP_EXCEPT': # Special entry for HAVE_ARGUMENT
fobj.write(DEFINE.format("HAVE_ARGUMENT", opcode["HAVE_ARGUMENT"]))

for spec_name in deoptmap:
fobj.write(DEFINE.format(spec_name, opmap[spec_name]))
for name in opcode['_specialized_instructions']:
while used[next_op]:
next_op += 1
fobj.write(DEFINE.format(name, next_op))
used[next_op] = True
fobj.write(DEFINE.format('DO_TRACING', 255))
fobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n")
fobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n")
Expand All @@ -82,7 +88,10 @@ def main(opcode_py, outfile='Include/opcode.h'):
fobj.write("};\n")
deoptcodes = {}
for basic in opmap:
deoptcodes[basic] = deoptmap[basic] if basic in deoptmap else basic
deoptcodes[basic] = basic
for basic, family in opcode["_specializations"].items():
for specialized in family:
deoptcodes[specialized] = basic
fobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n")
for opt, deopt in sorted(deoptcodes.items()):
fobj.write(f" [{opt}] = {deopt},\n")
Expand Down
0