GDB (xrefs)
/tmp/gdb-7.10/gdb/bcache.h
Go to the documentation of this file.
1 /* Include file cached obstack implementation.
2  Written by Fred Fish <fnf@cygnus.com>
3  Rewritten by Jim Blandy <jimb@cygnus.com>
4 
5  Copyright (C) 1999-2015 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 #ifndef BCACHE_H
23 #define BCACHE_H 1
24 
25 /* A bcache is a data structure for factoring out duplication in
26  read-only structures. You give the bcache some string of bytes S.
27  If the bcache already contains a copy of S, it hands you back a
28  pointer to its copy. Otherwise, it makes a fresh copy of S, and
29  hands you back a pointer to that. In either case, you can throw
30  away your copy of S, and use the bcache's.
31 
32  The "strings" in question are arbitrary strings of bytes --- they
33  can contain zero bytes. You pass in the length explicitly when you
34  call the bcache function.
35 
36  This means that you can put ordinary C objects in a bcache.
37  However, if you do this, remember that structs can contain `holes'
38  between members, added for alignment. These bytes usually contain
39  garbage. If you try to bcache two objects which are identical from
40  your code's point of view, but have different garbage values in the
41  structure's holes, then the bcache will treat them as separate
42  strings, and you won't get the nice elimination of duplicates you
43  were hoping for. So, remember to memset your structures full of
44  zeros before bcaching them!
45 
46  You shouldn't modify the strings you get from a bcache, because:
47 
48  - You don't necessarily know who you're sharing space with. If I
49  stick eight bytes of text in a bcache, and then stick an eight-byte
50  structure in the same bcache, there's no guarantee those two
51  objects don't actually comprise the same sequence of bytes. If
52  they happen to, the bcache will use a single byte string for both
53  of them. Then, modifying the structure will change the string. In
54  bizarre ways.
55 
56  - Even if you know for some other reason that all that's okay,
57  there's another problem. A bcache stores all its strings in a hash
58  table. If you modify a string's contents, you will probably change
59  its hash value. This means that the modified string is now in the
60  wrong place in the hash table, and future bcache probes will never
61  find it. So by mutating a string, you give up any chance of
62  sharing its space with future duplicates.
63 
64 
65  Size of bcache VS hashtab:
66 
67  For bcache, the most critical cost is size (or more exactly the
68  overhead added by the bcache). It turns out that the bcache is
69  remarkably efficient.
70 
71  Assuming a 32-bit system (the hash table slots are 4 bytes),
72  ignoring alignment, and limit strings to 255 bytes (1 byte length)
73  we get ...
74 
75  bcache: This uses a separate linked list to track the hash chain.
76  The numbers show roughly 100% occupancy of the hash table and an
77  average chain length of 4. Spreading the slot cost over the 4
78  chain elements:
79 
80  4 (slot) / 4 (chain length) + 1 (length) + 4 (chain) = 6 bytes
81 
82  hashtab: This uses a more traditional re-hash algorithm where the
83  chain is maintained within the hash table. The table occupancy is
84  kept below 75% but we'll assume its perfect:
85 
86  4 (slot) x 4/3 (occupancy) + 1 (length) = 6 1/3 bytes
87 
88  So a perfect hashtab has just slightly larger than an average
89  bcache.
90 
91  It turns out that an average hashtab is far worse. Two things
92  hurt:
93 
94  - Hashtab's occupancy is more like 50% (it ranges between 38% and
95  75%) giving a per slot cost of 4x2 vs 4x4/3.
96 
97  - the string structure needs to be aligned to 8 bytes which for
98  hashtab wastes 7 bytes, while for bcache wastes only 3.
99 
100  This gives:
101 
102  hashtab: 4 x 2 + 1 + 7 = 16 bytes
103 
104  bcache 4 / 4 + 1 + 4 + 3 = 9 bytes
105 
106  The numbers of GDB debugging GDB support this. ~40% vs ~70% overhead.
107 
108 
109  Speed of bcache VS hashtab (the half hash hack):
110 
111  While hashtab has a typical chain length of 1, bcache has a chain
112  length of round 4. This means that the bcache will require
113  something like double the number of compares after that initial
114  hash. In both cases the comparison takes the form:
115 
116  a.length == b.length && memcmp (a.data, b.data, a.length) == 0
117 
118  That is lengths are checked before doing the memcmp.
119 
120  For GDB debugging GDB, it turned out that all lengths were 24 bytes
121  (no C++ so only psymbols were cached) and hence, all compares
122  required a call to memcmp. As a hack, two bytes of padding
123  (mentioned above) are used to store the upper 16 bits of the
124  string's hash value and then that is used in the comparison vis:
125 
126  a.half_hash == b.half_hash && a.length == b.length && memcmp
127  (a.data, b.data, a.length)
128 
129  The numbers from GDB debugging GDB show this to be a remarkable
130  100% effective (only necessary length and memcmp tests being
131  performed).
132 
133  Mind you, looking at the wall clock, the same GDB debugging GDB
134  showed only marginal speed up (0.780 vs 0.773s). Seems GDB is too
135  busy doing something else :-(
136 
137 */
138 
139 
140 struct bcache;
141 
142 /* Find a copy of the LENGTH bytes at ADDR in BCACHE. If BCACHE has
143  never seen those bytes before, add a copy of them to BCACHE. In
144  either case, return a pointer to BCACHE's copy of that string.
145  Since the cached value is ment to be read-only, return a const
146  buffer. */
147 extern const void *bcache (const void *addr, int length,
148  struct bcache *bcache);
149 
150 /* Like bcache, but if ADDED is not NULL, set *ADDED to true if the
151  bytes were newly added to the cache, or to false if the bytes were
152  found in the cache. */
153 extern const void *bcache_full (const void *addr, int length,
154  struct bcache *bcache, int *added);
155 
156 /* Free all the storage used by BCACHE. */
157 extern void bcache_xfree (struct bcache *bcache);
158 
159 /* Create a new bcache object. */
160 extern struct bcache *bcache_xmalloc (
161  unsigned long (*hash_function)(const void *, int length),
162  int (*compare_function)(const void *, const void *, int length));
163 
164 /* Print statistics on BCACHE's memory usage and efficacity at
165  eliminating duplication. TYPE should be a string describing the
166  kind of data BCACHE holds. Statistics are printed using
167  `printf_filtered' and its ilk. */
168 extern void print_bcache_statistics (struct bcache *bcache, char *type);
169 extern int bcache_memory_used (struct bcache *bcache);
170 
171 /* The hash functions */
172 extern unsigned long hash(const void *addr, int length);
173 extern unsigned long hash_continue (const void *addr, int length,
174  unsigned long h);
175 
176 #endif /* BCACHE_H */
const void * bcache(const void *addr, int length, struct bcache *bcache)
Definition: bcache.c:206
int(* compare_function)(const void *, const void *, int length)
Definition: bcache.c:91
Definition: gdbtypes.h:749
unsigned long hash_continue(const void *addr, int length, unsigned long h)
Definition: bcache.c:106
struct bcache * bcache_xmalloc(unsigned long(*hash_function)(const void *, int length), int(*compare_function)(const void *, const void *, int length))
Definition: bcache.c:305
void print_bcache_statistics(struct bcache *bcache, char *type)
Definition: bcache.c:358
unsigned long(* hash_function)(const void *addr, int length)
Definition: bcache.c:88
Definition: bcache.c:57
void bcache_xfree(struct bcache *bcache)
Definition: bcache.c:327
int bcache_memory_used(struct bcache *bcache)
Definition: bcache.c:485
const void * bcache_full(const void *addr, int length, struct bcache *bcache, int *added)
Definition: bcache.c:218
unsigned long hash(const void *addr, int length)
Definition: bcache.c:98