mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
GH-116468: Use constants instead of oparg
in stack effects when oparg
is known to be a constant. (GH-116469)
This commit is contained in:
parent
8d7fde655f
commit
4e5df2013f
5 changed files with 98 additions and 108 deletions
10
Include/internal/pycore_opcode_metadata.h
generated
10
Include/internal/pycore_opcode_metadata.h
generated
|
@ -116,7 +116,7 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
||||||
case CALL_LEN:
|
case CALL_LEN:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case CALL_LIST_APPEND:
|
case CALL_LIST_APPEND:
|
||||||
return 2 + oparg;
|
return 3;
|
||||||
case CALL_METHOD_DESCRIPTOR_FAST:
|
case CALL_METHOD_DESCRIPTOR_FAST:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
|
case CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS:
|
||||||
|
@ -130,11 +130,11 @@ int _PyOpcode_num_popped(int opcode, int oparg) {
|
||||||
case CALL_PY_WITH_DEFAULTS:
|
case CALL_PY_WITH_DEFAULTS:
|
||||||
return 2 + oparg;
|
return 2 + oparg;
|
||||||
case CALL_STR_1:
|
case CALL_STR_1:
|
||||||
return 2 + oparg;
|
return 3;
|
||||||
case CALL_TUPLE_1:
|
case CALL_TUPLE_1:
|
||||||
return 2 + oparg;
|
return 3;
|
||||||
case CALL_TYPE_1:
|
case CALL_TYPE_1:
|
||||||
return 2 + oparg;
|
return 3;
|
||||||
case CHECK_EG_MATCH:
|
case CHECK_EG_MATCH:
|
||||||
return 2;
|
return 2;
|
||||||
case CHECK_EXC_MATCH:
|
case CHECK_EXC_MATCH:
|
||||||
|
@ -879,7 +879,7 @@ int _PyOpcode_num_pushed(int opcode, int oparg) {
|
||||||
case UNPACK_SEQUENCE_TUPLE:
|
case UNPACK_SEQUENCE_TUPLE:
|
||||||
return oparg;
|
return oparg;
|
||||||
case UNPACK_SEQUENCE_TWO_TUPLE:
|
case UNPACK_SEQUENCE_TWO_TUPLE:
|
||||||
return oparg;
|
return 2;
|
||||||
case WITH_EXCEPT_START:
|
case WITH_EXCEPT_START:
|
||||||
return 5;
|
return 5;
|
||||||
case YIELD_VALUE:
|
case YIELD_VALUE:
|
||||||
|
|
|
@ -129,6 +129,8 @@ dummy_func(
|
||||||
PyObject *top;
|
PyObject *top;
|
||||||
PyObject *type;
|
PyObject *type;
|
||||||
PyObject *typevars;
|
PyObject *typevars;
|
||||||
|
PyObject *val0;
|
||||||
|
PyObject *val1;
|
||||||
int values_or_none;
|
int values_or_none;
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
|
@ -1223,13 +1225,13 @@ dummy_func(
|
||||||
|
|
||||||
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE;
|
macro(UNPACK_SEQUENCE) = _SPECIALIZE_UNPACK_SEQUENCE + _UNPACK_SEQUENCE;
|
||||||
|
|
||||||
inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- values[oparg])) {
|
inst(UNPACK_SEQUENCE_TWO_TUPLE, (unused/1, seq -- val1, val0)) {
|
||||||
|
assert(oparg == 2);
|
||||||
DEOPT_IF(!PyTuple_CheckExact(seq));
|
DEOPT_IF(!PyTuple_CheckExact(seq));
|
||||||
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2);
|
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2);
|
||||||
assert(oparg == 2);
|
|
||||||
STAT_INC(UNPACK_SEQUENCE, hit);
|
STAT_INC(UNPACK_SEQUENCE, hit);
|
||||||
values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
||||||
values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
||||||
DECREF_INPUTS();
|
DECREF_INPUTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3236,39 +3238,33 @@ dummy_func(
|
||||||
DISPATCH_INLINED(new_frame);
|
DISPATCH_INLINED(new_frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
|
inst(CALL_TYPE_1, (unused/1, unused/2, callable, null, arg -- res)) {
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL);
|
DEOPT_IF(null != NULL);
|
||||||
PyObject *obj = args[0];
|
|
||||||
DEOPT_IF(callable != (PyObject *)&PyType_Type);
|
DEOPT_IF(callable != (PyObject *)&PyType_Type);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
res = Py_NewRef(Py_TYPE(obj));
|
res = Py_NewRef(Py_TYPE(arg));
|
||||||
Py_DECREF(obj);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyType_Type); // I.e., callable
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(CALL_STR_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
|
inst(CALL_STR_1, (unused/1, unused/2, callable, null, arg -- res)) {
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL);
|
DEOPT_IF(null != NULL);
|
||||||
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type);
|
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PyObject_Str(arg);
|
res = PyObject_Str(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyUnicode_Type); // I.e., callable
|
|
||||||
ERROR_IF(res == NULL, error);
|
ERROR_IF(res == NULL, error);
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
}
|
}
|
||||||
|
|
||||||
inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, args[oparg] -- res)) {
|
inst(CALL_TUPLE_1, (unused/1, unused/2, callable, null, arg -- res)) {
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL);
|
DEOPT_IF(null != NULL);
|
||||||
DEOPT_IF(callable != (PyObject *)&PyTuple_Type);
|
DEOPT_IF(callable != (PyObject *)&PyTuple_Type);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PySequence_Tuple(arg);
|
res = PySequence_Tuple(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyTuple_Type); // I.e., tuple
|
|
||||||
ERROR_IF(res == NULL, error);
|
ERROR_IF(res == NULL, error);
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
}
|
}
|
||||||
|
@ -3490,14 +3486,14 @@ dummy_func(
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is secretly a super-instruction
|
// This is secretly a super-instruction
|
||||||
tier1 inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, args[oparg] -- unused)) {
|
tier1 inst(CALL_LIST_APPEND, (unused/1, unused/2, callable, self, arg -- unused)) {
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
DEOPT_IF(callable != interp->callable_cache.list_append);
|
DEOPT_IF(callable != interp->callable_cache.list_append);
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
DEOPT_IF(!PyList_Check(self));
|
DEOPT_IF(!PyList_Check(self));
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) {
|
if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) {
|
||||||
goto pop_1_error; // Since arg is DECREF'ed already
|
goto pop_1_error; // Since arg is DECREF'ed already
|
||||||
}
|
}
|
||||||
Py_DECREF(self);
|
Py_DECREF(self);
|
||||||
|
|
64
Python/executor_cases.c.h
generated
64
Python/executor_cases.c.h
generated
|
@ -1061,18 +1061,20 @@
|
||||||
|
|
||||||
case _UNPACK_SEQUENCE_TWO_TUPLE: {
|
case _UNPACK_SEQUENCE_TWO_TUPLE: {
|
||||||
PyObject *seq;
|
PyObject *seq;
|
||||||
PyObject **values;
|
PyObject *val1;
|
||||||
|
PyObject *val0;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
seq = stack_pointer[-1];
|
seq = stack_pointer[-1];
|
||||||
values = &stack_pointer[-1];
|
assert(oparg == 2);
|
||||||
if (!PyTuple_CheckExact(seq)) goto deoptimize;
|
if (!PyTuple_CheckExact(seq)) goto deoptimize;
|
||||||
if (PyTuple_GET_SIZE(seq) != 2) goto deoptimize;
|
if (PyTuple_GET_SIZE(seq) != 2) goto deoptimize;
|
||||||
assert(oparg == 2);
|
|
||||||
STAT_INC(UNPACK_SEQUENCE, hit);
|
STAT_INC(UNPACK_SEQUENCE, hit);
|
||||||
values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
||||||
values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
||||||
Py_DECREF(seq);
|
Py_DECREF(seq);
|
||||||
stack_pointer += -1 + oparg;
|
stack_pointer[-1] = val1;
|
||||||
|
stack_pointer[0] = val0;
|
||||||
|
stack_pointer += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3057,71 +3059,65 @@
|
||||||
/* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 */
|
/* _CALL_PY_WITH_DEFAULTS is not a viable micro-op for tier 2 */
|
||||||
|
|
||||||
case _CALL_TYPE_1: {
|
case _CALL_TYPE_1: {
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
if (null != NULL) goto deoptimize;
|
if (null != NULL) goto deoptimize;
|
||||||
PyObject *obj = args[0];
|
|
||||||
if (callable != (PyObject *)&PyType_Type) goto deoptimize;
|
if (callable != (PyObject *)&PyType_Type) goto deoptimize;
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
res = Py_NewRef(Py_TYPE(obj));
|
res = Py_NewRef(Py_TYPE(arg));
|
||||||
Py_DECREF(obj);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyType_Type); // I.e., callable
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case _CALL_STR_1: {
|
case _CALL_STR_1: {
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
if (null != NULL) goto deoptimize;
|
if (null != NULL) goto deoptimize;
|
||||||
if (callable != (PyObject *)&PyUnicode_Type) goto deoptimize;
|
if (callable != (PyObject *)&PyUnicode_Type) goto deoptimize;
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PyObject_Str(arg);
|
res = PyObject_Str(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyUnicode_Type); // I.e., callable
|
if (res == NULL) goto pop_3_error_tier_two;
|
||||||
if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; }
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case _CALL_TUPLE_1: {
|
case _CALL_TUPLE_1: {
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
oparg = CURRENT_OPARG();
|
oparg = CURRENT_OPARG();
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
if (null != NULL) goto deoptimize;
|
if (null != NULL) goto deoptimize;
|
||||||
if (callable != (PyObject *)&PyTuple_Type) goto deoptimize;
|
if (callable != (PyObject *)&PyTuple_Type) goto deoptimize;
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PySequence_Tuple(arg);
|
res = PySequence_Tuple(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyTuple_Type); // I.e., tuple
|
if (res == NULL) goto pop_3_error_tier_two;
|
||||||
if (res == NULL) { stack_pointer += -2 - oparg; goto error_tier_two; }
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
74
Python/generated_cases.c.h
generated
74
Python/generated_cases.c.h
generated
|
@ -1472,21 +1472,21 @@
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_LIST_APPEND);
|
INSTRUCTION_STATS(CALL_LIST_APPEND);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *self;
|
PyObject *self;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
/* Skip 2 cache entries */
|
/* Skip 2 cache entries */
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
self = stack_pointer[-1 - oparg];
|
self = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
PyInterpreterState *interp = tstate->interp;
|
PyInterpreterState *interp = tstate->interp;
|
||||||
DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
|
DEOPT_IF(callable != interp->callable_cache.list_append, CALL);
|
||||||
assert(self != NULL);
|
assert(self != NULL);
|
||||||
DEOPT_IF(!PyList_Check(self), CALL);
|
DEOPT_IF(!PyList_Check(self), CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
if (_PyList_AppendTakeRef((PyListObject *)self, args[0]) < 0) {
|
if (_PyList_AppendTakeRef((PyListObject *)self, arg) < 0) {
|
||||||
goto pop_1_error; // Since arg is DECREF'ed already
|
goto pop_1_error; // Since arg is DECREF'ed already
|
||||||
}
|
}
|
||||||
Py_DECREF(self);
|
Py_DECREF(self);
|
||||||
|
@ -1810,26 +1810,24 @@
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_STR_1);
|
INSTRUCTION_STATS(CALL_STR_1);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
/* Skip 2 cache entries */
|
/* Skip 2 cache entries */
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL, CALL);
|
DEOPT_IF(null != NULL, CALL);
|
||||||
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
|
DEOPT_IF(callable != (PyObject *)&PyUnicode_Type, CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PyObject_Str(arg);
|
res = PyObject_Str(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyUnicode_Type); // I.e., callable
|
if (res == NULL) goto pop_3_error;
|
||||||
if (res == NULL) { stack_pointer += -2 - oparg; goto error; }
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
@ -1839,26 +1837,24 @@
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_TUPLE_1);
|
INSTRUCTION_STATS(CALL_TUPLE_1);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
/* Skip 2 cache entries */
|
/* Skip 2 cache entries */
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL, CALL);
|
DEOPT_IF(null != NULL, CALL);
|
||||||
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
|
DEOPT_IF(callable != (PyObject *)&PyTuple_Type, CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
PyObject *arg = args[0];
|
|
||||||
res = PySequence_Tuple(arg);
|
res = PySequence_Tuple(arg);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyTuple_Type); // I.e., tuple
|
if (res == NULL) goto pop_3_error;
|
||||||
if (res == NULL) { stack_pointer += -2 - oparg; goto error; }
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
CHECK_EVAL_BREAKER();
|
CHECK_EVAL_BREAKER();
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
@ -1868,25 +1864,23 @@
|
||||||
next_instr += 4;
|
next_instr += 4;
|
||||||
INSTRUCTION_STATS(CALL_TYPE_1);
|
INSTRUCTION_STATS(CALL_TYPE_1);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_CALL == 3, "incorrect cache size");
|
||||||
PyObject **args;
|
PyObject *arg;
|
||||||
PyObject *null;
|
PyObject *null;
|
||||||
PyObject *callable;
|
PyObject *callable;
|
||||||
PyObject *res;
|
PyObject *res;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
/* Skip 2 cache entries */
|
/* Skip 2 cache entries */
|
||||||
args = &stack_pointer[-oparg];
|
arg = stack_pointer[-1];
|
||||||
null = stack_pointer[-1 - oparg];
|
null = stack_pointer[-2];
|
||||||
callable = stack_pointer[-2 - oparg];
|
callable = stack_pointer[-3];
|
||||||
assert(oparg == 1);
|
assert(oparg == 1);
|
||||||
DEOPT_IF(null != NULL, CALL);
|
DEOPT_IF(null != NULL, CALL);
|
||||||
PyObject *obj = args[0];
|
|
||||||
DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL);
|
DEOPT_IF(callable != (PyObject *)&PyType_Type, CALL);
|
||||||
STAT_INC(CALL, hit);
|
STAT_INC(CALL, hit);
|
||||||
res = Py_NewRef(Py_TYPE(obj));
|
res = Py_NewRef(Py_TYPE(arg));
|
||||||
Py_DECREF(obj);
|
Py_DECREF(arg);
|
||||||
Py_DECREF(&PyType_Type); // I.e., callable
|
stack_pointer[-3] = res;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer += -2;
|
||||||
stack_pointer += -1 - oparg;
|
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5910,18 +5904,20 @@
|
||||||
INSTRUCTION_STATS(UNPACK_SEQUENCE_TWO_TUPLE);
|
INSTRUCTION_STATS(UNPACK_SEQUENCE_TWO_TUPLE);
|
||||||
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
|
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
|
||||||
PyObject *seq;
|
PyObject *seq;
|
||||||
PyObject **values;
|
PyObject *val1;
|
||||||
|
PyObject *val0;
|
||||||
/* Skip 1 cache entry */
|
/* Skip 1 cache entry */
|
||||||
seq = stack_pointer[-1];
|
seq = stack_pointer[-1];
|
||||||
values = &stack_pointer[-1];
|
assert(oparg == 2);
|
||||||
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
|
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
|
||||||
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
|
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
|
||||||
assert(oparg == 2);
|
|
||||||
STAT_INC(UNPACK_SEQUENCE, hit);
|
STAT_INC(UNPACK_SEQUENCE, hit);
|
||||||
values[0] = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
val0 = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
||||||
values[1] = Py_NewRef(PyTuple_GET_ITEM(seq, 0));
|
val1 = Py_NewRef(PyTuple_GET_ITEM(seq, 1));
|
||||||
Py_DECREF(seq);
|
Py_DECREF(seq);
|
||||||
stack_pointer += -1 + oparg;
|
stack_pointer[-1] = val1;
|
||||||
|
stack_pointer[0] = val0;
|
||||||
|
stack_pointer += 1;
|
||||||
DISPATCH();
|
DISPATCH();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
28
Python/optimizer_cases.c.h
generated
28
Python/optimizer_cases.c.h
generated
|
@ -684,13 +684,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
case _UNPACK_SEQUENCE_TWO_TUPLE: {
|
case _UNPACK_SEQUENCE_TWO_TUPLE: {
|
||||||
_Py_UopsSymbol **values;
|
_Py_UopsSymbol *val1;
|
||||||
values = &stack_pointer[-1];
|
_Py_UopsSymbol *val0;
|
||||||
for (int _i = oparg; --_i >= 0;) {
|
val1 = sym_new_unknown(ctx);
|
||||||
values[_i] = sym_new_unknown(ctx);
|
if (val1 == NULL) goto out_of_space;
|
||||||
if (values[_i] == NULL) goto out_of_space;
|
val0 = sym_new_unknown(ctx);
|
||||||
}
|
if (val0 == NULL) goto out_of_space;
|
||||||
stack_pointer += -1 + oparg;
|
stack_pointer[-1] = val1;
|
||||||
|
stack_pointer[0] = val0;
|
||||||
|
stack_pointer += 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1632,8 +1634,8 @@
|
||||||
_Py_UopsSymbol *res;
|
_Py_UopsSymbol *res;
|
||||||
res = sym_new_unknown(ctx);
|
res = sym_new_unknown(ctx);
|
||||||
if (res == NULL) goto out_of_space;
|
if (res == NULL) goto out_of_space;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-3] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1641,8 +1643,8 @@
|
||||||
_Py_UopsSymbol *res;
|
_Py_UopsSymbol *res;
|
||||||
res = sym_new_unknown(ctx);
|
res = sym_new_unknown(ctx);
|
||||||
if (res == NULL) goto out_of_space;
|
if (res == NULL) goto out_of_space;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-3] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1650,8 +1652,8 @@
|
||||||
_Py_UopsSymbol *res;
|
_Py_UopsSymbol *res;
|
||||||
res = sym_new_unknown(ctx);
|
res = sym_new_unknown(ctx);
|
||||||
if (res == NULL) goto out_of_space;
|
if (res == NULL) goto out_of_space;
|
||||||
stack_pointer[-2 - oparg] = res;
|
stack_pointer[-3] = res;
|
||||||
stack_pointer += -1 - oparg;
|
stack_pointer += -2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue