diff options
author | Irit Katriel <1055913+iritkatriel@users.noreply.github.com> | 2023-08-16 22:25:18 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-16 22:25:18 (GMT) |
commit | 665a4391e10167dad1c854fb604c86f336fcd331 (patch) | |
tree | e1d55069486dd67e6857a13fafc12b6e865cacf7 /Tools/build | |
parent | e88eb3775ecdcb3af6c6d694a935b7fa5f41e5ce (diff) | |
download | cpython-665a4391e10167dad1c854fb604c86f336fcd331.zip cpython-665a4391e10167dad1c854fb604c86f336fcd331.tar.gz cpython-665a4391e10167dad1c854fb604c86f336fcd331.tar.bz2 |
gh-105481: generate op IDs from bytecode.c instead of hard coding them in opcode.py (#107971)
Diffstat (limited to 'Tools/build')
-rw-r--r-- | Tools/build/deepfreeze.py | 8 | ||||
-rw-r--r-- | Tools/build/generate_opcode_h.py | 106 |
2 files changed, 6 insertions, 108 deletions
diff --git a/Tools/build/deepfreeze.py b/Tools/build/deepfreeze.py index ce609bd..8dbb7bf 100644 --- a/Tools/build/deepfreeze.py +++ b/Tools/build/deepfreeze.py @@ -22,7 +22,7 @@ ROOT = os.path.dirname(os.path.dirname(os.path.dirname(__file__))) verbose = False # This must be kept in sync with opcode.py -RESUME = 151 +RESUME = 166 def isprintable(b: bytes) -> bool: return all(0x20 <= c < 0x7f for c in b) @@ -297,10 +297,12 @@ class Printer: self.write(f".co_linetable = {co_linetable},") self.write(f"._co_cached = NULL,") self.write(f".co_code_adaptive = {co_code_adaptive},") - for i, op in enumerate(code.co_code[::2]): + first_traceable = 0 + for op in code.co_code[::2]: if op == RESUME: - self.write(f"._co_firsttraceable = {i},") break + first_traceable += 1 + self.write(f"._co_firsttraceable = {first_traceable},") name_as_code = f"(PyCodeObject *)&{name}" self.finis.append(f"_PyStaticCode_Fini({name_as_code});") self.inits.append(f"_PyStaticCode_Init({name_as_code})") diff --git a/Tools/build/generate_opcode_h.py b/Tools/build/generate_opcode_h.py index 67f4a2c..344709a 100644 --- a/Tools/build/generate_opcode_h.py +++ b/Tools/build/generate_opcode_h.py @@ -27,27 +27,6 @@ opcode_h_footer = """ #endif /* !Py_OPCODE_H */ """ -opcode_ids_h_header = f""" -// Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} - -#ifndef Py_OPCODE_IDS_H -#define Py_OPCODE_IDS_H -#ifdef __cplusplus -extern "C" {{ -#endif - - -/* Instruction opcodes for compiled code */ -""".lstrip() - -opcode_ids_h_footer = """ - -#ifdef __cplusplus -} -#endif -#endif /* !Py_OPCODE_IDS_H */ -""" - internal_header = f""" // Auto-generated by {SCRIPT_NAME} from {PYTHON_OPCODE} @@ -83,52 +62,10 @@ def get_python_module_dict(filename): return mod def main(opcode_py, - _opcode_metadata_py='Lib/_opcode_metadata.py', - opcode_ids_h='Include/opcode_ids.h', opcode_h='Include/opcode.h', - opcode_targets_h='Python/opcode_targets.h', internal_opcode_h='Include/internal/pycore_opcode.h'): - _opcode_metadata = get_python_module_dict(_opcode_metadata_py) - opcode = get_python_module_dict(opcode_py) - opmap = opcode['opmap'] - opname = opcode['opname'] - - MIN_INSTRUMENTED_OPCODE = opcode["MIN_INSTRUMENTED_OPCODE"] - - NUM_OPCODES = len(opname) - used = [ False ] * len(opname) - next_op = 1 - - for name, op in opmap.items(): - used[op] = True - - specialized_opmap = {} - opname_including_specialized = opname.copy() - for name in _opcode_metadata['_specialized_instructions']: - while used[next_op]: - next_op += 1 - specialized_opmap[name] = next_op - opname_including_specialized[next_op] = name - used[next_op] = True - - with open(opcode_ids_h, 'w') as fobj: - fobj.write(opcode_ids_h_header) - - for name in opname: - if name in opmap: - op = opmap[name] - if op == MIN_INSTRUMENTED_OPCODE: - fobj.write(DEFINE.format("MIN_INSTRUMENTED_OPCODE", MIN_INSTRUMENTED_OPCODE)) - - fobj.write(DEFINE.format(name, op)) - - - for name, op in specialized_opmap.items(): - fobj.write(DEFINE.format(name, op)) - - fobj.write(opcode_ids_h_footer) with open(opcode_h, 'w') as fobj: fobj.write(opcode_h_header) @@ -143,7 +80,6 @@ def main(opcode_py, iobj.write(internal_header) iobj.write("\nextern const uint8_t _PyOpcode_Caches[256];\n") - iobj.write("\nextern const uint8_t _PyOpcode_Deopt[256];\n") iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") iobj.write("\nconst uint8_t _PyOpcode_Caches[256] = {\n") @@ -151,52 +87,12 @@ def main(opcode_py, iobj.write(f" [{name}] = {entries},\n") iobj.write("};\n") - deoptcodes = {} - for basic, op in opmap.items(): - if op < 256: - deoptcodes[basic] = basic - for basic, family in _opcode_metadata["_specializations"].items(): - for specialized in family: - deoptcodes[specialized] = basic - iobj.write("\nconst uint8_t _PyOpcode_Deopt[256] = {\n") - for opt, deopt in sorted(deoptcodes.items()): - iobj.write(f" [{opt}] = {deopt},\n") - iobj.write("};\n") - iobj.write("#endif // NEED_OPCODE_TABLES\n") - - iobj.write("\n") - iobj.write(f"\nextern const char *const _PyOpcode_OpName[{NUM_OPCODES}];\n") - iobj.write("\n#ifdef NEED_OPCODE_TABLES\n") - iobj.write(f"const char *const _PyOpcode_OpName[{NUM_OPCODES}] = {{\n") - for op, name in enumerate(opname_including_specialized): - if name[0] != "<": - op = name - iobj.write(f''' [{op}] = "{name}",\n''') - iobj.write("};\n") iobj.write("#endif // NEED_OPCODE_TABLES\n") - iobj.write("\n") - iobj.write("#define EXTRA_CASES \\\n") - for i, flag in enumerate(used): - if not flag: - iobj.write(f" case {i}: \\\n") - iobj.write(" ;\n") - iobj.write(internal_footer) - with open(opcode_targets_h, "w") as f: - targets = ["_unknown_opcode"] * 256 - for op, name in enumerate(opname_including_specialized): - if op < 256 and not name.startswith("<"): - targets[op] = f"TARGET_{name}" - - f.write("static void *opcode_targets[256] = {\n") - f.write(",\n".join([f" &&{s}" for s in targets])) - f.write("\n};\n") - print(f"{opcode_h} regenerated from {opcode_py}") if __name__ == '__main__': - main(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], - sys.argv[5], sys.argv[6]) + main(sys.argv[1], sys.argv[2], sys.argv[3]) |