summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2007-02-25 19:44:48 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2007-02-25 19:44:48 (GMT)
commitee3a1b5244e60566c5d5c8f6a1ea4b381de99f1c (patch)
treead52a17fc77530870a575107a7cea9c27de17606 /Objects
parent5a3e812444609329b30be837a08c11269d917b72 (diff)
downloadcpython-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.c2
-rw-r--r--Objects/exceptions.c3
-rw-r--r--Objects/intobject.c2
-rw-r--r--Objects/listobject.c2
-rw-r--r--Objects/longobject.c2
-rw-r--r--Objects/stringobject.c2
-rw-r--r--Objects/tupleobject.c2
-rw-r--r--Objects/typeobject.c22
-rw-r--r--Objects/unicodeobject.c2
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 */