aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_instruments.h1
-rw-r--r--Include/internal/pycore_opcode_metadata.h22
-rw-r--r--Lib/importlib/_bootstrap_external.py3
-rw-r--r--Lib/opcode.py12
-rw-r--r--Lib/test/support/__init__.py17
-rw-r--r--Lib/test/test_capi/test_misc.py45
-rw-r--r--Lib/test/test_dis.py222
-rw-r--r--Lib/test/test_monitoring.py16
-rw-r--r--Lib/test/test_regrtest.py7
-rw-r--r--Python/bytecodes.c50
-rw-r--r--Python/generated_cases.c.h58
-rw-r--r--Python/instrumentation.c1
-rw-r--r--Python/optimizer.c28
-rw-r--r--Python/specialize.c20
-rw-r--r--Tools/cases_generator/generate_cases.py18
15 files changed, 339 insertions, 181 deletions
diff --git a/Include/internal/pycore_instruments.h b/Include/internal/pycore_instruments.h
index fad475c3daf..97dcfb9f867 100644
--- a/Include/internal/pycore_instruments.h
+++ b/Include/internal/pycore_instruments.h
@@ -5,7 +5,6 @@
# error "this header requires Py_BUILD_CORE define"
#endif
-#include "pycore_bitutils.h" // _Py_popcount32
#include "pycore_frame.h" // _PyInterpreterFrame
#ifdef __cplusplus
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index f70b75a56c1..e1de21255f6 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1361,11 +1361,11 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[JUMP] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[JUMP_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[ENTER_EXECUTOR] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG | HAS_EVAL_BREAK_FLAG | HAS_ERROR_FLAG },
- [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[IS_NONE] = { true, INSTR_FMT_IX, 0 },
- [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
- [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
+ [POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
[GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG },
@@ -1449,10 +1449,10 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[OPCODE_METADATA_SIZE] = {
[INSTRUMENTED_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[INSTRUMENTED_JUMP_BACKWARD] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_EVAL_BREAK_FLAG },
- [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
- [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
+ [INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
[CACHE] = { true, INSTR_FMT_IX, 0 },
[RESERVED] = { true, INSTR_FMT_IX, 0 },
@@ -1885,7 +1885,6 @@ extern const uint8_t _PyOpcode_Caches[256];
#ifdef NEED_OPCODE_METADATA
const uint8_t _PyOpcode_Caches[256] = {
[TO_BOOL] = 3,
- [BINARY_OP] = 1,
[BINARY_SUBSCR] = 1,
[STORE_SUBSCR] = 1,
[SEND] = 1,
@@ -1895,8 +1894,13 @@ const uint8_t _PyOpcode_Caches[256] = {
[LOAD_SUPER_ATTR] = 1,
[LOAD_ATTR] = 9,
[COMPARE_OP] = 1,
+ [POP_JUMP_IF_FALSE] = 1,
+ [POP_JUMP_IF_TRUE] = 1,
[FOR_ITER] = 1,
[CALL] = 3,
+ [BINARY_OP] = 1,
+ [POP_JUMP_IF_NONE] = 1,
+ [POP_JUMP_IF_NOT_NONE] = 1,
[JUMP_BACKWARD] = 1,
};
#endif // NEED_OPCODE_METADATA
diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py
index 7a83a58d087..843af300500 100644
--- a/Lib/importlib/_bootstrap_external.py
+++ b/Lib/importlib/_bootstrap_external.py
@@ -456,6 +456,7 @@ _code_type = type(_write_atomic.__code__)
# Python 3.13a1 3558 (Reorder the stack items for CALL)
# Python 3.13a1 3559 (Generate opcode IDs from bytecodes.c)
# Python 3.13a1 3560 (Add RESUME_CHECK instruction)
+# Python 3.13a1 3561 (Add cache entry to branch instructions)
# Python 3.14 will start with 3600
@@ -472,7 +473,7 @@ _code_type = type(_write_atomic.__code__)
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
# in PC/launcher.c must also be updated.
-MAGIC_NUMBER = (3560).to_bytes(2, 'little') + b'\r\n'
+MAGIC_NUMBER = (3561).to_bytes(2, 'little') + b'\r\n'
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
diff --git a/Lib/opcode.py b/Lib/opcode.py
index 386a2fba396..88f4df7c0e8 100644
--- a/Lib/opcode.py
+++ b/Lib/opcode.py
@@ -93,6 +93,18 @@ _cache_format = {
"counter": 1,
"version": 2,
},
+ "POP_JUMP_IF_TRUE": {
+ "counter": 1,
+ },
+ "POP_JUMP_IF_FALSE": {
+ "counter": 1,
+ },
+ "POP_JUMP_IF_NONE": {
+ "counter": 1,
+ },
+ "POP_JUMP_IF_NOT_NONE": {
+ "counter": 1,
+ },
}
_inline_cache_entries = {
diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py
index 6fc85ff5d70..0d9efe10c65 100644
--- a/Lib/test/support/__init__.py
+++ b/Lib/test/support/__init__.py
@@ -62,6 +62,7 @@ __all__ = [
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
"Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT",
"skip_on_s390x",
+ "without_optimizer",
]
@@ -2533,3 +2534,19 @@ skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == '
'skipped on s390x')
Py_TRACE_REFS = hasattr(sys, 'getobjects')
+
+# Decorator to disable optimizer while a function run
+def without_optimizer(func):
+ try:
+ import _testinternalcapi
+ except ImportError:
+ return func
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ save_opt = _testinternalcapi.get_optimizer()
+ try:
+ _testinternalcapi.set_optimizer(None)
+ return func(*args, **kwargs)
+ finally:
+ _testinternalcapi.set_optimizer(save_opt)
+ return wrapper
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index 004ce397696..964886ad1ca 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -2455,7 +2455,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2470,7 +2470,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2485,7 +2485,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(range(10))
+ testfunc(range(20))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2495,12 +2495,13 @@ class TestUops(unittest.TestCase):
def test_pop_jump_if_not_none(self):
def testfunc(a):
for x in a:
+ x = None
if x is not None:
x = 0
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(range(10))
+ testfunc(range(20))
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2515,7 +2516,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2530,7 +2531,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2550,7 +2551,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2568,8 +2569,8 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- total = testfunc(10)
- self.assertEqual(total, 45)
+ total = testfunc(20)
+ self.assertEqual(total, 190)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2589,9 +2590,9 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- a = list(range(10))
+ a = list(range(20))
total = testfunc(a)
- self.assertEqual(total, 45)
+ self.assertEqual(total, 190)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2611,9 +2612,9 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- a = tuple(range(10))
+ a = tuple(range(20))
total = testfunc(a)
- self.assertEqual(total, 45)
+ self.assertEqual(total, 190)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2647,7 +2648,7 @@ class TestUops(unittest.TestCase):
opt = _testinternalcapi.get_uop_optimizer()
with temporary_optimizer(opt):
- testfunc(10)
+ testfunc(20)
ex = get_first_executor(testfunc)
self.assertIsNotNone(ex)
@@ -2655,6 +2656,22 @@ class TestUops(unittest.TestCase):
self.assertIn("_PUSH_FRAME", uops)
self.assertIn("_BINARY_OP_ADD_INT", uops)
+ def test_branch_taken(self):
+ def testfunc(n):
+ for i in range(n):
+ if i < 0:
+ i = 0
+ else:
+ i = 1
+
+ opt = _testinternalcapi.get_uop_optimizer()
+ with temporary_optimizer(opt):
+ testfunc(20)
+
+ ex = get_first_executor(testfunc)
+ self.assertIsNotNone(ex)
+ uops = {opname for opname, _, _ in ex}
+ self.assertIn("_POP_JUMP_IF_TRUE", uops)
if __name__ == "__main__":
diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py
index eae1918efc3..c3ad105fb2a 100644
--- a/Lib/test/test_dis.py
+++ b/Lib/test/test_dis.py
@@ -404,7 +404,7 @@ None >> PUSH_EXC_INFO
%4d LOAD_GLOBAL 0 (Exception)
CHECK_EXC_MATCH
- POP_JUMP_IF_FALSE 23 (to 80)
+ POP_JUMP_IF_FALSE 23 (to 82)
STORE_FAST 0 (e)
%4d LOAD_FAST 0 (e)
@@ -492,7 +492,7 @@ dis_with = """\
%4d >> PUSH_EXC_INFO
WITH_EXCEPT_START
TO_BOOL
- POP_JUMP_IF_TRUE 1 (to 50)
+ POP_JUMP_IF_TRUE 1 (to 52)
RERAISE 2
>> POP_TOP
POP_EXCEPT
@@ -579,7 +579,7 @@ None JUMP_BACKWARD 11 (to 60)
>> CLEANUP_THROW
>> END_SEND
TO_BOOL
- POP_JUMP_IF_TRUE 1 (to 116)
+ POP_JUMP_IF_TRUE 1 (to 118)
RERAISE 2
>> POP_TOP
POP_EXCEPT
@@ -1273,7 +1273,8 @@ class DisTests(DisTestBase):
got = self.get_disassembly(loop_test, adaptive=True)
expected = dis_loop_test_quickened_code
if _testinternalcapi.get_optimizer():
- expected = expected.replace("JUMP_BACKWARD ", "ENTER_EXECUTOR")
+ # We *may* see ENTER_EXECUTOR in the disassembly
+ got = got.replace("ENTER_EXECUTOR", "JUMP_BACKWARD ")
self.do_disassembly_compare(got, expected)
@cpython_only
@@ -1713,7 +1714,7 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_CONST', opcode=143, arg=1, argval=10, argrepr='10', offset=12, start_offset=12, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=14, start_offset=14, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='GET_ITER', opcode=31, arg=None, argval=None, argrepr='', offset=22, start_offset=22, starts_line=False, line_number=3, is_jump_target=False, positions=None),
- Instruction(opname='FOR_ITER', opcode=115, arg=28, argval=84, argrepr='to 84', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None),
+ Instruction(opname='FOR_ITER', opcode=115, arg=30, argval=88, argrepr='to 88', offset=24, start_offset=24, starts_line=False, line_number=3, is_jump_target=True, positions=None),
Instruction(opname='STORE_FAST', opcode=177, arg=0, argval='i', argrepr='i', offset=28, start_offset=28, starts_line=False, line_number=3, is_jump_target=False, positions=None),
Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=30, start_offset=30, starts_line=True, line_number=4, is_jump_target=False, positions=None),
Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=40, start_offset=40, starts_line=False, line_number=4, is_jump_target=False, positions=None),
@@ -1722,108 +1723,108 @@ expected_opinfo_jumpy = [
Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=52, start_offset=52, starts_line=True, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='LOAD_CONST', opcode=143, arg=2, argval=4, argrepr='4', offset=54, start_offset=54, starts_line=False, line_number=5, is_jump_target=False, positions=None),
Instruction(opname='COMPARE_OP', opcode=98, arg=18, argval='<', argrepr='bool(<)', offset=56, start_offset=56, starts_line=False, line_number=5, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=66, argrepr='to 66', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=21, argval=24, argrepr='to 24', offset=62, start_offset=62, starts_line=True, line_number=6, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=66, start_offset=66, starts_line=True, line_number=7, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=3, argval=6, argrepr='6', offset=68, start_offset=68, starts_line=False, line_number=7, is_jump_target=False, positions=None),
- Instruction(opname='COMPARE_OP', opcode=98, arg=148, argval='>', argrepr='bool(>)', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=164, arg=2, argval=80, argrepr='to 80', offset=74, start_offset=74, starts_line=False, line_number=7, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=28, argval=24, argrepr='to 24', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=80, start_offset=80, starts_line=True, line_number=8, is_jump_target=True, positions=None),
- Instruction(opname='JUMP_FORWARD', opcode=126, arg=12, argval=108, argrepr='to 108', offset=82, start_offset=82, starts_line=False, line_number=8, is_jump_target=False, positions=None),
- Instruction(opname='END_FOR', opcode=24, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=3, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=86, start_offset=86, starts_line=True, line_number=10, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=96, start_offset=96, starts_line=False, line_number=10, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=98, start_offset=98, starts_line=False, line_number=10, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=106, start_offset=106, starts_line=False, line_number=10, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST_CHECK', opcode=147, arg=0, argval='i', argrepr='i', offset=108, start_offset=108, starts_line=True, line_number=11, is_jump_target=True, positions=None),
- Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=11, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=37, argval=194, argrepr='to 194', offset=118, start_offset=118, starts_line=False, line_number=11, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=120, start_offset=120, starts_line=True, line_number=12, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=130, start_offset=130, starts_line=False, line_number=12, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=132, start_offset=132, starts_line=False, line_number=12, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=140, start_offset=140, starts_line=False, line_number=12, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=142, start_offset=142, starts_line=True, line_number=13, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=5, argval=1, argrepr='1', offset=144, start_offset=144, starts_line=False, line_number=13, is_jump_target=False, positions=None),
- Instruction(opname='BINARY_OP', opcode=68, arg=23, argval=23, argrepr='-=', offset=146, start_offset=146, starts_line=False, line_number=13, is_jump_target=False, positions=None),
- Instruction(opname='STORE_FAST', opcode=177, arg=0, argval='i', argrepr='i', offset=150, start_offset=150, starts_line=False, line_number=13, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=152, start_offset=152, starts_line=True, line_number=14, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=3, argval=6, argrepr='6', offset=154, start_offset=154, starts_line=False, line_number=14, is_jump_target=False, positions=None),
- Instruction(opname='COMPARE_OP', opcode=98, arg=148, argval='>', argrepr='bool(>)', offset=156, start_offset=156, starts_line=False, line_number=14, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=166, argrepr='to 166', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=29, argval=108, argrepr='to 108', offset=162, start_offset=162, starts_line=True, line_number=15, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=166, start_offset=166, starts_line=True, line_number=16, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=2, argval=4, argrepr='4', offset=168, start_offset=168, starts_line=False, line_number=16, is_jump_target=False, positions=None),
- Instruction(opname='COMPARE_OP', opcode=98, arg=18, argval='<', argrepr='bool(<)', offset=170, start_offset=170, starts_line=False, line_number=16, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=1, argval=178, argrepr='to 178', offset=174, start_offset=174, starts_line=False, line_number=16, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_FORWARD', opcode=126, arg=19, argval=216, argrepr='to 216', offset=176, start_offset=176, starts_line=True, line_number=17, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=178, start_offset=178, starts_line=True, line_number=11, is_jump_target=True, positions=None),
- Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=180, start_offset=180, starts_line=False, line_number=11, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=194, argrepr='to 194', offset=188, start_offset=188, starts_line=False, line_number=11, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=37, argval=120, argrepr='to 120', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=194, start_offset=194, starts_line=True, line_number=19, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=204, start_offset=204, starts_line=False, line_number=19, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=206, start_offset=206, starts_line=False, line_number=19, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=214, start_offset=214, starts_line=False, line_number=19, is_jump_target=False, positions=None),
- Instruction(opname='NOP', opcode=42, arg=None, argval=None, argrepr='', offset=216, start_offset=216, starts_line=True, line_number=20, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=5, argval=1, argrepr='1', offset=218, start_offset=218, starts_line=True, line_number=21, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=7, argval=0, argrepr='0', offset=220, start_offset=220, starts_line=False, line_number=21, is_jump_target=False, positions=None),
- Instruction(opname='BINARY_OP', opcode=68, arg=11, argval=11, argrepr='/', offset=222, start_offset=222, starts_line=False, line_number=21, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=21, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=228, start_offset=228, starts_line=True, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=230, start_offset=230, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='STORE_FAST', opcode=177, arg=1, argval='dodgy', argrepr='dodgy', offset=232, start_offset=232, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=234, start_offset=234, starts_line=True, line_number=26, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=244, start_offset=244, starts_line=False, line_number=26, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=246, start_offset=246, starts_line=False, line_number=26, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=254, start_offset=254, starts_line=False, line_number=26, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=256, start_offset=256, starts_line=True, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=258, start_offset=258, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=260, start_offset=260, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=2, argval=2, argrepr='', offset=262, start_offset=262, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=270, start_offset=270, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=272, start_offset=272, starts_line=True, line_number=28, is_jump_target=True, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=282, start_offset=282, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=284, start_offset=284, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=292, start_offset=292, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='RETURN_CONST', opcode=168, arg=0, argval=None, argrepr='None', offset=294, start_offset=294, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=296, start_offset=296, starts_line=True, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='WITH_EXCEPT_START', opcode=67, arg=None, argval=None, argrepr='', offset=298, start_offset=298, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=300, start_offset=300, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_TRUE', opcode=164, arg=1, argval=312, argrepr='to 312', offset=308, start_offset=308, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=2, argval=2, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, is_jump_target=True, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=314, start_offset=314, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=316, start_offset=316, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=318, start_offset=318, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=26, argval=272, argrepr='to 272', offset=320, start_offset=320, starts_line=False, line_number=25, is_jump_target=False, positions=None),
- Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=324, start_offset=324, starts_line=True, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=332, start_offset=332, starts_line=True, line_number=22, is_jump_target=False, positions=None),
- Instruction(opname='CHECK_EXC_MATCH', opcode=20, arg=None, argval=None, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=22, is_jump_target=False, positions=None),
- Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=15, argval=376, argrepr='to 376', offset=344, start_offset=344, starts_line=False, line_number=22, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=346, start_offset=346, starts_line=False, line_number=22, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=348, start_offset=348, starts_line=True, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=358, start_offset=358, starts_line=False, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=360, start_offset=360, starts_line=False, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=368, start_offset=368, starts_line=False, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=370, start_offset=370, starts_line=False, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='JUMP_BACKWARD', opcode=124, arg=52, argval=272, argrepr='to 272', offset=372, start_offset=372, starts_line=False, line_number=23, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=0, argval=0, argrepr='', offset=376, start_offset=376, starts_line=True, line_number=22, is_jump_target=True, positions=None),
- Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=378, start_offset=378, starts_line=True, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=380, start_offset=380, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=382, start_offset=382, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=None, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=386, start_offset=386, starts_line=True, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='LOAD_CONST', opcode=143, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=396, start_offset=396, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=406, start_offset=406, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=0, argval=0, argrepr='', offset=408, start_offset=408, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=410, start_offset=410, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=412, start_offset=412, starts_line=False, line_number=28, is_jump_target=False, positions=None),
- Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=68, argrepr='to 68', offset=60, start_offset=60, starts_line=False, line_number=5, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=22, argval=24, argrepr='to 24', offset=64, start_offset=64, starts_line=True, line_number=6, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=68, start_offset=68, starts_line=True, line_number=7, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=3, argval=6, argrepr='6', offset=70, start_offset=70, starts_line=False, line_number=7, is_jump_target=False, positions=None),
+ Instruction(opname='COMPARE_OP', opcode=98, arg=148, argval='>', argrepr='bool(>)', offset=72, start_offset=72, starts_line=False, line_number=7, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=164, arg=2, argval=84, argrepr='to 84', offset=76, start_offset=76, starts_line=False, line_number=7, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=30, argval=24, argrepr='to 24', offset=80, start_offset=80, starts_line=False, line_number=7, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=84, start_offset=84, starts_line=True, line_number=8, is_jump_target=True, positions=None),
+ Instruction(opname='JUMP_FORWARD', opcode=126, arg=12, argval=112, argrepr='to 112', offset=86, start_offset=86, starts_line=False, line_number=8, is_jump_target=False, positions=None),
+ Instruction(opname='END_FOR', opcode=24, arg=None, argval=None, argrepr='', offset=88, start_offset=88, starts_line=True, line_number=3, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=90, start_offset=90, starts_line=True, line_number=10, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=4, argval='I can haz else clause?', argrepr="'I can haz else clause?'", offset=100, start_offset=100, starts_line=False, line_number=10, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=102, start_offset=102, starts_line=False, line_number=10, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=110, start_offset=110, starts_line=False, line_number=10, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST_CHECK', opcode=147, arg=0, argval='i', argrepr='i', offset=112, start_offset=112, starts_line=True, line_number=11, is_jump_target=True, positions=None),
+ Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=114, start_offset=114, starts_line=False, line_number=11, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=40, argval=206, argrepr='to 206', offset=122, start_offset=122, starts_line=False, line_number=11, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=126, start_offset=126, starts_line=True, line_number=12, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=136, start_offset=136, starts_line=False, line_number=12, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=138, start_offset=138, starts_line=False, line_number=12, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=146, start_offset=146, starts_line=False, line_number=12, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=148, start_offset=148, starts_line=True, line_number=13, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=5, argval=1, argrepr='1', offset=150, start_offset=150, starts_line=False, line_number=13, is_jump_target=False, positions=None),
+ Instruction(opname='BINARY_OP', opcode=68, arg=23, argval=23, argrepr='-=', offset=152, start_offset=152, starts_line=False, line_number=13, is_jump_target=False, positions=None),
+ Instruction(opname='STORE_FAST', opcode=177, arg=0, argval='i', argrepr='i', offset=156, start_offset=156, starts_line=False, line_number=13, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=158, start_offset=158, starts_line=True, line_number=14, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=3, argval=6, argrepr='6', offset=160, start_offset=160, starts_line=False, line_number=14, is_jump_target=False, positions=None),
+ Instruction(opname='COMPARE_OP', opcode=98, arg=148, argval='>', argrepr='bool(>)', offset=162, start_offset=162, starts_line=False, line_number=14, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=174, argrepr='to 174', offset=166, start_offset=166, starts_line=False, line_number=14, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=31, argval=112, argrepr='to 112', offset=170, start_offset=170, starts_line=True, line_number=15, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=174, start_offset=174, starts_line=True, line_number=16, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=2, argval=4, argrepr='4', offset=176, start_offset=176, starts_line=False, line_number=16, is_jump_target=False, positions=None),
+ Instruction(opname='COMPARE_OP', opcode=98, arg=18, argval='<', argrepr='bool(<)', offset=178, start_offset=178, starts_line=False, line_number=16, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=1, argval=188, argrepr='to 188', offset=182, start_offset=182, starts_line=False, line_number=16, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_FORWARD', opcode=126, arg=20, argval=228, argrepr='to 228', offset=186, start_offset=186, starts_line=True, line_number=17, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=188, start_offset=188, starts_line=True, line_number=11, is_jump_target=True, positions=None),
+ Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=190, start_offset=190, starts_line=False, line_number=11, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=2, argval=206, argrepr='to 206', offset=198, start_offset=198, starts_line=False, line_number=11, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=40, argval=126, argrepr='to 126', offset=202, start_offset=202, starts_line=False, line_number=11, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=206, start_offset=206, starts_line=True, line_number=19, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=6, argval='Who let lolcatz into this test suite?', argrepr="'Who let lolcatz into this test suite?'", offset=216, start_offset=216, starts_line=False, line_number=19, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=218, start_offset=218, starts_line=False, line_number=19, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=226, start_offset=226, starts_line=False, line_number=19, is_jump_target=False, positions=None),
+ Instruction(opname='NOP', opcode=42, arg=None, argval=None, argrepr='', offset=228, start_offset=228, starts_line=True, line_number=20, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=5, argval=1, argrepr='1', offset=230, start_offset=230, starts_line=True, line_number=21, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=7, argval=0, argrepr='0', offset=232, start_offset=232, starts_line=False, line_number=21, is_jump_target=False, positions=None),
+ Instruction(opname='BINARY_OP', opcode=68, arg=11, argval=11, argrepr='/', offset=234, start_offset=234, starts_line=False, line_number=21, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=238, start_offset=238, starts_line=False, line_number=21, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_FAST', opcode=145, arg=0, argval='i', argrepr='i', offset=240, start_offset=240, starts_line=True, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='BEFORE_WITH', opcode=2, arg=None, argval=None, argrepr='', offset=242, start_offset=242, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='STORE_FAST', opcode=177, arg=1, argval='dodgy', argrepr='dodgy', offset=244, start_offset=244, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=246, start_offset=246, starts_line=True, line_number=26, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=8, argval='Never reach this', argrepr="'Never reach this'", offset=256, start_offset=256, starts_line=False, line_number=26, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=258, start_offset=258, starts_line=False, line_number=26, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=266, start_offset=266, starts_line=False, line_number=26, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=268, start_offset=268, starts_line=True, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=270, start_offset=270, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=0, argval=None, argrepr='None', offset=272, start_offset=272, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=2, argval=2, argrepr='', offset=274, start_offset=274, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=282, start_offset=282, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=284, start_offset=284, starts_line=True, line_number=28, is_jump_target=True, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=294, start_offset=294, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=296, start_offset=296, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=304, start_offset=304, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='RETURN_CONST', opcode=168, arg=0, argval=None, argrepr='None', offset=306, start_offset=306, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=308, start_offset=308, starts_line=True, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='WITH_EXCEPT_START', opcode=67, arg=None, argval=None, argrepr='', offset=310, start_offset=310, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='TO_BOOL', opcode=57, arg=None, argval=None, argrepr='', offset=312, start_offset=312, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_TRUE', opcode=164, arg=1, argval=326, argrepr='to 326', offset=320, start_offset=320, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=2, argval=2, argrepr='', offset=324, start_offset=324, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=326, start_offset=326, starts_line=False, line_number=25, is_jump_target=True, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=328, start_offset=328, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=330, start_offset=330, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=332, start_offset=332, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=27, argval=284, argrepr='to 284', offset=334, start_offset=334, starts_line=False, line_number=25, is_jump_target=False, positions=None),
+ Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=338, start_offset=338, starts_line=True, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=340, start_offset=340, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=342, start_offset=342, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=344, start_offset=344, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=4, argval='ZeroDivisionError', argrepr='ZeroDivisionError', offset=346, start_offset=346, starts_line=True, line_number=22, is_jump_target=False, positions=None),
+ Instruction(opname='CHECK_EXC_MATCH', opcode=20, arg=None, argval=None, argrepr='', offset=356, start_offset=356, starts_line=False, line_number=22, is_jump_target=False, positions=None),
+ Instruction(opname='POP_JUMP_IF_FALSE', opcode=161, arg=15, argval=392, argrepr='to 392', offset=358, start_offset=358, starts_line=False, line_number=22, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=362, start_offset=362, starts_line=False, line_number=22, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=364, start_offset=364, starts_line=True, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=9, argval='Here we go, here we go, here we go...', argrepr="'Here we go, here we go, here we go...'", offset=374, start_offset=374, starts_line=False, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=376, start_offset=376, starts_line=False, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=384, start_offset=384, starts_line=False, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=386, start_offset=386, starts_line=False, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='JUMP_BACKWARD', opcode=124, arg=54, argval=284, argrepr='to 284', offset=388, start_offset=388, starts_line=False, line_number=23, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=0, argval=0, argrepr='', offset=392, start_offset=392, starts_line=True, line_number=22, is_jump_target=True, positions=None),
+ Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=394, start_offset=394, starts_line=True, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=396, start_offset=396, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=398, start_offset=398, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='PUSH_EXC_INFO', opcode=45, arg=None, argval=None, argrepr='', offset=400, start_offset=400, starts_line=False, line_number=None, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_GLOBAL', opcode=151, arg=3, argval='print', argrepr='print + NULL', offset=402, start_offset=402, starts_line=True, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='LOAD_CONST', opcode=143, arg=10, argval="OK, now we're done", argrepr='"OK, now we\'re done"', offset=412, start_offset=412, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='CALL', opcode=76, arg=1, argval=1, argrepr='', offset=414, start_offset=414, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='POP_TOP', opcode=44, arg=None, argval=None, argrepr='', offset=422, start_offset=422, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=0, argval=0, argrepr='', offset=424, start_offset=424, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='COPY', opcode=104, arg=3, argval=3, argrepr='', offset=426, start_offset=426, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='POP_EXCEPT', opcode=43, arg=None, argval=None, argrepr='', offset=428, start_offset=428, starts_line=False, line_number=28, is_jump_target=False, positions=None),
+ Instruction(opname='RERAISE', opcode=167, arg=1, argval=1, argrepr='', offset=430, start_offset=430, starts_line=False, line_number=28, is_jump_target=False, positions=None),
]
# One last piece of inspect fodder to check the default line number handling
@@ -2026,6 +2027,7 @@ class InstructionTests(InstructionTestCase):
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
+ opcode.opmap["CACHE"], 0x00,
])
jump = list(dis._get_instructions_bytes(code))[-1]
self.assertEqual(8, jump.offset)
@@ -2035,18 +2037,20 @@ class InstructionTests(InstructionTestCase):
opcode.opmap["LOAD_FAST"], 0x00,
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
+ opcode.opmap["CACHE"], 0x00,
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["EXTENDED_ARG"], 0x01,
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
+ opcode.opmap["CACHE"], 0x00,
])
instructions = list(dis._get_instructions_bytes(code))
# 1st jump
self.assertEqual(4, instructions[2].offset)
self.assertEqual(2, instructions[2].start_offset)
# 2nd jump
- self.assertEqual(12, instructions[6].offset)
- self.assertEqual(6, instructions[6].start_offset)
+ self.assertEqual(14, instructions[6].offset)
+ self.assertEqual(8, instructions[6].start_offset)
def test_cache_offset_and_end_offset(self):
code = bytes([
diff --git a/Lib/test/test_monitoring.py b/Lib/test/test_monitoring.py
index e575eca42fa..a4725be2170 100644
--- a/Lib/test/test_monitoring.py
+++ b/Lib/test/test_monitoring.py
@@ -1348,10 +1348,10 @@ class TestBranchAndJumpEvents(CheckEvents):
self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
('branch', 'func', 2, 2),
- ('branch', 'func', 3, 6),
+ ('branch', 'func', 3, 4),
('jump', 'func', 6, 2),
('branch', 'func', 2, 2),
- ('branch', 'func', 3, 4),
+ ('branch', 'func', 3, 3),
('jump', 'func', 4, 2),
('branch', 'func', 2, 2)])
@@ -1361,13 +1361,13 @@ class TestBranchAndJumpEvents(CheckEvents):
('line', 'func', 2),
('branch', 'func', 2, 2),
('line', 'func', 3),
- ('branch', 'func', 3, 6),
+ ('branch', 'func', 3, 4),
('line', 'func', 6),
('jump', 'func', 6, 2),
('line', 'func', 2),
('branch', 'func', 2, 2),
('line', 'func', 3),
- ('branch', 'func', 3, 4),
+ ('branch', 'func', 3, 3),
('line', 'func', 4),
('jump', 'func', 4, 2),
('line', 'func', 2),
@@ -1400,8 +1400,8 @@ class TestBranchAndJumpEvents(CheckEvents):
('line', 'func', 5),
('line', 'meth', 1),
('jump', 'func', 5, 5),
- ('jump', 'func', 5, '[offset=112]'),
- ('branch', 'func', '[offset=118]', '[offset=120]'),
+ ('jump', 'func', 5, '[offset=114]'),
+ ('branch', 'func', '[offset=120]', '[offset=122]'),
('line', 'get_events', 11)])
self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [
@@ -1416,8 +1416,8 @@ class TestBranchAndJumpEvents(CheckEvents):
('line', 'meth', 1),
('return', None),
('jump', 'func', 5, 5),
- ('jump', 'func', 5, '[offset=112]'),
- ('branch', 'func', '[offset=118]', '[offset=120]'),
+ ('jump', 'func', 5, '[offset=114]'),
+ ('branch', 'func', '[offset=120]', '[offset=122]'),
('return', None),
('line', 'get_events', 11)])
diff --git a/Lib/test/test_regrtest.py b/Lib/test/test_regrtest.py
index f587a8f919d..466b6f66797 100644
--- a/Lib/test/test_regrtest.py
+++ b/Lib/test/test_regrtest.py
@@ -19,7 +19,7 @@ import tempfile
import textwrap
import unittest
from test import support
-from test.support import os_helper, TestStats
+from test.support import os_helper, TestStats, without_optimizer
from test.libregrtest import cmdline
from test.libregrtest import utils
from test.libregrtest import setup
@@ -1018,12 +1018,13 @@ class ArgsTestCase(BaseTestCase):
stats=TestStats(4, 1),
forever=True)
+ @without_optimizer
def check_leak(self, code, what, *, multiprocessing=False):
test = self.create_test('huntrleaks', code=code)
filename = 'reflog.txt'
self.addCleanup(os_helper.unlink, filename)
- cmd = ['--huntrleaks', '6:3:']
+ cmd = ['--huntrleaks', '3:3:']
if multiprocessing:
cmd.append('-j1')
cmd.append(test)
@@ -1032,7 +1033,7 @@ class ArgsTestCase(BaseTestCase):
stderr=subprocess.STDOUT)
self.check_executed_tests(output, [test], failed=test, stats=1)
- line = 'beginning 9 repetitions\n123456789\n.........\n'
+ line = 'beginning 6 repetitions\n123456\n......\n'
self.check_line(output, re.escape(line))
line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what)
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index ff95f37b900..c9dea5c4562 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -2292,14 +2292,22 @@ dummy_func(
goto resume_frame;
}
- inst(POP_JUMP_IF_FALSE, (cond -- )) {
+ inst(POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsFalse(cond));
+ int flag = Py_IsFalse(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
}
- inst(POP_JUMP_IF_TRUE, (cond -- )) {
+ inst(POP_JUMP_IF_TRUE, (unused/1, cond -- )) {
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsTrue(cond));
+ int flag = Py_IsTrue(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
}
op(IS_NONE, (value -- b)) {
@@ -3751,47 +3759,63 @@ dummy_func(
INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP);
}
- inst(INSTRUMENTED_POP_JUMP_IF_TRUE, ( -- )) {
+ inst(INSTRUMENTED_POP_JUMP_IF_TRUE, (unused/1 -- )) {
PyObject *cond = POP();
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
- int offset = Py_IsTrue(cond) * oparg;
+ int flag = Py_IsTrue(cond);
+ int offset = flag * oparg;
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
- inst(INSTRUMENTED_POP_JUMP_IF_FALSE, ( -- )) {
+ inst(INSTRUMENTED_POP_JUMP_IF_FALSE, (unused/1 -- )) {
PyObject *cond = POP();
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
- int offset = Py_IsFalse(cond) * oparg;
+ int flag = Py_IsFalse(cond);
+ int offset = flag * oparg;
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
- inst(INSTRUMENTED_POP_JUMP_IF_NONE, ( -- )) {
+ inst(INSTRUMENTED_POP_JUMP_IF_NONE, (unused/1 -- )) {
PyObject *value = POP();
- _Py_CODEUNIT *here = next_instr-1;
+ _Py_CODEUNIT *here = next_instr - 1;
+ int flag = Py_IsNone(value);
int offset;
- if (Py_IsNone(value)) {
+ if (flag) {
offset = oparg;
}
else {
Py_DECREF(value);
offset = 0;
}
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
- inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, ( -- )) {
+ inst(INSTRUMENTED_POP_JUMP_IF_NOT_NONE, (unused/1 -- )) {
PyObject *value = POP();
_Py_CODEUNIT *here = next_instr-1;
int offset;
- if (Py_IsNone(value)) {
+ int nflag = Py_IsNone(value);
+ if (nflag) {
offset = 0;
}
else {
Py_DECREF(value);
offset = oparg;
}
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | !nflag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
}
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index e84599d87a6..a4944c7fcdf 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -2996,8 +2996,13 @@
PyObject *cond;
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsFalse(cond));
+ int flag = Py_IsFalse(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
STACK_SHRINK(1);
+ next_instr += 1;
DISPATCH();
}
@@ -3005,8 +3010,13 @@
PyObject *cond;
cond = stack_pointer[-1];
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsTrue(cond));
+ int flag = Py_IsTrue(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
STACK_SHRINK(1);
+ next_instr += 1;
DISPATCH();
}
@@ -3029,9 +3039,14 @@
cond = b;
{
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsTrue(cond));
+ int flag = Py_IsTrue(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
}
STACK_SHRINK(1);
+ next_instr += 1;
DISPATCH();
}
@@ -3054,9 +3069,14 @@
cond = b;
{
assert(PyBool_Check(cond));
- JUMPBY(oparg * Py_IsFalse(cond));
+ int flag = Py_IsFalse(cond);
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
+ JUMPBY(oparg * flag);
}
STACK_SHRINK(1);
+ next_instr += 1;
DISPATCH();
}
@@ -4921,8 +4941,13 @@
PyObject *cond = POP();
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
- int offset = Py_IsTrue(cond) * oparg;
+ int flag = Py_IsTrue(cond);
+ int offset = flag * oparg;
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ next_instr += 1;
DISPATCH();
}
@@ -4930,23 +4955,33 @@
PyObject *cond = POP();
assert(PyBool_Check(cond));
_Py_CODEUNIT *here = next_instr - 1;
- int offset = Py_IsFalse(cond) * oparg;
+ int flag = Py_IsFalse(cond);
+ int offset = flag * oparg;
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ next_instr += 1;
DISPATCH();
}
TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
PyObject *value = POP();
- _Py_CODEUNIT *here = next_instr-1;
+ _Py_CODEUNIT *here = next_instr - 1;
+ int flag = Py_IsNone(value);
int offset;
- if (Py_IsNone(value)) {
+ if (flag) {
offset = oparg;
}
else {
Py_DECREF(value);
offset = 0;
}
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | flag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ next_instr += 1;
DISPATCH();
}
@@ -4954,14 +4989,19 @@
PyObject *value = POP();
_Py_CODEUNIT *here = next_instr-1;
int offset;
- if (Py_IsNone(value)) {
+ int nflag = Py_IsNone(value);
+ if (nflag) {
offset = 0;
}
else {
Py_DECREF(value);
offset = oparg;
}
+ #if ENABLE_SPECIALIZATION
+ next_instr->cache = (next_instr->cache << 1) | !nflag;
+ #endif
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
+ next_instr += 1;
DISPATCH();
}
diff --git a/Python/instrumentation.c b/Python/instrumentation.c
index 5f714602eaf..fee6eae1734 100644
--- a/Python/instrumentation.c
+++ b/Python/instrumentation.c
@@ -2,6 +2,7 @@
#include "opcode_ids.h"
+#include "pycore_bitutils.h" // _Py_popcount32
#include "pycore_call.h"
#include "pycore_code.h" // _PyCode_Clear_Executors()
#include "pycore_frame.h"
diff --git a/Python/optimizer.c b/Python/optimizer.c
index c6d0f9e5bf2..8eca37a7e4a 100644
--- a/Python/optimizer.c
+++ b/Python/optimizer.c
@@ -1,6 +1,7 @@
#include "Python.h"
#include "opcode.h"
#include "pycore_interp.h"
+#include "pycore_bitutils.h" // _Py_popcount32()
#include "pycore_opcode_metadata.h" // _PyOpcode_OpName()
#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
@@ -501,7 +502,7 @@ translate_bytecode_to_trace(
code->co_firstlineno,
2 * INSTR_IP(initial_instr, code));
-top: // Jump here after _PUSH_FRAME
+top: // Jump here after _PUSH_FRAME or likely branches
for (;;) {
RESERVE_RAW(2, "epilogue"); // Always need space for SAVE_IP and EXIT_TRACE
ADD_TO_TRACE(SAVE_IP, INSTR_IP(instr, code), 0);
@@ -547,16 +548,29 @@ top: // Jump here after _PUSH_FRAME
case POP_JUMP_IF_TRUE:
{
pop_jump_if_bool:
- // Assume jump unlikely (TODO: handle jump likely case)
RESERVE(1, 2);
- _Py_CODEUNIT *target_instr =
- instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg;
max_length -= 2; // Really the start of the stubs
- uint32_t uopcode = opcode == POP_JUMP_IF_TRUE ?
+ int counter = instr[1].cache;
+ int bitcount = _Py_popcount32(counter);
+ bool jump_likely = bitcount > 8;
+ bool jump_sense = opcode == POP_JUMP_IF_TRUE;
+ uint32_t uopcode = jump_sense ^ jump_likely ?
_POP_JUMP_IF_TRUE : _POP_JUMP_IF_FALSE;
+ _Py_CODEUNIT *next_instr = instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]];
+ _Py_CODEUNIT *target_instr = next_instr + oparg;
+ _Py_CODEUNIT *stub_target = jump_likely ? next_instr : target_instr;
+ DPRINTF(4, "%s(%d): counter=%x, bitcount=%d, likely=%d, sense=%d, uopcode=%s\n",
+ uop_name(opcode), oparg,
+ counter, bitcount, jump_likely, jump_sense, uop_name(uopcode));
ADD_TO_TRACE(uopcode, max_length, 0);
- ADD_TO_STUB(max_length, SAVE_IP, INSTR_IP(target_instr, code), 0);
+ ADD_TO_STUB(max_length, SAVE_IP, INSTR_IP(stub_target, code), 0);
ADD_TO_STUB(max_length + 1, EXIT_TRACE, 0, 0);
+ if (jump_likely) {
+ DPRINTF(2, "Jump likely (%x = %d bits), continue at byte offset %d\n",
+ instr[1].cache, bitcount, 2 * INSTR_IP(target_instr, code));
+ instr = target_instr;
+ goto top;
+ }
break;
}
@@ -927,6 +941,6 @@ PyUnstable_Optimizer_NewUOpOptimizer(void)
opt->resume_threshold = UINT16_MAX;
// Need at least 3 iterations to settle specializations.
// A few lower bits of the counter are reserved for other flags.
- opt->backedge_threshold = 3 << OPTIMIZER_BITS_IN_COUNTER;
+ opt->backedge_threshold = 16 << OPTIMIZER_BITS_IN_COUNTER;
return (PyObject *)opt;
}
diff --git a/Python/specialize.c b/Python/specialize.c
index 8b4aac2f890..91243419ec6 100644
--- a/Python/specialize.c
+++ b/Python/specialize.c
@@ -338,9 +338,23 @@ _PyCode_Quicken(PyCodeObject *code)
assert(opcode < MIN_INSTRUMENTED_OPCODE);
int caches = _PyOpcode_Caches[opcode];
if (caches) {
- // JUMP_BACKWARD counter counts up from 0 until it is > backedge_threshold
- instructions[i + 1].cache =
- opcode == JUMP_BACKWARD ? 0 : adaptive_counter_warmup();
+ // The initial value depends on the opcode
+ int initial_value;
+ switch (opcode) {
+ case JUMP_BACKWARD:
+ initial_value = 0;
+ break;
+ case POP_JUMP_IF_FALSE:
+ case POP_JUMP_IF_TRUE:
+ case POP_JUMP_IF_NONE:
+ case POP_JUMP_IF_NOT_NONE:
+ initial_value = 0x5555; // Alternating 0, 1 bits
+ break;
+ default:
+ initial_value = adaptive_counter_warmup();
+ break;
+ }
+ instructions[i + 1].cache = initial_value;
i += caches;
}
}
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index 1335c0c29eb..ad4a99931d9 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -549,10 +549,20 @@ class Generator(Analyzer):
"=",
";",
):
- for name, _ in self.families.items():
- instr = self.instrs[name]
- if instr.cache_offset > 0:
- self.out.emit(f'[{name}] = {instr.cache_offset},')
+ family_member_names: set[str] = set()
+ for family in self.families.values():
+ family_member_names.update(family.members)
+ for instr in self.instrs.values():
+ if (
+ instr.name not in family_member_names
+ and instr.cache_offset > 0
+ and instr.kind == "inst"
+ and not instr.name.startswith("INSTRUMENTED_")
+ ):
+ self.out.emit(f"[{instr.name}] = {instr.cache_offset},")
+ for mac in self.macro_instrs.values():
+ if mac.name not in family_member_names and mac.cache_offset > 0:
+ self.out.emit(f"[{mac.name}] = {mac.cache_offset},")
# Irregular case:
self.out.emit('[JUMP_BACKWARD] = 1,')