bootsnap 1.18.6 → 1.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +101 -7
- data/LICENSE.txt +2 -1
- data/README.md +57 -10
- data/ext/bootsnap/bootsnap.c +297 -154
- data/ext/bootsnap/extconf.rb +2 -1
- data/lib/bootsnap/cli/worker_pool.rb +3 -3
- data/lib/bootsnap/cli.rb +4 -31
- data/lib/bootsnap/compile_cache/iseq.rb +183 -77
- data/lib/bootsnap/compile_cache/ruby_bug_22023_canary.rb +1 -0
- data/lib/bootsnap/compile_cache/yaml.rb +98 -46
- data/lib/bootsnap/compile_cache.rb +5 -10
- data/lib/bootsnap/load_path_cache/cache.rb +11 -14
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +9 -4
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +1 -1
- data/lib/bootsnap/load_path_cache/path.rb +34 -27
- data/lib/bootsnap/load_path_cache/path_scanner.rb +78 -32
- data/lib/bootsnap/load_path_cache/store.rb +2 -2
- data/lib/bootsnap/rake.rb +14 -0
- data/lib/bootsnap/version.rb +1 -1
- data/lib/bootsnap.rb +51 -10
- metadata +11 -11
- data/ext/bootsnap/bootsnap.h +0 -6
- data/lib/bootsnap/compile_cache/json.rb +0 -89
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6227028d2a559d0e5129ef91915f65a064082b2e1326517dd67da2f11d91d194
|
|
4
|
+
data.tar.gz: 1c7cbf82581f9162601a7723812201d240661c0d3477373b820cf7e942b9d416
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 385183b9de17b6f72634b7307fdfc5481108afc06554b48bb2dede97e51ba4275d076357934d338286fceb3a221f1468ec2ea10e2f0f869de5a7b5b97fc444a8
|
|
7
|
+
data.tar.gz: c74bb8bdfe0e6f3615bbc4a6ea4f7c5a7a1d8589a3469da964c25b44451fbb3f54f10521b8549dc6ac400d7fb17ba4a686b5b289115e8b3bac81d7a5449e3c0b
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,99 @@
|
|
|
1
1
|
# Unreleased
|
|
2
2
|
|
|
3
|
+
# 1.26.0
|
|
4
|
+
|
|
5
|
+
* Handle top level `Coverage` constant being defined, but without it being the true stdlib `coverage` module.
|
|
6
|
+
* Fix `bootsnap precompile` that could generate a corrupted cache entry if an already cached YAML file was modified
|
|
7
|
+
without changing its size.
|
|
8
|
+
* Workaround a potential Ruby SEGV if `Bootsnap.instrumentation` raised an error.
|
|
9
|
+
|
|
10
|
+
# 1.25.0
|
|
11
|
+
|
|
12
|
+
* Improve YAML parsing cache to more efficiently handle `Time`, `Date` and `DateTime`.
|
|
13
|
+
|
|
14
|
+
* Don't invalidate the compile cache when YJIT is toggled. YJIT is a runtime JIT and doesn't change the
|
|
15
|
+
serialized instruction sequences that are cached, but enabling it (via `--yjit`, `RUBYOPT`, or
|
|
16
|
+
`RubyVM::YJIT.enable`) adds a ` +YJIT` marker to `RUBY_DESCRIPTION` (` +YJIT <token>` on `YJIT_SUPPORT`
|
|
17
|
+
builds), which is part of the cache key. This previously discarded the entire compile cache whenever YJIT
|
|
18
|
+
was enabled at runtime but not at precompile time (or vice versa). The marker is now stripped before hashing.
|
|
19
|
+
|
|
20
|
+
* Fix `CompileCache::Native.fetch` and `.precompile` reading a non-`String` path argument (e.g. a `Pathname`)
|
|
21
|
+
with `RSTRING_PTR`. Regression from 1.24.0.
|
|
22
|
+
|
|
23
|
+
# 1.24.6
|
|
24
|
+
|
|
25
|
+
* Fix detection of Ruby bug #22023 on some patch versions of Ruby 3.4, and properly apply the workaround.
|
|
26
|
+
|
|
27
|
+
# 1.24.5
|
|
28
|
+
|
|
29
|
+
* No longer load the config file by default when setup is done manually. This is so cli applications like homebrew
|
|
30
|
+
don't mistakenly load another app's boostnap config.
|
|
31
|
+
|
|
32
|
+
# 1.24.4
|
|
33
|
+
|
|
34
|
+
* Fix several compatibility issues with Ruby `4.0.4`, particularly the `should not compile with coverage` error. See #547.
|
|
35
|
+
* Fix `Bootsnap.enable_frozen_string_literal` to work even when coverage is enabled. Unfortunately only possible on Ruby `4.0.4+`.
|
|
36
|
+
On older rubies if coverage is enabled a warning will be issued and the feature won't work.
|
|
37
|
+
* Reduced cache files header size from 64 to 32 bytes, and got rid of the random padding element.
|
|
38
|
+
* Avoid leaking a private method in `Object` when testing for Parse.y bugs.
|
|
39
|
+
|
|
40
|
+
# 1.24.3
|
|
41
|
+
|
|
42
|
+
* Fix the `1.24.2` workaround to parse Ruby files with UTF-8 even when the `LANG` environment variable
|
|
43
|
+
is unset or set to `C`.
|
|
44
|
+
|
|
45
|
+
# 1.24.2
|
|
46
|
+
|
|
47
|
+
* Workaround two Ruby bugs in `RubyVM::InstructionSequence.compile_file`, that were causing
|
|
48
|
+
files to be loaded with the old Ruby parser instead of Prism, causing issues with some pattern matching syntax.
|
|
49
|
+
Ref: https://bugs.ruby-lang.org/issues/22023
|
|
50
|
+
|
|
51
|
+
# 1.24.1
|
|
52
|
+
|
|
53
|
+
* Fix encoding of Ruby source files loaded when `BOOTSNAP_READONLY` is set.
|
|
54
|
+
Files would incorectly be loaded in `ASCII-8BIT` causing literal strings outside
|
|
55
|
+
the pure ASCII range to have `ASCII-8BIT` encoding instead of `UTF-8`.
|
|
56
|
+
This bug was introduced in `1.24.0`.
|
|
57
|
+
|
|
58
|
+
# 1.24.0
|
|
59
|
+
|
|
60
|
+
* Added a hook API to customize Ruby compilation.
|
|
61
|
+
|
|
62
|
+
# 1.23.0
|
|
63
|
+
|
|
64
|
+
* Require Ruby 2.7.
|
|
65
|
+
* Fix support for absolute paths in `BOOTSNAP_IGNORE_DIRECTORIES`.
|
|
66
|
+
|
|
67
|
+
# 1.22.0
|
|
68
|
+
|
|
69
|
+
* Better fix for the `opendir` crash.
|
|
70
|
+
* Add `bootsnap/rake` for cleaning the bootsnap cache as part of `rake clobber`.
|
|
71
|
+
|
|
72
|
+
# 1.21.1
|
|
73
|
+
|
|
74
|
+
* Prevent a Ruby crash while scanning load path if `opendir` fails without setting `errno`.
|
|
75
|
+
According to the C spec this should not happen, but according to user reports, it did.
|
|
76
|
+
|
|
77
|
+
# 1.21.0
|
|
78
|
+
|
|
79
|
+
* Fix the `require` decorator to handle `Bootsnap.unload_cache!` being called.
|
|
80
|
+
* Minor optimization: Eagerly clear cache buffers to appease the GC.
|
|
81
|
+
|
|
82
|
+
# 1.20.1
|
|
83
|
+
|
|
84
|
+
* Handle broken symlinks in load path scanning code.
|
|
85
|
+
Should fix `Errno::ENOENT fstatat` issues some users have encountered after upgrading to 1.20.0.
|
|
86
|
+
|
|
87
|
+
# 1.20.0
|
|
88
|
+
|
|
89
|
+
* Optimized load path scanning with a C extension. Should be about 2x faster on supported platforms.
|
|
90
|
+
|
|
91
|
+
# 1.19.0
|
|
92
|
+
|
|
93
|
+
* Remove JSON parsing cache. Recent versions of the `json` gem are as fast as `msgpack` if not faster.
|
|
94
|
+
|
|
95
|
+
# 1.18.6
|
|
96
|
+
|
|
3
97
|
* Fix cgroup CPU limits detection in CLI.
|
|
4
98
|
|
|
5
99
|
# 1.18.5
|
|
@@ -103,7 +197,7 @@
|
|
|
103
197
|
|
|
104
198
|
* Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
|
|
105
199
|
This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
|
|
106
|
-
|
|
200
|
+
|
|
107
201
|
* Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
|
|
108
202
|
|
|
109
203
|
# 1.10.3
|
|
@@ -229,7 +323,7 @@
|
|
|
229
323
|
* Adds an instrumentation API to monitor cache misses.
|
|
230
324
|
* Allow to control the behavior of `require 'bootsnap/setup'` using environment variables.
|
|
231
325
|
* Deprecate the `disable_trace` option.
|
|
232
|
-
* Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
|
|
326
|
+
* Deprecate the `ActiveSupport::Dependencies` (AKA Classic autoloader) integration. (#344)
|
|
233
327
|
|
|
234
328
|
# 1.6.0
|
|
235
329
|
|
|
@@ -249,12 +343,12 @@
|
|
|
249
343
|
|
|
250
344
|
# 1.4.9
|
|
251
345
|
|
|
252
|
-
* [Windows support](https://github.com/
|
|
253
|
-
* [Fix potential crash](https://github.com/
|
|
346
|
+
* [Windows support](https://github.com/rails/bootsnap/pull/319)
|
|
347
|
+
* [Fix potential crash](https://github.com/rails/bootsnap/pull/322)
|
|
254
348
|
|
|
255
349
|
# 1.4.8
|
|
256
350
|
|
|
257
|
-
* [Prevent FallbackScan from polluting exception cause](https://github.com/
|
|
351
|
+
* [Prevent FallbackScan from polluting exception cause](https://github.com/rails/bootsnap/pull/314)
|
|
258
352
|
|
|
259
353
|
# 1.4.7
|
|
260
354
|
|
|
@@ -267,7 +361,7 @@
|
|
|
267
361
|
required if a different file with the same name was already being required
|
|
268
362
|
|
|
269
363
|
Example:
|
|
270
|
-
|
|
364
|
+
|
|
271
365
|
require 'foo'
|
|
272
366
|
require 'foo.en'
|
|
273
367
|
|
|
@@ -321,7 +415,7 @@
|
|
|
321
415
|
|
|
322
416
|
# 1.3.0
|
|
323
417
|
|
|
324
|
-
* Handle cases where load path entries are symlinked (https://github.com/
|
|
418
|
+
* Handle cases where load path entries are symlinked (https://github.com/rails/bootsnap/pull/136)
|
|
325
419
|
|
|
326
420
|
# 1.2.1
|
|
327
421
|
|
data/LICENSE.txt
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
The MIT License (MIT)
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2017-
|
|
3
|
+
Copyright (c) 2017-2025 Shopify, Inc.
|
|
4
|
+
Copyright (c) 2025-present Rails Foundation
|
|
4
5
|
|
|
5
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Bootsnap [](https://github.com/rails/bootsnap/actions)
|
|
2
2
|
|
|
3
3
|
Bootsnap is a library that plugs into Ruby, with optional support for `YAML` and `JSON`,
|
|
4
4
|
to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
|
|
@@ -41,7 +41,7 @@ getting progressively slower, this is almost certainly the cause.**
|
|
|
41
41
|
It's technically possible to simply specify `gem 'bootsnap', require: 'bootsnap/setup'`, but it's
|
|
42
42
|
important to load Bootsnap as early as possible to get maximum performance improvement.
|
|
43
43
|
|
|
44
|
-
You can see how this require works [here](https://github.com/
|
|
44
|
+
You can see how this require works [here](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/setup.rb).
|
|
45
45
|
|
|
46
46
|
If you are not using Rails, or if you are but want more control over things, add this to your
|
|
47
47
|
application setup immediately after `require 'bundler/setup'` (i.e. as early as possible: the sooner
|
|
@@ -57,13 +57,12 @@ Bootsnap.setup(
|
|
|
57
57
|
load_path_cache: true, # Optimize the LOAD_PATH with a cache
|
|
58
58
|
compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
|
|
59
59
|
compile_cache_yaml: true, # Compile YAML into a cache
|
|
60
|
-
compile_cache_json: true, # Compile JSON into a cache
|
|
61
60
|
readonly: true, # Use the caches but don't update them on miss or stale entries.
|
|
62
61
|
)
|
|
63
62
|
```
|
|
64
63
|
|
|
65
64
|
**Protip:** You can replace `require 'bootsnap'` with `BootLib::Require.from_gem('bootsnap',
|
|
66
|
-
'bootsnap')` using [this trick](https://github.com/
|
|
65
|
+
'bootsnap')` using [this trick](https://github.com/rails/bootsnap/wiki/Bootlib::Require). This
|
|
67
66
|
will help optimize boot time further if you have an extremely large `$LOAD_PATH`.
|
|
68
67
|
|
|
69
68
|
Note: Bootsnap and [Spring](https://github.com/rails/spring) are orthogonal tools. While Bootsnap
|
|
@@ -76,6 +75,7 @@ well together.
|
|
|
76
75
|
`require 'bootsnap/setup'` behavior can be changed using environment variables:
|
|
77
76
|
|
|
78
77
|
- `BOOTSNAP_CACHE_DIR` allows to define the cache location.
|
|
78
|
+
- `BOOTSNAP_CONFIG` allows to change the default config location (`config/bootsnap.rb`).
|
|
79
79
|
- `DISABLE_BOOTSNAP` allows to entirely disable bootsnap.
|
|
80
80
|
- `DISABLE_BOOTSNAP_LOAD_PATH_CACHE` allows to disable load path caching.
|
|
81
81
|
- `DISABLE_BOOTSNAP_COMPILE_CACHE` allows to disable ISeq and YAML caches.
|
|
@@ -170,7 +170,7 @@ The only directories considered "stable" are things under the Ruby install prefi
|
|
|
170
170
|
"volatile".
|
|
171
171
|
|
|
172
172
|
In addition to the [`Bootsnap::LoadPathCache::Cache`
|
|
173
|
-
source](https://github.com/
|
|
173
|
+
source](https://github.com/rails/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
|
|
174
174
|
this diagram may help clarify how entry resolution works:
|
|
175
175
|
|
|
176
176
|

|
|
@@ -237,14 +237,15 @@ This may look worse at a glance, but underlies a large performance difference.
|
|
|
237
237
|
useful. [This ruby patch](https://bugs.ruby-lang.org/issues/13378) optimizes them out when coupled
|
|
238
238
|
with bootsnap.)*
|
|
239
239
|
|
|
240
|
-
Bootsnap writes a cache file containing a
|
|
240
|
+
Bootsnap writes a cache file containing a 32 byte header followed by the cache contents. The header
|
|
241
241
|
is a cache key including several fields:
|
|
242
242
|
|
|
243
|
-
* `
|
|
244
|
-
*
|
|
245
|
-
*
|
|
246
|
-
*
|
|
243
|
+
* `ruby_version_digest`, a digest of:
|
|
244
|
+
* The `RUBY_DESCRIPTION` constant e.g. `"ruby 4.0.2 (2026-03-17 revision d3da9fec82) +PRISM [arm64-darwin25]"`.
|
|
245
|
+
* Bootsnap's cache version. Hardcoded in bootsnap. Essentially a schema version;
|
|
246
|
+
* The content of `RubyVM::InstructionSequence.compile_option`.
|
|
247
247
|
* `size`, the size of the source file;
|
|
248
|
+
* `digest`, a fnv1a_64 hash of the source file;
|
|
248
249
|
* `mtime`, the last-modification timestamp of the source file when it was compiled; and
|
|
249
250
|
* `data_size`, the number of bytes following the header, which we need to read it into a buffer.
|
|
250
251
|
|
|
@@ -321,6 +322,38 @@ open /c/nope.bundle -> -1
|
|
|
321
322
|
# (nothing!)
|
|
322
323
|
```
|
|
323
324
|
|
|
325
|
+
## Custom Compilers
|
|
326
|
+
|
|
327
|
+
Bootsnap allows substituing the default Ruby compiler by another one.
|
|
328
|
+
This can be configured from the bootsnap config file (defaults to `config/bootsnap.rb`).
|
|
329
|
+
|
|
330
|
+
The main use case is to programmatically enable frozen string literals for your project without impacting dependencies:
|
|
331
|
+
|
|
332
|
+
```ruby
|
|
333
|
+
Bootsnap.enable_frozen_string_literal(app_only: true)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
But it can also be used for more fine grained logic, or to implement all sort of Ruby code preprocessing:
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
# config/bootsnap.rb
|
|
340
|
+
gems_root = File.join(Bundler.bundle_path.cleanpath, "")
|
|
341
|
+
app_root = File.join(Dir.pwd, "")
|
|
342
|
+
Bootsnap::CompileCache::ISeq.compiler_selector = ->(path) do
|
|
343
|
+
# Enable `frozen_string_literal: true` for app code, but not gems.
|
|
344
|
+
|
|
345
|
+
if path.start_with?(app_root) && !path.start_with?(gems_root)
|
|
346
|
+
Bootsnap::CompileCache::ISeq::FROZEN_STRING_LITERAL
|
|
347
|
+
else
|
|
348
|
+
Bootsnap::CompileCache::ISeq::DEFAULT
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
*Important note*: This feature is only fully supported by Ruby `4.0.4` and newer.
|
|
354
|
+
On older rubies the feature work except if the `Coverage` module is enabled, in which case a warning will be emitted
|
|
355
|
+
and the default Ruby compiler will be used.
|
|
356
|
+
|
|
324
357
|
## Precompilation
|
|
325
358
|
|
|
326
359
|
In development environments the bootsnap compilation cache is generated on the fly when source files are loaded.
|
|
@@ -334,6 +367,20 @@ Example:
|
|
|
334
367
|
$ bundle exec bootsnap precompile --gemfile app/ lib/ config/
|
|
335
368
|
```
|
|
336
369
|
|
|
370
|
+
## Known issues
|
|
371
|
+
|
|
372
|
+
### QEMU environments
|
|
373
|
+
|
|
374
|
+
When building cross-platform Docker images, QEMU is often used for emulation and can be the source of a limitation that causes forked processes to hang. While Bootsnap includes automatic detection for this issue (as of [PR #501](https://github.com/rails/bootsnap/pull/501)), the detection may not always be sufficient.
|
|
375
|
+
|
|
376
|
+
If you encounter hangs during precompilation in QEMU-based environments (such as when using Docker buildx for cross-platform builds), you can work around this by disabling parallelization with the `-j 0` option:
|
|
377
|
+
|
|
378
|
+
```bash
|
|
379
|
+
$ bundle exec bootsnap precompile -j 0 --gemfile app/ lib/ config/
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
See [Issue #495](https://github.com/rails/bootsnap/issues/495) for more details about this QEMU-related issue.
|
|
383
|
+
|
|
337
384
|
## When not to use Bootsnap
|
|
338
385
|
|
|
339
386
|
*Alternative engines*: Bootsnap is pretty reliant on MRI features, and parts are disabled entirely on alternative ruby
|