@@ -146,3 +146,86 @@ size_t refc_binary_total_size(Context *ctx)
146146 synclist_unlock (& ctx -> global -> refc_binaries );
147147 return size ;
148148}
149+
150+ COLD_FUNC void refc_binary_dump_info (Context * ctx )
151+ {
152+ struct ListHead * item ;
153+ struct ListHead * refc_binaries = synclist_rdlock (& ctx -> global -> refc_binaries );
154+
155+ // Note: This only counts non-const refc binaries (ones that allocate memory).
156+ // Const binaries (created by term_from_const_binary) point to existing data
157+ // and are never added to the global refc_binaries list, so they don't appear here.
158+
159+ // First pass: count and calculate total size
160+ size_t count = 0 ;
161+ size_t total_size = 0 ;
162+ LIST_FOR_EACH (item , refc_binaries ) {
163+ struct RefcBinary * refc = GET_LIST_ENTRY (item , struct RefcBinary , head );
164+ count ++ ;
165+ total_size += refc -> size ;
166+ }
167+
168+ fprintf (stderr , "refc_binary_count = %d\n" , (int ) count );
169+ fprintf (stderr , "refc_binary_total_size = %d\n" , (int ) total_size );
170+
171+ if (count == 0 ) {
172+ synclist_unlock (& ctx -> global -> refc_binaries );
173+ return ;
174+ }
175+
176+ // Find top 5 largest binaries
177+ #define TOP_N 5
178+ struct RefcBinary * top [TOP_N ] = { NULL };
179+ size_t top_indices [TOP_N ] = { 0 };
180+
181+ size_t index = 0 ;
182+ LIST_FOR_EACH (item , refc_binaries ) {
183+ struct RefcBinary * refc = GET_LIST_ENTRY (item , struct RefcBinary , head );
184+
185+ // Try to insert into top 5
186+ for (size_t i = 0 ; i < TOP_N ; i ++ ) {
187+ if (top [i ] == NULL || refc -> size > top [i ]-> size ) {
188+ // Shift down
189+ for (size_t j = TOP_N - 1 ; j > i ; j -- ) {
190+ top [j ] = top [j - 1 ];
191+ top_indices [j ] = top_indices [j - 1 ];
192+ }
193+ top [i ] = refc ;
194+ top_indices [i ] = index ;
195+ break ;
196+ }
197+ }
198+ index ++ ;
199+ }
200+
201+ // Display top binaries
202+ fprintf (stderr , "\nTop %d largest refc binaries:\n" , TOP_N );
203+ for (size_t i = 0 ; i < TOP_N && top [i ] != NULL ; i ++ ) {
204+ struct RefcBinary * refc = top [i ];
205+ fprintf (stderr , " [%zu] size=%d bytes (%.1f%%), refcount=%d" ,
206+ top_indices [i ],
207+ (int ) refc -> size ,
208+ (double ) refc -> size * 100.0 / (double ) total_size ,
209+ (int ) refc -> ref_count );
210+
211+ if (refc -> resource_type ) {
212+ fprintf (stderr , " [resource]" );
213+ }
214+
215+ // Print first 32 bytes as hex
216+ fprintf (stderr , "\n data: " );
217+ size_t print_size = refc -> size < 32 ? refc -> size : 32 ;
218+ for (size_t j = 0 ; j < print_size ; j ++ ) {
219+ fprintf (stderr , "%02x" , refc -> data [j ]);
220+ if (j % 4 == 3 && j < print_size - 1 ) {
221+ fprintf (stderr , " " );
222+ }
223+ }
224+ if (refc -> size > 32 ) {
225+ fprintf (stderr , "..." );
226+ }
227+ fprintf (stderr , "\n" );
228+ }
229+
230+ synclist_unlock (& ctx -> global -> refc_binaries );
231+ }
0 commit comments