@@ -54,37 +54,71 @@ _PyObject_CheckConsistency(PyObject *op, int check_content)
54
54
55
55
56
56
#ifdef Py_REF_DEBUG
57
+ /* We keep the legacy symbol around for backward compatibility. */
57
58
Py_ssize_t _Py_RefTotal ;
58
59
60
+ static inline Py_ssize_t
61
+ get_legacy_reftotal (void )
62
+ {
63
+ return _Py_RefTotal ;
64
+ }
65
+ #endif
66
+
67
+ #ifdef Py_REF_DEBUG
68
+
69
+ # define REFTOTAL (runtime ) \
70
+ (runtime)->object_state.reftotal
71
+
72
+ static inline void
73
+ reftotal_increment (_PyRuntimeState * runtime )
74
+ {
75
+ REFTOTAL (runtime )++ ;
76
+ }
77
+
59
78
static inline void
60
- reftotal_increment ( void )
79
+ reftotal_decrement ( _PyRuntimeState * runtime )
61
80
{
62
- _Py_RefTotal ++ ;
81
+ REFTOTAL ( runtime ) -- ;
63
82
}
64
83
65
84
static inline void
66
- reftotal_decrement ( void )
85
+ reftotal_add ( _PyRuntimeState * runtime , Py_ssize_t n )
67
86
{
68
- _Py_RefTotal -- ;
87
+ REFTOTAL ( runtime ) += n ;
69
88
}
70
89
90
+ static inline Py_ssize_t get_global_reftotal (_PyRuntimeState * );
91
+
92
+ /* We preserve the number of refs leaked during runtime finalization,
93
+ so they can be reported if the runtime is initialized again. */
94
+ // XXX We don't lose any information by dropping this,
95
+ // so we should consider doing so.
96
+ static Py_ssize_t last_final_reftotal = 0 ;
97
+
71
98
void
72
- _Py_AddRefTotal ( Py_ssize_t n )
99
+ _Py_FinalizeRefTotal ( _PyRuntimeState * runtime )
73
100
{
74
- _Py_RefTotal += n ;
101
+ last_final_reftotal = get_global_reftotal (runtime );
102
+ REFTOTAL (runtime ) = 0 ;
75
103
}
76
104
77
- Py_ssize_t
78
- _Py_GetRefTotal ( void )
105
+ static inline Py_ssize_t
106
+ get_global_reftotal ( _PyRuntimeState * runtime )
79
107
{
80
- return _Py_RefTotal ;
108
+ /* For an update from _Py_RefTotal first. */
109
+ Py_ssize_t legacy = get_legacy_reftotal ();
110
+ return REFTOTAL (runtime ) + legacy + last_final_reftotal ;
81
111
}
82
112
113
+ #undef REFTOTAL
114
+
83
115
void
84
116
_PyDebug_PrintTotalRefs (void ) {
117
+ _PyRuntimeState * runtime = & _PyRuntime ;
85
118
fprintf (stderr ,
86
119
"[%zd refs, %zd blocks]\n" ,
87
- _Py_GetRefTotal (), _Py_GetAllocatedBlocks ());
120
+ get_global_reftotal (runtime ), _Py_GetAllocatedBlocks ());
121
+ /* It may be helpful to also print the "legacy" reftotal separately. */
88
122
}
89
123
#endif /* Py_REF_DEBUG */
90
124
@@ -139,30 +173,50 @@ _Py_NegativeRefcount(const char *filename, int lineno, PyObject *op)
139
173
filename , lineno , __func__ );
140
174
}
141
175
142
- /* This is exposed strictly for use in Py_INCREF(). */
143
- PyAPI_FUNC ( void )
176
+ /* This is used strictly by Py_INCREF(). */
177
+ void
144
178
_Py_IncRefTotal_DO_NOT_USE_THIS (void )
145
179
{
146
- reftotal_increment ();
180
+ reftotal_increment (& _PyRuntime );
147
181
}
148
182
149
- /* This is exposed strictly for use in Py_DECREF(). */
150
- PyAPI_FUNC ( void )
183
+ /* This is used strictly by Py_DECREF(). */
184
+ void
151
185
_Py_DecRefTotal_DO_NOT_USE_THIS (void )
152
186
{
153
- reftotal_decrement ();
187
+ reftotal_decrement (& _PyRuntime );
154
188
}
155
189
156
190
void
157
191
_Py_IncRefTotal (void )
158
192
{
159
- reftotal_increment ();
193
+ reftotal_increment (& _PyRuntime );
160
194
}
161
195
162
196
void
163
197
_Py_DecRefTotal (void )
164
198
{
165
- reftotal_decrement ();
199
+ reftotal_decrement (& _PyRuntime );
200
+ }
201
+
202
+ void
203
+ _Py_AddRefTotal (Py_ssize_t n )
204
+ {
205
+ reftotal_add (& _PyRuntime , n );
206
+ }
207
+
208
+ /* This includes the legacy total
209
+ and any carried over from the last runtime init/fini cycle. */
210
+ Py_ssize_t
211
+ _Py_GetGlobalRefTotal (void )
212
+ {
213
+ return get_global_reftotal (& _PyRuntime );
214
+ }
215
+
216
+ Py_ssize_t
217
+ _Py_GetLegacyRefTotal (void )
218
+ {
219
+ return get_legacy_reftotal ();
166
220
}
167
221
168
222
#endif /* Py_REF_DEBUG */
@@ -182,21 +236,18 @@ Py_DecRef(PyObject *o)
182
236
void
183
237
_Py_IncRef (PyObject * o )
184
238
{
185
- #ifdef Py_REF_DEBUG
186
- reftotal_increment ();
187
- #endif
188
239
Py_INCREF (o );
189
240
}
190
241
191
242
void
192
243
_Py_DecRef (PyObject * o )
193
244
{
194
- #ifdef Py_REF_DEBUG
195
- reftotal_decrement ();
196
- #endif
197
245
Py_DECREF (o );
198
246
}
199
247
248
+
249
+ /**************************************/
250
+
200
251
PyObject *
201
252
PyObject_Init (PyObject * op , PyTypeObject * tp )
202
253
{
@@ -2077,7 +2128,7 @@ void
2077
2128
_Py_NewReference (PyObject * op )
2078
2129
{
2079
2130
#ifdef Py_REF_DEBUG
2080
- reftotal_increment ();
2131
+ reftotal_increment (& _PyRuntime );
2081
2132
#endif
2082
2133
new_reference (op );
2083
2134
}
0 commit comments