Switch the license of all .c files to GPLv3.
[deliverable/binutils-gdb.git] / gdb / bcache.c
CommitLineData
c906108c 1/* Implement a cached obstack.
c2d11a7d
JM
2 Written by Fred Fish <fnf@cygnus.com>
3 Rewritten by Jim Blandy <jimb@cygnus.com>
2c7ef074 4
6aba47ca 5 Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
c906108c 6
c5aa993b 7 This file is part of GDB.
c906108c 8
c5aa993b
JM
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
c5aa993b 12 (at your option) any later version.
c906108c 13
c5aa993b
JM
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
c906108c 18
c5aa993b 19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
c906108c
SS
21
22#include "defs.h"
04ea0df1 23#include "gdb_obstack.h"
c906108c
SS
24#include "bcache.h"
25#include "gdb_string.h" /* For memcpy declaration */
2160782c 26#include "gdb_assert.h"
c906108c 27
2c7ef074
AC
28#include <stddef.h>
29#include <stdlib.h>
30
af5f3db6
AC
31/* The type used to hold a single bcache string. The user data is
32 stored in d.data. Since it can be any type, it needs to have the
33 same alignment as the most strict alignment of any type on the host
34 machine. I don't know of any really correct way to do this in
35 stock ANSI C, so just do it the same way obstack.h does. */
36
37struct bstring
38{
49df298f 39 /* Hash chain. */
af5f3db6 40 struct bstring *next;
49df298f
AC
41 /* Assume the data length is no more than 64k. */
42 unsigned short length;
43 /* The half hash hack. This contains the upper 16 bits of the hash
44 value and is used as a pre-check when comparing two strings and
45 avoids the need to do length or memcmp calls. It proves to be
46 roughly 100% effective. */
47 unsigned short half_hash;
af5f3db6
AC
48
49 union
50 {
51 char data[1];
52 double dummy;
53 }
54 d;
55};
56
57
58/* The structure for a bcache itself. The bcache is initialized, in
59 bcache_xmalloc(), by filling it with zeros and then setting the
60 corresponding obstack's malloc() and free() methods. */
61
62struct bcache
63{
64 /* All the bstrings are allocated here. */
65 struct obstack cache;
66
67 /* How many hash buckets we're using. */
68 unsigned int num_buckets;
69
70 /* Hash buckets. This table is allocated using malloc, so when we
71 grow the table we can return the old table to the system. */
72 struct bstring **bucket;
73
74 /* Statistics. */
75 unsigned long unique_count; /* number of unique strings */
76 long total_count; /* total number of strings cached, including dups */
77 long unique_size; /* size of unique strings, in bytes */
78 long total_size; /* total number of bytes cached, including dups */
79 long structure_size; /* total size of bcache, including infrastructure */
2160782c
AC
80 /* Number of times that the hash table is expanded and hence
81 re-built, and the corresponding number of times that a string is
82 [re]hashed as part of entering it into the expanded table. The
83 total number of hashes can be computed by adding TOTAL_COUNT to
84 expand_hash_count. */
85 unsigned long expand_count;
86 unsigned long expand_hash_count;
49df298f
AC
87 /* Number of times that the half-hash compare hit (compare the upper
88 16 bits of hash values) hit, but the corresponding combined
89 length/data compare missed. */
90 unsigned long half_hash_miss_count;
af5f3db6
AC
91};
92
357e46e7
DB
93/* The old hash function was stolen from SDBM. This is what DB 3.0 uses now,
94 * and is better than the old one.
95 */
c2d11a7d 96\f
c2d11a7d 97unsigned long
d85a5daf 98hash(const void *addr, int length)
c2d11a7d 99{
357e46e7
DB
100 const unsigned char *k, *e;
101 unsigned long h;
102
103 k = (const unsigned char *)addr;
104 e = k+length;
105 for (h=0; k< e;++k)
106 {
107 h *=16777619;
108 h ^= *k;
109 }
110 return (h);
c906108c 111}
c2d11a7d
JM
112\f
113/* Growing the bcache's hash table. */
114
115/* If the average chain length grows beyond this, then we want to
116 resize our hash table. */
117#define CHAIN_LENGTH_THRESHOLD (5)
118
119static void
120expand_hash_table (struct bcache *bcache)
c906108c 121{
c2d11a7d
JM
122 /* A table of good hash table sizes. Whenever we grow, we pick the
123 next larger size from this table. sizes[i] is close to 1 << (i+10),
124 so we roughly double the table size each time. After we fall off
125 the end of this table, we just double. Don't laugh --- there have
126 been executables sighted with a gigabyte of debug info. */
127 static unsigned long sizes[] = {
128 1021, 2053, 4099, 8191, 16381, 32771,
129 65537, 131071, 262144, 524287, 1048573, 2097143,
130 4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
131 268435459, 536870923, 1073741827, 2147483659UL
132 };
745b8ca0 133 unsigned int new_num_buckets;
c2d11a7d 134 struct bstring **new_buckets;
745b8ca0 135 unsigned int i;
c2d11a7d 136
2160782c
AC
137 /* Count the stats. Every unique item needs to be re-hashed and
138 re-entered. */
139 bcache->expand_count++;
140 bcache->expand_hash_count += bcache->unique_count;
141
c2d11a7d 142 /* Find the next size. */
745b8ca0 143 new_num_buckets = bcache->num_buckets * 2;
c2d11a7d
JM
144 for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
145 if (sizes[i] > bcache->num_buckets)
146 {
147 new_num_buckets = sizes[i];
148 break;
149 }
c2d11a7d
JM
150
151 /* Allocate the new table. */
152 {
153 size_t new_size = new_num_buckets * sizeof (new_buckets[0]);
154 new_buckets = (struct bstring **) xmalloc (new_size);
155 memset (new_buckets, 0, new_size);
156
157 bcache->structure_size -= (bcache->num_buckets
158 * sizeof (bcache->bucket[0]));
159 bcache->structure_size += new_size;
160 }
c906108c 161
c2d11a7d
JM
162 /* Rehash all existing strings. */
163 for (i = 0; i < bcache->num_buckets; i++)
c906108c 164 {
c2d11a7d
JM
165 struct bstring *s, *next;
166
167 for (s = bcache->bucket[i]; s; s = next)
c906108c 168 {
c2d11a7d
JM
169 struct bstring **new_bucket;
170 next = s->next;
171
172 new_bucket = &new_buckets[(hash (&s->d.data, s->length)
173 % new_num_buckets)];
174 s->next = *new_bucket;
175 *new_bucket = s;
c906108c
SS
176 }
177 }
c2d11a7d
JM
178
179 /* Plug in the new table. */
180 if (bcache->bucket)
b8c9b27d 181 xfree (bcache->bucket);
c2d11a7d
JM
182 bcache->bucket = new_buckets;
183 bcache->num_buckets = new_num_buckets;
c906108c
SS
184}
185
c2d11a7d
JM
186\f
187/* Looking up things in the bcache. */
188
189/* The number of bytes needed to allocate a struct bstring whose data
190 is N bytes long. */
191#define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n))
192
193/* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
194 never seen those bytes before, add a copy of them to BCACHE. In
195 either case, return a pointer to BCACHE's copy of that string. */
3a16a68c
AC
196static void *
197bcache_data (const void *addr, int length, struct bcache *bcache)
c906108c 198{
49df298f
AC
199 unsigned long full_hash;
200 unsigned short half_hash;
c2d11a7d
JM
201 int hash_index;
202 struct bstring *s;
c906108c 203
c2d11a7d
JM
204 /* If our average chain length is too high, expand the hash table. */
205 if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD)
206 expand_hash_table (bcache);
207
208 bcache->total_count++;
209 bcache->total_size += length;
210
49df298f
AC
211 full_hash = hash (addr, length);
212 half_hash = (full_hash >> 16);
213 hash_index = full_hash % bcache->num_buckets;
c2d11a7d 214
49df298f
AC
215 /* Search the hash bucket for a string identical to the caller's.
216 As a short-circuit first compare the upper part of each hash
217 values. */
c2d11a7d 218 for (s = bcache->bucket[hash_index]; s; s = s->next)
49df298f
AC
219 {
220 if (s->half_hash == half_hash)
221 {
222 if (s->length == length
223 && ! memcmp (&s->d.data, addr, length))
224 return &s->d.data;
225 else
226 bcache->half_hash_miss_count++;
227 }
228 }
c2d11a7d
JM
229
230 /* The user's string isn't in the list. Insert it after *ps. */
231 {
232 struct bstring *new
233 = obstack_alloc (&bcache->cache, BSTRING_SIZE (length));
234 memcpy (&new->d.data, addr, length);
235 new->length = length;
236 new->next = bcache->bucket[hash_index];
49df298f 237 new->half_hash = half_hash;
c2d11a7d
JM
238 bcache->bucket[hash_index] = new;
239
240 bcache->unique_count++;
241 bcache->unique_size += length;
242 bcache->structure_size += BSTRING_SIZE (length);
243
244 return &new->d.data;
245 }
c906108c
SS
246}
247
3a16a68c
AC
248void *
249deprecated_bcache (const void *addr, int length, struct bcache *bcache)
250{
251 return bcache_data (addr, length, bcache);
252}
253
254const void *
255bcache (const void *addr, int length, struct bcache *bcache)
256{
257 return bcache_data (addr, length, bcache);
258}
c2d11a7d 259\f
af5f3db6
AC
260/* Allocating and freeing bcaches. */
261
262struct bcache *
263bcache_xmalloc (void)
264{
265 /* Allocate the bcache pre-zeroed. */
266 struct bcache *b = XCALLOC (1, struct bcache);
1ab21617
EZ
267 /* We could use obstack_specify_allocation here instead, but
268 gdb_obstack.h specifies the allocation/deallocation
269 functions. */
270 obstack_init (&b->cache);
af5f3db6
AC
271 return b;
272}
c2d11a7d
JM
273
274/* Free all the storage associated with BCACHE. */
c906108c 275void
af5f3db6 276bcache_xfree (struct bcache *bcache)
c906108c 277{
af5f3db6
AC
278 if (bcache == NULL)
279 return;
c2d11a7d 280 obstack_free (&bcache->cache, 0);
af5f3db6
AC
281 xfree (bcache->bucket);
282 xfree (bcache);
c2d11a7d
JM
283}
284
285
286\f
287/* Printing statistics. */
288
289static int
290compare_ints (const void *ap, const void *bp)
291{
292 /* Because we know we're comparing two ints which are positive,
293 there's no danger of overflow here. */
294 return * (int *) ap - * (int *) bp;
295}
296
297
298static void
299print_percentage (int portion, int total)
300{
301 if (total == 0)
3d263c1d
BI
302 /* i18n: Like "Percentage of duplicates, by count: (not applicable)" */
303 printf_filtered (_("(not applicable)\n"));
c906108c 304 else
b2ba182e 305 printf_filtered ("%3d%%\n", (int) (portion * 100.0 / total));
c2d11a7d
JM
306}
307
308
309/* Print statistics on BCACHE's memory usage and efficacity at
310 eliminating duplication. NAME should describe the kind of data
311 BCACHE holds. Statistics are printed using `printf_filtered' and
312 its ilk. */
313void
314print_bcache_statistics (struct bcache *c, char *type)
315{
316 int occupied_buckets;
317 int max_chain_length;
318 int median_chain_length;
2160782c
AC
319 int max_entry_size;
320 int median_entry_size;
c2d11a7d 321
2160782c
AC
322 /* Count the number of occupied buckets, tally the various string
323 lengths, and measure chain lengths. */
c2d11a7d 324 {
745b8ca0 325 unsigned int b;
2160782c
AC
326 int *chain_length = XCALLOC (c->num_buckets + 1, int);
327 int *entry_size = XCALLOC (c->unique_count + 1, int);
328 int stringi = 0;
c2d11a7d
JM
329
330 occupied_buckets = 0;
331
332 for (b = 0; b < c->num_buckets; b++)
333 {
334 struct bstring *s = c->bucket[b];
335
336 chain_length[b] = 0;
337
338 if (s)
339 {
340 occupied_buckets++;
341
342 while (s)
343 {
2160782c 344 gdb_assert (b < c->num_buckets);
c2d11a7d 345 chain_length[b]++;
2160782c
AC
346 gdb_assert (stringi < c->unique_count);
347 entry_size[stringi++] = s->length;
c2d11a7d
JM
348 s = s->next;
349 }
350 }
351 }
352
353 /* To compute the median, we need the set of chain lengths sorted. */
354 qsort (chain_length, c->num_buckets, sizeof (chain_length[0]),
355 compare_ints);
2160782c
AC
356 qsort (entry_size, c->unique_count, sizeof (entry_size[0]),
357 compare_ints);
c2d11a7d
JM
358
359 if (c->num_buckets > 0)
360 {
361 max_chain_length = chain_length[c->num_buckets - 1];
362 median_chain_length = chain_length[c->num_buckets / 2];
363 }
364 else
365 {
366 max_chain_length = 0;
367 median_chain_length = 0;
368 }
2160782c
AC
369 if (c->unique_count > 0)
370 {
371 max_entry_size = entry_size[c->unique_count - 1];
372 median_entry_size = entry_size[c->unique_count / 2];
373 }
374 else
375 {
376 max_entry_size = 0;
377 median_entry_size = 0;
378 }
379
380 xfree (chain_length);
381 xfree (entry_size);
c2d11a7d
JM
382 }
383
3d263c1d
BI
384 printf_filtered (_(" Cached '%s' statistics:\n"), type);
385 printf_filtered (_(" Total object count: %ld\n"), c->total_count);
386 printf_filtered (_(" Unique object count: %lu\n"), c->unique_count);
387 printf_filtered (_(" Percentage of duplicates, by count: "));
c2d11a7d
JM
388 print_percentage (c->total_count - c->unique_count, c->total_count);
389 printf_filtered ("\n");
390
3d263c1d
BI
391 printf_filtered (_(" Total object size: %ld\n"), c->total_size);
392 printf_filtered (_(" Unique object size: %ld\n"), c->unique_size);
393 printf_filtered (_(" Percentage of duplicates, by size: "));
c2d11a7d
JM
394 print_percentage (c->total_size - c->unique_size, c->total_size);
395 printf_filtered ("\n");
396
3d263c1d
BI
397 printf_filtered (_(" Max entry size: %d\n"), max_entry_size);
398 printf_filtered (_(" Average entry size: "));
2160782c
AC
399 if (c->unique_count > 0)
400 printf_filtered ("%ld\n", c->unique_size / c->unique_count);
401 else
3d263c1d
BI
402 /* i18n: "Average entry size: (not applicable)" */
403 printf_filtered (_("(not applicable)\n"));
404 printf_filtered (_(" Median entry size: %d\n"), median_entry_size);
2160782c
AC
405 printf_filtered ("\n");
406
3d263c1d 407 printf_filtered (_(" Total memory used by bcache, including overhead: %ld\n"),
c2d11a7d 408 c->structure_size);
3d263c1d 409 printf_filtered (_(" Percentage memory overhead: "));
c2d11a7d 410 print_percentage (c->structure_size - c->unique_size, c->unique_size);
3d263c1d 411 printf_filtered (_(" Net memory savings: "));
c2d11a7d
JM
412 print_percentage (c->total_size - c->structure_size, c->total_size);
413 printf_filtered ("\n");
414
3d263c1d
BI
415 printf_filtered (_(" Hash table size: %3d\n"), c->num_buckets);
416 printf_filtered (_(" Hash table expands: %lu\n"),
2160782c 417 c->expand_count);
3d263c1d 418 printf_filtered (_(" Hash table hashes: %lu\n"),
2160782c 419 c->total_count + c->expand_hash_count);
3d263c1d 420 printf_filtered (_(" Half hash misses: %lu\n"),
49df298f 421 c->half_hash_miss_count);
3d263c1d 422 printf_filtered (_(" Hash table population: "));
c2d11a7d 423 print_percentage (occupied_buckets, c->num_buckets);
3d263c1d 424 printf_filtered (_(" Median hash chain length: %3d\n"),
c2d11a7d 425 median_chain_length);
3d263c1d 426 printf_filtered (_(" Average hash chain length: "));
c2d11a7d 427 if (c->num_buckets > 0)
745b8ca0 428 printf_filtered ("%3lu\n", c->unique_count / c->num_buckets);
c906108c 429 else
3d263c1d
BI
430 /* i18n: "Average hash chain length: (not applicable)" */
431 printf_filtered (_("(not applicable)\n"));
432 printf_filtered (_(" Maximum hash chain length: %3d\n"), max_chain_length);
c2d11a7d 433 printf_filtered ("\n");
c906108c 434}
af5f3db6
AC
435
436int
437bcache_memory_used (struct bcache *bcache)
438{
439 return obstack_memory_used (&bcache->cache);
440}
This page took 0.59843 seconds and 4 git commands to generate.