Skip to content

Commit 163b718

Browse files
committed
Reduce the cache key to RUBY_REVISION + RUBY_PLATFORM
Fix: #409 Various system versions were added, but as far as I could gather it was just overly conservative. This was reducing the usefulness of bootsnap when using Alpine linux containers.
1 parent 5bb937a commit 163b718

File tree

3 files changed

+5
-50
lines changed

3 files changed

+5
-50
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Unreleased
22

3+
* Remove `uname` and other patform specific version from the cache keys. `RUBY_PLATFORM + RUBY_REVISION` should be
4+
enough to ensure bytecode compatibility. This should improve caching for alpine based setups. See #409.
5+
36
# 1.11.1
47

58
* Fix the `can't modify frozen Hash` error on load path cache mutation. See #411.

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -232,9 +232,9 @@ Bootsnap writes a cache file containing a 64 byte header followed by the cache c
232232
is a cache key including several fields:
233233

234234
* `version`, hardcoded in bootsnap. Essentially a schema version;
235-
* `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable and glibc version (on Linux) or OS version (`uname -v` on BSD, macOS)
235+
* `ruby_platform`, A hash of `RUBY_PLATFORM` (e.g. x86_64-linux-gnu) variable.
236236
* `compile_option`, which changes with `RubyVM::InstructionSequence.compile_option` does;
237-
* `ruby_revision`, the version of Ruby this was compiled with;
237+
* `ruby_revision`, A hash of `RUBY_REVISION`, the exact version of Ruby;
238238
* `size`, the size of the source file;
239239
* `mtime`, the last-modification timestamp of the source file when it was compiled; and
240240
* `data_size`, the number of bytes following the header, which we need to read it into a buffer.

ext/bootsnap/bootsnap.c

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@
1919
#include <errno.h>
2020
#include <fcntl.h>
2121
#include <sys/stat.h>
22-
#ifndef _WIN32
23-
#include <sys/utsname.h>
24-
#endif
25-
#ifdef __GLIBC__
26-
#include <gnu/libc-version.h>
27-
#endif
2822

2923
/* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
3024
* 981 for the cache dir */
@@ -205,29 +199,6 @@ bs_compile_option_crc32_set(VALUE self, VALUE crc32_v)
205199
return Qnil;
206200
}
207201

208-
/*
209-
* We use FNV1a-64 to derive cache paths. The choice is somewhat arbitrary but
210-
* it has several nice properties:
211-
*
212-
* - Tiny implementation
213-
* - No external dependency
214-
* - Solid performance
215-
* - Solid randomness
216-
* - 32 bits doesn't feel collision-resistant enough; 64 is nice.
217-
*/
218-
static uint64_t
219-
fnv1a_64_iter_cstr(uint64_t h, const char *str)
220-
{
221-
unsigned char *s = (unsigned char *)str;
222-
223-
while (*s) {
224-
h ^= (uint64_t)*s++;
225-
h += (h << 1) + (h << 4) + (h << 5) + (h << 7) + (h << 8) + (h << 40);
226-
}
227-
228-
return h;
229-
}
230-
231202
static uint64_t
232203
fnv1a_64_iter(uint64_t h, const VALUE str)
233204
{
@@ -272,10 +243,6 @@ get_ruby_revision(void)
272243
/*
273244
* When ruby's version doesn't change, but it's recompiled on a different OS
274245
* (or OS version), we need to invalidate the cache.
275-
*
276-
* We actually factor in some extra information here, to be extra confident
277-
* that we don't try to re-use caches that will not be compatible, by factoring
278-
* in utsname.version.
279246
*/
280247
static uint32_t
281248
get_ruby_platform(void)
@@ -285,22 +252,7 @@ get_ruby_platform(void)
285252

286253
ruby_platform = rb_const_get(rb_cObject, rb_intern("RUBY_PLATFORM"));
287254
hash = fnv1a_64(ruby_platform);
288-
289-
#ifdef _WIN32
290-
return (uint32_t)(hash >> 32) ^ (uint32_t)GetVersion();
291-
#elif defined(__GLIBC__)
292-
hash = fnv1a_64_iter_cstr(hash, gnu_get_libc_version());
293255
return (uint32_t)(hash >> 32);
294-
#else
295-
struct utsname utsname;
296-
297-
/* Not worth crashing if this fails; lose extra cache invalidation potential */
298-
if (uname(&utsname) >= 0) {
299-
hash = fnv1a_64_iter_cstr(hash, utsname.version);
300-
}
301-
302-
return (uint32_t)(hash >> 32);
303-
#endif
304256
}
305257

306258
/*

0 commit comments

Comments
 (0)