diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2022-08-04 17:28:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-08-04 17:28:15 (GMT) |
commit | bdbadb905ae638b67a6c9a6767be396e18839dd6 (patch) | |
tree | b43f9af37788bcef962f8d87fbacaca57289b0dd /Include | |
parent | 60f54d94852771854cf1cb647df7cef7c1617d9e (diff) | |
download | cpython-bdbadb905ae638b67a6c9a6767be396e18839dd6.zip cpython-bdbadb905ae638b67a6c9a6767be396e18839dd6.tar.gz cpython-bdbadb905ae638b67a6c9a6767be396e18839dd6.tar.bz2 |
gh-94673: Recover Weaklist Lookup Performance (gh-95544)
gh-95302 seems to have introduced a small performance regression. Here we make some minor changes to recover that lost performance.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/internal/pycore_object.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 173d367..b3b0b84 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -217,6 +217,16 @@ extern void _Py_PrintReferences(FILE *); extern void _Py_PrintReferenceAddresses(FILE *); #endif + +/* Return the *address* of the object's weaklist. The address may be + * dereferenced to get the current head of the weaklist. This is useful + * for iterating over the linked list of weakrefs, especially when the + * list is being modified externally (e.g. refs getting removed). + * + * The returned pointer should not be used to change the head of the list + * nor should it be used to add, remove, or swap any refs in the list. + * That is the sole responsibility of the code in weakrefobject.c. + */ static inline PyObject ** _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) { @@ -226,10 +236,33 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) (PyTypeObject *)op); return _PyStaticType_GET_WEAKREFS_LISTPTR(state); } + // Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(): Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; return (PyObject **)((char *)op + offset); } +/* This is a special case of _PyObject_GET_WEAKREFS_LISTPTR(). + * Only the most fundamental lookup path is used. + * Consequently, static types should not be used. + * + * For static builtin types the returned pointer will always point + * to a NULL tp_weaklist. This is fine for any deallocation cases, + * since static types are never deallocated and static builtin types + * are only finalized at the end of runtime finalization. + * + * If the weaklist for static types is actually needed then use + * _PyObject_GET_WEAKREFS_LISTPTR(). + */ +static inline PyWeakReference ** +_PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op) +{ + assert(!PyType_Check(op) || + ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE); + Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; + return (PyWeakReference **)((char *)op + offset); +} + + // Fast inlined version of PyObject_IS_GC() static inline int _PyObject_IS_GC(PyObject *obj) |