Upgrade GDB from 7.4.1 to 7.6.1 on the vendor branch
[dragonfly.git] / contrib / gdb-7 / gdb / bcache.c
1 /* Implement a cached obstack.
2    Written by Fred Fish <fnf@cygnus.com>
3    Rewritten by Jim Blandy <jimb@cygnus.com>
4
5    Copyright (C) 1999-2013 Free Software Foundation, Inc.
6
7    This file is part of GDB.
8
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
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
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.
18
19    You should have received a copy of the GNU General Public License
20    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
21
22 #include "defs.h"
23 #include "gdb_obstack.h"
24 #include "bcache.h"
25 #include "gdb_string.h"         /* For memcpy declaration */
26 #include "gdb_assert.h"
27
28 #include <stddef.h>
29 #include <stdlib.h>
30
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
37 struct bstring
38 {
39   /* Hash chain.  */
40   struct bstring *next;
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;
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
62 struct 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 */
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;
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;
91
92   /* Hash function to be used for this bcache object.  */
93   unsigned long (*hash_function)(const void *addr, int length);
94
95   /* Compare function to be used for this bcache object.  */
96   int (*compare_function)(const void *, const void *, int length);
97 };
98
99 /* The old hash function was stolen from SDBM. This is what DB 3.0
100    uses now, and is better than the old one.  */
101 \f
102 unsigned long
103 hash(const void *addr, int length)
104 {
105   return hash_continue (addr, length, 0);
106 }
107
108 /* Continue the calculation of the hash H at the given address.  */
109
110 unsigned long
111 hash_continue (const void *addr, int length, unsigned long h)
112 {
113   const unsigned char *k, *e;
114
115   k = (const unsigned char *)addr;
116   e = k+length;
117   for (; k< e;++k)
118     {
119       h *=16777619;
120       h ^= *k;
121     }
122   return (h);
123 }
124 \f
125 /* Growing the bcache's hash table.  */
126
127 /* If the average chain length grows beyond this, then we want to
128    resize our hash table.  */
129 #define CHAIN_LENGTH_THRESHOLD (5)
130
131 static void
132 expand_hash_table (struct bcache *bcache)
133 {
134   /* A table of good hash table sizes.  Whenever we grow, we pick the
135      next larger size from this table.  sizes[i] is close to 1 << (i+10),
136      so we roughly double the table size each time.  After we fall off 
137      the end of this table, we just double.  Don't laugh --- there have
138      been executables sighted with a gigabyte of debug info.  */
139   static unsigned long sizes[] = { 
140     1021, 2053, 4099, 8191, 16381, 32771,
141     65537, 131071, 262144, 524287, 1048573, 2097143,
142     4194301, 8388617, 16777213, 33554467, 67108859, 134217757,
143     268435459, 536870923, 1073741827, 2147483659UL
144   };
145   unsigned int new_num_buckets;
146   struct bstring **new_buckets;
147   unsigned int i;
148
149   /* Count the stats.  Every unique item needs to be re-hashed and
150      re-entered.  */
151   bcache->expand_count++;
152   bcache->expand_hash_count += bcache->unique_count;
153
154   /* Find the next size.  */
155   new_num_buckets = bcache->num_buckets * 2;
156   for (i = 0; i < (sizeof (sizes) / sizeof (sizes[0])); i++)
157     if (sizes[i] > bcache->num_buckets)
158       {
159         new_num_buckets = sizes[i];
160         break;
161       }
162
163   /* Allocate the new table.  */
164   {
165     size_t new_size = new_num_buckets * sizeof (new_buckets[0]);
166
167     new_buckets = (struct bstring **) xmalloc (new_size);
168     memset (new_buckets, 0, new_size);
169
170     bcache->structure_size -= (bcache->num_buckets
171                                * sizeof (bcache->bucket[0]));
172     bcache->structure_size += new_size;
173   }
174
175   /* Rehash all existing strings.  */
176   for (i = 0; i < bcache->num_buckets; i++)
177     {
178       struct bstring *s, *next;
179
180       for (s = bcache->bucket[i]; s; s = next)
181         {
182           struct bstring **new_bucket;
183           next = s->next;
184
185           new_bucket = &new_buckets[(bcache->hash_function (&s->d.data,
186                                                             s->length)
187                                      % new_num_buckets)];
188           s->next = *new_bucket;
189           *new_bucket = s;
190         }
191     }
192
193   /* Plug in the new table.  */
194   if (bcache->bucket)
195     xfree (bcache->bucket);
196   bcache->bucket = new_buckets;
197   bcache->num_buckets = new_num_buckets;
198 }
199
200 \f
201 /* Looking up things in the bcache.  */
202
203 /* The number of bytes needed to allocate a struct bstring whose data
204    is N bytes long.  */
205 #define BSTRING_SIZE(n) (offsetof (struct bstring, d.data) + (n))
206
207 /* Find a copy of the LENGTH bytes at ADDR in BCACHE.  If BCACHE has
208    never seen those bytes before, add a copy of them to BCACHE.  In
209    either case, return a pointer to BCACHE's copy of that string.  */
210 const void *
211 bcache (const void *addr, int length, struct bcache *cache)
212 {
213   return bcache_full (addr, length, cache, NULL);
214 }
215
216 /* Find a copy of the LENGTH bytes at ADDR in BCACHE.  If BCACHE has
217    never seen those bytes before, add a copy of them to BCACHE.  In
218    either case, return a pointer to BCACHE's copy of that string.  If
219    optional ADDED is not NULL, return 1 in case of new entry or 0 if
220    returning an old entry.  */
221
222 const void *
223 bcache_full (const void *addr, int length, struct bcache *bcache, int *added)
224 {
225   unsigned long full_hash;
226   unsigned short half_hash;
227   int hash_index;
228   struct bstring *s;
229
230   if (added)
231     *added = 0;
232
233   /* Lazily initialize the obstack.  This can save quite a bit of
234      memory in some cases.  */
235   if (bcache->total_count == 0)
236     {
237       /* We could use obstack_specify_allocation here instead, but
238          gdb_obstack.h specifies the allocation/deallocation
239          functions.  */
240       obstack_init (&bcache->cache);
241     }
242
243   /* If our average chain length is too high, expand the hash table.  */
244   if (bcache->unique_count >= bcache->num_buckets * CHAIN_LENGTH_THRESHOLD)
245     expand_hash_table (bcache);
246
247   bcache->total_count++;
248   bcache->total_size += length;
249
250   full_hash = bcache->hash_function (addr, length);
251
252   half_hash = (full_hash >> 16);
253   hash_index = full_hash % bcache->num_buckets;
254
255   /* Search the hash bucket for a string identical to the caller's.
256      As a short-circuit first compare the upper part of each hash
257      values.  */
258   for (s = bcache->bucket[hash_index]; s; s = s->next)
259     {
260       if (s->half_hash == half_hash)
261         {
262           if (s->length == length
263               && bcache->compare_function (&s->d.data, addr, length))
264             return &s->d.data;
265           else
266             bcache->half_hash_miss_count++;
267         }
268     }
269
270   /* The user's string isn't in the list.  Insert it after *ps.  */
271   {
272     struct bstring *new
273       = obstack_alloc (&bcache->cache, BSTRING_SIZE (length));
274
275     memcpy (&new->d.data, addr, length);
276     new->length = length;
277     new->next = bcache->bucket[hash_index];
278     new->half_hash = half_hash;
279     bcache->bucket[hash_index] = new;
280
281     bcache->unique_count++;
282     bcache->unique_size += length;
283     bcache->structure_size += BSTRING_SIZE (length);
284
285     if (added)
286       *added = 1;
287
288     return &new->d.data;
289   }
290 }
291 \f
292
293 /* Compare the byte string at ADDR1 of lenght LENGHT to the
294    string at ADDR2.  Return 1 if they are equal.  */
295
296 static int
297 bcache_compare (const void *addr1, const void *addr2, int length)
298 {
299   return memcmp (addr1, addr2, length) == 0;
300 }
301
302 /* Allocating and freeing bcaches.  */
303
304 /* Allocated a bcache.  HASH_FUNCTION and COMPARE_FUNCTION can be used
305    to pass in custom hash, and compare functions to be used by this
306    bcache.  If HASH_FUNCTION is NULL hash() is used and if
307    COMPARE_FUNCTION is NULL memcmp() is used.  */
308
309 struct bcache *
310 bcache_xmalloc (unsigned long (*hash_function)(const void *, int length),
311                 int (*compare_function)(const void *, 
312                                         const void *, 
313                                         int length))
314 {
315   /* Allocate the bcache pre-zeroed.  */
316   struct bcache *b = XCALLOC (1, struct bcache);
317
318   if (hash_function)
319     b->hash_function = hash_function;
320   else
321     b->hash_function = hash;
322
323   if (compare_function)
324     b->compare_function = compare_function;
325   else
326     b->compare_function = bcache_compare;
327   return b;
328 }
329
330 /* Free all the storage associated with BCACHE.  */
331 void
332 bcache_xfree (struct bcache *bcache)
333 {
334   if (bcache == NULL)
335     return;
336   /* Only free the obstack if we actually initialized it.  */
337   if (bcache->total_count > 0)
338     obstack_free (&bcache->cache, 0);
339   xfree (bcache->bucket);
340   xfree (bcache);
341 }
342
343
344 \f
345 /* Printing statistics.  */
346
347 static void
348 print_percentage (int portion, int total)
349 {
350   if (total == 0)
351     /* i18n: Like "Percentage of duplicates, by count: (not applicable)".  */
352     printf_filtered (_("(not applicable)\n"));
353   else
354     printf_filtered ("%3d%%\n", (int) (portion * 100.0 / total));
355 }
356
357
358 /* Print statistics on BCACHE's memory usage and efficacity at
359    eliminating duplication.  NAME should describe the kind of data
360    BCACHE holds.  Statistics are printed using `printf_filtered' and
361    its ilk.  */
362 void
363 print_bcache_statistics (struct bcache *c, char *type)
364 {
365   int occupied_buckets;
366   int max_chain_length;
367   int median_chain_length;
368   int max_entry_size;
369   int median_entry_size;
370
371   /* Count the number of occupied buckets, tally the various string
372      lengths, and measure chain lengths.  */
373   {
374     unsigned int b;
375     int *chain_length = XCALLOC (c->num_buckets + 1, int);
376     int *entry_size = XCALLOC (c->unique_count + 1, int);
377     int stringi = 0;
378
379     occupied_buckets = 0;
380
381     for (b = 0; b < c->num_buckets; b++)
382       {
383         struct bstring *s = c->bucket[b];
384
385         chain_length[b] = 0;
386
387         if (s)
388           {
389             occupied_buckets++;
390             
391             while (s)
392               {
393                 gdb_assert (b < c->num_buckets);
394                 chain_length[b]++;
395                 gdb_assert (stringi < c->unique_count);
396                 entry_size[stringi++] = s->length;
397                 s = s->next;
398               }
399           }
400       }
401
402     /* To compute the median, we need the set of chain lengths
403        sorted.  */
404     qsort (chain_length, c->num_buckets, sizeof (chain_length[0]),
405            compare_positive_ints);
406     qsort (entry_size, c->unique_count, sizeof (entry_size[0]),
407            compare_positive_ints);
408
409     if (c->num_buckets > 0)
410       {
411         max_chain_length = chain_length[c->num_buckets - 1];
412         median_chain_length = chain_length[c->num_buckets / 2];
413       }
414     else
415       {
416         max_chain_length = 0;
417         median_chain_length = 0;
418       }
419     if (c->unique_count > 0)
420       {
421         max_entry_size = entry_size[c->unique_count - 1];
422         median_entry_size = entry_size[c->unique_count / 2];
423       }
424     else
425       {
426         max_entry_size = 0;
427         median_entry_size = 0;
428       }
429
430     xfree (chain_length);
431     xfree (entry_size);
432   }
433
434   printf_filtered (_("  Cached '%s' statistics:\n"), type);
435   printf_filtered (_("    Total object count:  %ld\n"), c->total_count);
436   printf_filtered (_("    Unique object count: %lu\n"), c->unique_count);
437   printf_filtered (_("    Percentage of duplicates, by count: "));
438   print_percentage (c->total_count - c->unique_count, c->total_count);
439   printf_filtered ("\n");
440
441   printf_filtered (_("    Total object size:   %ld\n"), c->total_size);
442   printf_filtered (_("    Unique object size:  %ld\n"), c->unique_size);
443   printf_filtered (_("    Percentage of duplicates, by size:  "));
444   print_percentage (c->total_size - c->unique_size, c->total_size);
445   printf_filtered ("\n");
446
447   printf_filtered (_("    Max entry size:     %d\n"), max_entry_size);
448   printf_filtered (_("    Average entry size: "));
449   if (c->unique_count > 0)
450     printf_filtered ("%ld\n", c->unique_size / c->unique_count);
451   else
452     /* i18n: "Average entry size: (not applicable)".  */
453     printf_filtered (_("(not applicable)\n"));    
454   printf_filtered (_("    Median entry size:  %d\n"), median_entry_size);
455   printf_filtered ("\n");
456
457   printf_filtered (_("    \
458 Total memory used by bcache, including overhead: %ld\n"),
459                    c->structure_size);
460   printf_filtered (_("    Percentage memory overhead: "));
461   print_percentage (c->structure_size - c->unique_size, c->unique_size);
462   printf_filtered (_("    Net memory savings:         "));
463   print_percentage (c->total_size - c->structure_size, c->total_size);
464   printf_filtered ("\n");
465
466   printf_filtered (_("    Hash table size:           %3d\n"), 
467                    c->num_buckets);
468   printf_filtered (_("    Hash table expands:        %lu\n"),
469                    c->expand_count);
470   printf_filtered (_("    Hash table hashes:         %lu\n"),
471                    c->total_count + c->expand_hash_count);
472   printf_filtered (_("    Half hash misses:          %lu\n"),
473                    c->half_hash_miss_count);
474   printf_filtered (_("    Hash table population:     "));
475   print_percentage (occupied_buckets, c->num_buckets);
476   printf_filtered (_("    Median hash chain length:  %3d\n"),
477                    median_chain_length);
478   printf_filtered (_("    Average hash chain length: "));
479   if (c->num_buckets > 0)
480     printf_filtered ("%3lu\n", c->unique_count / c->num_buckets);
481   else
482     /* i18n: "Average hash chain length: (not applicable)".  */
483     printf_filtered (_("(not applicable)\n"));
484   printf_filtered (_("    Maximum hash chain length: %3d\n"), 
485                    max_chain_length);
486   printf_filtered ("\n");
487 }
488
489 int
490 bcache_memory_used (struct bcache *bcache)
491 {
492   if (bcache->total_count == 0)
493     return 0;
494   return obstack_memory_used (&bcache->cache);
495 }