diff options
author | Neal Norwitz <nnorwitz@gmail.com> | 2007-02-25 19:44:48 (GMT) |
---|---|---|
committer | Neal Norwitz <nnorwitz@gmail.com> | 2007-02-25 19:44:48 (GMT) |
commit | ee3a1b5244e60566c5d5c8f6a1ea4b381de99f1c (patch) | |
tree | ad52a17fc77530870a575107a7cea9c27de17606 /Objects | |
parent | 5a3e812444609329b30be837a08c11269d917b72 (diff) | |
download | cpython-ee3a1b5244e60566c5d5c8f6a1ea4b381de99f1c.zip cpython-ee3a1b5244e60566c5d5c8f6a1ea4b381de99f1c.tar.gz cpython-ee3a1b5244e60566c5d5c8f6a1ea4b381de99f1c.tar.bz2 |
Variation of patch # 1624059 to speed up checking if an object is a subclass
of some of the common builtin types.
Use a bit in tp_flags for each common builtin type. Check the bit
to determine if any instance is a subclass of these common types.
The check avoids a function call and O(n) search of the base classes.
The check is done in the various Py*_Check macros rather than calling
PyType_IsSubtype().
All the bits are set in tp_flags when the type is declared
in the Objects/*object.c files because PyType_Ready() is not called
for all the types. Should PyType_Ready() be called for all types?
If so and the change is made, the changes to the Objects/*object.c files
can be reverted (remove setting the tp_flags). Objects/typeobject.c
would also have to be modified to add conditions
for Py*_CheckExact() in addition to each the PyType_IsSubtype check.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/dictobject.c | 2 | ||||
-rw-r--r-- | Objects/exceptions.c | 3 | ||||
-rw-r--r-- | Objects/intobject.c | 2 | ||||
-rw-r--r-- | Objects/listobject.c | 2 | ||||
-rw-r--r-- | Objects/longobject.c | 2 | ||||
-rw-r--r-- | Objects/stringobject.c | 2 | ||||
-rw-r--r-- | Objects/tupleobject.c | 2 | ||||
-rw-r--r-- | Objects/typeobject.c | 22 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 2 |
9 files changed, 30 insertions, 9 deletions
diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 1cb3ee6..587dad3 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -2112,7 +2112,7 @@ PyTypeObject PyDict_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_DICT_SUBCLASS, /* tp_flags */ dictionary_doc, /* tp_doc */ dict_traverse, /* tp_traverse */ dict_tp_clear, /* tp_clear */ diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 0cd819c..c6ea6a4 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -300,7 +300,8 @@ static PyTypeObject _PyExc_BaseException = { PyObject_GenericGetAttr, /*tp_getattro*/ PyObject_GenericSetAttr, /*tp_setattro*/ 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC | + Py_TPFLAGS_BASE_EXC_SUBCLASS, /*tp_flags*/ PyDoc_STR("Common base class for all exceptions"), /* tp_doc */ (traverseproc)BaseException_traverse, /* tp_traverse */ (inquiry)BaseException_clear, /* tp_clear */ diff --git a/Objects/intobject.c b/Objects/intobject.c index f504af7..9ffc295 100644 --- a/Objects/intobject.c +++ b/Objects/intobject.c @@ -1138,7 +1138,7 @@ PyTypeObject PyInt_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS, /* tp_flags */ int_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/listobject.c b/Objects/listobject.c index 3083b5f..2ac5e86 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -2672,7 +2672,7 @@ PyTypeObject PyList_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LIST_SUBCLASS, /* tp_flags */ list_doc, /* tp_doc */ (traverseproc)list_traverse, /* tp_traverse */ (inquiry)list_clear, /* tp_clear */ diff --git a/Objects/longobject.c b/Objects/longobject.c index 4d886cd..ef3e242 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3418,7 +3418,7 @@ PyTypeObject PyLong_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */ long_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 416457d..ca94d72 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -4017,7 +4017,7 @@ PyTypeObject PyString_Type = { 0, /* tp_setattro */ &string_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_STRING_SUBCLASS, /* tp_flags */ string_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index c85b35a..dacc3ee 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -669,7 +669,7 @@ PyTypeObject PyTuple_Type = { 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TUPLE_SUBCLASS, /* tp_flags */ tuple_doc, /* tp_doc */ (traverseproc)tupletraverse, /* tp_traverse */ 0, /* tp_clear */ diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 20b530c..4b0816e 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2288,7 +2288,7 @@ PyTypeObject PyType_Type = { (setattrofunc)type_setattro, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_TYPE_SUBCLASS, /* tp_flags */ type_doc, /* tp_doc */ (traverseproc)type_traverse, /* tp_traverse */ (inquiry)type_clear, /* tp_clear */ @@ -2967,6 +2967,26 @@ inherit_special(PyTypeObject *type, PyTypeObject *base) if (type->tp_flags & base->tp_flags & Py_TPFLAGS_HAVE_CLASS) { COPYVAL(tp_dictoffset); } + + /* Setup fast subclass flags */ + if (PyType_IsSubtype(base, (PyTypeObject*)PyExc_BaseException)) + type->tp_flags |= Py_TPFLAGS_BASE_EXC_SUBCLASS; + else if (PyType_IsSubtype(base, &PyType_Type)) + type->tp_flags |= Py_TPFLAGS_TYPE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyInt_Type)) + type->tp_flags |= Py_TPFLAGS_INT_SUBCLASS; + else if (PyType_IsSubtype(base, &PyLong_Type)) + type->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS; + else if (PyType_IsSubtype(base, &PyString_Type)) + type->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS; + else if (PyType_IsSubtype(base, &PyUnicode_Type)) + type->tp_flags |= Py_TPFLAGS_UNICODE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyTuple_Type)) + type->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS; + else if (PyType_IsSubtype(base, &PyList_Type)) + type->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS; + else if (PyType_IsSubtype(base, &PyDict_Type)) + type->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS; } static void diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 290e8df..a49fe39 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -7967,7 +7967,7 @@ PyTypeObject PyUnicode_Type = { 0, /* tp_setattro */ &unicode_as_buffer, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES | - Py_TPFLAGS_BASETYPE, /* tp_flags */ + Py_TPFLAGS_BASETYPE | Py_TPFLAGS_UNICODE_SUBCLASS, /* tp_flags */ unicode_doc, /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ |