8000 Get quickened in dis · python/cpython@e896538 · GitHub
[go: up one dir, main page]

Skip to content

Commit e896538

Browse files
committed
Get quickened in dis
1 parent 794536f commit e896538

File tree

3 files changed

+73
-47
lines changed

3 files changed

+73
-47
lines changed

Include/internal/pycore_code.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ typedef struct {
9797
/* We want to compare to zero for efficiency, so we offset values accordingly */
9898
#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY)
9999

100-
PyAPI_FUNC(void) _PyCode_Quicken(PyCodeObject *code);
100+
void _PyCode_Quicken(PyCodeObject *code);
101101

102102
static inline void
103103
_PyCode_Warmup(PyCodeObject *code)

Lib/test/test_dis.py

Lines changed: 72 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import sys
88
import types
99
import unittest
10-
from test.support import captured_stdout, requires_debug_ranges, import_helper, cpython_only
10+
from test.support import captured_stdout, requires_debug_ranges, cpython_only
1111
from test.support.bytecode_helper import BytecodeTestCase
1212

1313
import opcode
@@ -583,7 +583,7 @@ def foo(x):
583583
_h.__code__.co_firstlineno + 3,
584584
)
585585

586-
def load_test(x, y):
586+
def load_test(x, y=0):
587587
a, b = x, y
588588
return a, b
589589

@@ -603,10 +603,37 @@ def load_test(x, y):
603603
load_test.__code__.co_firstlineno + 1,
604604
load_test.__code__.co_firstlineno + 2)
605605

606-
def binary_test(x, y):
607-
a = x + y
608-
b = x - y
609-
return a + b
606+
def loop_test():
607+
for i in [1, 2, 3] * 3:
608+
load_test(i)
609+
610+
dis_loop_test_quickened_code = """\
611+
%3d 0 RESUME_QUICK 0
612+
613+
%3d 2 BUILD_LIST 0
614+
4 LOAD_CONST 1 ((1, 2, 3))
615+
6 LIST_EXTEND 1
616+
8 LOAD_CONST 2 (3)
617+
10 BINARY_OP_ADAPTIVE 5 (*)
618+
14 GET_ITER
619+
16 FOR_ITER 17 (to 52)
620+
18 STORE_FAST 0 (i)
621+
622+
%3d 20 LOAD_GLOBAL_MODULE 1 (NULL + load_test)
623+
32 LOAD_FAST 0 (i)
624+
34 PRECALL_PYFUNC 1
625+
38 CALL_PY_WITH_DEFAULTS 1
626+
48 POP_TOP
627+
50 JUMP_BACKWARD_QUICK 18 (to 16)
628+
629+
%3d >> 52 LOAD_CONST 0 (None)
630+
54 RETURN_VALUE
631+
""" % (loop_test.__code__.co_firstlineno,
632+
loop_test.__code__.co_firstlineno + 1,
633+
loop_test.__code__.co_firstlineno + 2,
634+
loop_test.__code__.co_firstlineno + 1,)
635+
636+
QUICKENING_WARMUP_DELAY = 8
610637

611638
class DisTestBase(unittest.TestCase):
612639
"Common utilities for DisTests and TestDisTraceback"
@@ -887,11 +914,14 @@ def check(expected, **kwargs):
887914
check(dis_nested_2, depth=None)
888915
check(dis_nested_2)
889916

890-
_testinternalcapi = import_helper.import_module('_testinternalcapi')
917+
@staticmethod
918+
def code_quicken(f, times=QUICKENING_WARMUP_DELAY):
919+
for _ in range(times):
920+
f()
891921

892922
@cpython_only
893923
def test_super_instructions(self):
894-
self._testinternalcapi.code_quicken(load_test.__code__)
924+
self.code_quicken(lambda: load_test(0, 0))
895925
got = self.get_disassembly(load_test, adaptive=True)
896926
self.do_disassembly_compare(got, dis_load_test_quickened_code, True)
897927

@@ -906,35 +936,46 @@ def test_binary_specialize(self):
906936
10 RETURN_VALUE
907937
"""
908938
co_int = compile('a + b', "<int>", "eval")
909-
self._testinternalcapi.code_quicken(co_int)
910-
got = self.get_disassembly(co_int, adaptive=True)
911-
self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADAPTIVE 0 (+)", True)
912-
exec(co_int, {}, {'a': 1, 'b': 2})
939+
self.code_quicken(lambda: exec(co_int, {}, {'a': 1, 'b': 2}))
913940
got = self.get_disassembly(co_int, adaptive=True)
914941
self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_INT 0 (+)", True)
915942

916943
co_unicode = compile('a + b', "<unicode>", "eval")
917-
self._testinternalcapi.code_quicken(co_unicode)
918-
exec(co_unicode, {}, {'a': 'a', 'b': 'b'})
944+
self.code_quicken(lambda: exec(co_unicode, {}, {'a': 'a', 'b': 'b'}))
919945
got = self.get_disassembly(co_unicode, adaptive=True)
920946
self.do_disassembly_compare(got, binary_op_quicken % "BINARY_OP_ADD_UNICODE 0 (+)", True)
921947

948+
binary_subsrc_quicken = """\
949+
0 RESUME_QUICK 0
950+
951+
1 2 LOAD_NAME 0 (a)
952+
4 LOAD_CONST 0 (0)
953+
6 %s
954+
16 RETURN_VALUE
955+
"""
956+
co_list = compile('a[0]', "<list>", "eval")
957+
self.code_quicken(lambda: exec(co_list, {}, {'a': [0]}))
958+
got = self.get_disassembly(co_list, adaptive=True)
959+
self.do_disassembly_compare(got, binary_subsrc_quicken % "BINARY_SUBSCR_LIST_INT", True)
960+
961+
co_dict = compile('a[0]', "<dict>", "eval")
962+
self.code_quicken(lambda: exec(co_dict, {}, {'a': {0: '1'}}))
963+
got = self.get_disassembly(co_dict, adaptive=True)
964+
self.do_disassembly_compare(got, binary_subsrc_quicken % "BINARY_SUBSCR_DICT", True)
965+
922966
@cpython_only
923967
def test_load_attr_specialize(self):
924968
load_attr_quicken = """\
925969
0 RESUME_QUICK 0
926970
927971
1 2 LOAD_CONST 0 ('a')
928-
4 %s
972+
4 LOAD_ATTR_SLOT 0 (__class__)
929973
14 RETURN_VALUE
930974
"""
931975
co = compile("'a'.__class__", "", "eval")
932-
self._testinternalcapi.code_quicken(co)
976+
self.code_quicken(lambda: exec(co, {}, {}))
933977
got = self.get_disassembly(co, adaptive=True)
934-
self.do_disassembly_compare(got, load_attr_quicken % "LOAD_ATTR_ADAPTIVE 0 (__class__)", True)
935-
exec(co, {}, {})
936-
got = self.get_disassembly(co, adaptive=True)
937-
self.do_disassembly_compare(got, load_attr_quicken % "LOAD_ATTR_SLOT 0 (__class__)", True)
978+
self.do_disassembly_compare(got, load_attr_quicken, True)
938979

939980
@cpython_only
940981
def test_call_specialize(self):
@@ -944,21 +985,21 @@ def test_call_specialize(self):
944985
1 2 PUSH_NULL
945986
4 LOAD_NAME 0 (str)
946987
6 LOAD_CONST 0 (1)
947-
8 %s
948-
12 %s
988+
8 PRECALL_NO_KW_STR_1 1
989+
12 CALL_ADAPTIVE 1
949990
22 RETURN_VALUE
950991
"""
951992
co = compile("str(1)", "", "eval")
952-
self._testinternalcapi.code_quicken(co)
953-
got = self.get_disassembly(co, adaptive=True)
954-
self.do_disassembly_compare(got, call_quicken % (
955-
"PRECALL_ADAPTIVE 1",
956-
"CALL_ADAPTIVE 1"), True)
957-
exec(co, {}, {})
993+
self.code_quicken(lambda: exec(co, {}, {}))
958994
got = self.get_disassembly(co, adaptive=True)
959-
self.do_disassembly_compare(got, call_quicken % (
960-
"PRECALL_NO_KW_STR_1 1",
961-
"CALL_ADAPTIVE 1"), True)
995+
self.do_disassembly_compare(got, call_quicken, True)
996+
997+
@cpython_only
998+
def test_loop_quicken(self):
999+
# Loop can trigger a quicken where the loop is located
1000+
self.code_quicken(loop_test, 1)
1001+
got = self.get_disassembly(loop_test, adaptive=True)
1002+
self.do_disassembly_compare(got, dis_loop_test_quickened_code, True)
9621003

9631004

9641005
class DisWithFileTests(DisTests):

Modules/_testinternalcapi.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include "Python.h"
1515
#include "pycore_atomic_funcs.h" // _Py_atomic_int_get()
1616
#include "pycore_bitutils.h" // _Py_bswap32()
17-
#include "pycore_code.h" // _PyCode_Quicken
1817
#include "pycore_fileutils.h" // _Py_normpath
1918
#include "pycore_gc.h" // PyGC_Head
2019
#include "pycore_hashtable.h" // _Py_hashtable_new()
@@ -492,19 +491,6 @@ decode_locale_ex(PyObject *self, PyObject *args)
492491
return res;
493492
}
494493

495-
static PyObject *
496-
code_quicken(PyObject *self, PyObject *code)
497-
{
498-
if (!PyCode_Check(code)) {
499-
PyErr_SetString(PyExc_TypeError, "argument must be a code object");
500-
return NULL;
501-
}
502-
PyCodeObject *co = (PyCodeObject *) code;
503-
co->co_warmup = 0;
504-
_PyCode_Quicken(co);
505-
Py_RETURN_NONE;
506-
}
507-
508494

509495
static PyMethodDef TestMethods[] = {
510496
{"get_configs", get_configs, METH_NOARGS},
@@ -522,7 +508,6 @@ static PyMethodDef TestMethods[] = {
522508
{"get_getpath_codeobject", get_getpath_codeobject, METH_NOARGS, NULL},
523509
{"EncodeLocaleEx", encode_locale_ex, METH_VARARGS},
524510
{"DecodeLocaleEx", decode_locale_ex, METH_VARARGS},
525-
{"code_quicken", code_quicken, METH_O, NULL},
526511
{NULL, NULL} /* sentinel */
527512
};
528513

0 commit comments

Comments
 (0)
0