@@ -86,15 +86,17 @@ _PyObject_AssignUniqueId(PyObject *obj)
8686 if (pool -> freelist == NULL ) {
8787 if (resize_interp_type_id_pool (pool ) < 0 ) {
8888 UNLOCK_POOL (pool );
89- return -1 ;
89+ return _Py_INVALID_UNIQUE_ID ;
9090 }
9191 }
9292
9393 _Py_unique_id_entry * entry = pool -> freelist ;
9494 pool -> freelist = entry -> next ;
9595 entry -> obj = obj ;
9696 _PyObject_SetDeferredRefcount (obj );
97- Py_ssize_t unique_id = (entry - pool -> table );
97+ // The unique id is one plus the index of the entry in the table.
98+ Py_ssize_t unique_id = (entry - pool -> table ) + 1 ;
99+ assert (unique_id > 0 );
98100 UNLOCK_POOL (pool );
99101 return unique_id ;
100102}
@@ -106,8 +108,9 @@ _PyObject_ReleaseUniqueId(Py_ssize_t unique_id)
106108 struct _Py_unique_id_pool * pool = & interp -> unique_ids ;
107109
108110 LOCK_POOL (pool );
109- assert (unique_id >= 0 && unique_id < pool -> size );
110- _Py_unique_id_entry * entry = & pool -> table [unique_id ];
111+ assert (unique_id > 0 && unique_id <= pool -> size );
112+ Py_ssize_t idx = unique_id - 1 ;
113+ _Py_unique_id_entry * entry = & pool -> table [idx ];
111114 entry -> next = pool -> freelist ;
112115 pool -> freelist = entry ;
113116 UNLOCK_POOL (pool );
@@ -116,18 +119,18 @@ _PyObject_ReleaseUniqueId(Py_ssize_t unique_id)
116119static Py_ssize_t
117120clear_unique_id (PyObject * obj )
118121{
119- Py_ssize_t id = -1 ;
122+ Py_ssize_t id = _Py_INVALID_UNIQUE_ID ;
120123 if (PyType_Check (obj )) {
121124 if (PyType_HasFeature ((PyTypeObject * )obj , Py_TPFLAGS_HEAPTYPE )) {
122125 PyHeapTypeObject * ht = (PyHeapTypeObject * )obj ;
123126 id = ht -> unique_id ;
124- ht -> unique_id = -1 ;
127+ ht -> unique_id = _Py_INVALID_UNIQUE_ID ;
125128 }
126129 }
127130 else if (PyCode_Check (obj )) {
128131 PyCodeObject * co = (PyCodeObject * )obj ;
129132 id = co -> _co_unique_id ;
130- co -> _co_unique_id = -1 ;
133+ co -> _co_unique_id = _Py_INVALID_UNIQUE_ID ;
131134 }
132135 else if (PyDict_Check (obj )) {
133136 PyDictObject * mp = (PyDictObject * )obj ;
@@ -141,23 +144,23 @@ void
141144_PyObject_DisablePerThreadRefcounting (PyObject * obj )
142145{
143146 Py_ssize_t id = clear_unique_id (obj );
144- if (id >= 0 ) {
147+ if (id != _Py_INVALID_UNIQUE_ID ) {
145148 _PyObject_ReleaseUniqueId (id );
146149 }
147150}
148151
149152void
150- _PyObject_ThreadIncrefSlow (PyObject * obj , Py_ssize_t unique_id )
153+ _PyObject_ThreadIncrefSlow (PyObject * obj , size_t idx )
151154{
152155 _PyThreadStateImpl * tstate = (_PyThreadStateImpl * )_PyThreadState_GET ();
153- if (unique_id < 0 || resize_local_refcounts (tstate ) < 0 ) {
156+ if ((( Py_ssize_t ) idx ) < 0 || resize_local_refcounts (tstate ) < 0 ) {
154157 // just incref the object directly.
155158 Py_INCREF (obj );
156159 return ;
157160 }
158161
159- assert (unique_id < tstate -> refcounts .size );
160- tstate -> refcounts .values [unique_id ]++ ;
162+ assert (idx < ( size_t ) tstate -> refcounts .size );
163+ tstate -> refcounts .values [idx ]++ ;
161164#ifdef Py_REF_DEBUG
162165 _Py_IncRefTotal ((PyThreadState * )tstate );
163166#endif
@@ -217,7 +220,7 @@ _PyObject_FinalizeUniqueIdPool(PyInterpreterState *interp)
217220 if (obj != NULL ) {
218221 Py_ssize_t id = clear_unique_id (obj );
219222 (void )id ;
220- assert (id == i );
223+ assert (id == i + 1 );
221224 }
222225 }
223226 PyMem_Free (pool -> table );
0 commit comments