@@ -2514,6 +2514,47 @@ code_offset_to_line(PyObject* self, PyObject* const* args, Py_ssize_t nargsf)
25142514 return PyLong_FromInt32 (PyCode_Addr2Line (code , offset ));
25152515}
25162516
2517+ typedef struct {
2518+ Py_ssize_t create_count ;
2519+ Py_ssize_t destroy_count ;
2520+ void * prev_data ;
2521+ int (* prev_tracer )(PyObject * , PyRefTracerEvent , void * );
2522+ } reftrace_counter_data ;
2523+
2524+ static int _reftrace_counter (PyObject * obj , PyRefTracerEvent event , void * counter_data )
2525+ {
2526+ if (event == PyRefTracer_CREATE ) {
2527+ ((reftrace_counter_data * )counter_data )-> create_count ++ ;
2528+ } else {
2529+ ((reftrace_counter_data * )counter_data )-> destroy_count ++ ;
2530+ }
2531+ return 0 ;
2532+ }
2533+
2534+ // A very simple reftrace counter for very simple tests
2535+ static PyObject *
2536+ toggle_reftrace_counter (PyObject * ob , PyObject * Py_UNUSED (args ))
2537+ {
2538+ static reftrace_counter_data counter_data = {0 , 0 , NULL , (void * )toggle_reftrace_counter }; // sentinel
2539+
2540+ if (counter_data .prev_tracer == (void * )toggle_reftrace_counter ) {
2541+ // toggle counter on
2542+ counter_data .create_count = counter_data .destroy_count = 0 ;
2543+ counter_data .prev_tracer = PyRefTracer_GetTracer (& counter_data .prev_data );
2544+
2545+ PyRefTracer_SetTracer (_reftrace_counter , & counter_data );
2546+
2547+ Py_RETURN_NONE ;
2548+ }
2549+
2550+ // toggle counter off
2551+ PyRefTracer_SetTracer (counter_data .prev_tracer , counter_data .prev_data );
2552+
2553+ counter_data .prev_tracer = (void * )toggle_reftrace_counter ;
2554+
2555+ return Py_BuildValue ("(nn)" , counter_data .create_count , counter_data .destroy_count );
2556+ }
2557+
25172558
25182559static PyMethodDef TestMethods [] = {
25192560 {"set_errno" , set_errno , METH_VARARGS },
@@ -2608,6 +2649,7 @@ static PyMethodDef TestMethods[] = {
26082649 {"finalize_thread_hang" , finalize_thread_hang , METH_O , NULL },
26092650 {"test_atexit" , test_atexit , METH_NOARGS },
26102651 {"code_offset_to_line" , _PyCFunction_CAST (code_offset_to_line ), METH_FASTCALL },
2652+ {"toggle_reftrace_counter" , toggle_reftrace_counter , METH_NOARGS },
26112653 {NULL , NULL } /* sentinel */
26122654};
26132655
0 commit comments