@@ -483,9 +483,11 @@ struct _odictobject {
483483 PyDictObject od_dict ; /* the underlying dict */
484484 _ODictNode * od_first ; /* first node in the linked list, if any */
485485 _ODictNode * od_last ; /* last node in the linked list, if any */
486- /* od_size and od_fast_nodes are managed by _odict_resize() */
487- Py_ssize_t od_size ; /* hash table that mirrors the dict table */
488- _ODictNode * * od_fast_nodes ; /* managed by _odict_resize() */
486+ /* od_fast_nodes and od_resize_sentinel are managed by _odict_resize()
487+ * Note that we rely on implementation details of dict for both. */
488+ _ODictNode * * od_fast_nodes ; /* hash table that mirrors the dict table */
489+ Py_uintptr_t od_resize_sentinel ; /* changes if odict should be resized */
490+
489491 size_t od_state ; /* incremented whenever the LL changes */
490492 PyObject * od_inst_dict ; /* OrderedDict().__dict__ */
491493 PyObject * od_weakreflist ; /* holds weakrefs to the odict */
@@ -510,7 +512,6 @@ struct _odictnode {
510512/* borrowed reference */
511513#define _odictnode_VALUE (node , od ) \
512514 PyODict_GetItemWithError((PyObject *)od, _odictnode_KEY(node))
513- /* If needed we could also have _odictnode_HASH. */
514515#define _odictnode_PREV (node ) (node->prev)
515516#define _odictnode_NEXT (node ) (node->next)
516517
@@ -520,6 +521,7 @@ struct _odictnode {
520521#define _odict_FOREACH (od , node ) \
521522 for (node = _odict_FIRST(od); node != NULL; node = _odictnode_NEXT(node))
522523
524+ #define _odict_FAST_SIZE (od ) ((PyDictObject *)od)->ma_keys->dk_size
523525
524526static void
525527_odict_free_fast_nodes (PyODictObject * od ) {
@@ -573,7 +575,7 @@ _odict_resize(PyODictObject *od) {
573575 /* Replace the old fast nodes table. */
574576 _odict_free_fast_nodes (od );
575577 od -> od_fast_nodes = fast_nodes ;
576- od -> od_size = size ;
578+ od -> od_resize_sentinel = ( Py_uintptr_t )((( PyDictObject * ) od ) -> ma_keys ) ;
577579 return 0 ;
578580}
579581
@@ -591,7 +593,7 @@ _odict_get_index(PyODictObject *od, PyObject *key)
591593 keys = ((PyDictObject * )od )-> ma_keys ;
592594
593595 /* Ensure od_fast_nodes and dk_entries are in sync. */
594- if (keys -> dk_size != od -> od_size ) {
596+ if (od -> od_resize_sentinel != ( Py_uintptr_t ) keys ) {
595597 int resize_res = _odict_resize (od );
596598 if (resize_res < 0 )
597599 return -1 ;
@@ -656,6 +658,7 @@ _odict_add_tail(PyODictObject *od, _ODictNode *node)
656658 _odictnode_NEXT (_odict_LAST (od )) = node ;
657659 _odict_LAST (od ) = node ;
658660 }
661+
659662 od -> od_state ++ ;
660663}
661664
@@ -980,7 +983,7 @@ odict_sizeof(PyODictObject *od)
980983 return NULL ;
981984 res += temp ;
982985
983- res += sizeof (_ODictNode ) * od -> od_size ; /* od_fast_nodes */
986+ res += sizeof (_ODictNode ) * _odict_FAST_SIZE ( od ) ; /* od_fast_nodes */
984987 if (!_odict_EMPTY (od )) {
985988 res += sizeof (_ODictNode ) * PyODict_SIZE (od ); /* linked-list */
986989 }
0 commit comments