@@ -1394,18 +1394,33 @@ gc_list_set_space(PyGC_Head *list, int space)
13941394static struct gc_generation_stats *
13951395gc_get_stats (GCState * gcstate , int gen )
13961396{
1397- struct gc_generation_stats_buffer * buffer = & gcstate -> generation_stats .gen [gen ];
1398- buffer -> index = (buffer -> index + 1 ) % 11 ;
1399- struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1400- return stats ;
1397+ if (gen == 0 ) {
1398+ struct gc_young_stats_buffer * buffer = & gcstate -> generation_stats .young ;
1399+ buffer -> index = (buffer -> index + 1 ) % GC_YOUNG_STATS_SIZE ;
1400+ struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1401+ return stats ;
1402+ }
1403+ else {
1404+ struct gc_old_stats_buffer * buffer = & gcstate -> generation_stats .old [gen - 1 ];
1405+ buffer -> index = (buffer -> index + 1 ) % GC_OLD_STATS_SIZE ;
1406+ struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1407+ return stats ;
1408+ }
14011409}
14021410
14031411static struct gc_generation_stats *
14041412gc_get_prev_stats (GCState * gcstate , int gen )
14051413{
1406- struct gc_generation_stats_buffer * buffer = & gcstate -> generation_stats .gen [gen ];
1407- struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1408- return stats ;
1414+ if (gen == 0 ) {
1415+ struct gc_young_stats_buffer * buffer = & gcstate -> generation_stats .young ;
1416+ struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1417+ return stats ;
1418+ }
1419+ else {
1420+ struct gc_old_stats_buffer * buffer = & gcstate -> generation_stats .old [gen - 1 ];
1421+ struct gc_generation_stats * stats = & buffer -> items [buffer -> index ];
1422+ return stats ;
1423+ }
14091424}
14101425
14111426static void
@@ -1414,18 +1429,21 @@ add_stats(GCState *gcstate, int gen, struct gc_generation_stats *stats)
14141429 struct gc_generation_stats * prev_stats = gc_get_prev_stats (gcstate , gen );
14151430 struct gc_generation_stats * cur_stats = gc_get_stats (gcstate , gen );
14161431
1417- cur_stats -> ts = stats -> ts ;
1418- cur_stats -> collections = prev_stats -> collections + 1 ;
1419- cur_stats -> object_visits = prev_stats -> object_visits + stats -> object_visits ;
1420- cur_stats -> collected = prev_stats -> collected + stats -> collected ;
1421- cur_stats -> objects_transitively_reachable = prev_stats -> objects_transitively_reachable + stats -> objects_transitively_reachable ;
1422- cur_stats -> objects_not_transitively_reachable = prev_stats -> objects_not_transitively_reachable + stats -> objects_not_transitively_reachable ;
1423- cur_stats -> uncollectable = prev_stats -> uncollectable + stats -> uncollectable ;
1424- cur_stats -> candidates = prev_stats -> candidates + stats -> candidates ;
1425- cur_stats -> duration = stats -> duration ;
1426- cur_stats -> total_duration = prev_stats -> total_duration + stats -> duration ;
1427- cur_stats -> heap_size = gcstate -> heap_size ;
1428- cur_stats -> work_to_do = gcstate -> work_to_do ;
1432+ memcpy (cur_stats , prev_stats , sizeof (struct gc_generation_stats ));
1433+
1434+ cur_stats -> ts_start = stats -> ts_start ;
1435+ cur_stats -> ts_stop = stats -> ts_stop ;
1436+ cur_stats -> heap_size = stats -> heap_size ;
1437+ cur_stats -> work_to_do = stats -> work_to_do ;
1438+
1439+ cur_stats -> collections += 1 ;
1440+ cur_stats -> object_visits += stats -> object_visits ;
1441+ cur_stats -> collected += stats -> collected ;
1442+ cur_stats -> uncollectable += stats -> uncollectable ;
1443+ cur_stats -> candidates += stats -> candidates ;
1444+
1445+ cur_stats -> objects_transitively_reachable += stats -> objects_transitively_reachable ;
1446+ cur_stats -> objects_not_transitively_reachable += stats -> objects_not_transitively_reachable ;
14291447}
14301448
14311449static void
@@ -1907,12 +1925,13 @@ do_gc_callback(GCState *gcstate, const char *phase,
19071925 assert (PyList_CheckExact (gcstate -> callbacks ));
19081926 PyObject * info = NULL ;
19091927 if (PyList_GET_SIZE (gcstate -> callbacks ) != 0 ) {
1928+ double duration = PyTime_AsSecondsDouble (stats -> ts_stop - stats -> ts_start );
19101929 info = Py_BuildValue ("{sisnsnsnsd}" ,
19111930 "generation" , generation ,
19121931 "collected" , stats -> collected ,
19131932 "uncollectable" , stats -> uncollectable ,
19141933 "candidates" , stats -> candidates ,
1915- "duration" , stats -> duration );
1934+ "duration" , duration );
19161935 if (info == NULL ) {
19171936 PyErr_FormatUnraisable ("Exception ignored while invoking gc callbacks" );
19181937 return ;
@@ -2150,7 +2169,9 @@ _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason)
21502169 if (PyDTrace_GC_START_ENABLED ()) {
21512170 PyDTrace_GC_START (generation );
21522171 }
2153- (void )PyTime_PerfCounterRaw (& stats .ts );
2172+ stats .heap_size = gcstate -> heap_size ;
2173+ stats .work_to_do = gcstate -> work_to_do ;
2174+ (void )PyTime_PerfCounterRaw (& stats .ts_start );
21542175 PyObject * exc = _PyErr_GetRaisedException (tstate );
21552176 switch (generation ) {
21562177 case 0 :
@@ -2165,9 +2186,7 @@ _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason)
21652186 default :
21662187 Py_UNREACHABLE ();
21672188 }
2168- PyTime_t stop ;
2169- (void )PyTime_PerfCounterRaw (& stop );
2170- stats .duration = PyTime_AsSecondsDouble (stop - stats .ts );
2189+ (void )PyTime_PerfCounterRaw (& stats .ts_stop );
21712190 add_stats (gcstate , generation , & stats );
21722191 if (PyDTrace_GC_DONE_ENABLED ()) {
21732192 PyDTrace_GC_DONE (stats .uncollectable + stats .collected );
@@ -2190,9 +2209,10 @@ _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason)
21902209 _Py_atomic_store_int (& gcstate -> collecting , 0 );
21912210
21922211 if (gcstate -> debug & _PyGC_DEBUG_STATS ) {
2212+ double duration = PyTime_AsSecondsDouble (stats .ts_stop - stats .ts_start );
21932213 PySys_WriteStderr (
21942214 "gc: done, %zd unreachable, %zd uncollectable, %.4fs elapsed\n" ,
2195- stats .collected + stats .uncollectable , stats .uncollectable , stats . duration
2215+ stats .collected + stats .uncollectable , stats .uncollectable , duration
21962216 );
21972217 }
21982218
0 commit comments