3333/* Progress callback frequency */
3434#define PROGRESS_CALLBACK_INTERVAL 1000
3535
36- /* Cap per-batch RLE samples to bound the timestamp list (gh-151378) */
37- #define MAX_RLE_BATCH_SAMPLES 8192
38-
3936/* ============================================================================
4037 * BINARY READER IMPLEMENTATION
4138 * ============================================================================ */
@@ -1086,6 +1083,21 @@ emit_sample(RemoteDebuggingState *state, PyObject *collector,
10861083 return 0 ;
10871084}
10881085
1086+ /* Helper to trim timestamp list and emit batch. Returns 0 on success, -1 on error. */
1087+ static int
1088+ emit_batch (RemoteDebuggingState * state , PyObject * collector ,
1089+ uint64_t thread_id , uint32_t interpreter_id , uint8_t status ,
1090+ const uint32_t * frame_indices , size_t stack_depth ,
1091+ BinaryReader * reader , PyObject * timestamps_list , Py_ssize_t actual_size )
1092+ {
1093+ /* Trim list to actual size */
1094+ if (PyList_SetSlice (timestamps_list , actual_size , PyList_GET_SIZE (timestamps_list ), NULL ) < 0 ) {
1095+ return -1 ;
1096+ }
1097+ return emit_sample (state , collector , thread_id , interpreter_id , status ,
1098+ frame_indices , stack_depth , reader , timestamps_list );
1099+ }
1100+
10891101/* Helper to invoke progress callback, returns -1 on error */
10901102static inline int
10911103invoke_progress_callback (PyObject * callback , Py_ssize_t current , uint64_t total )
@@ -1214,18 +1226,17 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
12141226 ts -> prev_timestamp += delta ;
12151227
12161228 /* Start new batch on first sample or status change */
1217- if (i == 0 || status != batch_status
1218- || batch_idx >= MAX_RLE_BATCH_SAMPLES ) {
1229+ if (i == 0 || status != batch_status ) {
12191230 if (timestamps_list ) {
1220- int rc = emit_sample (state , collector , thread_id , interpreter_id ,
1221- batch_status , ts -> current_stack , ts -> current_stack_depth ,
1222- reader , timestamps_list );
1231+ int rc = emit_batch (state , collector , thread_id , interpreter_id ,
1232+ batch_status , ts -> current_stack , ts -> current_stack_depth ,
1233+ reader , timestamps_list , batch_idx );
12231234 Py_DECREF (timestamps_list );
12241235 if (rc < 0 ) {
12251236 return -1 ;
12261237 }
12271238 }
1228- timestamps_list = PyList_New (0 );
1239+ timestamps_list = PyList_New (count - i );
12291240 if (!timestamps_list ) {
12301241 return -1 ;
12311242 }
@@ -1238,20 +1249,14 @@ binary_reader_replay(BinaryReader *reader, PyObject *collector, PyObject *progre
12381249 Py_DECREF (timestamps_list );
12391250 return -1 ;
12401251 }
1241- int append_rc = PyList_Append (timestamps_list , ts_obj );
1242- Py_DECREF (ts_obj );
1243- if (append_rc < 0 ) {
1244- Py_DECREF (timestamps_list );
1245- return -1 ;
1246- }
1247- batch_idx ++ ;
1252+ PyList_SET_ITEM (timestamps_list , batch_idx ++ , ts_obj );
12481253 }
12491254
12501255 /* Emit final batch */
12511256 if (timestamps_list ) {
1252- int rc = emit_sample (state , collector , thread_id , interpreter_id ,
1253- batch_status , ts -> current_stack , ts -> current_stack_depth ,
1254- reader , timestamps_list );
1257+ int rc = emit_batch (state , collector , thread_id , interpreter_id ,
1258+ batch_status , ts -> current_stack , ts -> current_stack_depth ,
1259+ reader , timestamps_list , batch_idx );
12551260 Py_DECREF (timestamps_list );
12561261 if (rc < 0 ) {
12571262 return -1 ;
0 commit comments