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 /Include | |
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 'Include')
-rw-r--r-- | Include/dictobject.h | 3 | ||||
-rw-r--r-- | Include/intobject.h | 3 | ||||
-rw-r--r-- | Include/listobject.h | 3 | ||||
-rw-r--r-- | Include/longobject.h | 3 | ||||
-rw-r--r-- | Include/object.h | 15 | ||||
-rw-r--r-- | Include/pyerrors.h | 8 | ||||
-rw-r--r-- | Include/stringobject.h | 3 | ||||
-rw-r--r-- | Include/tupleobject.h | 3 | ||||
-rw-r--r-- | Include/unicodeobject.h | 3 |
9 files changed, 31 insertions, 13 deletions
diff --git a/Include/dictobject.h b/Include/dictobject.h index 44b0838..ec2e0c8 100644 --- a/Include/dictobject.h +++ b/Include/dictobject.h @@ -90,7 +90,8 @@ struct _dictobject { PyAPI_DATA(PyTypeObject) PyDict_Type; -#define PyDict_Check(op) PyObject_TypeCheck(op, &PyDict_Type) +#define PyDict_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_DICT_SUBCLASS) #define PyDict_CheckExact(op) ((op)->ob_type == &PyDict_Type) PyAPI_FUNC(PyObject *) PyDict_New(void); diff --git a/Include/intobject.h b/Include/intobject.h index 1f4846e..51d3e1b 100644 --- a/Include/intobject.h +++ b/Include/intobject.h @@ -27,7 +27,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyInt_Type; -#define PyInt_Check(op) PyObject_TypeCheck(op, &PyInt_Type) +#define PyInt_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_INT_SUBCLASS) #define PyInt_CheckExact(op) ((op)->ob_type == &PyInt_Type) PyAPI_FUNC(PyObject *) PyInt_FromString(char*, char**, int); diff --git a/Include/listobject.h b/Include/listobject.h index d9012ce..db3124e 100644 --- a/Include/listobject.h +++ b/Include/listobject.h @@ -40,7 +40,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyList_Type; -#define PyList_Check(op) PyObject_TypeCheck(op, &PyList_Type) +#define PyList_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_LIST_SUBCLASS) #define PyList_CheckExact(op) ((op)->ob_type == &PyList_Type) PyAPI_FUNC(PyObject *) PyList_New(Py_ssize_t size); diff --git a/Include/longobject.h b/Include/longobject.h index eef4e9b..3893ad6 100644 --- a/Include/longobject.h +++ b/Include/longobject.h @@ -11,7 +11,8 @@ typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */ PyAPI_DATA(PyTypeObject) PyLong_Type; -#define PyLong_Check(op) PyObject_TypeCheck(op, &PyLong_Type) +#define PyLong_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_LONG_SUBCLASS) #define PyLong_CheckExact(op) ((op)->ob_type == &PyLong_Type) PyAPI_FUNC(PyObject *) PyLong_FromLong(long); diff --git a/Include/object.h b/Include/object.h index b0817e6..0f6ff77 100644 --- a/Include/object.h +++ b/Include/object.h @@ -376,7 +376,8 @@ PyAPI_DATA(PyTypeObject) PyType_Type; /* built-in 'type' */ PyAPI_DATA(PyTypeObject) PyBaseObject_Type; /* built-in 'object' */ PyAPI_DATA(PyTypeObject) PySuper_Type; /* built-in 'super' */ -#define PyType_Check(op) PyObject_TypeCheck(op, &PyType_Type) +#define PyType_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_TYPE_SUBCLASS) #define PyType_CheckExact(op) ((op)->ob_type == &PyType_Type) PyAPI_FUNC(int) PyType_Ready(PyTypeObject *); @@ -517,6 +518,17 @@ given type object has a specified feature. /* Objects support nb_index in PyNumberMethods */ #define Py_TPFLAGS_HAVE_INDEX (1L<<17) +/* These flags are used to determine if a type is a subclass. */ +#define Py_TPFLAGS_INT_SUBCLASS (1L<<23) +#define Py_TPFLAGS_LONG_SUBCLASS (1L<<24) +#define Py_TPFLAGS_LIST_SUBCLASS (1L<<25) +#define Py_TPFLAGS_TUPLE_SUBCLASS (1L<<26) +#define Py_TPFLAGS_STRING_SUBCLASS (1L<<27) +#define Py_TPFLAGS_UNICODE_SUBCLASS (1L<<28) +#define Py_TPFLAGS_DICT_SUBCLASS (1L<<29) +#define Py_TPFLAGS_BASE_EXC_SUBCLASS (1L<<30) +#define Py_TPFLAGS_TYPE_SUBCLASS (1L<<31) + #define Py_TPFLAGS_DEFAULT ( \ Py_TPFLAGS_HAVE_GETCHARBUFFER | \ Py_TPFLAGS_HAVE_SEQUENCE_IN | \ @@ -530,6 +542,7 @@ given type object has a specified feature. 0) #define PyType_HasFeature(t,f) (((t)->tp_flags & (f)) != 0) +#define PyType_FastSubclass(t,f) PyType_HasFeature(t,f) /* diff --git a/Include/pyerrors.h b/Include/pyerrors.h index 9532e32..9671692 100644 --- a/Include/pyerrors.h +++ b/Include/pyerrors.h @@ -95,14 +95,12 @@ PyAPI_FUNC(void) PyErr_NormalizeException(PyObject**, PyObject**, PyObject**); /* */ #define PyExceptionClass_Check(x) \ - (PyClass_Check((x)) \ - || (PyType_Check((x)) && PyType_IsSubtype( \ - (PyTypeObject*)(x), (PyTypeObject*)PyExc_BaseException))) - + (PyClass_Check((x)) || (PyType_Check((x)) && \ + PyType_FastSubclass((PyTypeObject*)(x), Py_TPFLAGS_BASE_EXC_SUBCLASS))) #define PyExceptionInstance_Check(x) \ (PyInstance_Check((x)) || \ - (PyType_IsSubtype((x)->ob_type, (PyTypeObject*)PyExc_BaseException))) + PyType_FastSubclass((x)->ob_type, Py_TPFLAGS_BASE_EXC_SUBCLASS)) #define PyExceptionClass_Name(x) \ (PyClass_Check((x)) \ diff --git a/Include/stringobject.h b/Include/stringobject.h index 5f8a6f0..03c3777 100644 --- a/Include/stringobject.h +++ b/Include/stringobject.h @@ -55,7 +55,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyBaseString_Type; PyAPI_DATA(PyTypeObject) PyString_Type; -#define PyString_Check(op) PyObject_TypeCheck(op, &PyString_Type) +#define PyString_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_STRING_SUBCLASS) #define PyString_CheckExact(op) ((op)->ob_type == &PyString_Type) PyAPI_FUNC(PyObject *) PyString_FromStringAndSize(const char *, Py_ssize_t); diff --git a/Include/tupleobject.h b/Include/tupleobject.h index 8c37cab..738cea1 100644 --- a/Include/tupleobject.h +++ b/Include/tupleobject.h @@ -33,7 +33,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyTuple_Type; -#define PyTuple_Check(op) PyObject_TypeCheck(op, &PyTuple_Type) +#define PyTuple_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_TUPLE_SUBCLASS) #define PyTuple_CheckExact(op) ((op)->ob_type == &PyTuple_Type) PyAPI_FUNC(PyObject *) PyTuple_New(Py_ssize_t size); diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 33aa185..0bad8c3 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -392,7 +392,8 @@ typedef struct { PyAPI_DATA(PyTypeObject) PyUnicode_Type; -#define PyUnicode_Check(op) PyObject_TypeCheck(op, &PyUnicode_Type) +#define PyUnicode_Check(op) \ + PyType_FastSubclass((op)->ob_type, Py_TPFLAGS_UNICODE_SUBCLASS) #define PyUnicode_CheckExact(op) ((op)->ob_type == &PyUnicode_Type) /* Fast access macros */ |