summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-08-01 13:34:54 (GMT)
committerGitHub <noreply@github.com>2022-08-01 13:34:54 (GMT)
commitde388c0a7b71c094d36ce40fecef87bdbb8a87d3 (patch)
treeb2318318e6c9a80bc9f45ecf5fc05aa66efb7825 /Python/ceval.c
parentfb75d015f487e50079e8d2ea7859750684b124e4 (diff)
downloadcpython-de388c0a7b71c094d36ce40fecef87bdbb8a87d3.zip
cpython-de388c0a7b71c094d36ce40fecef87bdbb8a87d3.tar.gz
cpython-de388c0a7b71c094d36ce40fecef87bdbb8a87d3.tar.bz2
GH-95245: Store object values and dict pointers in single tagged pointer. (GH-95278)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index 7ad26a7..abb934d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -3564,9 +3564,9 @@ handle_eval_breaker:
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
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[cache->index];
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
+ res = _PyDictOrValues_GetValues(dorv)->values[cache->index];
DEOPT_IF(res == NULL, LOAD_ATTR);
STAT_INC(LOAD_ATTR, hit);
Py_INCREF(res);
@@ -3613,7 +3613,9 @@ handle_eval_breaker:
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, LOAD_ATTR);
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
DEOPT_IF(dict == NULL, LOAD_ATTR);
assert(PyDict_CheckExact((PyObject *)dict));
PyObject *name = GETITEM(names, oparg>>1);
@@ -3750,12 +3752,13 @@ handle_eval_breaker:
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictValues *values = *_PyObject_ValuesPointer(owner);
- DEOPT_IF(values == NULL, STORE_ATTR);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(!_PyDictOrValues_IsValues(dorv), STORE_ATTR);
STAT_INC(STORE_ATTR, hit);
Py_ssize_t index = cache->index;
STACK_SHRINK(1);
PyObject *value = POP();
+ PyDictValues *values = _PyDictOrValues_GetValues(dorv);
PyObject *old_value = values->values[index];
values->values[index] = value;
if (old_value == NULL) {
@@ -3778,7 +3781,9 @@ handle_eval_breaker:
assert(type_version != 0);
DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR);
assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictObject *dict = *(PyDictObject **)_PyObject_ManagedDictPointer(owner);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(owner);
+ DEOPT_IF(_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
+ PyDictObject *dict = (PyDictObject *)_PyDictOrValues_GetDict(dorv);
DEOPT_IF(dict == NULL, STORE_ATTR);
assert(PyDict_CheckExact((PyObject *)dict));
PyObject *name = GETITEM(names, oparg);
@@ -4680,8 +4685,8 @@ handle_eval_breaker:
assert(type_version != 0);
DEOPT_IF(self_cls->tp_version_tag != type_version, LOAD_ATTR);
assert(self_cls->tp_flags & Py_TPFLAGS_MANAGED_DICT);
- PyDictObject *dict = *(PyDictObject**)_PyObject_ManagedDictPointer(self);
- DEOPT_IF(dict != NULL, LOAD_ATTR);
+ PyDictOrValues dorv = *_PyObject_DictOrValuesPointer(self);
+ DEOPT_IF(!_PyDictOrValues_IsValues(dorv), LOAD_ATTR);
PyHeapTypeObject *self_heap_type = (PyHeapTypeObject *)self_cls;
DEOPT_IF(self_heap_type->ht_cached_keys->dk_version !=
read_u32(cache->keys_version), LOAD_ATTR);