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