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