diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2023-04-27 22:19:43 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-27 22:19:43 (GMT) |
commit | d2e2e53f733f8c8098035bbbc452bd1892796cb3 (patch) | |
tree | 4f01c11ff1f6ad9ebbcd4786bca991878226a4c6 | |
parent | 56c7176d1de3a0770085cad3865c1de42ba86f42 (diff) | |
download | cpython-d2e2e53f733f8c8098035bbbc452bd1892796cb3.zip cpython-d2e2e53f733f8c8098035bbbc452bd1892796cb3.tar.gz cpython-d2e2e53f733f8c8098035bbbc452bd1892796cb3.tar.bz2 |
gh-94673: Ensure Builtin Static Types are Readied Properly (gh-103940)
There were cases where we do unnecessary work for builtin static types. This also simplifies some work necessary for a per-interpreter GIL.
-rw-r--r-- | Include/internal/pycore_bytesobject.h | 5 | ||||
-rw-r--r-- | Include/internal/pycore_tuple.h | 1 | ||||
-rw-r--r-- | Modules/_io/_iomodule.c | 10 | ||||
-rw-r--r-- | Modules/mathmodule.c | 2 | ||||
-rw-r--r-- | Modules/symtablemodule.c | 7 | ||||
-rw-r--r-- | Objects/bytesobject.c | 19 | ||||
-rw-r--r-- | Objects/classobject.c | 4 | ||||
-rw-r--r-- | Objects/exceptions.c | 4 | ||||
-rw-r--r-- | Objects/floatobject.c | 16 | ||||
-rw-r--r-- | Objects/longobject.c | 14 | ||||
-rw-r--r-- | Objects/object.c | 7 | ||||
-rw-r--r-- | Objects/structseq.c | 24 | ||||
-rw-r--r-- | Objects/tupleobject.c | 18 | ||||
-rw-r--r-- | Objects/typeobject.c | 64 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 4 | ||||
-rw-r--r-- | Python/bltinmodule.c | 2 | ||||
-rw-r--r-- | Python/errors.c | 12 | ||||
-rw-r--r-- | Python/modsupport.c | 3 | ||||
-rw-r--r-- | Python/pylifecycle.c | 12 | ||||
-rw-r--r-- | Python/sysmodule.c | 22 | ||||
-rw-r--r-- | Python/thread.c | 6 |
21 files changed, 88 insertions, 168 deletions
diff --git a/Include/internal/pycore_bytesobject.h b/Include/internal/pycore_bytesobject.h index 9173a4f..d36fa95 100644 --- a/Include/internal/pycore_bytesobject.h +++ b/Include/internal/pycore_bytesobject.h @@ -9,11 +9,6 @@ extern "C" { #endif -/* runtime lifecycle */ - -extern PyStatus _PyBytes_InitTypes(PyInterpreterState *); - - /* Substring Search. Returns the index of the first occurrence of diff --git a/Include/internal/pycore_tuple.h b/Include/internal/pycore_tuple.h index edc7084..335edad 100644 --- a/Include/internal/pycore_tuple.h +++ b/Include/internal/pycore_tuple.h @@ -14,7 +14,6 @@ extern "C" { /* runtime lifecycle */ extern PyStatus _PyTuple_InitGlobalObjects(PyInterpreterState *); -extern PyStatus _PyTuple_InitTypes(PyInterpreterState *); extern void _PyTuple_Fini(PyInterpreterState *); diff --git a/Modules/_io/_iomodule.c b/Modules/_io/_iomodule.c index 7f4f1d9..a3bfbc9 100644 --- a/Modules/_io/_iomodule.c +++ b/Modules/_io/_iomodule.c @@ -671,13 +671,11 @@ static PyTypeObject* static_types[] = { PyStatus _PyIO_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - // Set type base classes #ifdef HAVE_WINDOWS_CONSOLE_IO - PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + if (_Py_IsMainInterpreter(interp)) { + // Set type base classes + PyWindowsConsoleIO_Type.tp_base = &PyRawIOBase_Type; + } #endif for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index eddc1a3..a5e82d5 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -2096,7 +2096,7 @@ math_trunc(PyObject *module, PyObject *x) return PyFloat_Type.tp_as_number->nb_int(x); } - if (Py_TYPE(x)->tp_dict == NULL) { + if (_PyType_IsReady(Py_TYPE(x))) { if (PyType_Ready(Py_TYPE(x)) < 0) return NULL; } diff --git a/Modules/symtablemodule.c b/Modules/symtablemodule.c index 4ef1d8c..91538b4 100644 --- a/Modules/symtablemodule.c +++ b/Modules/symtablemodule.c @@ -67,12 +67,6 @@ static PyMethodDef symtable_methods[] = { }; static int -symtable_init_stentry_type(PyObject *m) -{ - return PyType_Ready(&PySTEntry_Type); -} - -static int symtable_init_constants(PyObject *m) { if (PyModule_AddIntMacro(m, USE) < 0) return -1; @@ -105,7 +99,6 @@ symtable_init_constants(PyObject *m) } static PyModuleDef_Slot symtable_slots[] = { - {Py_mod_exec, symtable_init_stentry_type}, {Py_mod_exec, symtable_init_constants}, {0, NULL} }; diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 2d8dab6..27b2ad4 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -3090,25 +3090,6 @@ error: } -PyStatus -_PyBytes_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyBytes_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes type"); - } - - if (PyType_Ready(&PyBytesIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize bytes iterator type"); - } - - return _PyStatus_OK(); -} - - /*********************** Bytes Iterator ****************************/ typedef struct { diff --git a/Objects/classobject.c b/Objects/classobject.c index 2cb192e..71c4a4e 100644 --- a/Objects/classobject.c +++ b/Objects/classobject.c @@ -181,7 +181,7 @@ method_getattro(PyObject *obj, PyObject *name) PyObject *descr = NULL; { - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } @@ -395,7 +395,7 @@ instancemethod_getattro(PyObject *self, PyObject *name) PyTypeObject *tp = Py_TYPE(self); PyObject *descr = NULL; - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return NULL; } diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 55a6768..6c9dfbd 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -3596,10 +3596,6 @@ static struct static_exception static_exceptions[] = { int _PyExc_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return 0; - } - for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { PyTypeObject *exc = static_exceptions[i].exc; if (_PyStaticType_InitBuiltin(exc) < 0) { diff --git a/Objects/floatobject.c b/Objects/floatobject.c index d641311..9c23157 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1990,20 +1990,10 @@ _PyFloat_InitState(PyInterpreterState *interp) PyStatus _PyFloat_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyFloat_Type) < 0) { - return _PyStatus_ERR("Can't initialize float type"); - } - /* Init float info */ - if (FloatInfoType.tp_name == NULL) { - if (_PyStructSequence_InitBuiltin(&FloatInfoType, - &floatinfo_desc) < 0) { - return _PyStatus_ERR("can't init float info type"); - } + if (_PyStructSequence_InitBuiltin(&FloatInfoType, + &floatinfo_desc) < 0) { + return _PyStatus_ERR("can't init float info type"); } return _PyStatus_OK(); diff --git a/Objects/longobject.c b/Objects/longobject.c index d98bbbb..f84809b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -6351,19 +6351,9 @@ PyLong_GetInfo(void) PyStatus _PyLong_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyLong_Type) < 0) { - return _PyStatus_ERR("Can't initialize int type"); - } - /* initialize int_info */ - if (Int_InfoType.tp_name == NULL) { - if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) { - return _PyStatus_ERR("can't init int info type"); - } + if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) { + return _PyStatus_ERR("can't init int info type"); } return _PyStatus_OK(); diff --git a/Objects/object.c b/Objects/object.c index 65c296e..cd61029 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -890,7 +890,7 @@ PyObject_Hash(PyObject *v) * an explicit call to PyType_Ready, we implicitly call * PyType_Ready here and then check the tp_hash slot again */ - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) return -1; if (tp->tp_hash != NULL) @@ -1385,7 +1385,7 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, } Py_INCREF(name); - if (tp->tp_dict == NULL) { + if (!_PyType_IsReady(tp)) { if (PyType_Ready(tp) < 0) goto done; } @@ -1507,8 +1507,9 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name, return -1; } - if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + if (!_PyType_IsReady(tp) && PyType_Ready(tp) < 0) { return -1; + } Py_INCREF(name); Py_INCREF(tp); diff --git a/Objects/structseq.c b/Objects/structseq.c index 2a53438..727d728 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -509,6 +509,13 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type, PyStructSequence_Desc *desc, unsigned long tp_flags) { + if (type->tp_flags & Py_TPFLAGS_READY) { + if (_PyStaticType_InitBuiltin(type) < 0) { + goto failed_init_builtin; + } + return 0; + } + PyMemberDef *members; Py_ssize_t n_members, n_unnamed_members; @@ -517,18 +524,25 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type, return -1; } initialize_static_fields(type, desc, members, tp_flags); + + Py_INCREF(type); // XXX It should be immortal. if (_PyStaticType_InitBuiltin(type) < 0) { PyMem_Free(members); - PyErr_Format(PyExc_RuntimeError, - "Can't initialize builtin type %s", - desc->name); - return -1; + goto failed_init_builtin; } - if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + + if (initialize_structseq_dict( + desc, type->tp_dict, n_members, n_unnamed_members) < 0) { PyMem_Free(members); return -1; } return 0; + +failed_init_builtin: + PyErr_Format(PyExc_RuntimeError, + "Can't initialize builtin type %s", + desc->name); + return -1; } int diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 61fab40..991edcc 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -960,24 +960,6 @@ _PyTuple_Resize(PyObject **pv, Py_ssize_t newsize) } -PyStatus -_PyTuple_InitTypes(PyInterpreterState *interp) -{ - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (PyType_Ready(&PyTuple_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple type"); - } - - if (PyType_Ready(&PyTupleIter_Type) < 0) { - return _PyStatus_ERR("Can't initialize tuple iterator type"); - } - - return _PyStatus_OK(); -} - static void maybe_freelist_clear(PyInterpreterState *, int); void diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 9194eba..38b9931 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6948,8 +6948,12 @@ type_ready_post_checks(PyTypeObject *type) static int type_ready(PyTypeObject *type) { + _PyObject_ASSERT((PyObject *)type, + (type->tp_flags & Py_TPFLAGS_READYING) == 0); + type->tp_flags |= Py_TPFLAGS_READYING; + if (type_ready_pre_checks(type) < 0) { - return -1; + goto error; } #ifdef Py_TRACE_REFS @@ -6963,41 +6967,49 @@ type_ready(PyTypeObject *type) /* Initialize tp_dict: _PyType_IsReady() tests if tp_dict != NULL */ if (type_ready_set_dict(type) < 0) { - return -1; + goto error; } if (type_ready_set_bases(type) < 0) { - return -1; + goto error; } if (type_ready_mro(type) < 0) { - return -1; + goto error; } if (type_ready_set_new(type) < 0) { - return -1; + goto error; } if (type_ready_fill_dict(type) < 0) { - return -1; + goto error; } if (type_ready_inherit(type) < 0) { - return -1; + goto error; } if (type_ready_preheader(type) < 0) { - return -1; + goto error; } if (type_ready_set_hash(type) < 0) { - return -1; + goto error; } if (type_ready_add_subclasses(type) < 0) { - return -1; + goto error; } if (type_ready_managed_dict(type) < 0) { - return -1; + goto error; } if (type_ready_post_checks(type) < 0) { - return -1; + goto error; } + + /* All done -- set the ready flag */ + type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; + + assert(_PyType_CheckConsistency(type)); return 0; -} +error: + type->tp_flags &= ~Py_TPFLAGS_READYING; + return -1; +} int PyType_Ready(PyTypeObject *type) @@ -7006,31 +7018,29 @@ PyType_Ready(PyTypeObject *type) assert(_PyType_CheckConsistency(type)); return 0; } - _PyObject_ASSERT((PyObject *)type, - (type->tp_flags & Py_TPFLAGS_READYING) == 0); - - type->tp_flags |= Py_TPFLAGS_READYING; + assert(!(type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN)); /* Historically, all static types were immutable. See bpo-43908 */ if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) { type->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; } - if (type_ready(type) < 0) { - type->tp_flags &= ~Py_TPFLAGS_READYING; - return -1; - } - - /* All done -- set the ready flag */ - type->tp_flags = (type->tp_flags & ~Py_TPFLAGS_READYING) | Py_TPFLAGS_READY; - assert(_PyType_CheckConsistency(type)); - return 0; + return type_ready(type); } int _PyStaticType_InitBuiltin(PyTypeObject *self) { + assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE)); + + if (self->tp_flags & Py_TPFLAGS_READY) { + assert(self->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN); + assert(_PyType_CheckConsistency(self)); + return 0; + } + self->tp_flags |= _Py_TPFLAGS_STATIC_BUILTIN; + self->tp_flags |= Py_TPFLAGS_IMMUTABLETYPE; assert(NEXT_GLOBAL_VERSION_TAG <= _Py_MAX_GLOBAL_TYPE_VERSION_TAG); self->tp_version_tag = NEXT_GLOBAL_VERSION_TAG++; @@ -7038,7 +7048,7 @@ _PyStaticType_InitBuiltin(PyTypeObject *self) static_builtin_state_init(self); - int res = PyType_Ready(self); + int res = type_ready(self); if (res < 0) { static_builtin_state_clear(self); } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index fd056e3..7537c12 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14573,10 +14573,6 @@ _PyUnicode_InitGlobalObjects(PyInterpreterState *interp) PyStatus _PyUnicode_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) { goto error; } diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index fcb4d7a..8840bba 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -2316,7 +2316,7 @@ builtin_round_impl(PyObject *module, PyObject *number, PyObject *ndigits) { PyObject *round, *result; - if (Py_TYPE(number)->tp_dict == NULL) { + if (!_PyType_IsReady(Py_TYPE(number))) { if (PyType_Ready(Py_TYPE(number)) < 0) return NULL; } diff --git a/Python/errors.c b/Python/errors.c index 0ff6a0d..7fc2673 100644 --- a/Python/errors.c +++ b/Python/errors.c @@ -1342,15 +1342,9 @@ static PyStructSequence_Desc UnraisableHookArgs_desc = { PyStatus _PyErr_InitTypes(PyInterpreterState *interp) { - if (!_Py_IsMainInterpreter(interp)) { - return _PyStatus_OK(); - } - - if (UnraisableHookArgsType.tp_name == NULL) { - if (_PyStructSequence_InitBuiltin(&UnraisableHookArgsType, - &UnraisableHookArgs_desc) < 0) { - return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); - } + if (_PyStructSequence_InitBuiltin(&UnraisableHookArgsType, + &UnraisableHookArgs_desc) < 0) { + return _PyStatus_ERR("failed to initialize UnraisableHookArgs type"); } return _PyStatus_OK(); } diff --git a/Python/modsupport.c b/Python/modsupport.c index 7569845..be229c9 100644 --- a/Python/modsupport.c +++ b/Python/modsupport.c @@ -3,6 +3,7 @@ #include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() +#include "pycore_object.h" // _PyType_IsReady() #define FLAG_SIZE_T 1 typedef double va_double; @@ -693,7 +694,7 @@ PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) int PyModule_AddType(PyObject *module, PyTypeObject *type) { - if (PyType_Ready(type) < 0) { + if (!_PyType_IsReady(type) && PyType_Ready(type) < 0) { return -1; } diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index ebf1a0b..d525fb1 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2,7 +2,6 @@ #include "Python.h" -#include "pycore_bytesobject.h" // _PyBytes_InitTypes() #include "pycore_ceval.h" // _PyEval_FiniGIL() #include "pycore_context.h" // _PyContext_Init() #include "pycore_exceptions.h" // _PyExc_InitTypes() @@ -26,7 +25,6 @@ #include "pycore_sliceobject.h" // _PySlice_Fini() #include "pycore_sysmodule.h" // _PySys_ClearAuditHooks() #include "pycore_traceback.h" // _Py_DumpTracebackThreads() -#include "pycore_tuple.h" // _PyTuple_InitTypes() #include "pycore_typeobject.h" // _PyTypes_InitTypes() #include "pycore_unicodeobject.h" // _PyUnicode_InitTypes() #include "opcode.h" @@ -684,11 +682,6 @@ pycore_init_types(PyInterpreterState *interp) return status; } - status = _PyBytes_InitTypes(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - status = _PyLong_InitTypes(interp); if (_PyStatus_EXCEPTION(status)) { return status; @@ -704,11 +697,6 @@ pycore_init_types(PyInterpreterState *interp) return status; } - status = _PyTuple_InitTypes(interp); - if (_PyStatus_EXCEPTION(status)) { - return status; - } - if (_PyExc_InitTypes(interp) < 0) { return _PyStatus_ERR("failed to initialize an exception type"); } diff --git a/Python/sysmodule.c b/Python/sysmodule.c index 58ed488..d673e40 100644 --- a/Python/sysmodule.c +++ b/Python/sysmodule.c @@ -3166,10 +3166,8 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("float_info", PyFloat_GetInfo()); SET_SYS("int_info", PyLong_GetInfo()); /* initialize hash_info */ - if (Hash_InfoType.tp_name == NULL) { - if (_PyStructSequence_InitBuiltin(&Hash_InfoType, &hash_info_desc) < 0) { - goto type_init_failed; - } + if (_PyStructSequence_InitBuiltin(&Hash_InfoType, &hash_info_desc) < 0) { + goto type_init_failed; } SET_SYS("hash_info", get_hash_info(tstate)); SET_SYS("maxunicode", PyLong_FromLong(0x10FFFF)); @@ -3191,11 +3189,9 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) #define ENSURE_INFO_TYPE(TYPE, DESC) \ do { \ - if (TYPE.tp_name == NULL) { \ - if (_PyStructSequence_InitBuiltinWithFlags( \ - &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \ - goto type_init_failed; \ - } \ + if (_PyStructSequence_InitBuiltinWithFlags( \ + &TYPE, &DESC, Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) { \ + goto type_init_failed; \ } \ } while (0) @@ -3230,11 +3226,9 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict) SET_SYS("thread_info", PyThread_GetInfo()); /* initialize asyncgen_hooks */ - if (AsyncGenHooksType.tp_name == NULL) { - if (_PyStructSequence_InitBuiltin( - &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { - goto type_init_failed; - } + if (_PyStructSequence_InitBuiltin( + &AsyncGenHooksType, &asyncgen_hooks_desc) < 0) { + goto type_init_failed; } #ifdef __EMSCRIPTEN__ diff --git a/Python/thread.c b/Python/thread.c index 4581f1a..7fdedb0 100644 --- a/Python/thread.c +++ b/Python/thread.c @@ -137,10 +137,8 @@ PyThread_GetInfo(void) int len; #endif - if (ThreadInfoType.tp_name == 0) { - if (_PyStructSequence_InitBuiltin(&ThreadInfoType, - &threadinfo_desc) < 0) - return NULL; + if (_PyStructSequence_InitBuiltin(&ThreadInfoType, &threadinfo_desc) < 0) { + return NULL; } threadinfo = PyStructSequence_New(&ThreadInfoType); |