Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 66c75a2

Browse files
Merge remote-tracking branch 'upstream/main' into add_checks_tp_version
2 parents ba81186 + 3a60bfe commit 66c75a2

6 files changed

Lines changed: 105 additions & 40 deletions

File tree

Include/opcode.h

Lines changed: 26 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Lib/opcode.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,8 @@ def jabs_op(name, op):
259259
"CALL_NO_KW_PY_SIMPLE",
260260
"CALL_NO_KW_LIST_APPEND",
261261
"CALL_NO_KW_METHOD_DESCRIPTOR_O",
262+
"CALL_NO_KW_TYPE_1",
263+
"CALL_NO_KW_BUILTIN_CLASS_1",
262264
"CALL_NO_KW_METHOD_DESCRIPTOR_FAST",
263265
"JUMP_ABSOLUTE_QUICK",
264266
"LOAD_ATTR_ADAPTIVE",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Specialize the CALL_FUNCTION instruction for calls to builtin types with a
2+
single argument. Speeds up ``range(x)``, ``list(x)``, and specifically
3+
``type(obj)``.

Python/ceval.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4854,6 +4854,41 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
48544854
goto start_frame;
48554855
}
48564856

4857+
TARGET(CALL_NO_KW_TYPE_1) {
4858+
assert(STACK_ADJUST_IS_RESET);
4859+
assert(GET_CACHE()->adaptive.original_oparg == 1);
4860+
PyObject *obj = TOP();
4861+
PyObject *callable = SECOND();
4862+
DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL_NO_KW);
4863+
PyObject *res = Py_NewRef(Py_TYPE(obj));
4864+
STACK_SHRINK(1);
4865+
Py_DECREF(callable);
4866+
Py_DECREF(obj);
4867+
SET_TOP(res);
4868+
DISPATCH();
4869+
}
4870+
4871+
TARGET(CALL_NO_KW_BUILTIN_CLASS_1) {
4872+
assert(STACK_ADJUST_IS_RESET);
4873+
SpecializedCacheEntry *caches = GET_CACHE();
4874+
_PyAdaptiveEntry *cache0 = &caches[0].adaptive;
4875+
assert(cache0->original_oparg == 1);
4876+
PyObject *callable = SECOND();
4877+
PyObject *arg = TOP();
4878+
DEOPT_IF(!PyType_Check(callable), CALL_NO_KW);
4879+
PyTypeObject *tp = (PyTypeObject *)callable;
4880+
DEOPT_IF(tp->tp_version_tag != cache0->version, CALL_NO_KW);
4881+
STACK_SHRINK(1);
4882+
PyObject *res = tp->tp_vectorcall((PyObject *)tp, stack_pointer, 1, NULL);
4883+
SET_TOP(res);
4884+
Py_DECREF(tp);
4885+
Py_DECREF(arg);
4886+
if (res == NULL) {
4887+
goto error;
4888+
}
4889+
DISPATCH();
4890+
}
4891+
48574892
TARGET(CALL_NO_KW_BUILTIN_O) {
48584893
assert(cframe.use_tracing == 0);
48594894
assert(STACK_ADJUST_IS_RESET);

Python/opcode_targets.h

Lines changed: 14 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Python/specialize.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,10 @@ initial_counter_value(void) {
491491
#define SPEC_FAIL_PYCFUNCTION_NOARGS 16
492492
#define SPEC_FAIL_BAD_CALL_FLAGS 17
493493
#define SPEC_FAIL_CLASS 18
494-
#define SPEC_FAIL_C_METHOD_CALL 19
495-
#define SPEC_FAIL_METHDESCR_NON_METHOD 20
494+
#define SPEC_FAIL_PYTHON_CLASS 19
495+
#define SPEC_FAIL_C_METHOD_CALL 20
496+
#define SPEC_FAIL_METHDESCR_NON_METHOD 21
497+
#define SPEC_FAIL_METHOD_CALL_CLASS 22
496498

497499
/* COMPARE_OP */
498500
#define SPEC_FAIL_STRING_COMPARE 13
@@ -1292,6 +1294,27 @@ specialize_class_call(
12921294
PyObject *callable, _Py_CODEUNIT *instr,
12931295
int nargs, SpecializedCacheEntry *cache)
12941296
{
1297+
assert(PyType_Check(callable));
1298+
PyTypeObject *tp = (PyTypeObject *)callable;
1299+
if (_Py_OPCODE(instr[-1]) == PRECALL_METHOD) {
1300+
SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_METHOD_CALL_CLASS);
1301+
return -1;
1302+
}
1303+
if (tp->tp_new == PyBaseObject_Type.tp_new) {
1304+
SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_PYTHON_CLASS);
1305+
return -1;
1306+
}
1307+
if (nargs == 1) {
1308+
if (tp == &PyType_Type) {
1309+
*instr = _Py_MAKECODEUNIT(CALL_NO_KW_TYPE_1, _Py_OPARG(*instr));
1310+
return 0;
1311+
}
1312+
if ((tp->tp_flags & Py_TPFLAGS_IMMUTABLETYPE) && tp->tp_vectorcall != NULL) {
1313+
cache->adaptive.version = tp->tp_version_tag;
1314+
*instr = _Py_MAKECODEUNIT(CALL_NO_KW_BUILTIN_CLASS_1, _Py_OPARG(*instr));
1315+
return 0;
1316+
}
1317+
}
12951318
SPECIALIZATION_FAIL(CALL_NO_KW, SPEC_FAIL_CLASS);
12961319
return -1;
12971320
}

0 commit comments

Comments
 (0)