mirror of
https://github.com/python/cpython.git
synced 2026-01-06 07:22:09 +00:00
GH-128914: Remove all but one conditional stack effects (GH-129226)
* Remove all 'if (0)' and 'if (1)' conditional stack effects * Use array instead of conditional for BUILD_SLICE args * Refactor LOAD_GLOBAL to use a common conditional uop * Remove conditional stack effects from LOAD_ATTR specializations * Replace conditional stack effects in LOAD_ATTR with a 0 or 1 sized array. * Remove conditional stack effects from CALL_FUNCTION_EX
This commit is contained in:
parent
8ec76d9034
commit
75b4962157
19 changed files with 518 additions and 758 deletions
|
|
@ -1665,10 +1665,13 @@ dummy_func(
|
|||
}
|
||||
|
||||
// res[1] because we need a pointer to res to pass it to _PyEval_LoadGlobalStackRef
|
||||
op(_LOAD_GLOBAL, ( -- res[1], null if (oparg & 1))) {
|
||||
op(_LOAD_GLOBAL, ( -- res[1])) {
|
||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
|
||||
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
|
||||
ERROR_IF(PyStackRef_IsNull(*res), error);
|
||||
}
|
||||
|
||||
op(_PUSH_NULL_CONDITIONAL, ( -- null if (oparg & 1))) {
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
|
|
@ -1677,7 +1680,8 @@ dummy_func(
|
|||
counter/1 +
|
||||
globals_version/1 +
|
||||
builtins_version/1 +
|
||||
_LOAD_GLOBAL;
|
||||
_LOAD_GLOBAL +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
op(_GUARD_GLOBALS_VERSION, (version/1 --)) {
|
||||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
|
|
@ -1707,7 +1711,7 @@ dummy_func(
|
|||
assert(DK_IS_UNICODE(builtins_keys));
|
||||
}
|
||||
|
||||
op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
|
||||
op(_LOAD_GLOBAL_MODULE_FROM_KEYS, (index/1, globals_keys: PyDictKeysObject* -- res)) {
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
|
||||
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
|
||||
DEAD(globals_keys);
|
||||
|
|
@ -1721,10 +1725,9 @@ dummy_func(
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res, null if (oparg & 1))) {
|
||||
op(_LOAD_GLOBAL_BUILTINS_FROM_KEYS, (index/1, builtins_keys: PyDictKeysObject* -- res)) {
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
|
||||
PyObject *res_o = FT_ATOMIC_LOAD_PTR_RELAXED(entries[index].me_value);
|
||||
DEAD(builtins_keys);
|
||||
|
|
@ -1738,20 +1741,21 @@ dummy_func(
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
macro(LOAD_GLOBAL_MODULE) =
|
||||
unused/1 + // Skip over the counter
|
||||
_GUARD_GLOBALS_VERSION_PUSH_KEYS +
|
||||
unused/1 + // Skip over the builtins version
|
||||
_LOAD_GLOBAL_MODULE_FROM_KEYS;
|
||||
_LOAD_GLOBAL_MODULE_FROM_KEYS +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
macro(LOAD_GLOBAL_BUILTIN) =
|
||||
unused/1 + // Skip over the counter
|
||||
_GUARD_GLOBALS_VERSION +
|
||||
_GUARD_BUILTINS_VERSION_PUSH_KEYS +
|
||||
_LOAD_GLOBAL_BUILTINS_FROM_KEYS;
|
||||
_LOAD_GLOBAL_BUILTINS_FROM_KEYS +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
inst(DELETE_FAST, (--)) {
|
||||
_PyStackRef v = GETLOCAL(oparg);
|
||||
|
|
@ -2030,7 +2034,7 @@ dummy_func(
|
|||
#endif /* ENABLE_SPECIALIZATION_FT */
|
||||
}
|
||||
|
||||
tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr, null if (oparg & 1))) {
|
||||
tier1 op(_LOAD_SUPER_ATTR, (global_super_st, class_st, self_st -- attr)) {
|
||||
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
|
||||
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
|
||||
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
|
||||
|
|
@ -2072,12 +2076,11 @@ dummy_func(
|
|||
Py_DECREF(super);
|
||||
ERROR_IF(attr_o == NULL, error);
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR;
|
||||
macro(LOAD_SUPER_ATTR) = _SPECIALIZE_LOAD_SUPER_ATTR + _LOAD_SUPER_ATTR + _PUSH_NULL_CONDITIONAL;
|
||||
|
||||
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st, unused if (0))) {
|
||||
inst(LOAD_SUPER_ATTR_ATTR, (unused/1, global_super_st, class_st, self_st -- attr_st)) {
|
||||
PyObject *global_super = PyStackRef_AsPyObjectBorrow(global_super_st);
|
||||
PyObject *class = PyStackRef_AsPyObjectBorrow(class_st);
|
||||
PyObject *self = PyStackRef_AsPyObjectBorrow(self_st);
|
||||
|
|
@ -2152,7 +2155,7 @@ dummy_func(
|
|||
#endif /* ENABLE_SPECIALIZATION_FT */
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR, (owner -- attr, self_or_null[oparg&1])) {
|
||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||
PyObject *attr_o;
|
||||
if (oparg & 1) {
|
||||
|
|
@ -2165,7 +2168,7 @@ dummy_func(
|
|||
meth | self | arg1 | ... | argN
|
||||
*/
|
||||
assert(attr_o != NULL); // No errors on this branch
|
||||
self_or_null = owner; // Transfer ownership
|
||||
self_or_null[0] = owner; // Transfer ownership
|
||||
DEAD(owner);
|
||||
}
|
||||
else {
|
||||
|
|
@ -2177,7 +2180,7 @@ dummy_func(
|
|||
*/
|
||||
DECREF_INPUTS();
|
||||
ERROR_IF(attr_o == NULL, error);
|
||||
self_or_null = PyStackRef_NULL;
|
||||
self_or_null[0] = PyStackRef_NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -2185,12 +2188,11 @@ dummy_func(
|
|||
attr_o = PyObject_GetAttr(PyStackRef_AsPyObjectBorrow(owner), name);
|
||||
DECREF_INPUTS();
|
||||
ERROR_IF(attr_o == NULL, error);
|
||||
/* We need to define self_or_null on all paths */
|
||||
self_or_null = PyStackRef_NULL;
|
||||
}
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
}
|
||||
|
||||
|
||||
macro(LOAD_ATTR) =
|
||||
_SPECIALIZE_LOAD_ATTR +
|
||||
unused/8 +
|
||||
|
|
@ -2220,7 +2222,7 @@ dummy_func(
|
|||
DEOPT_IF(!FT_ATOMIC_LOAD_UINT8(_PyObject_InlineValues(owner_o)->valid));
|
||||
}
|
||||
|
||||
split op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
|
||||
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
|
||||
|
|
@ -2233,7 +2235,6 @@ dummy_func(
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
||||
|
|
@ -2242,7 +2243,8 @@ dummy_func(
|
|||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_MANAGED_OBJECT_HAS_VALUES +
|
||||
_LOAD_ATTR_INSTANCE_VALUE +
|
||||
unused/5; // Skip over rest of cache
|
||||
unused/5 +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
op(_CHECK_ATTR_MODULE_PUSH_KEYS, (dict_version/2, owner -- owner, mod_keys: PyDictKeysObject *)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -2254,7 +2256,7 @@ dummy_func(
|
|||
mod_keys = keys;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys: PyDictKeysObject * -- attr)) {
|
||||
assert(mod_keys->dk_kind == DICT_KEYS_UNICODE);
|
||||
assert(index < FT_ATOMIC_LOAD_SSIZE_RELAXED(mod_keys->dk_nentries));
|
||||
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(mod_keys) + index;
|
||||
|
|
@ -2272,7 +2274,6 @@ dummy_func(
|
|||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
|
||||
|
|
@ -2280,7 +2281,8 @@ dummy_func(
|
|||
unused/1 +
|
||||
_CHECK_ATTR_MODULE_PUSH_KEYS +
|
||||
_LOAD_ATTR_MODULE_FROM_KEYS +
|
||||
unused/5;
|
||||
unused/5 +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
op(_CHECK_ATTR_WITH_HINT, (owner -- owner, dict: PyDictObject *)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -2292,7 +2294,7 @@ dummy_func(
|
|||
dict = dict_o;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict: PyDictObject * -- attr)) {
|
||||
PyObject *attr_o;
|
||||
if (!LOCK_OBJECT(dict)) {
|
||||
POP_INPUT(dict);
|
||||
|
|
@ -2326,7 +2328,6 @@ dummy_func(
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
UNLOCK_OBJECT(dict);
|
||||
DEAD(dict);
|
||||
null = PyStackRef_NULL;
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
||||
|
|
@ -2335,9 +2336,10 @@ dummy_func(
|
|||
_GUARD_TYPE_VERSION +
|
||||
_CHECK_ATTR_WITH_HINT +
|
||||
_LOAD_ATTR_WITH_HINT +
|
||||
unused/5;
|
||||
unused/5 +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
split op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
||||
PyObject **addr = (PyObject **)((char *)owner_o + index);
|
||||
|
|
@ -2350,7 +2352,6 @@ dummy_func(
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
||||
|
|
@ -2358,7 +2359,8 @@ dummy_func(
|
|||
unused/1 +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_LOAD_ATTR_SLOT + // NOTE: This action may also deopt
|
||||
unused/5;
|
||||
unused/5 +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
op(_CHECK_ATTR_CLASS, (type_version/2, owner -- owner)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -2368,11 +2370,10 @@ dummy_func(
|
|||
EXIT_IF(FT_ATOMIC_LOAD_UINT_RELAXED(((PyTypeObject *)owner_o)->tp_version_tag) != type_version);
|
||||
}
|
||||
|
||||
split op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
null = PyStackRef_NULL;
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
||||
|
|
@ -2380,13 +2381,15 @@ dummy_func(
|
|||
unused/1 +
|
||||
_CHECK_ATTR_CLASS +
|
||||
unused/2 +
|
||||
_LOAD_ATTR_CLASS;
|
||||
_LOAD_ATTR_CLASS +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
macro(LOAD_ATTR_CLASS_WITH_METACLASS_CHECK) =
|
||||
unused/1 +
|
||||
_CHECK_ATTR_CLASS +
|
||||
_GUARD_TYPE_VERSION +
|
||||
_LOAD_ATTR_CLASS;
|
||||
_LOAD_ATTR_CLASS +
|
||||
_PUSH_NULL_CONDITIONAL;
|
||||
|
||||
op(_LOAD_ATTR_PROPERTY_FRAME, (fget/4, owner -- new_frame: _PyInterpreterFrame *)) {
|
||||
assert((oparg & 1) == 0);
|
||||
|
|
@ -2412,7 +2415,7 @@ dummy_func(
|
|||
_SAVE_RETURN_OFFSET +
|
||||
_PUSH_FRAME;
|
||||
|
||||
inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused, unused if (0))) {
|
||||
inst(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN, (unused/1, type_version/2, func_version/2, getattribute/4, owner -- unused)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
||||
assert((oparg & 1) == 0);
|
||||
|
|
@ -3348,7 +3351,7 @@ dummy_func(
|
|||
DEOPT_IF(FT_ATOMIC_LOAD_UINT32_RELAXED(keys->dk_version) != keys_version);
|
||||
}
|
||||
|
||||
split op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
|
||||
assert(oparg & 1);
|
||||
/* Cached method object */
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
|
|
@ -3366,7 +3369,7 @@ dummy_func(
|
|||
_GUARD_KEYS_VERSION +
|
||||
_LOAD_ATTR_METHOD_WITH_VALUES;
|
||||
|
||||
op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self)) {
|
||||
assert(oparg & 1);
|
||||
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
|
|
@ -3383,7 +3386,7 @@ dummy_func(
|
|||
unused/2 +
|
||||
_LOAD_ATTR_METHOD_NO_DICT;
|
||||
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr, unused if (0))) {
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES, (descr/4, owner -- attr)) {
|
||||
assert((oparg & 1) == 0);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
|
|
@ -3398,7 +3401,7 @@ dummy_func(
|
|||
_GUARD_KEYS_VERSION +
|
||||
_LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES;
|
||||
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr, unused if (0))) {
|
||||
op(_LOAD_ATTR_NONDESCRIPTOR_NO_DICT, (descr/4, owner -- attr)) {
|
||||
assert((oparg & 1) == 0);
|
||||
assert(Py_TYPE(PyStackRef_AsPyObjectBorrow(owner))->tp_dictoffset == 0);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
|
|
@ -3420,7 +3423,7 @@ dummy_func(
|
|||
DEOPT_IF(dict != NULL);
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) {
|
||||
assert(oparg & 1);
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
|
|
@ -4537,7 +4540,7 @@ dummy_func(
|
|||
GO_TO_INSTRUCTION(CALL_FUNCTION_EX);
|
||||
}
|
||||
|
||||
op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in if (oparg & 1) -- func, unused, tuple, kwargs_out if (oparg & 1))) {
|
||||
op(_MAKE_CALLARGS_A_TUPLE, (func, unused, callargs, kwargs_in -- func, unused, tuple, kwargs_out)) {
|
||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||
if (PyTuple_CheckExact(callargs_o)) {
|
||||
tuple = callargs;
|
||||
|
|
@ -4561,7 +4564,7 @@ dummy_func(
|
|||
}
|
||||
}
|
||||
|
||||
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st if (oparg & 1) -- result)) {
|
||||
op(_DO_CALL_FUNCTION_EX, (func_st, unused, callargs_st, kwargs_st -- result)) {
|
||||
PyObject *func = PyStackRef_AsPyObjectBorrow(func_st);
|
||||
|
||||
// DICT_MERGE is called before this opcode if there are kwargs.
|
||||
|
|
@ -4695,11 +4698,10 @@ dummy_func(
|
|||
LLTRACE_RESUME_FRAME();
|
||||
}
|
||||
|
||||
inst(BUILD_SLICE, (start, stop, step if (oparg == 3) -- slice)) {
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
|
||||
PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
|
||||
|
||||
inst(BUILD_SLICE, (args[oparg] -- slice)) {
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]);
|
||||
PyObject *step_o = oparg == 3 ? PyStackRef_AsPyObjectBorrow(args[2]) : NULL;
|
||||
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
|
||||
DECREF_INPUTS();
|
||||
ERROR_IF(slice_o == NULL, error);
|
||||
|
|
@ -5026,43 +5028,31 @@ dummy_func(
|
|||
value = PyStackRef_FromPyObjectImmortal(ptr);
|
||||
}
|
||||
|
||||
tier2 pure op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) {
|
||||
value = PyStackRef_FromPyObjectNew(ptr);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
tier2 pure op(_LOAD_CONST_INLINE_BORROW_WITH_NULL, (ptr/4 -- value, null)) {
|
||||
value = PyStackRef_FromPyObjectImmortal(ptr);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
tier2 op(_CHECK_FUNCTION, (func_version/2 -- )) {
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
PyFunctionObject *func = (PyFunctionObject *)PyStackRef_AsPyObjectBorrow(frame->f_funcobj);
|
||||
DEOPT_IF(func->func_version != func_version);
|
||||
}
|
||||
|
||||
tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res, null if (oparg & 1))) {
|
||||
tier2 op(_LOAD_GLOBAL_MODULE, (index/1 -- res)) {
|
||||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
|
||||
PyObject *res_o = entries[index].me_value;
|
||||
DEOPT_IF(res_o == NULL);
|
||||
Py_INCREF(res_o);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res, null if (oparg & 1))) {
|
||||
tier2 op(_LOAD_GLOBAL_BUILTINS, (index/1 -- res)) {
|
||||
PyDictObject *dict = (PyDictObject *)BUILTINS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
|
||||
PyObject *res_o = entries[index].me_value;
|
||||
DEOPT_IF(res_o == NULL);
|
||||
Py_INCREF(res_o);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
|
||||
tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr, null if (oparg & 1))) {
|
||||
tier2 op(_LOAD_ATTR_MODULE, (index/1, owner -- attr)) {
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
PyDictObject *dict = (PyDictObject *)((PyModuleObject *)owner_o)->md_dict;
|
||||
assert(dict->ma_keys->dk_kind == DICT_KEYS_UNICODE);
|
||||
|
|
@ -5073,7 +5063,6 @@ dummy_func(
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
Py_INCREF(attr_o);
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
null = PyStackRef_NULL;
|
||||
DECREF_INPUTS();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4108,7 +4108,10 @@ codegen_call_helper_impl(compiler *c, location loc,
|
|||
}
|
||||
assert(have_dict);
|
||||
}
|
||||
ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
|
||||
if (nkwelts == 0) {
|
||||
ADDOP(c, loc, PUSH_NULL);
|
||||
}
|
||||
ADDOP(c, loc, CALL_FUNCTION_EX);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
244
Python/executor_cases.c.h
generated
244
Python/executor_cases.c.h
generated
|
|
@ -1953,7 +1953,6 @@
|
|||
|
||||
case _LOAD_GLOBAL: {
|
||||
_PyStackRef *res;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
res = &stack_pointer[0];
|
||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1);
|
||||
|
|
@ -1961,9 +1960,17 @@
|
|||
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (PyStackRef_IsNull(*res)) JUMP_TO_ERROR();
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _PUSH_NULL_CONDITIONAL: {
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
null = PyStackRef_NULL;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -2029,8 +2036,6 @@
|
|||
case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
|
||||
PyDictKeysObject *globals_keys;
|
||||
_PyStackRef res;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
globals_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(globals_keys);
|
||||
|
|
@ -2052,10 +2057,8 @@
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -2063,8 +2066,6 @@
|
|||
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
|
||||
PyDictKeysObject *builtins_keys;
|
||||
_PyStackRef res;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
builtins_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(builtins_keys);
|
||||
|
|
@ -2086,10 +2087,8 @@
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -2608,9 +2607,10 @@
|
|||
case _LOAD_ATTR: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self_or_null = PyStackRef_NULL;
|
||||
_PyStackRef *self_or_null;
|
||||
oparg = CURRENT_OPARG();
|
||||
owner = stack_pointer[-1];
|
||||
self_or_null = &stack_pointer[0];
|
||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||
PyObject *attr_o;
|
||||
if (oparg & 1) {
|
||||
|
|
@ -2625,7 +2625,7 @@
|
|||
meth | self | arg1 | ... | argN
|
||||
*/
|
||||
assert(attr_o != NULL); // No errors on this branch
|
||||
self_or_null = owner; // Transfer ownership
|
||||
self_or_null[0] = owner; // Transfer ownership
|
||||
}
|
||||
else {
|
||||
/* meth is not an unbound method (but a regular attr, or
|
||||
|
|
@ -2636,7 +2636,7 @@
|
|||
*/
|
||||
PyStackRef_CLOSE(owner);
|
||||
if (attr_o == NULL) JUMP_TO_ERROR();
|
||||
self_or_null = PyStackRef_NULL;
|
||||
self_or_null[0] = PyStackRef_NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -2646,13 +2646,10 @@
|
|||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
PyStackRef_CLOSE(owner);
|
||||
if (attr_o == NULL) JUMP_TO_ERROR();
|
||||
/* We need to define self_or_null on all paths */
|
||||
self_or_null = PyStackRef_NULL;
|
||||
}
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = self_or_null;
|
||||
stack_pointer += (oparg & 1);
|
||||
stack_pointer += (oparg&1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -2704,11 +2701,9 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_INSTANCE_VALUE_0: {
|
||||
case _LOAD_ATTR_INSTANCE_VALUE: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t offset = (uint16_t)CURRENT_OPERAND0();
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -2729,48 +2724,11 @@
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_INSTANCE_VALUE_1: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t offset = (uint16_t)CURRENT_OPERAND0();
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
PyObject **value_ptr = (PyObject**)(((char *)owner_o) + offset);
|
||||
PyObject *attr_o = FT_ATOMIC_LOAD_PTR_ACQUIRE(*value_ptr);
|
||||
if (attr_o == NULL) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
#ifdef Py_GIL_DISABLED
|
||||
if (!_Py_TryIncrefCompareStackRef(value_ptr, attr_o, &attr)) {
|
||||
if (true) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
}
|
||||
#else
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = null;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
/* _LOAD_ATTR_INSTANCE_VALUE is split on (oparg & 1) */
|
||||
|
||||
case _CHECK_ATTR_MODULE_PUSH_KEYS: {
|
||||
_PyStackRef owner;
|
||||
PyDictKeysObject *mod_keys;
|
||||
|
|
@ -2799,8 +2757,6 @@
|
|||
PyDictKeysObject *mod_keys;
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
mod_keys = (PyDictKeysObject *)stack_pointer[-1].bits;
|
||||
owner = stack_pointer[-2];
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
|
|
@ -2828,12 +2784,8 @@
|
|||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2860,7 +2812,6 @@
|
|||
PyDictObject *dict;
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
dict = (PyDictObject *)stack_pointer[-1].bits;
|
||||
owner = stack_pointer[-2];
|
||||
|
|
@ -2916,20 +2867,16 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
UNLOCK_OBJECT(dict);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-2] = attr;
|
||||
if (oparg & 1) stack_pointer[-1] = null;
|
||||
stack_pointer += -1 + (oparg & 1);
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_SLOT_0: {
|
||||
case _LOAD_ATTR_SLOT: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -2949,47 +2896,11 @@
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_SLOT_1: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
PyObject **addr = (PyObject **)((char *)owner_o + index);
|
||||
PyObject *attr_o = FT_ATOMIC_LOAD_PTR(*addr);
|
||||
if (attr_o == NULL) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
#ifdef Py_GIL_DISABLED
|
||||
int increfed = _Py_TryIncrefCompareStackRef(addr, attr_o, &attr);
|
||||
if (!increfed) {
|
||||
UOP_STAT_INC(uopcode, miss);
|
||||
JUMP_TO_JUMP_TARGET();
|
||||
}
|
||||
#else
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = null;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
/* _LOAD_ATTR_SLOT is split on (oparg & 1) */
|
||||
|
||||
case _CHECK_ATTR_CLASS: {
|
||||
_PyStackRef owner;
|
||||
owner = stack_pointer[-1];
|
||||
|
|
@ -3007,43 +2918,19 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_CLASS_0: {
|
||||
case _LOAD_ATTR_CLASS: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_CLASS_1: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
(void)null;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
stack_pointer[0] = null;
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
/* _LOAD_ATTR_CLASS is split on (oparg & 1) */
|
||||
|
||||
case _LOAD_ATTR_PROPERTY_FRAME: {
|
||||
_PyStackRef owner;
|
||||
_PyInterpreterFrame *new_frame;
|
||||
|
|
@ -4059,7 +3946,7 @@
|
|||
case _LOAD_ATTR_METHOD_WITH_VALUES: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
oparg = CURRENT_OPARG();
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
|
||||
|
|
@ -4080,7 +3967,7 @@
|
|||
case _LOAD_ATTR_METHOD_NO_DICT: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
oparg = CURRENT_OPARG();
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
|
||||
|
|
@ -4146,7 +4033,7 @@
|
|||
case _LOAD_ATTR_METHOD_LAZY_DICT: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
oparg = CURRENT_OPARG();
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)CURRENT_OPERAND0();
|
||||
|
|
@ -5644,15 +5531,14 @@
|
|||
/* _INSTRUMENTED_CALL_FUNCTION_EX is not a viable micro-op for tier 2 because it is instrumented */
|
||||
|
||||
case _MAKE_CALLARGS_A_TUPLE: {
|
||||
_PyStackRef kwargs_in = PyStackRef_NULL;
|
||||
_PyStackRef kwargs_in;
|
||||
_PyStackRef callargs;
|
||||
_PyStackRef func;
|
||||
_PyStackRef tuple;
|
||||
_PyStackRef kwargs_out = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
|
||||
callargs = stack_pointer[-1 - (oparg & 1)];
|
||||
func = stack_pointer[-3 - (oparg & 1)];
|
||||
_PyStackRef kwargs_out;
|
||||
kwargs_in = stack_pointer[-1];
|
||||
callargs = stack_pointer[-2];
|
||||
func = stack_pointer[-4];
|
||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||
if (PyTuple_CheckExact(callargs_o)) {
|
||||
tuple = callargs;
|
||||
|
|
@ -5675,8 +5561,8 @@
|
|||
PyStackRef_CLOSE(callargs);
|
||||
tuple = PyStackRef_FromPyObjectSteal(tuple_o);
|
||||
}
|
||||
stack_pointer[-1 - (oparg & 1)] = tuple;
|
||||
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
|
||||
stack_pointer[-2] = tuple;
|
||||
stack_pointer[-1] = kwargs_out;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -5753,25 +5639,21 @@
|
|||
}
|
||||
|
||||
case _BUILD_SLICE: {
|
||||
_PyStackRef step = PyStackRef_NULL;
|
||||
_PyStackRef stop;
|
||||
_PyStackRef start;
|
||||
_PyStackRef *args;
|
||||
_PyStackRef slice;
|
||||
oparg = CURRENT_OPARG();
|
||||
if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
|
||||
stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
|
||||
start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
|
||||
PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
|
||||
args = &stack_pointer[-oparg];
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]);
|
||||
PyObject *step_o = oparg == 3 ? PyStackRef_AsPyObjectBorrow(args[2]) : NULL;
|
||||
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
|
||||
PyStackRef_CLOSE(start);
|
||||
PyStackRef_CLOSE(stop);
|
||||
PyStackRef_XCLOSE(step);
|
||||
for (int _i = oparg; --_i >= 0;) {
|
||||
PyStackRef_CLOSE(args[_i]);
|
||||
}
|
||||
if (slice_o == NULL) JUMP_TO_ERROR();
|
||||
slice = PyStackRef_FromPyObjectSteal(slice_o);
|
||||
stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
|
||||
stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
|
||||
stack_pointer[-oparg] = slice;
|
||||
stack_pointer += 1 - oparg;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -6099,32 +5981,6 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST_INLINE_WITH_NULL: {
|
||||
_PyStackRef value;
|
||||
_PyStackRef null;
|
||||
PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
|
||||
value = PyStackRef_FromPyObjectNew(ptr);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = null;
|
||||
stack_pointer += 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST_INLINE_BORROW_WITH_NULL: {
|
||||
_PyStackRef value;
|
||||
_PyStackRef null;
|
||||
PyObject *ptr = (PyObject *)CURRENT_OPERAND0();
|
||||
value = PyStackRef_FromPyObjectImmortal(ptr);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = null;
|
||||
stack_pointer += 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_FUNCTION: {
|
||||
uint32_t func_version = (uint32_t)CURRENT_OPERAND0();
|
||||
assert(PyStackRef_FunctionCheck(frame->f_funcobj));
|
||||
|
|
@ -6138,8 +5994,6 @@
|
|||
|
||||
case _LOAD_GLOBAL_MODULE: {
|
||||
_PyStackRef res;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyDictObject *dict = (PyDictObject *)GLOBALS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
|
||||
|
|
@ -6150,18 +6004,14 @@
|
|||
}
|
||||
Py_INCREF(res_o);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_BUILTINS: {
|
||||
_PyStackRef res;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyDictObject *dict = (PyDictObject *)BUILTINS();
|
||||
PyDictUnicodeEntry *entries = DK_UNICODE_ENTRIES(dict->ma_keys);
|
||||
|
|
@ -6172,10 +6022,8 @@
|
|||
}
|
||||
Py_INCREF(res_o);
|
||||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
null = PyStackRef_NULL;
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -6183,8 +6031,6 @@
|
|||
case _LOAD_ATTR_MODULE: {
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef null = PyStackRef_NULL;
|
||||
oparg = CURRENT_OPARG();
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t index = (uint16_t)CURRENT_OPERAND0();
|
||||
PyObject *owner_o = PyStackRef_AsPyObjectBorrow(owner);
|
||||
|
|
@ -6200,12 +6046,8 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
Py_INCREF(attr_o);
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
124
Python/generated_cases.c.h
generated
124
Python/generated_cases.c.h
generated
|
|
@ -840,28 +840,24 @@
|
|||
frame->instr_ptr = next_instr;
|
||||
next_instr += 1;
|
||||
INSTRUCTION_STATS(BUILD_SLICE);
|
||||
_PyStackRef start;
|
||||
_PyStackRef stop;
|
||||
_PyStackRef step = PyStackRef_NULL;
|
||||
_PyStackRef *args;
|
||||
_PyStackRef slice;
|
||||
if (oparg == 3) { step = stack_pointer[-((oparg == 3) ? 1 : 0)]; }
|
||||
stop = stack_pointer[-1 - ((oparg == 3) ? 1 : 0)];
|
||||
start = stack_pointer[-2 - ((oparg == 3) ? 1 : 0)];
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(start);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(stop);
|
||||
PyObject *step_o = PyStackRef_AsPyObjectBorrow(step);
|
||||
args = &stack_pointer[-oparg];
|
||||
PyObject *start_o = PyStackRef_AsPyObjectBorrow(args[0]);
|
||||
PyObject *stop_o = PyStackRef_AsPyObjectBorrow(args[1]);
|
||||
PyObject *step_o = oparg == 3 ? PyStackRef_AsPyObjectBorrow(args[2]) : NULL;
|
||||
PyObject *slice_o = PySlice_New(start_o, stop_o, step_o);
|
||||
PyStackRef_CLOSE(start);
|
||||
PyStackRef_CLOSE(stop);
|
||||
PyStackRef_XCLOSE(step);
|
||||
for (int _i = oparg; --_i >= 0;) {
|
||||
PyStackRef_CLOSE(args[_i]);
|
||||
}
|
||||
if (slice_o == NULL) {
|
||||
stack_pointer += -2 - ((oparg == 3) ? 1 : 0);
|
||||
stack_pointer += -oparg;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
goto error;
|
||||
}
|
||||
slice = PyStackRef_FromPyObjectSteal(slice_o);
|
||||
stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
|
||||
stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
|
||||
stack_pointer[-oparg] = slice;
|
||||
stack_pointer += 1 - oparg;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
}
|
||||
|
|
@ -1713,18 +1709,18 @@
|
|||
(void)this_instr;
|
||||
_PyStackRef func;
|
||||
_PyStackRef callargs;
|
||||
_PyStackRef kwargs_in = PyStackRef_NULL;
|
||||
_PyStackRef kwargs_in;
|
||||
_PyStackRef tuple;
|
||||
_PyStackRef kwargs_out = PyStackRef_NULL;
|
||||
_PyStackRef kwargs_out;
|
||||
_PyStackRef func_st;
|
||||
_PyStackRef callargs_st;
|
||||
_PyStackRef kwargs_st = PyStackRef_NULL;
|
||||
_PyStackRef kwargs_st;
|
||||
_PyStackRef result;
|
||||
// _MAKE_CALLARGS_A_TUPLE
|
||||
{
|
||||
if (oparg & 1) { kwargs_in = stack_pointer[-(oparg & 1)]; }
|
||||
callargs = stack_pointer[-1 - (oparg & 1)];
|
||||
func = stack_pointer[-3 - (oparg & 1)];
|
||||
kwargs_in = stack_pointer[-1];
|
||||
callargs = stack_pointer[-2];
|
||||
func = stack_pointer[-4];
|
||||
PyObject *callargs_o = PyStackRef_AsPyObjectBorrow(callargs);
|
||||
if (PyTuple_CheckExact(callargs_o)) {
|
||||
tuple = callargs;
|
||||
|
|
@ -1766,8 +1762,8 @@
|
|||
assert(PyTuple_CheckExact(callargs));
|
||||
PyObject *arg = PyTuple_GET_SIZE(callargs) > 0 ?
|
||||
PyTuple_GET_ITEM(callargs, 0) : &_PyInstrumentation_MISSING;
|
||||
stack_pointer[-1 - (oparg & 1)] = callargs_st;
|
||||
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
|
||||
stack_pointer[-2] = callargs_st;
|
||||
stack_pointer[-1] = kwargs_st;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int err = _Py_call_instrumentation_2args(
|
||||
tstate, PY_MONITORING_EVENT_CALL,
|
||||
|
|
@ -1810,7 +1806,7 @@
|
|||
Py_ssize_t nargs = PyTuple_GET_SIZE(callargs);
|
||||
int code_flags = ((PyCodeObject *)PyFunction_GET_CODE(func))->co_flags;
|
||||
PyObject *locals = code_flags & CO_OPTIMIZED ? NULL : Py_NewRef(PyFunction_GET_GLOBALS(func));
|
||||
stack_pointer += -2 - (oparg & 1);
|
||||
stack_pointer += -3;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
_PyInterpreterFrame *new_frame = _PyEvalFramePushAndInit_Ex(
|
||||
|
|
@ -1831,8 +1827,8 @@
|
|||
assert(PyTuple_CheckExact(callargs));
|
||||
PyObject *kwargs = PyStackRef_AsPyObjectBorrow(kwargs_st);
|
||||
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||
stack_pointer[-1 - (oparg & 1)] = callargs_st;
|
||||
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_st;
|
||||
stack_pointer[-2] = callargs_st;
|
||||
stack_pointer[-1] = kwargs_st;
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
result_o = PyObject_Call(func, callargs, kwargs);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
|
|
@ -1842,11 +1838,7 @@
|
|||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
PyStackRef_CLOSE(callargs_st);
|
||||
PyStackRef_CLOSE(func_st);
|
||||
if (result_o == NULL) {
|
||||
stack_pointer += -3 - (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
goto error;
|
||||
}
|
||||
if (result_o == NULL) goto pop_4_error;
|
||||
result = PyStackRef_FromPyObjectSteal(result_o);
|
||||
}
|
||||
// _CHECK_PERIODIC
|
||||
|
|
@ -1854,19 +1846,19 @@
|
|||
_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY();
|
||||
QSBR_QUIESCENT_STATE(tstate);
|
||||
if (_Py_atomic_load_uintptr_relaxed(&tstate->eval_breaker) & _PY_EVAL_EVENTS_MASK) {
|
||||
stack_pointer[-3 - (oparg & 1)] = result;
|
||||
stack_pointer += -2 - (oparg & 1);
|
||||
stack_pointer[-4] = result;
|
||||
stack_pointer += -3;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||
int err = _Py_HandlePending(tstate);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (err != 0) goto error;
|
||||
stack_pointer += 2 + (oparg & 1);
|
||||
stack_pointer += 3;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
}
|
||||
}
|
||||
stack_pointer[-3 - (oparg & 1)] = result;
|
||||
stack_pointer += -2 - (oparg & 1);
|
||||
stack_pointer[-4] = result;
|
||||
stack_pointer += -3;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
}
|
||||
|
|
@ -5308,7 +5300,7 @@
|
|||
(void)this_instr;
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self_or_null = PyStackRef_NULL;
|
||||
_PyStackRef *self_or_null;
|
||||
// _SPECIALIZE_LOAD_ATTR
|
||||
{
|
||||
owner = stack_pointer[-1];
|
||||
|
|
@ -5330,6 +5322,7 @@
|
|||
/* Skip 8 cache entries */
|
||||
// _LOAD_ATTR
|
||||
{
|
||||
self_or_null = &stack_pointer[0];
|
||||
PyObject *name = GETITEM(FRAME_CO_NAMES, oparg >> 1);
|
||||
PyObject *attr_o;
|
||||
if (oparg & 1) {
|
||||
|
|
@ -5344,7 +5337,7 @@
|
|||
meth | self | arg1 | ... | argN
|
||||
*/
|
||||
assert(attr_o != NULL); // No errors on this branch
|
||||
self_or_null = owner; // Transfer ownership
|
||||
self_or_null[0] = owner; // Transfer ownership
|
||||
}
|
||||
else {
|
||||
/* meth is not an unbound method (but a regular attr, or
|
||||
|
|
@ -5355,7 +5348,7 @@
|
|||
*/
|
||||
PyStackRef_CLOSE(owner);
|
||||
if (attr_o == NULL) goto pop_1_error;
|
||||
self_or_null = PyStackRef_NULL;
|
||||
self_or_null[0] = PyStackRef_NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
@ -5365,14 +5358,11 @@
|
|||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
PyStackRef_CLOSE(owner);
|
||||
if (attr_o == NULL) goto pop_1_error;
|
||||
/* We need to define self_or_null on all paths */
|
||||
self_or_null = PyStackRef_NULL;
|
||||
}
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = self_or_null;
|
||||
stack_pointer += (oparg & 1);
|
||||
stack_pointer += (oparg&1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
DISPATCH();
|
||||
}
|
||||
|
|
@ -5402,9 +5392,12 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -5443,9 +5436,12 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
assert(descr != NULL);
|
||||
attr = PyStackRef_FromPyObjectNew(descr);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -5528,10 +5524,13 @@
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
/* Skip 5 cache entries */
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -5546,7 +5545,7 @@
|
|||
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
/* Skip 1 cache entry */
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
|
|
@ -5589,7 +5588,7 @@
|
|||
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
/* Skip 1 cache entry */
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
|
|
@ -5625,7 +5624,7 @@
|
|||
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
|
||||
_PyStackRef owner;
|
||||
_PyStackRef attr;
|
||||
_PyStackRef self = PyStackRef_NULL;
|
||||
_PyStackRef self;
|
||||
/* Skip 1 cache entry */
|
||||
// _GUARD_TYPE_VERSION
|
||||
{
|
||||
|
|
@ -5709,10 +5708,13 @@
|
|||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
/* Skip 5 cache entries */
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -5891,10 +5893,13 @@
|
|||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_ATTR, hit);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
/* Skip 5 cache entries */
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -5958,10 +5963,13 @@
|
|||
STAT_INC(LOAD_ATTR, hit);
|
||||
attr = PyStackRef_FromPyObjectNew(attr_o);
|
||||
UNLOCK_OBJECT(dict);
|
||||
null = PyStackRef_NULL;
|
||||
PyStackRef_CLOSE(owner);
|
||||
}
|
||||
/* Skip 5 cache entries */
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
|
|
@ -6295,6 +6303,9 @@
|
|||
_PyEval_LoadGlobalStackRef(GLOBALS(), BUILTINS(), name, res);
|
||||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (PyStackRef_IsNull(*res)) goto error;
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
|
|
@ -6345,6 +6356,9 @@
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[0] = res;
|
||||
|
|
@ -6388,6 +6402,9 @@
|
|||
res = PyStackRef_FromPyObjectSteal(res_o);
|
||||
#endif
|
||||
STAT_INC(LOAD_GLOBAL, hit);
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[0] = res;
|
||||
|
|
@ -6575,6 +6592,9 @@
|
|||
stack_pointer = _PyFrame_GetStackPointer(frame);
|
||||
if (attr_o == NULL) goto error;
|
||||
attr = PyStackRef_FromPyObjectSteal(attr_o);
|
||||
}
|
||||
// _PUSH_NULL_CONDITIONAL
|
||||
{
|
||||
null = PyStackRef_NULL;
|
||||
}
|
||||
stack_pointer[0] = attr;
|
||||
|
|
|
|||
4
Python/opcode_targets.h
generated
4
Python/opcode_targets.h
generated
|
|
@ -3,6 +3,7 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_BINARY_SLICE,
|
||||
&&TARGET_BINARY_SUBSCR,
|
||||
&&TARGET_BINARY_OP_INPLACE_ADD_UNICODE,
|
||||
&&TARGET_CALL_FUNCTION_EX,
|
||||
&&TARGET_CHECK_EG_MATCH,
|
||||
&&TARGET_CHECK_EXC_MATCH,
|
||||
&&TARGET_CLEANUP_THROW,
|
||||
|
|
@ -15,8 +16,8 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_FORMAT_WITH_SPEC,
|
||||
&&TARGET_GET_AITER,
|
||||
&&TARGET_GET_ANEXT,
|
||||
&&TARGET_GET_ITER,
|
||||
&&TARGET_RESERVED,
|
||||
&&TARGET_GET_ITER,
|
||||
&&TARGET_GET_LEN,
|
||||
&&TARGET_GET_YIELD_FROM_ITER,
|
||||
&&TARGET_INTERPRETER_EXIT,
|
||||
|
|
@ -51,7 +52,6 @@ static void *opcode_targets[256] = {
|
|||
&&TARGET_BUILD_STRING,
|
||||
&&TARGET_BUILD_TUPLE,
|
||||
&&TARGET_CALL,
|
||||
&&TARGET_CALL_FUNCTION_EX,
|
||||
&&TARGET_CALL_INTRINSIC_1,
|
||||
&&TARGET_CALL_INTRINSIC_2,
|
||||
&&TARGET_CALL_KW,
|
||||
|
|
|
|||
|
|
@ -1276,15 +1276,16 @@ uop_optimize(
|
|||
int oparg = buffer[pc].oparg;
|
||||
if (_PyUop_Flags[opcode] & HAS_OPARG_AND_1_FLAG) {
|
||||
buffer[pc].opcode = opcode + 1 + (oparg & 1);
|
||||
assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
|
||||
}
|
||||
else if (oparg < _PyUop_Replication[opcode]) {
|
||||
buffer[pc].opcode = opcode + oparg + 1;
|
||||
assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
|
||||
}
|
||||
else if (is_terminator(&buffer[pc])) {
|
||||
break;
|
||||
}
|
||||
assert(_PyOpcode_uop_name[buffer[pc].opcode]);
|
||||
assert(strncmp(_PyOpcode_uop_name[buffer[pc].opcode], _PyOpcode_uop_name[opcode], strlen(_PyOpcode_uop_name[opcode])) == 0);
|
||||
}
|
||||
OPT_HIST(effective_trace_length(buffer, length), optimized_trace_length_hist);
|
||||
length = prepare_for_execution(buffer, length);
|
||||
|
|
|
|||
|
|
@ -109,10 +109,14 @@ convert_global_to_const(_PyUOpInstruction *inst, PyObject *obj)
|
|||
return NULL;
|
||||
}
|
||||
if (_Py_IsImmortal(res)) {
|
||||
inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_BORROW_WITH_NULL : _LOAD_CONST_INLINE_BORROW;
|
||||
inst->opcode = _LOAD_CONST_INLINE_BORROW;
|
||||
}
|
||||
else {
|
||||
inst->opcode = (inst->oparg & 1) ? _LOAD_CONST_INLINE_WITH_NULL : _LOAD_CONST_INLINE;
|
||||
inst->opcode = _LOAD_CONST_INLINE;
|
||||
}
|
||||
if (inst->oparg & 1) {
|
||||
assert(inst[1].opcode == _PUSH_NULL_CONDITIONAL);
|
||||
assert(inst[1].oparg & 1);
|
||||
}
|
||||
inst->operand0 = (uint64_t)res;
|
||||
return res;
|
||||
|
|
|
|||
|
|
@ -507,16 +507,6 @@ dummy_func(void) {
|
|||
value = sym_new_const(ctx, ptr);
|
||||
}
|
||||
|
||||
op(_LOAD_CONST_INLINE_WITH_NULL, (ptr/4 -- value, null)) {
|
||||
value = sym_new_const(ctx, ptr);
|
||||
null = sym_new_null(ctx);
|
||||
}
|
||||
|
||||
op(_LOAD_CONST_INLINE_BORROW_WITH_NULL, (ptr/4 -- value, null)) {
|
||||
value = sym_new_const(ctx, ptr);
|
||||
null = sym_new_null(ctx);
|
||||
}
|
||||
|
||||
op(_COPY, (bottom, unused[oparg-1] -- bottom, unused[oparg-1], top)) {
|
||||
assert(oparg > 0);
|
||||
top = bottom;
|
||||
|
|
@ -528,9 +518,8 @@ dummy_func(void) {
|
|||
top_out = top_in;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_INSTANCE_VALUE, (offset/1, owner -- attr)) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)offset;
|
||||
(void)owner;
|
||||
}
|
||||
|
|
@ -553,15 +542,22 @@ dummy_func(void) {
|
|||
}
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR, (owner -- attr, self_or_null if (oparg & 1))) {
|
||||
(void)owner;
|
||||
attr = sym_new_not_null(ctx);
|
||||
self_or_null = sym_new_unknown(ctx);
|
||||
op (_PUSH_NULL_CONDITIONAL, ( -- null if (oparg & 1))) {
|
||||
int opcode = (oparg & 1) ? _PUSH_NULL : _NOP;
|
||||
REPLACE_OP(this_instr, opcode, 0, 0);
|
||||
null = sym_new_null(ctx);
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR, (owner -- attr, self_or_null[oparg&1])) {
|
||||
(void)owner;
|
||||
attr = sym_new_not_null(ctx);
|
||||
if (oparg &1) {
|
||||
self_or_null[0] = sym_new_unknown(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_MODULE_FROM_KEYS, (index/1, owner, mod_keys -- attr)) {
|
||||
(void)index;
|
||||
null = sym_new_null(ctx);
|
||||
attr = NULL;
|
||||
if (this_instr[-1].opcode == _NOP) {
|
||||
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
|
||||
|
|
@ -589,41 +585,38 @@ dummy_func(void) {
|
|||
(void)owner;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_WITH_HINT, (hint/1, owner, dict -- attr)) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)hint;
|
||||
(void)owner;
|
||||
(void)dict;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_SLOT, (index/1, owner -- attr)) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)index;
|
||||
(void)owner;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr, null if (oparg & 1))) {
|
||||
op(_LOAD_ATTR_CLASS, (descr/4, owner -- attr)) {
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)descr;
|
||||
(void)owner;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_WITH_VALUES, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
attr = sym_new_not_null(ctx);
|
||||
self = owner;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_NO_DICT, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
attr = sym_new_not_null(ctx);
|
||||
self = owner;
|
||||
}
|
||||
|
||||
op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self if (1))) {
|
||||
op(_LOAD_ATTR_METHOD_LAZY_DICT, (descr/4, owner -- attr, self)) {
|
||||
(void)descr;
|
||||
attr = sym_new_not_null(ctx);
|
||||
self = owner;
|
||||
|
|
|
|||
121
Python/optimizer_cases.c.h
generated
121
Python/optimizer_cases.c.h
generated
|
|
@ -928,12 +928,20 @@
|
|||
|
||||
case _LOAD_GLOBAL: {
|
||||
JitOptSymbol **res;
|
||||
JitOptSymbol *null = NULL;
|
||||
res = &stack_pointer[0];
|
||||
res[0] = sym_new_not_null(ctx);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _PUSH_NULL_CONDITIONAL: {
|
||||
JitOptSymbol *null = NULL;
|
||||
int opcode = (oparg & 1) ? _PUSH_NULL : _NOP;
|
||||
REPLACE_OP(this_instr, opcode, 0, 0);
|
||||
null = sym_new_null(ctx);
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -966,25 +974,15 @@
|
|||
|
||||
case _LOAD_GLOBAL_MODULE_FROM_KEYS: {
|
||||
JitOptSymbol *res;
|
||||
JitOptSymbol *null = NULL;
|
||||
res = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[-1] = res;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_BUILTINS_FROM_KEYS: {
|
||||
JitOptSymbol *res;
|
||||
JitOptSymbol *null = NULL;
|
||||
res = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[-1] = res;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1133,14 +1131,16 @@
|
|||
case _LOAD_ATTR: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *self_or_null = NULL;
|
||||
JitOptSymbol **self_or_null;
|
||||
owner = stack_pointer[-1];
|
||||
self_or_null = &stack_pointer[0];
|
||||
(void)owner;
|
||||
attr = sym_new_not_null(ctx);
|
||||
self_or_null = sym_new_unknown(ctx);
|
||||
if (oparg &1) {
|
||||
self_or_null[0] = sym_new_unknown(ctx);
|
||||
}
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = self_or_null;
|
||||
stack_pointer += (oparg & 1);
|
||||
stack_pointer += (oparg&1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1182,17 +1182,12 @@
|
|||
case _LOAD_ATTR_INSTANCE_VALUE: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t offset = (uint16_t)this_instr->operand0;
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)offset;
|
||||
(void)owner;
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1230,11 +1225,9 @@
|
|||
case _LOAD_ATTR_MODULE_FROM_KEYS: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
owner = stack_pointer[-2];
|
||||
uint16_t index = (uint16_t)this_instr->operand0;
|
||||
(void)index;
|
||||
null = sym_new_null(ctx);
|
||||
attr = NULL;
|
||||
if (this_instr[-1].opcode == _NOP) {
|
||||
// Preceding _CHECK_ATTR_MODULE_PUSH_KEYS was removed: mod is const and dict is watched.
|
||||
|
|
@ -1243,8 +1236,7 @@
|
|||
assert(PyModule_CheckExact(mod));
|
||||
PyObject *dict = mod->md_dict;
|
||||
stack_pointer[-2] = attr;
|
||||
if (oparg & 1) stack_pointer[-1] = null;
|
||||
stack_pointer += -1 + (oparg & 1);
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
PyObject *res = convert_global_to_const(this_instr, dict);
|
||||
if (res != NULL) {
|
||||
|
|
@ -1254,7 +1246,7 @@
|
|||
else {
|
||||
this_instr->opcode = _LOAD_ATTR_MODULE;
|
||||
}
|
||||
stack_pointer += 1 - (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
}
|
||||
if (attr == NULL) {
|
||||
|
|
@ -1262,8 +1254,7 @@
|
|||
attr = sym_new_not_null(ctx);
|
||||
}
|
||||
stack_pointer[-2] = attr;
|
||||
if (oparg & 1) stack_pointer[-1] = null;
|
||||
stack_pointer += -1 + (oparg & 1);
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1284,18 +1275,15 @@
|
|||
JitOptSymbol *dict;
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
dict = stack_pointer[-1];
|
||||
owner = stack_pointer[-2];
|
||||
uint16_t hint = (uint16_t)this_instr->operand0;
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)hint;
|
||||
(void)owner;
|
||||
(void)dict;
|
||||
stack_pointer[-2] = attr;
|
||||
if (oparg & 1) stack_pointer[-1] = null;
|
||||
stack_pointer += -1 + (oparg & 1);
|
||||
stack_pointer += -1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -1303,17 +1291,12 @@
|
|||
case _LOAD_ATTR_SLOT: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
owner = stack_pointer[-1];
|
||||
uint16_t index = (uint16_t)this_instr->operand0;
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)index;
|
||||
(void)owner;
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1324,17 +1307,12 @@
|
|||
case _LOAD_ATTR_CLASS: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)this_instr->operand0;
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
(void)descr;
|
||||
(void)owner;
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -1723,7 +1701,7 @@
|
|||
case _LOAD_ATTR_METHOD_WITH_VALUES: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *self = NULL;
|
||||
JitOptSymbol *self;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)this_instr->operand0;
|
||||
(void)descr;
|
||||
|
|
@ -1739,7 +1717,7 @@
|
|||
case _LOAD_ATTR_METHOD_NO_DICT: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *self = NULL;
|
||||
JitOptSymbol *self;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)this_instr->operand0;
|
||||
(void)descr;
|
||||
|
|
@ -1773,7 +1751,7 @@
|
|||
case _LOAD_ATTR_METHOD_LAZY_DICT: {
|
||||
JitOptSymbol *owner;
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *self = NULL;
|
||||
JitOptSymbol *self;
|
||||
owner = stack_pointer[-1];
|
||||
PyObject *descr = (PyObject *)this_instr->operand0;
|
||||
(void)descr;
|
||||
|
|
@ -2262,11 +2240,11 @@
|
|||
|
||||
case _MAKE_CALLARGS_A_TUPLE: {
|
||||
JitOptSymbol *tuple;
|
||||
JitOptSymbol *kwargs_out = NULL;
|
||||
JitOptSymbol *kwargs_out;
|
||||
tuple = sym_new_not_null(ctx);
|
||||
kwargs_out = sym_new_not_null(ctx);
|
||||
stack_pointer[-1 - (oparg & 1)] = tuple;
|
||||
if (oparg & 1) stack_pointer[-(oparg & 1)] = kwargs_out;
|
||||
stack_pointer[-2] = tuple;
|
||||
stack_pointer[-1] = kwargs_out;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2315,8 +2293,8 @@
|
|||
case _BUILD_SLICE: {
|
||||
JitOptSymbol *slice;
|
||||
slice = sym_new_not_null(ctx);
|
||||
stack_pointer[-2 - ((oparg == 3) ? 1 : 0)] = slice;
|
||||
stack_pointer += -1 - ((oparg == 3) ? 1 : 0);
|
||||
stack_pointer[-oparg] = slice;
|
||||
stack_pointer += 1 - oparg;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
|
@ -2607,69 +2585,32 @@
|
|||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST_INLINE_WITH_NULL: {
|
||||
JitOptSymbol *value;
|
||||
JitOptSymbol *null;
|
||||
PyObject *ptr = (PyObject *)this_instr->operand0;
|
||||
value = sym_new_const(ctx, ptr);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = null;
|
||||
stack_pointer += 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_CONST_INLINE_BORROW_WITH_NULL: {
|
||||
JitOptSymbol *value;
|
||||
JitOptSymbol *null;
|
||||
PyObject *ptr = (PyObject *)this_instr->operand0;
|
||||
value = sym_new_const(ctx, ptr);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[0] = value;
|
||||
stack_pointer[1] = null;
|
||||
stack_pointer += 2;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _CHECK_FUNCTION: {
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_MODULE: {
|
||||
JitOptSymbol *res;
|
||||
JitOptSymbol *null = NULL;
|
||||
res = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_GLOBAL_BUILTINS: {
|
||||
JitOptSymbol *res;
|
||||
JitOptSymbol *null = NULL;
|
||||
res = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[0] = res;
|
||||
if (oparg & 1) stack_pointer[1] = null;
|
||||
stack_pointer += 1 + (oparg & 1);
|
||||
stack_pointer += 1;
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
case _LOAD_ATTR_MODULE: {
|
||||
JitOptSymbol *attr;
|
||||
JitOptSymbol *null = NULL;
|
||||
attr = sym_new_not_null(ctx);
|
||||
null = sym_new_null(ctx);
|
||||
stack_pointer[-1] = attr;
|
||||
if (oparg & 1) stack_pointer[0] = null;
|
||||
stack_pointer += (oparg & 1);
|
||||
assert(WITHIN_STACK_BOUNDS());
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue