diff options
author | Mark Shannon <mark@hotpy.org> | 2021-12-07 16:02:53 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-07 16:02:53 (GMT) |
commit | 8319114feedd2a5b77378bba24eb9fb2689c5033 (patch) | |
tree | b96bfa2c7b8d36124b713170f421f653360a4b5c /Python/ceval.c | |
parent | c7e7a4b969b5728d4b4f3c59bf98e1e830d5c6d6 (diff) | |
download | cpython-8319114feedd2a5b77378bba24eb9fb2689c5033.zip cpython-8319114feedd2a5b77378bba24eb9fb2689c5033.tar.gz cpython-8319114feedd2a5b77378bba24eb9fb2689c5033.tar.bz2 |
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 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index a8bbad3..446772d 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -3599,9 +3599,9 @@ check_eval_breaker: _PyAttrCache *cache1 = &caches[-1].attr; assert(cache1->tp_version != 0); DEOPT_IF(tp->tp_version_tag != cache1->tp_version, LOAD_ATTR); - assert(tp->tp_dictoffset > 0); - assert(tp->tp_inline_values_offset > 0); - PyDictValues *values = *(PyDictValues **)(((char *)owner) + tp->tp_inline_values_offset); + assert(tp->tp_dictoffset < 0); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictValues *values = *_PyObject_ValuesPointer(owner); DEOPT_IF(values == NULL, LOAD_ATTR); res = values->values[cache0->index]; DEOPT_IF(res == NULL, LOAD_ATTR); @@ -3633,8 +3633,8 @@ check_eval_breaker: _PyAttrCache *cache1 = &caches[-1].attr; assert(cache1->tp_version != 0); DEOPT_IF(tp->tp_version_tag != cache1->tp_version, LOAD_ATTR); - assert(tp->tp_dictoffset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)owner) + tp->tp_dictoffset); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(names, cache0->original_oparg); @@ -3701,9 +3701,8 @@ check_eval_breaker: _PyAttrCache *cache1 = &caches[-1].attr; assert(cache1->tp_version != 0); DEOPT_IF(tp->tp_version_tag != cache1->tp_version, STORE_ATTR); - assert(tp->tp_dictoffset > 0); - assert(tp->tp_inline_values_offset > 0); - PyDictValues *values = *(PyDictValues **)(((char *)owner) + tp->tp_inline_values_offset); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictValues *values = *_PyObject_ValuesPointer(owner); DEOPT_IF(values == NULL, STORE_ATTR); STAT_INC(STORE_ATTR, hit); int index = cache0->index; @@ -3731,8 +3730,8 @@ check_eval_breaker: _PyAttrCache *cache1 = &caches[-1].attr; assert(cache1->tp_version != 0); DEOPT_IF(tp->tp_version_tag != cache1->tp_version, STORE_ATTR); - assert(tp->tp_dictoffset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)owner) + tp->tp_dictoffset); + assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner); DEOPT_IF(dict == NULL, STORE_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(names, cache0->original_oparg); @@ -4506,9 +4505,8 @@ check_eval_breaker: _PyObjectCache *cache2 = &caches[-2].obj; DEOPT_IF(self_cls->tp_version_tag != cache1->tp_version, LOAD_METHOD); - assert(self_cls->tp_dictoffset > 0); - assert(self_cls->tp_inline_values_offset > 0); - PyDictObject *dict = *(PyDictObject **)(((char *)self) + self_cls->tp_dictoffset); + assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT); + PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self); DEOPT_IF(dict != NULL, LOAD_METHOD); DEOPT_IF(((PyHeapTypeObject *)self_cls)->ht_cached_keys->dk_version != cache1->dk_version_or_hint, LOAD_METHOD); STAT_INC(LOAD_METHOD, hit); |