mirror of
https://github.com/python/cpython.git
synced 2025-10-09 08:31:26 +00:00
gh-109039: Branch prediction for Tier 2 interpreter (#109038)
This adds a 16-bit inline cache entry to the conditional branch instructions POP_JUMP_IF_{FALSE,TRUE,NONE,NOT_NONE} and their instrumented variants, which is used to keep track of the branch direction. Each time we encounter these instructions we shift the cache entry left by one and set the bottom bit to whether we jumped. Then when it's time to translate such a branch to Tier 2 uops, we use the bit count from the cache entry to decided whether to continue translating the "didn't jump" branch or the "jumped" branch. The counter is initialized to a pattern of alternating ones and zeros to avoid bias. The .pyc file magic number is updated. There's a new test, some fixes for existing tests, and a few miscellaneous cleanups.
This commit is contained in:
parent
ecd21a629a
commit
bcce5e2718
15 changed files with 339 additions and 181 deletions
|
@ -5,7 +5,6 @@
|
||||||
# error "this header requires Py_BUILD_CORE define"
|
# error "this header requires Py_BUILD_CORE define"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "pycore_bitutils.h" // _Py_popcount32
|
|
||||||
#include "pycore_frame.h" // _PyInterpreterFrame
|
#include "pycore_frame.h" // _PyInterpreterFrame
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
22
Include/internal/pycore_opcode_metadata.h
generated
22
Include/internal/pycore_opcode_metadata.h
generated
|
@ -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] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[JUMP_NO_INTERRUPT] = { 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 },
|
[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_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[POP_JUMP_IF_TRUE] = { true, INSTR_FMT_IB, 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 },
|
[IS_NONE] = { true, INSTR_FMT_IX, 0 },
|
||||||
[POP_JUMP_IF_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_IB, 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 },
|
[JUMP_BACKWARD_NO_INTERRUPT] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_JUMP_FLAG },
|
||||||
[GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
|
[GET_LEN] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
|
||||||
[MATCH_CLASS] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | 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_INSTRUCTION] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG },
|
||||||
[INSTRUMENTED_JUMP_FORWARD] = { true, INSTR_FMT_IB, HAS_ARG_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_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_TRUE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_FALSE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
[INSTRUMENTED_POP_JUMP_IF_NONE] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG },
|
||||||
[INSTRUMENTED_POP_JUMP_IF_NOT_NONE] = { true, INSTR_FMT_IB, 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 },
|
[EXTENDED_ARG] = { true, INSTR_FMT_IB, HAS_ARG_FLAG },
|
||||||
[CACHE] = { true, INSTR_FMT_IX, 0 },
|
[CACHE] = { true, INSTR_FMT_IX, 0 },
|
||||||
[RESERVED] = { 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
|
#ifdef NEED_OPCODE_METADATA
|
||||||
const uint8_t _PyOpcode_Caches[256] = {
|
const uint8_t _PyOpcode_Caches[256] = {
|
||||||
[TO_BOOL] = 3,
|
[TO_BOOL] = 3,
|
||||||
[BINARY_OP] = 1,
|
|
||||||
[BINARY_SUBSCR] = 1,
|
[BINARY_SUBSCR] = 1,
|
||||||
[STORE_SUBSCR] = 1,
|
[STORE_SUBSCR] = 1,
|
||||||
[SEND] = 1,
|
[SEND] = 1,
|
||||||
|
@ -1895,8 +1894,13 @@ const uint8_t _PyOpcode_Caches[256] = {
|
||||||
[LOAD_SUPER_ATTR] = 1,
|
[LOAD_SUPER_ATTR] = 1,
|
||||||
[LOAD_ATTR] = 9,
|
[LOAD_ATTR] = 9,
|
||||||
[COMPARE_OP] = 1,
|
[COMPARE_OP] = 1,
|
||||||
|
[POP_JUMP_IF_FALSE] = 1,
|
||||||
|
[POP_JUMP_IF_TRUE] = 1,
|
||||||
[FOR_ITER] = 1,
|
[FOR_ITER] = 1,
|
||||||
[CALL] = 3,
|
[CALL] = 3,
|
||||||
|
[BINARY_OP] = 1,
|
||||||
|
[POP_JUMP_IF_NONE] = 1,
|
||||||
|
[POP_JUMP_IF_NOT_NONE] = 1,
|
||||||
[JUMP_BACKWARD] = 1,
|
[JUMP_BACKWARD] = 1,
|
||||||
};
|
};
|
||||||
#endif // NEED_OPCODE_METADATA
|
#endif // NEED_OPCODE_METADATA
|
||||||
|
|
|
@ -456,6 +456,7 @@ _code_type = type(_write_atomic.__code__)
|
||||||
# Python 3.13a1 3558 (Reorder the stack items for CALL)
|
# Python 3.13a1 3558 (Reorder the stack items for CALL)
|
||||||
# Python 3.13a1 3559 (Generate opcode IDs from bytecodes.c)
|
# Python 3.13a1 3559 (Generate opcode IDs from bytecodes.c)
|
||||||
# Python 3.13a1 3560 (Add RESUME_CHECK instruction)
|
# 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
|
# 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
|
# Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array
|
||||||
# in PC/launcher.c must also be updated.
|
# 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
|
_RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,18 @@ _cache_format = {
|
||||||
"counter": 1,
|
"counter": 1,
|
||||||
"version": 2,
|
"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 = {
|
_inline_cache_entries = {
|
||||||
|
|
|
@ -62,6 +62,7 @@ __all__ = [
|
||||||
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
|
"LOOPBACK_TIMEOUT", "INTERNET_TIMEOUT", "SHORT_TIMEOUT", "LONG_TIMEOUT",
|
||||||
"Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT",
|
"Py_DEBUG", "EXCEEDS_RECURSION_LIMIT", "Py_C_RECURSION_LIMIT",
|
||||||
"skip_on_s390x",
|
"skip_on_s390x",
|
||||||
|
"without_optimizer",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -2533,3 +2534,19 @@ skip_on_s390x = unittest.skipIf(hasattr(os, 'uname') and os.uname().machine == '
|
||||||
'skipped on s390x')
|
'skipped on s390x')
|
||||||
|
|
||||||
Py_TRACE_REFS = hasattr(sys, 'getobjects')
|
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
|
||||||
|
|
|
@ -2455,7 +2455,7 @@ class TestUops(unittest.TestCase):
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
|
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2470,7 +2470,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2485,7 +2485,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(range(10))
|
testfunc(range(20))
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2495,12 +2495,13 @@ class TestUops(unittest.TestCase):
|
||||||
def test_pop_jump_if_not_none(self):
|
def test_pop_jump_if_not_none(self):
|
||||||
def testfunc(a):
|
def testfunc(a):
|
||||||
for x in a:
|
for x in a:
|
||||||
|
x = None
|
||||||
if x is not None:
|
if x is not None:
|
||||||
x = 0
|
x = 0
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(range(10))
|
testfunc(range(20))
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2515,7 +2516,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2530,7 +2531,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2550,7 +2551,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2568,8 +2569,8 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
total = testfunc(10)
|
total = testfunc(20)
|
||||||
self.assertEqual(total, 45)
|
self.assertEqual(total, 190)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2589,9 +2590,9 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
a = list(range(10))
|
a = list(range(20))
|
||||||
total = testfunc(a)
|
total = testfunc(a)
|
||||||
self.assertEqual(total, 45)
|
self.assertEqual(total, 190)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2611,9 +2612,9 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
a = tuple(range(10))
|
a = tuple(range(20))
|
||||||
total = testfunc(a)
|
total = testfunc(a)
|
||||||
self.assertEqual(total, 45)
|
self.assertEqual(total, 190)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2647,7 +2648,7 @@ class TestUops(unittest.TestCase):
|
||||||
|
|
||||||
opt = _testinternalcapi.get_uop_optimizer()
|
opt = _testinternalcapi.get_uop_optimizer()
|
||||||
with temporary_optimizer(opt):
|
with temporary_optimizer(opt):
|
||||||
testfunc(10)
|
testfunc(20)
|
||||||
|
|
||||||
ex = get_first_executor(testfunc)
|
ex = get_first_executor(testfunc)
|
||||||
self.assertIsNotNone(ex)
|
self.assertIsNotNone(ex)
|
||||||
|
@ -2655,6 +2656,22 @@ class TestUops(unittest.TestCase):
|
||||||
self.assertIn("_PUSH_FRAME", uops)
|
self.assertIn("_PUSH_FRAME", uops)
|
||||||
self.assertIn("_BINARY_OP_ADD_INT", 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__":
|
if __name__ == "__main__":
|
||||||
|
|
|
@ -404,7 +404,7 @@ None >> PUSH_EXC_INFO
|
||||||
|
|
||||||
%4d LOAD_GLOBAL 0 (Exception)
|
%4d LOAD_GLOBAL 0 (Exception)
|
||||||
CHECK_EXC_MATCH
|
CHECK_EXC_MATCH
|
||||||
POP_JUMP_IF_FALSE 23 (to 80)
|
POP_JUMP_IF_FALSE 23 (to 82)
|
||||||
STORE_FAST 0 (e)
|
STORE_FAST 0 (e)
|
||||||
|
|
||||||
%4d LOAD_FAST 0 (e)
|
%4d LOAD_FAST 0 (e)
|
||||||
|
@ -492,7 +492,7 @@ dis_with = """\
|
||||||
%4d >> PUSH_EXC_INFO
|
%4d >> PUSH_EXC_INFO
|
||||||
WITH_EXCEPT_START
|
WITH_EXCEPT_START
|
||||||
TO_BOOL
|
TO_BOOL
|
||||||
POP_JUMP_IF_TRUE 1 (to 50)
|
POP_JUMP_IF_TRUE 1 (to 52)
|
||||||
RERAISE 2
|
RERAISE 2
|
||||||
>> POP_TOP
|
>> POP_TOP
|
||||||
POP_EXCEPT
|
POP_EXCEPT
|
||||||
|
@ -579,7 +579,7 @@ None JUMP_BACKWARD 11 (to 60)
|
||||||
>> CLEANUP_THROW
|
>> CLEANUP_THROW
|
||||||
>> END_SEND
|
>> END_SEND
|
||||||
TO_BOOL
|
TO_BOOL
|
||||||
POP_JUMP_IF_TRUE 1 (to 116)
|
POP_JUMP_IF_TRUE 1 (to 118)
|
||||||
RERAISE 2
|
RERAISE 2
|
||||||
>> POP_TOP
|
>> POP_TOP
|
||||||
POP_EXCEPT
|
POP_EXCEPT
|
||||||
|
@ -1273,7 +1273,8 @@ class DisTests(DisTestBase):
|
||||||
got = self.get_disassembly(loop_test, adaptive=True)
|
got = self.get_disassembly(loop_test, adaptive=True)
|
||||||
expected = dis_loop_test_quickened_code
|
expected = dis_loop_test_quickened_code
|
||||||
if _testinternalcapi.get_optimizer():
|
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)
|
self.do_disassembly_compare(got, expected)
|
||||||
|
|
||||||
@cpython_only
|
@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='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='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='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='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_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),
|
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_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='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='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='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=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='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=66, start_offset=66, starts_line=True, line_number=7, is_jump_target=True, 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=68, start_offset=68, starts_line=False, line_number=7, is_jump_target=False, 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=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=80, argrepr='to 80', offset=74, start_offset=74, 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=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='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=80, start_offset=80, starts_line=True, line_number=8, is_jump_target=True, 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=108, argrepr='to 108', offset=82, start_offset=82, starts_line=False, line_number=8, is_jump_target=False, 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=84, start_offset=84, starts_line=True, line_number=3, is_jump_target=True, 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=86, start_offset=86, starts_line=True, line_number=10, is_jump_target=False, 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=96, start_offset=96, starts_line=False, 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=98, start_offset=98, 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=106, start_offset=106, 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=108, start_offset=108, starts_line=True, line_number=11, is_jump_target=True, 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=110, start_offset=110, starts_line=False, line_number=11, is_jump_target=False, 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=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='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=120, start_offset=120, starts_line=True, line_number=12, is_jump_target=True, 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=130, start_offset=130, 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=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=132, start_offset=132, 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=140, start_offset=140, 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=142, start_offset=142, starts_line=True, line_number=13, 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=144, start_offset=144, starts_line=False, 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=146, start_offset=146, 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=150, start_offset=150, 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=152, start_offset=152, starts_line=True, line_number=14, 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=154, start_offset=154, starts_line=False, 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=156, start_offset=156, 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=166, argrepr='to 166', offset=160, start_offset=160, 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=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='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=166, start_offset=166, starts_line=True, line_number=16, is_jump_target=True, 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=168, start_offset=168, starts_line=False, line_number=16, is_jump_target=False, 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=170, start_offset=170, 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=178, argrepr='to 178', offset=174, start_offset=174, 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=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='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=178, start_offset=178, starts_line=True, line_number=11, is_jump_target=True, 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=180, start_offset=180, starts_line=False, line_number=11, is_jump_target=False, 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=194, argrepr='to 194', offset=188, start_offset=188, 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=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='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=194, start_offset=194, starts_line=True, line_number=19, is_jump_target=True, 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=204, start_offset=204, starts_line=False, line_number=19, is_jump_target=False, 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=206, start_offset=206, 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=214, start_offset=214, 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=216, start_offset=216, starts_line=True, line_number=20, is_jump_target=True, 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=218, start_offset=218, starts_line=True, line_number=21, is_jump_target=False, 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=220, start_offset=220, starts_line=False, 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=222, start_offset=222, 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=226, start_offset=226, 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=228, start_offset=228, starts_line=True, line_number=25, 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=230, start_offset=230, starts_line=False, 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=232, start_offset=232, 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=234, start_offset=234, starts_line=True, line_number=26, 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=244, start_offset=244, starts_line=False, 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=246, start_offset=246, 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=254, start_offset=254, 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=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=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=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=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=260, start_offset=260, 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=262, start_offset=262, 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=270, start_offset=270, 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=272, start_offset=272, starts_line=True, line_number=28, is_jump_target=True, 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=282, start_offset=282, starts_line=False, 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=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=284, start_offset=284, 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=292, start_offset=292, 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=294, start_offset=294, 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=296, start_offset=296, starts_line=True, line_number=25, 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=298, start_offset=298, starts_line=False, 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=300, start_offset=300, 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=312, argrepr='to 312', offset=308, start_offset=308, 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=310, start_offset=310, 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=312, start_offset=312, starts_line=False, line_number=25, is_jump_target=True, 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=314, start_offset=314, starts_line=False, line_number=25, is_jump_target=False, 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=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=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=318, start_offset=318, 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=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='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=324, start_offset=324, starts_line=True, line_number=None, 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=326, start_offset=326, starts_line=False, 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=328, start_offset=328, 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=330, start_offset=330, 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=332, start_offset=332, starts_line=True, line_number=22, 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=342, start_offset=342, starts_line=False, 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=376, argrepr='to 376', offset=344, start_offset=344, 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=346, start_offset=346, 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=348, start_offset=348, starts_line=True, line_number=23, 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=358, start_offset=358, starts_line=False, 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=360, start_offset=360, 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=368, start_offset=368, 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=370, start_offset=370, 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=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='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=376, start_offset=376, starts_line=True, line_number=22, is_jump_target=True, 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=378, start_offset=378, starts_line=True, line_number=None, is_jump_target=False, 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=380, start_offset=380, starts_line=False, 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=382, start_offset=382, 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=384, start_offset=384, 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=386, start_offset=386, starts_line=True, line_number=28, 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=396, start_offset=396, starts_line=False, 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=398, start_offset=398, 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=406, start_offset=406, 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=408, start_offset=408, 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=410, start_offset=410, 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=412, start_offset=412, 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=414, start_offset=414, 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
|
# 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["EXTENDED_ARG"], 0x01,
|
opcode.opmap["EXTENDED_ARG"], 0x01,
|
||||||
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
|
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
|
||||||
|
opcode.opmap["CACHE"], 0x00,
|
||||||
])
|
])
|
||||||
jump = list(dis._get_instructions_bytes(code))[-1]
|
jump = list(dis._get_instructions_bytes(code))[-1]
|
||||||
self.assertEqual(8, jump.offset)
|
self.assertEqual(8, jump.offset)
|
||||||
|
@ -2035,18 +2037,20 @@ class InstructionTests(InstructionTestCase):
|
||||||
opcode.opmap["LOAD_FAST"], 0x00,
|
opcode.opmap["LOAD_FAST"], 0x00,
|
||||||
opcode.opmap["EXTENDED_ARG"], 0x01,
|
opcode.opmap["EXTENDED_ARG"], 0x01,
|
||||||
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
|
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["EXTENDED_ARG"], 0x01,
|
||||||
opcode.opmap["EXTENDED_ARG"], 0x01,
|
opcode.opmap["EXTENDED_ARG"], 0x01,
|
||||||
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
|
opcode.opmap["POP_JUMP_IF_TRUE"], 0xFF,
|
||||||
|
opcode.opmap["CACHE"], 0x00,
|
||||||
])
|
])
|
||||||
instructions = list(dis._get_instructions_bytes(code))
|
instructions = list(dis._get_instructions_bytes(code))
|
||||||
# 1st jump
|
# 1st jump
|
||||||
self.assertEqual(4, instructions[2].offset)
|
self.assertEqual(4, instructions[2].offset)
|
||||||
self.assertEqual(2, instructions[2].start_offset)
|
self.assertEqual(2, instructions[2].start_offset)
|
||||||
# 2nd jump
|
# 2nd jump
|
||||||
self.assertEqual(12, instructions[6].offset)
|
self.assertEqual(14, instructions[6].offset)
|
||||||
self.assertEqual(6, instructions[6].start_offset)
|
self.assertEqual(8, instructions[6].start_offset)
|
||||||
|
|
||||||
def test_cache_offset_and_end_offset(self):
|
def test_cache_offset_and_end_offset(self):
|
||||||
code = bytes([
|
code = bytes([
|
||||||
|
|
|
@ -1348,10 +1348,10 @@ class TestBranchAndJumpEvents(CheckEvents):
|
||||||
|
|
||||||
self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
|
self.check_events(func, recorders = JUMP_AND_BRANCH_RECORDERS, expected = [
|
||||||
('branch', 'func', 2, 2),
|
('branch', 'func', 2, 2),
|
||||||
('branch', 'func', 3, 6),
|
('branch', 'func', 3, 4),
|
||||||
('jump', 'func', 6, 2),
|
('jump', 'func', 6, 2),
|
||||||
('branch', 'func', 2, 2),
|
('branch', 'func', 2, 2),
|
||||||
('branch', 'func', 3, 4),
|
('branch', 'func', 3, 3),
|
||||||
('jump', 'func', 4, 2),
|
('jump', 'func', 4, 2),
|
||||||
('branch', 'func', 2, 2)])
|
('branch', 'func', 2, 2)])
|
||||||
|
|
||||||
|
@ -1361,13 +1361,13 @@ class TestBranchAndJumpEvents(CheckEvents):
|
||||||
('line', 'func', 2),
|
('line', 'func', 2),
|
||||||
('branch', 'func', 2, 2),
|
('branch', 'func', 2, 2),
|
||||||
('line', 'func', 3),
|
('line', 'func', 3),
|
||||||
('branch', 'func', 3, 6),
|
('branch', 'func', 3, 4),
|
||||||
('line', 'func', 6),
|
('line', 'func', 6),
|
||||||
('jump', 'func', 6, 2),
|
('jump', 'func', 6, 2),
|
||||||
('line', 'func', 2),
|
('line', 'func', 2),
|
||||||
('branch', 'func', 2, 2),
|
('branch', 'func', 2, 2),
|
||||||
('line', 'func', 3),
|
('line', 'func', 3),
|
||||||
('branch', 'func', 3, 4),
|
('branch', 'func', 3, 3),
|
||||||
('line', 'func', 4),
|
('line', 'func', 4),
|
||||||
('jump', 'func', 4, 2),
|
('jump', 'func', 4, 2),
|
||||||
('line', 'func', 2),
|
('line', 'func', 2),
|
||||||
|
@ -1400,8 +1400,8 @@ class TestBranchAndJumpEvents(CheckEvents):
|
||||||
('line', 'func', 5),
|
('line', 'func', 5),
|
||||||
('line', 'meth', 1),
|
('line', 'meth', 1),
|
||||||
('jump', 'func', 5, 5),
|
('jump', 'func', 5, 5),
|
||||||
('jump', 'func', 5, '[offset=112]'),
|
('jump', 'func', 5, '[offset=114]'),
|
||||||
('branch', 'func', '[offset=118]', '[offset=120]'),
|
('branch', 'func', '[offset=120]', '[offset=122]'),
|
||||||
('line', 'get_events', 11)])
|
('line', 'get_events', 11)])
|
||||||
|
|
||||||
self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [
|
self.check_events(func, recorders = FLOW_AND_LINE_RECORDERS, expected = [
|
||||||
|
@ -1416,8 +1416,8 @@ class TestBranchAndJumpEvents(CheckEvents):
|
||||||
('line', 'meth', 1),
|
('line', 'meth', 1),
|
||||||
('return', None),
|
('return', None),
|
||||||
('jump', 'func', 5, 5),
|
('jump', 'func', 5, 5),
|
||||||
('jump', 'func', 5, '[offset=112]'),
|
('jump', 'func', 5, '[offset=114]'),
|
||||||
('branch', 'func', '[offset=118]', '[offset=120]'),
|
('branch', 'func', '[offset=120]', '[offset=122]'),
|
||||||
('return', None),
|
('return', None),
|
||||||
('line', 'get_events', 11)])
|
('line', 'get_events', 11)])
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import tempfile
|
||||||
import textwrap
|
import textwrap
|
||||||
import unittest
|
import unittest
|
||||||
from test import support
|
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 cmdline
|
||||||
from test.libregrtest import utils
|
from test.libregrtest import utils
|
||||||
from test.libregrtest import setup
|
from test.libregrtest import setup
|
||||||
|
@ -1018,12 +1018,13 @@ class ArgsTestCase(BaseTestCase):
|
||||||
stats=TestStats(4, 1),
|
stats=TestStats(4, 1),
|
||||||
forever=True)
|
forever=True)
|
||||||
|
|
||||||
|
@without_optimizer
|
||||||
def check_leak(self, code, what, *, multiprocessing=False):
|
def check_leak(self, code, what, *, multiprocessing=False):
|
||||||
test = self.create_test('huntrleaks', code=code)
|
test = self.create_test('huntrleaks', code=code)
|
||||||
|
|
||||||
filename = 'reflog.txt'
|
filename = 'reflog.txt'
|
||||||
self.addCleanup(os_helper.unlink, filename)
|
self.addCleanup(os_helper.unlink, filename)
|
||||||
cmd = ['--huntrleaks', '6:3:']
|
cmd = ['--huntrleaks', '3:3:']
|
||||||
if multiprocessing:
|
if multiprocessing:
|
||||||
cmd.append('-j1')
|
cmd.append('-j1')
|
||||||
cmd.append(test)
|
cmd.append(test)
|
||||||
|
@ -1032,7 +1033,7 @@ class ArgsTestCase(BaseTestCase):
|
||||||
stderr=subprocess.STDOUT)
|
stderr=subprocess.STDOUT)
|
||||||
self.check_executed_tests(output, [test], failed=test, stats=1)
|
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))
|
self.check_line(output, re.escape(line))
|
||||||
|
|
||||||
line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what)
|
line2 = '%s leaked [1, 1, 1] %s, sum=3\n' % (test, what)
|
||||||
|
|
|
@ -2292,14 +2292,22 @@ dummy_func(
|
||||||
goto resume_frame;
|
goto resume_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(POP_JUMP_IF_FALSE, (cond -- )) {
|
inst(POP_JUMP_IF_FALSE, (unused/1, cond -- )) {
|
||||||
assert(PyBool_Check(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));
|
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)) {
|
op(IS_NONE, (value -- b)) {
|
||||||
|
@ -3751,47 +3759,63 @@ dummy_func(
|
||||||
INSTRUMENTED_JUMP(next_instr-1, next_instr+1-oparg, PY_MONITORING_EVENT_JUMP);
|
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();
|
PyObject *cond = POP();
|
||||||
assert(PyBool_Check(cond));
|
assert(PyBool_Check(cond));
|
||||||
_Py_CODEUNIT *here = next_instr - 1;
|
_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);
|
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();
|
PyObject *cond = POP();
|
||||||
assert(PyBool_Check(cond));
|
assert(PyBool_Check(cond));
|
||||||
_Py_CODEUNIT *here = next_instr - 1;
|
_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);
|
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();
|
PyObject *value = POP();
|
||||||
_Py_CODEUNIT *here = next_instr-1;
|
_Py_CODEUNIT *here = next_instr - 1;
|
||||||
|
int flag = Py_IsNone(value);
|
||||||
int offset;
|
int offset;
|
||||||
if (Py_IsNone(value)) {
|
if (flag) {
|
||||||
offset = oparg;
|
offset = oparg;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
next_instr->cache = (next_instr->cache << 1) | flag;
|
||||||
|
#endif
|
||||||
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
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();
|
PyObject *value = POP();
|
||||||
_Py_CODEUNIT *here = next_instr-1;
|
_Py_CODEUNIT *here = next_instr-1;
|
||||||
int offset;
|
int offset;
|
||||||
if (Py_IsNone(value)) {
|
int nflag = Py_IsNone(value);
|
||||||
|
if (nflag) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
offset = oparg;
|
offset = oparg;
|
||||||
}
|
}
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
next_instr->cache = (next_instr->cache << 1) | !nflag;
|
||||||
|
#endif
|
||||||
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
58
Python/generated_cases.c.h
generated
58
Python/generated_cases.c.h
generated
|
@ -2996,8 +2996,13 @@
|
||||||
PyObject *cond;
|
PyObject *cond;
|
||||||
cond = stack_pointer[-1];
|
cond = stack_pointer[-1];
|
||||||
assert(PyBool_Check(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);
|
||||||
STACK_SHRINK(1);
|
STACK_SHRINK(1);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3005,8 +3010,13 @@
|
||||||
PyObject *cond;
|
PyObject *cond;
|
||||||
cond = stack_pointer[-1];
|
cond = stack_pointer[-1];
|
||||||
assert(PyBool_Check(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);
|
||||||
STACK_SHRINK(1);
|
STACK_SHRINK(1);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3029,9 +3039,14 @@
|
||||||
cond = b;
|
cond = b;
|
||||||
{
|
{
|
||||||
assert(PyBool_Check(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);
|
||||||
}
|
}
|
||||||
STACK_SHRINK(1);
|
STACK_SHRINK(1);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3054,9 +3069,14 @@
|
||||||
cond = b;
|
cond = b;
|
||||||
{
|
{
|
||||||
assert(PyBool_Check(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);
|
||||||
}
|
}
|
||||||
STACK_SHRINK(1);
|
STACK_SHRINK(1);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4921,8 +4941,13 @@
|
||||||
PyObject *cond = POP();
|
PyObject *cond = POP();
|
||||||
assert(PyBool_Check(cond));
|
assert(PyBool_Check(cond));
|
||||||
_Py_CODEUNIT *here = next_instr - 1;
|
_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);
|
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4930,23 +4955,33 @@
|
||||||
PyObject *cond = POP();
|
PyObject *cond = POP();
|
||||||
assert(PyBool_Check(cond));
|
assert(PyBool_Check(cond));
|
||||||
_Py_CODEUNIT *here = next_instr - 1;
|
_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);
|
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
|
TARGET(INSTRUMENTED_POP_JUMP_IF_NONE) {
|
||||||
PyObject *value = POP();
|
PyObject *value = POP();
|
||||||
_Py_CODEUNIT *here = next_instr-1;
|
_Py_CODEUNIT *here = next_instr - 1;
|
||||||
|
int flag = Py_IsNone(value);
|
||||||
int offset;
|
int offset;
|
||||||
if (Py_IsNone(value)) {
|
if (flag) {
|
||||||
offset = oparg;
|
offset = oparg;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
next_instr->cache = (next_instr->cache << 1) | flag;
|
||||||
|
#endif
|
||||||
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4954,14 +4989,19 @@
|
||||||
PyObject *value = POP();
|
PyObject *value = POP();
|
||||||
_Py_CODEUNIT *here = next_instr-1;
|
_Py_CODEUNIT *here = next_instr-1;
|
||||||
int offset;
|
int offset;
|
||||||
if (Py_IsNone(value)) {
|
int nflag = Py_IsNone(value);
|
||||||
|
if (nflag) {
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Py_DECREF(value);
|
Py_DECREF(value);
|
||||||
offset = oparg;
|
offset = oparg;
|
||||||
}
|
}
|
||||||
|
#if ENABLE_SPECIALIZATION
|
||||||
|
next_instr->cache = (next_instr->cache << 1) | !nflag;
|
||||||
|
#endif
|
||||||
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
INSTRUMENTED_JUMP(here, next_instr + offset, PY_MONITORING_EVENT_BRANCH);
|
||||||
|
next_instr += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include "opcode_ids.h"
|
#include "opcode_ids.h"
|
||||||
|
|
||||||
|
#include "pycore_bitutils.h" // _Py_popcount32
|
||||||
#include "pycore_call.h"
|
#include "pycore_call.h"
|
||||||
#include "pycore_code.h" // _PyCode_Clear_Executors()
|
#include "pycore_code.h" // _PyCode_Clear_Executors()
|
||||||
#include "pycore_frame.h"
|
#include "pycore_frame.h"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "opcode.h"
|
#include "opcode.h"
|
||||||
#include "pycore_interp.h"
|
#include "pycore_interp.h"
|
||||||
|
#include "pycore_bitutils.h" // _Py_popcount32()
|
||||||
#include "pycore_opcode_metadata.h" // _PyOpcode_OpName()
|
#include "pycore_opcode_metadata.h" // _PyOpcode_OpName()
|
||||||
#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE
|
#include "pycore_opcode_utils.h" // MAX_REAL_OPCODE
|
||||||
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
|
#include "pycore_optimizer.h" // _Py_uop_analyze_and_optimize()
|
||||||
|
@ -501,7 +502,7 @@ translate_bytecode_to_trace(
|
||||||
code->co_firstlineno,
|
code->co_firstlineno,
|
||||||
2 * INSTR_IP(initial_instr, code));
|
2 * INSTR_IP(initial_instr, code));
|
||||||
|
|
||||||
top: // Jump here after _PUSH_FRAME
|
top: // Jump here after _PUSH_FRAME or likely branches
|
||||||
for (;;) {
|
for (;;) {
|
||||||
RESERVE_RAW(2, "epilogue"); // Always need space for SAVE_IP and EXIT_TRACE
|
RESERVE_RAW(2, "epilogue"); // Always need space for SAVE_IP and EXIT_TRACE
|
||||||
ADD_TO_TRACE(SAVE_IP, INSTR_IP(instr, code), 0);
|
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:
|
case POP_JUMP_IF_TRUE:
|
||||||
{
|
{
|
||||||
pop_jump_if_bool:
|
pop_jump_if_bool:
|
||||||
// Assume jump unlikely (TODO: handle jump likely case)
|
|
||||||
RESERVE(1, 2);
|
RESERVE(1, 2);
|
||||||
_Py_CODEUNIT *target_instr =
|
|
||||||
instr + 1 + _PyOpcode_Caches[_PyOpcode_Deopt[opcode]] + oparg;
|
|
||||||
max_length -= 2; // Really the start of the stubs
|
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;
|
_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_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);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -927,6 +941,6 @@ PyUnstable_Optimizer_NewUOpOptimizer(void)
|
||||||
opt->resume_threshold = UINT16_MAX;
|
opt->resume_threshold = UINT16_MAX;
|
||||||
// Need at least 3 iterations to settle specializations.
|
// Need at least 3 iterations to settle specializations.
|
||||||
// A few lower bits of the counter are reserved for other flags.
|
// 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;
|
return (PyObject *)opt;
|
||||||
}
|
}
|
||||||
|
|
|
@ -338,9 +338,23 @@ _PyCode_Quicken(PyCodeObject *code)
|
||||||
assert(opcode < MIN_INSTRUMENTED_OPCODE);
|
assert(opcode < MIN_INSTRUMENTED_OPCODE);
|
||||||
int caches = _PyOpcode_Caches[opcode];
|
int caches = _PyOpcode_Caches[opcode];
|
||||||
if (caches) {
|
if (caches) {
|
||||||
// JUMP_BACKWARD counter counts up from 0 until it is > backedge_threshold
|
// The initial value depends on the opcode
|
||||||
instructions[i + 1].cache =
|
int initial_value;
|
||||||
opcode == JUMP_BACKWARD ? 0 : adaptive_counter_warmup();
|
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;
|
i += caches;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,10 +549,20 @@ class Generator(Analyzer):
|
||||||
"=",
|
"=",
|
||||||
";",
|
";",
|
||||||
):
|
):
|
||||||
for name, _ in self.families.items():
|
family_member_names: set[str] = set()
|
||||||
instr = self.instrs[name]
|
for family in self.families.values():
|
||||||
if instr.cache_offset > 0:
|
family_member_names.update(family.members)
|
||||||
self.out.emit(f'[{name}] = {instr.cache_offset},')
|
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:
|
# Irregular case:
|
||||||
self.out.emit('[JUMP_BACKWARD] = 1,')
|
self.out.emit('[JUMP_BACKWARD] = 1,')
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue