diff options
author | Mark Shannon <mark@hotpy.org> | 2021-12-07 16:02:53 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-07 16:02:53 +0000 |
commit | 8319114feedd2a5b77378bba24eb9fb2689c5033 (patch) | |
tree | b96bfa2c7b8d36124b713170f421f653360a4b5c /Include | |
parent | c7e7a4b969b5728d4b4f3c59bf98e1e830d5c6d6 (diff) | |
download | cpython-git-8319114feedd2a5b77378bba24eb9fb2689c5033.tar.gz |
bpo-45947: Place dict and values pointer at fixed (negative) offset just before GC header. (GH-29879)
* Place __dict__ immediately before GC header for plain Python objects.
* Fix up lazy dict creation logic to use managed dict pointers.
* Manage values pointer, placing them directly before managed dict pointers.
* Convert hint-based load/store attr specialization target managed dict classes.
* Specialize LOAD_METHOD for managed dict objects.
* Remove unsafe _PyObject_GC_Calloc function.
* Remove unsafe _PyObject_GC_Malloc() function.
* Add comment explaning use of Py_TPFLAGS_MANAGED_DICT.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/cpython/object.h | 1 | ||||
-rw-r--r-- | Include/cpython/objimpl.h | 3 | ||||
-rw-r--r-- | Include/internal/pycore_object.h | 23 | ||||
-rw-r--r-- | Include/object.h | 6 |
4 files changed, 28 insertions, 5 deletions
diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 3a8a256e3b..0c3957aff4 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -270,7 +270,6 @@ struct _typeobject { destructor tp_finalize; vectorcallfunc tp_vectorcall; - Py_ssize_t tp_inline_values_offset; }; /* The *real* layout of a type object when allocated on the heap */ diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h index d83700e2a4..4a905c25cc 100644 --- a/Include/cpython/objimpl.h +++ b/Include/cpython/objimpl.h @@ -90,9 +90,6 @@ PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); # define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) #endif -PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size); -PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size); - /* Test if a type supports weak references */ #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0) diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 3c126aaef1..9041a4dc8a 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -168,6 +168,15 @@ _PyObject_IS_GC(PyObject *obj) // Fast inlined version of PyType_IS_GC() #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) +static inline size_t +_PyType_PreHeaderSize(PyTypeObject *tp) +{ + return _PyType_IS_GC(tp) * sizeof(PyGC_Head) + + _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *); +} + +void _PyObject_GC_Link(PyObject *op); + // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); extern int _Py_CheckSlotResult( PyObject *obj, @@ -185,7 +194,19 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name, PyObject *value); PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values, PyObject *name); -PyDictValues ** _PyObject_ValuesPointer(PyObject *); + +static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj) +{ + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + return ((PyDictValues **)obj)-4; +} + +static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj) +{ + assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT); + return ((PyObject **)obj)-3; +} + PyObject ** _PyObject_DictPointer(PyObject *); int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg); void _PyObject_ClearInstanceAttributes(PyObject *self); diff --git a/Include/object.h b/Include/object.h index 33df303a44..e5544e8b58 100644 --- a/Include/object.h +++ b/Include/object.h @@ -334,6 +334,12 @@ given type object has a specified feature. #ifndef Py_LIMITED_API +/* Placement of dict (and values) pointers are managed by the VM, not by the type. + * The VM will automatically set tp_dictoffset. Should not be used for variable sized + * classes, such as classes that extend tuple. + */ +#define Py_TPFLAGS_MANAGED_DICT (1 << 4) + /* Set if instances of the type object are treated as sequences for pattern matching */ #define Py_TPFLAGS_SEQUENCE (1 << 5) /* Set if instances of the type object are treated as mappings for pattern matching */ |