bootsnap 1.7.2 → 1.11.1
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 +124 -0
- data/LICENSE.txt +1 -1
- data/README.md +2 -2
- data/exe/bootsnap +1 -1
- data/ext/bootsnap/bootsnap.c +53 -41
- data/ext/bootsnap/extconf.rb +13 -11
- data/lib/bootsnap/bundler.rb +1 -0
- data/lib/bootsnap/cli/worker_pool.rb +6 -1
- data/lib/bootsnap/cli.rb +78 -43
- data/lib/bootsnap/compile_cache/iseq.rb +42 -12
- data/lib/bootsnap/compile_cache/json.rb +88 -0
- data/lib/bootsnap/compile_cache/yaml.rb +283 -47
- data/lib/bootsnap/compile_cache.rb +20 -7
- data/lib/bootsnap/explicit_require.rb +4 -3
- data/lib/bootsnap/load_path_cache/cache.rb +61 -41
- data/lib/bootsnap/load_path_cache/change_observer.rb +4 -0
- data/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb +33 -73
- data/lib/bootsnap/load_path_cache/core_ext/loaded_features.rb +1 -0
- data/lib/bootsnap/load_path_cache/loaded_features_index.rb +34 -23
- data/lib/bootsnap/load_path_cache/path.rb +29 -5
- data/lib/bootsnap/load_path_cache/path_scanner.rb +6 -5
- data/lib/bootsnap/load_path_cache/store.rb +49 -13
- data/lib/bootsnap/load_path_cache.rb +16 -24
- data/lib/bootsnap/setup.rb +2 -1
- data/lib/bootsnap/version.rb +2 -1
- data/lib/bootsnap.rb +115 -88
- metadata +8 -78
- data/lib/bootsnap/load_path_cache/realpath_cache.rb +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1cc142349008790c310bcbc875a437996403242e579f85fb48f46eceecb383ad
|
4
|
+
data.tar.gz: fa1d21fafa8a4fa4d44ced76d597b773d3321e077dc815ccbcae3fe9dc4e661a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 81445538692ae0dc34b7309c44195fce5c864e508afe6eed4124d3d87bc1bfa07fd2ddb2c602faa2409f1537f8da63b885fd692bdc74e961febdd2a39e6e1919
|
7
|
+
data.tar.gz: 6389ce3a667c528660976665ce8184fb61d638da6cd4040e7b2d55441679574bdf691e4991294396c19a6e79bbf185ba1cdca848d5ea499a5b8e197dca143a5f
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,129 @@
|
|
1
1
|
# Unreleased
|
2
2
|
|
3
|
+
# 1.11.1
|
4
|
+
|
5
|
+
* Fix the `can't modify frozen Hash` error on load path cache mutation. See #411.
|
6
|
+
|
7
|
+
# 1.11.0
|
8
|
+
|
9
|
+
* Drop dependency on `fileutils`.
|
10
|
+
|
11
|
+
* Better respect `Kernel#require` duck typing. While it almost never comes up in practice, `Kernel#require`
|
12
|
+
follow a fairly intricate duck-typing protocol on its argument implemented as `rb_get_path(VALUE)` in MRI.
|
13
|
+
So when applicable we bind `rb_get_path` and use it for improved compatibility. See #396 and #406.
|
14
|
+
|
15
|
+
* Get rid of the `Kernel.require_relative` decorator by resolving `$LOAD_PATH` members to their real path.
|
16
|
+
This way we handle symlinks in `$LOAD_PATH` much more efficiently. See #402 for the detailed explanation.
|
17
|
+
|
18
|
+
* Drop support for Ruby 2.3 (to allow getting rid of the `Kernel.require_relative` decorator).
|
19
|
+
|
20
|
+
# 1.10.3
|
21
|
+
|
22
|
+
* Fix Regexp and Date type support in YAML compile cache. (#400)
|
23
|
+
|
24
|
+
* Improve the YAML compile cache to support `UTF-8` symbols. (#398, #399)
|
25
|
+
[The default `MessagePack` symbol serializer assumes all symbols are ASCII](https://github.com/msgpack/msgpack-ruby/pull/211),
|
26
|
+
because of this, non-ASCII compatible symbol would be restored with `ASCII_8BIT` encoding (AKA `BINARY`).
|
27
|
+
Bootsnap now properly cache them in `UTF-8`.
|
28
|
+
|
29
|
+
Note that the above only apply for actual YAML symbols (e..g `--- :foo`).
|
30
|
+
The issue is still present for string keys parsed with `YAML.load_file(..., symbolize_names: true)`, that is a bug
|
31
|
+
in `msgpack` that will hopefully be solved soon, see: https://github.com/msgpack/msgpack-ruby/pull/246
|
32
|
+
|
33
|
+
* Entirely disable the YAML compile cache if `Encoding.default_internal` is set to an encoding not supported by `msgpack`. (#398)
|
34
|
+
`Psych` coerce strings to `Encoding.default_internal`, but `MessagePack` doesn't. So in this scenario we can't provide
|
35
|
+
YAML caching at all without returning the strings in the wrong encoding.
|
36
|
+
This never came up in practice but might as well be safe.
|
37
|
+
|
38
|
+
# 1.10.2
|
39
|
+
|
40
|
+
* Reduce the `Kernel.require` extra stack frames some more. Now bootsnap should only add one extra frame per `require` call.
|
41
|
+
|
42
|
+
* Better check `freeze` option support in JSON compile cache.
|
43
|
+
Previously `JSON.load_file(..., freeze: true)` would be cached even when the msgpack version is missing support for it.
|
44
|
+
|
45
|
+
# 1.10.1
|
46
|
+
|
47
|
+
* Fix `Kernel#autoload`'s fallback path always being executed.
|
48
|
+
|
49
|
+
* Consider `unlink` failing with `ENOENT` as a success.
|
50
|
+
|
51
|
+
# 1.10.0
|
52
|
+
|
53
|
+
* Delay requiring `FileUtils`. (#285)
|
54
|
+
`FileUtils` can be installed as a gem, so it's best to wait for bundler to have setup the load path before requiring it.
|
55
|
+
|
56
|
+
* Improve support of Psych 4. (#392)
|
57
|
+
Since `1.8.0`, `YAML.load_file` was no longer cached when Psych 4 was used. This is because `load_file` loads
|
58
|
+
in safe mode by default, so the Bootsnap cache could defeat that safety.
|
59
|
+
Now when precompiling YAML files, Bootsnap first try to parse them in safe mode, and if it can't fallback to unsafe mode,
|
60
|
+
and the cache contains a flag that records whether it was generated in safe mode or not.
|
61
|
+
`YAML.unsafe_load_file` will use safe caches just fine, but `YAML.load_file` will fallback to uncached YAML parsing
|
62
|
+
if the cache was generated using unsafe parsing.
|
63
|
+
|
64
|
+
* Minimize the Kernel.require extra stack frames. (#393)
|
65
|
+
This should reduce the noise generated by bootsnap on `LoadError`.
|
66
|
+
|
67
|
+
# 1.9.4
|
68
|
+
|
69
|
+
* Ignore absolute paths in the loaded feature index. (#385)
|
70
|
+
This fixes a compatibility issue with Zeitwerk when Zeitwerk is loaded before bootsnap. It also should
|
71
|
+
reduce the memory usage and improve load performance of Zeitwerk managed files.
|
72
|
+
|
73
|
+
* Automatically invalidate the load path cache whenever the Ruby version change. (#387)
|
74
|
+
This is to avoid issues in case the same installation path is re-used for subsequent ruby patch releases.
|
75
|
+
|
76
|
+
# 1.9.3
|
77
|
+
|
78
|
+
* Only disable the compile cache for source files impacted by [Ruby 3.0.3 [Bug 18250]](https://bugs.ruby-lang.org/issues/18250).
|
79
|
+
This should keep the performance loss to a minimum.
|
80
|
+
|
81
|
+
# 1.9.2
|
82
|
+
|
83
|
+
* Disable compile cache if [Ruby 3.0.3's ISeq cache bug](https://bugs.ruby-lang.org/issues/18250) is detected.
|
84
|
+
AKA `iseq.rb:13 to_binary: wrong argument type false (expected Symbol)`
|
85
|
+
* Fix `Kernel.load` behavior: before `load 'a'` would load `a.rb` (and other tried extensions) and wouldn't load `a` unless `development_mode: true`, now only `a` would be loaded and files with extensions wouldn't be.
|
86
|
+
|
87
|
+
# 1.9.1
|
88
|
+
|
89
|
+
* Removed a forgotten debug statement in JSON precompilation.
|
90
|
+
|
91
|
+
# 1.9.0
|
92
|
+
|
93
|
+
* Added a compilation cache for `JSON.load_file`. (#370)
|
94
|
+
|
95
|
+
# 1.8.1
|
96
|
+
|
97
|
+
* Fixed support for older Psych. (#369)
|
98
|
+
|
99
|
+
# 1.8.0
|
100
|
+
|
101
|
+
* Improve support for Psych 4. (#368)
|
102
|
+
|
103
|
+
# 1.7.7
|
104
|
+
|
105
|
+
* Fix `require_relative` in evaled code on latest ruby 3.1.0-dev. (#366)
|
106
|
+
|
107
|
+
# 1.7.6
|
108
|
+
|
109
|
+
* Fix reliance on `set` to be required.
|
110
|
+
* Fix `Encoding::UndefinedConversionError` error for Rails applications when precompiling cache. (#364)
|
111
|
+
|
112
|
+
# 1.7.5
|
113
|
+
|
114
|
+
* Handle a regression of Ruby 2.7.3 causing Bootsnap to call the deprecated `untaint` method. (#360)
|
115
|
+
* Gracefully handle read-only file system as well as other errors preventing to persist the load path cache. (#358)
|
116
|
+
|
117
|
+
# 1.7.4
|
118
|
+
|
119
|
+
* Stop raising errors when encountering various file system errors. The cache is now best effort,
|
120
|
+
if somehow it can't be saved, bootsnap will gracefully fallback to the original operation (e.g. `Kernel.require`).
|
121
|
+
(#353, #177, #262)
|
122
|
+
|
123
|
+
# 1.7.3
|
124
|
+
|
125
|
+
* Disable YAML precompilation when encountering YAML tags. (#351)
|
126
|
+
|
3
127
|
# 1.7.2
|
4
128
|
|
5
129
|
* Fix compatibility with msgpack < 1. (#349)
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -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/Shopify/bootsnap/blob/
|
44
|
+
You can see how this require works [here](https://github.com/Shopify/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
|
@@ -161,7 +161,7 @@ The only directories considered "stable" are things under the Ruby install prefi
|
|
161
161
|
"volatile".
|
162
162
|
|
163
163
|
In addition to the [`Bootsnap::LoadPathCache::Cache`
|
164
|
-
source](https://github.com/Shopify/bootsnap/blob/
|
164
|
+
source](https://github.com/Shopify/bootsnap/blob/main/lib/bootsnap/load_path_cache/cache.rb),
|
165
165
|
this diagram may help clarify how entry resolution works:
|
166
166
|
|
167
167
|

|
data/exe/bootsnap
CHANGED
data/ext/bootsnap/bootsnap.c
CHANGED
@@ -75,7 +75,7 @@ struct bs_cache_key {
|
|
75
75
|
STATIC_ASSERT(sizeof(struct bs_cache_key) == KEY_SIZE);
|
76
76
|
|
77
77
|
/* Effectively a schema version. Bumping invalidates all previous caches */
|
78
|
-
static const uint32_t current_version =
|
78
|
+
static const uint32_t current_version = 4;
|
79
79
|
|
80
80
|
/* hash of e.g. "x86_64-darwin17", invalidating when ruby is recompiled on a
|
81
81
|
* new OS ABI, etc. */
|
@@ -91,8 +91,7 @@ static mode_t current_umask;
|
|
91
91
|
static VALUE rb_mBootsnap;
|
92
92
|
static VALUE rb_mBootsnap_CompileCache;
|
93
93
|
static VALUE rb_mBootsnap_CompileCache_Native;
|
94
|
-
static VALUE
|
95
|
-
static ID uncompilable;
|
94
|
+
static VALUE rb_cBootsnap_CompileCache_UNCOMPILABLE;
|
96
95
|
static ID instrumentation_method;
|
97
96
|
static VALUE sym_miss;
|
98
97
|
static VALUE sym_stale;
|
@@ -120,10 +119,8 @@ static uint32_t get_ruby_platform(void);
|
|
120
119
|
* exception.
|
121
120
|
*/
|
122
121
|
static int bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * output_data);
|
123
|
-
static VALUE prot_storage_to_output(VALUE arg);
|
124
122
|
static VALUE prot_input_to_output(VALUE arg);
|
125
123
|
static void bs_input_to_output(VALUE handler, VALUE args, VALUE input_data, VALUE * output_data, int * exception_tag);
|
126
|
-
static VALUE prot_input_to_storage(VALUE arg);
|
127
124
|
static int bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data);
|
128
125
|
struct s2o_data;
|
129
126
|
struct i2o_data;
|
@@ -138,6 +135,12 @@ bs_rb_coverage_running(VALUE self)
|
|
138
135
|
return RTEST(cov) ? Qtrue : Qfalse;
|
139
136
|
}
|
140
137
|
|
138
|
+
static VALUE
|
139
|
+
bs_rb_get_path(VALUE self, VALUE fname)
|
140
|
+
{
|
141
|
+
return rb_get_path(fname);
|
142
|
+
}
|
143
|
+
|
141
144
|
/*
|
142
145
|
* Ruby C extensions are initialized by calling Init_<extname>.
|
143
146
|
*
|
@@ -149,14 +152,17 @@ void
|
|
149
152
|
Init_bootsnap(void)
|
150
153
|
{
|
151
154
|
rb_mBootsnap = rb_define_module("Bootsnap");
|
155
|
+
|
156
|
+
rb_define_singleton_method(rb_mBootsnap, "rb_get_path", bs_rb_get_path, 1);
|
157
|
+
|
152
158
|
rb_mBootsnap_CompileCache = rb_define_module_under(rb_mBootsnap, "CompileCache");
|
153
159
|
rb_mBootsnap_CompileCache_Native = rb_define_module_under(rb_mBootsnap_CompileCache, "Native");
|
154
|
-
|
160
|
+
rb_cBootsnap_CompileCache_UNCOMPILABLE = rb_const_get(rb_mBootsnap_CompileCache, rb_intern("UNCOMPILABLE"));
|
161
|
+
rb_global_variable(&rb_cBootsnap_CompileCache_UNCOMPILABLE);
|
155
162
|
|
156
163
|
current_ruby_revision = get_ruby_revision();
|
157
164
|
current_ruby_platform = get_ruby_platform();
|
158
165
|
|
159
|
-
uncompilable = rb_intern("__bootsnap_uncompilable__");
|
160
166
|
instrumentation_method = rb_intern("_instrument");
|
161
167
|
|
162
168
|
sym_miss = ID2SYM(rb_intern("miss"));
|
@@ -426,6 +432,7 @@ open_current_file(char * path, struct bs_cache_key * key, const char ** errno_pr
|
|
426
432
|
#define ERROR_WITH_ERRNO -1
|
427
433
|
#define CACHE_MISS -2
|
428
434
|
#define CACHE_STALE -3
|
435
|
+
#define CACHE_UNCOMPILABLE -4
|
429
436
|
|
430
437
|
/*
|
431
438
|
* Read the cache key from the given fd, which must have position 0 (e.g.
|
@@ -464,8 +471,7 @@ open_cache_file(const char * path, struct bs_cache_key * key, const char ** errn
|
|
464
471
|
fd = open(path, O_RDONLY);
|
465
472
|
if (fd < 0) {
|
466
473
|
*errno_provenance = "bs_fetch:open_cache_file:open";
|
467
|
-
|
468
|
-
return ERROR_WITH_ERRNO;
|
474
|
+
return CACHE_MISS;
|
469
475
|
}
|
470
476
|
#ifdef _WIN32
|
471
477
|
setmode(fd, O_BINARY);
|
@@ -508,14 +514,14 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
|
|
508
514
|
if (data_size > 100000000000) {
|
509
515
|
*errno_provenance = "bs_fetch:fetch_cached_data:datasize";
|
510
516
|
errno = EINVAL; /* because wtf? */
|
511
|
-
ret =
|
517
|
+
ret = ERROR_WITH_ERRNO;
|
512
518
|
goto done;
|
513
519
|
}
|
514
520
|
data = ALLOC_N(char, data_size);
|
515
521
|
nread = read(fd, data, data_size);
|
516
522
|
if (nread < 0) {
|
517
523
|
*errno_provenance = "bs_fetch:fetch_cached_data:read";
|
518
|
-
ret =
|
524
|
+
ret = ERROR_WITH_ERRNO;
|
519
525
|
goto done;
|
520
526
|
}
|
521
527
|
if (nread != data_size) {
|
@@ -526,6 +532,10 @@ fetch_cached_data(int fd, ssize_t data_size, VALUE handler, VALUE args, VALUE *
|
|
526
532
|
storage_data = rb_str_new(data, data_size);
|
527
533
|
|
528
534
|
*exception_tag = bs_storage_to_output(handler, args, storage_data, output_data);
|
535
|
+
if (*output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
|
536
|
+
ret = CACHE_UNCOMPILABLE;
|
537
|
+
goto done;
|
538
|
+
}
|
529
539
|
ret = 0;
|
530
540
|
done:
|
531
541
|
if (data != NULL) xfree(data);
|
@@ -738,7 +748,15 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
|
|
738
748
|
&output_data, &exception_tag, &errno_provenance
|
739
749
|
);
|
740
750
|
if (exception_tag != 0) goto raise;
|
741
|
-
else if (res ==
|
751
|
+
else if (res == CACHE_UNCOMPILABLE) {
|
752
|
+
/* If fetch_cached_data returned `Uncompilable` we fallback to `input_to_output`
|
753
|
+
This happens if we have say, an unsafe YAML cache, but try to load it in safe mode */
|
754
|
+
if (bs_read_contents(current_fd, current_key.size, &contents, &errno_provenance) < 0) goto fail_errno;
|
755
|
+
input_data = rb_str_new(contents, current_key.size);
|
756
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
757
|
+
if (exception_tag != 0) goto raise;
|
758
|
+
goto succeed;
|
759
|
+
} else if (res == CACHE_MISS || res == CACHE_STALE) valid_cache = 0;
|
742
760
|
else if (res == ERROR_WITH_ERRNO) goto fail_errno;
|
743
761
|
else if (!NIL_P(output_data)) goto succeed; /* fast-path, goal */
|
744
762
|
}
|
@@ -755,7 +773,7 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
|
|
755
773
|
if (exception_tag != 0) goto raise;
|
756
774
|
/* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
|
757
775
|
* to cache anything; just return input_to_output(input_data) */
|
758
|
-
if (storage_data ==
|
776
|
+
if (storage_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
|
759
777
|
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
760
778
|
if (exception_tag != 0) goto raise;
|
761
779
|
goto succeed;
|
@@ -763,20 +781,30 @@ bs_fetch(char * path, VALUE path_v, char * cache_path, VALUE handler, VALUE args
|
|
763
781
|
/* If storage_data isn't a string, we can't cache it */
|
764
782
|
if (!RB_TYPE_P(storage_data, T_STRING)) goto invalid_type_storage_data;
|
765
783
|
|
766
|
-
/*
|
767
|
-
|
768
|
-
|
784
|
+
/* Attempt to write the cache key and storage_data to the cache directory.
|
785
|
+
* We do however ignore any failures to persist the cache, as it's better
|
786
|
+
* to move along, than to interrupt the process.
|
787
|
+
*/
|
788
|
+
atomic_write_cache_file(cache_path, ¤t_key, storage_data, &errno_provenance);
|
769
789
|
|
770
790
|
/* Having written the cache, now convert storage_data to output_data */
|
771
791
|
exception_tag = bs_storage_to_output(handler, args, storage_data, &output_data);
|
772
792
|
if (exception_tag != 0) goto raise;
|
773
793
|
|
774
|
-
|
775
|
-
|
776
|
-
|
794
|
+
if (output_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
|
795
|
+
/* If storage_to_output returned `Uncompilable` we fallback to `input_to_output` */
|
796
|
+
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
797
|
+
if (exception_tag != 0) goto raise;
|
798
|
+
} else if (NIL_P(output_data)) {
|
799
|
+
/* If output_data is nil, delete the cache entry and generate the output
|
800
|
+
* using input_to_output */
|
777
801
|
if (unlink(cache_path) < 0) {
|
778
|
-
|
779
|
-
|
802
|
+
/* If the cache was already deleted, it might be that another process did it before us.
|
803
|
+
* No point raising an error */
|
804
|
+
if (errno != ENOENT) {
|
805
|
+
errno_provenance = "bs_fetch:unlink";
|
806
|
+
goto fail_errno;
|
807
|
+
}
|
780
808
|
}
|
781
809
|
bs_input_to_output(handler, args, input_data, &output_data, &exception_tag);
|
782
810
|
if (exception_tag != 0) goto raise;
|
@@ -855,7 +883,7 @@ bs_precompile(char * path, VALUE path_v, char * cache_path, VALUE handler)
|
|
855
883
|
|
856
884
|
/* If input_to_storage raised Bootsnap::CompileCache::Uncompilable, don't try
|
857
885
|
* to cache anything; just return false */
|
858
|
-
if (storage_data ==
|
886
|
+
if (storage_data == rb_cBootsnap_CompileCache_UNCOMPILABLE) {
|
859
887
|
goto fail;
|
860
888
|
}
|
861
889
|
/* If storage_data isn't a string, we can't cache it */
|
@@ -918,7 +946,7 @@ struct i2s_data {
|
|
918
946
|
};
|
919
947
|
|
920
948
|
static VALUE
|
921
|
-
|
949
|
+
try_storage_to_output(VALUE arg)
|
922
950
|
{
|
923
951
|
struct s2o_data * data = (struct s2o_data *)arg;
|
924
952
|
return rb_funcall(data->handler, rb_intern("storage_to_output"), 2, data->storage_data, data->args);
|
@@ -933,7 +961,7 @@ bs_storage_to_output(VALUE handler, VALUE args, VALUE storage_data, VALUE * outp
|
|
933
961
|
.args = args,
|
934
962
|
.storage_data = storage_data,
|
935
963
|
};
|
936
|
-
*output_data = rb_protect(
|
964
|
+
*output_data = rb_protect(try_storage_to_output, (VALUE)&s2o_data, &state);
|
937
965
|
return state;
|
938
966
|
}
|
939
967
|
|
@@ -962,22 +990,6 @@ try_input_to_storage(VALUE arg)
|
|
962
990
|
return rb_funcall(data->handler, rb_intern("input_to_storage"), 2, data->input_data, data->pathval);
|
963
991
|
}
|
964
992
|
|
965
|
-
static VALUE
|
966
|
-
rescue_input_to_storage(VALUE arg, VALUE e)
|
967
|
-
{
|
968
|
-
return uncompilable;
|
969
|
-
}
|
970
|
-
|
971
|
-
static VALUE
|
972
|
-
prot_input_to_storage(VALUE arg)
|
973
|
-
{
|
974
|
-
struct i2s_data * data = (struct i2s_data *)arg;
|
975
|
-
return rb_rescue2(
|
976
|
-
try_input_to_storage, (VALUE)data,
|
977
|
-
rescue_input_to_storage, Qnil,
|
978
|
-
rb_eBootsnap_CompileCache_Uncompilable, 0);
|
979
|
-
}
|
980
|
-
|
981
993
|
static int
|
982
994
|
bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval, VALUE * storage_data)
|
983
995
|
{
|
@@ -987,6 +999,6 @@ bs_input_to_storage(VALUE handler, VALUE args, VALUE input_data, VALUE pathval,
|
|
987
999
|
.input_data = input_data,
|
988
1000
|
.pathval = pathval,
|
989
1001
|
};
|
990
|
-
*storage_data = rb_protect(
|
1002
|
+
*storage_data = rb_protect(try_input_to_storage, (VALUE)&i2s_data, &state);
|
991
1003
|
return state;
|
992
1004
|
}
|
data/ext/bootsnap/extconf.rb
CHANGED
@@ -1,21 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require("mkmf")
|
3
4
|
|
4
|
-
if RUBY_ENGINE ==
|
5
|
-
$CFLAGS <<
|
6
|
-
$CFLAGS <<
|
5
|
+
if RUBY_ENGINE == "ruby"
|
6
|
+
$CFLAGS << " -O3 "
|
7
|
+
$CFLAGS << " -std=c99"
|
7
8
|
|
8
9
|
# ruby.h has some -Wpedantic fails in some cases
|
9
10
|
# (e.g. https://github.com/Shopify/bootsnap/issues/15)
|
10
|
-
unless [
|
11
|
-
$CFLAGS <<
|
12
|
-
$CFLAGS <<
|
13
|
-
$CFLAGS <<
|
14
|
-
$CFLAGS <<
|
11
|
+
unless ["0", "", nil].include?(ENV["BOOTSNAP_PEDANTIC"])
|
12
|
+
$CFLAGS << " -Wall"
|
13
|
+
$CFLAGS << " -Werror"
|
14
|
+
$CFLAGS << " -Wextra"
|
15
|
+
$CFLAGS << " -Wpedantic"
|
15
16
|
|
16
|
-
$CFLAGS <<
|
17
|
-
$CFLAGS <<
|
18
|
-
$CFLAGS <<
|
17
|
+
$CFLAGS << " -Wno-unused-parameter" # VALUE self has to be there but we don't care what it is.
|
18
|
+
$CFLAGS << " -Wno-keyword-macro" # hiding return
|
19
|
+
$CFLAGS << " -Wno-gcc-compat" # ruby.h 2.6.0 on macos 10.14, dunno
|
20
|
+
$CFLAGS << " -Wno-compound-token-split-by-macro"
|
19
21
|
end
|
20
22
|
|
21
23
|
create_makefile("bootsnap/bootsnap")
|
data/lib/bootsnap/bundler.rb
CHANGED
@@ -37,7 +37,11 @@ module Bootsnap
|
|
37
37
|
|
38
38
|
def initialize(jobs)
|
39
39
|
@jobs = jobs
|
40
|
-
@pipe_out, @to_io = IO.pipe
|
40
|
+
@pipe_out, @to_io = IO.pipe(binmode: true)
|
41
|
+
# Set the writer encoding to binary since IO.pipe only sets it for the reader.
|
42
|
+
# https://github.com/rails/rails/issues/16514#issuecomment-52313290
|
43
|
+
@to_io.set_encoding(Encoding::BINARY)
|
44
|
+
|
41
45
|
@pid = nil
|
42
46
|
end
|
43
47
|
|
@@ -59,6 +63,7 @@ module Bootsnap
|
|
59
63
|
loop do
|
60
64
|
job, *args = Marshal.load(@pipe_out)
|
61
65
|
return if job == :exit
|
66
|
+
|
62
67
|
@jobs.fetch(job).call(*args)
|
63
68
|
end
|
64
69
|
rescue IOError
|