bootsnap 1.24.6 → 1.25.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c89c653bbd5db473e06179c6606268271c8c540a588cca938662f168d64f2d39
4
- data.tar.gz: 449c08c79a258dea90e56646c9d62a06e1d696c065ce96c38a7f50ef2fb83f7b
3
+ metadata.gz: e46c28f258eb76b8c90fa22a7fa2c83887695b7c12d3aff8dbbefda5051dca87
4
+ data.tar.gz: 33aaa301627c53d2f4db1b8e98db0b2f52dc8d20aa533c8de8dc9448bf0c0b8e
5
5
  SHA512:
6
- metadata.gz: 2ea80faffec0206b9bb7b3d19c1419b2e7eefc2dc5f4eb03352862b83afa07ed293d0b15f04fc069d89dac1cd4d4636770626e90e6129ffad77f0cfcb8c3f676
7
- data.tar.gz: 82dcb1a4c934a9de29a8aa935ffe2d1a7c6e23ebf36ea743c3d29a4d9a1d8bd42696cdefd37dacdd21a4102f88f0b605d1cc6faef9c15ccdc6d99eef15f4483e
6
+ metadata.gz: 77f885b700f2d249da6afd6ed4a70e4b37bf27303ddabefdfbed915fea6e61587d3e0fa56ee5159a95416072d58d4994498ee29bf69a3ab70c3b9e98471c3a0a
7
+ data.tar.gz: 7044ce0c6a30d7312d947da11b20755dbd496ee7b5f460293bf9188c83493ac951e6e683f75009b17860c45a7ff31e3264abffd69dcaf5a0e8c6b759b7631332
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # Unreleased
2
2
 
3
+ # 1.25.0
4
+
5
+ * Improve YAML parsing cache to more efficiently handle `Time`, `Date` and `DateTime`.
6
+
7
+ * Don't invalidate the compile cache when YJIT is toggled. YJIT is a runtime JIT and doesn't change the
8
+ serialized instruction sequences that are cached, but enabling it (via `--yjit`, `RUBYOPT`, or
9
+ `RubyVM::YJIT.enable`) adds a ` +YJIT` marker to `RUBY_DESCRIPTION` (` +YJIT <token>` on `YJIT_SUPPORT`
10
+ builds), which is part of the cache key. This previously discarded the entire compile cache whenever YJIT
11
+ was enabled at runtime but not at precompile time (or vice versa). The marker is now stripped before hashing.
12
+
13
+ * Fix `CompileCache::Native.fetch` and `.precompile` reading a non-`String` path argument (e.g. a `Pathname`)
14
+ with `RSTRING_PTR`. Regression from 1.24.0.
15
+
3
16
  # 1.24.6
4
17
 
5
18
  * Fix detection of Ruby bug #22023 on some patch versions of Ruby 3.4, and properly apply the workaround.
@@ -79,7 +79,7 @@ struct bs_cache_key {
79
79
  STATIC_ASSERT(sizeof(struct bs_cache_key) == KEY_SIZE);
80
80
 
81
81
  /* Effectively a schema version. Bumping invalidates all previous caches */
82
- static const uint32_t bootsnap_cache_version = 7;
82
+ static const uint32_t bootsnap_cache_version = 8;
83
83
 
84
84
  /* Invalidates cache when switching ruby version, platform or ABI */
85
85
  static uint64_t base_ruby_version_digest = 0;
@@ -384,7 +384,7 @@ bs_compile_option_crc32_set(VALUE self, VALUE crc32_v)
384
384
  static uint64_t
385
385
  get_ruby_version_digest(void)
386
386
  {
387
- uint64_t hash = fnv1a_64_str(rb_const_get(rb_cObject, rb_intern("RUBY_DESCRIPTION")));
387
+ uint64_t hash = fnv1a_64_str(rb_const_get(rb_mBootsnap, rb_intern("RUBY_CACHE_KEY")));
388
388
  hash = fnv1a_64_iter(hash, (unsigned char *)&bootsnap_cache_version, sizeof(bootsnap_cache_version));
389
389
  return hash;
390
390
  }
@@ -395,12 +395,14 @@ get_ruby_version_digest(void)
395
395
  * be stored.
396
396
  *
397
397
  * The path will look something like: <cachedir>/12/34567890abcdef
398
+ *
399
+ * `path_v` must already have been through FilePathValue(): the callers read it
400
+ * with RSTRING_PTR() too, so the conversion has to happen in the frame that
401
+ * owns the variable.
398
402
  */
399
403
  static void
400
404
  bs_cache_path(VALUE cachedir_v, VALUE namespace_v, VALUE path_v, char (* cache_path)[MAX_CACHEPATH_SIZE])
401
405
  {
402
- FilePathValue(path_v);
403
-
404
406
  Check_Type(cachedir_v, T_STRING);
405
407
  Check_Type(path_v, T_STRING);
406
408
 
@@ -492,6 +494,8 @@ static void bs_cache_key_digest(struct bs_cache_key *key,
492
494
  static VALUE
493
495
  bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE namespace_v, VALUE path_v, VALUE handler, VALUE args)
494
496
  {
497
+ FilePathValue(path_v);
498
+
495
499
  char cache_path[MAX_CACHEPATH_SIZE];
496
500
 
497
501
  /* generate cache path to cache_path */
@@ -508,6 +512,8 @@ bs_rb_fetch(VALUE self, VALUE cachedir_v, VALUE namespace_v, VALUE path_v, VALUE
508
512
  static VALUE
509
513
  bs_rb_precompile(VALUE self, VALUE cachedir_v, VALUE namespace_v, VALUE path_v, VALUE handler)
510
514
  {
515
+ FilePathValue(path_v);
516
+
511
517
  char cache_path[MAX_CACHEPATH_SIZE];
512
518
  /* generate cache path to cache_path */
513
519
  bs_cache_path(cachedir_v, namespace_v, path_v, &cache_path);
@@ -47,14 +47,6 @@ module Bootsnap
47
47
  SUPPORTED_INTERNAL_ENCODINGS.include?(Encoding.default_internal)
48
48
  end
49
49
 
50
- module EncodingAwareSymbols
51
- extend self
52
-
53
- def unpack(payload)
54
- (+payload).force_encoding(Encoding::UTF_8).to_sym
55
- end
56
- end
57
-
58
50
  def init!
59
51
  require "yaml"
60
52
  require "msgpack"
@@ -86,28 +78,78 @@ module Bootsnap
86
78
  0x00,
87
79
  Symbol,
88
80
  packer: :to_msgpack_ext,
89
- unpacker: EncodingAwareSymbols.method(:unpack).to_proc,
81
+ unpacker: :from_msgpack_ext,
82
+ optimized_symbol_parsing: true,
90
83
  )
91
84
 
92
- if defined? MessagePack::Timestamp
93
- factory.register_type(
94
- MessagePack::Timestamp::TYPE, # or just -1
95
- Time,
96
- packer: MessagePack::Time::Packer,
97
- unpacker: MessagePack::Time::Unpacker,
98
- )
85
+ factory.register_type(
86
+ MessagePack::Timestamp::TYPE, # or just -1
87
+ Time,
88
+ packer: MessagePack::Time::Packer,
89
+ unpacker: MessagePack::Time::Unpacker,
90
+ )
99
91
 
100
- marshal_fallback = {
101
- packer: ->(value) { Marshal.dump(value) },
102
- unpacker: ->(payload) { Marshal.load(payload) },
103
- }
104
- {
105
- Date => 0x01,
106
- Regexp => 0x02,
107
- }.each do |type, code|
108
- factory.register_type(code, type, marshal_fallback)
109
- end
110
- end
92
+ factory.register_type(
93
+ 0x01,
94
+ Date,
95
+ packer: lambda { |date, packer|
96
+ packer.write(date.year)
97
+ packer.write(date.month)
98
+ packer.write(date.day)
99
+ },
100
+ unpacker: lambda { |unpacker|
101
+ ::Date.new(unpacker.read, unpacker.read, unpacker.read)
102
+ },
103
+ recursive: true,
104
+ )
105
+
106
+ factory.register_type(
107
+ 0x02,
108
+ Regexp,
109
+ packer: ->(value) { Marshal.dump(value) },
110
+ unpacker: ->(payload) { Marshal.load(payload) },
111
+ )
112
+
113
+ factory.register_type(
114
+ 0x03,
115
+ DateTime,
116
+ packer: lambda { |dt, packer|
117
+ packer.write(dt.year)
118
+ packer.write(dt.month)
119
+ packer.write(dt.day)
120
+ packer.write(dt.hour)
121
+ packer.write(dt.minute)
122
+
123
+ sec = dt.sec + dt.sec_fraction
124
+ packer.write(sec.numerator)
125
+ packer.write(sec.denominator)
126
+
127
+ offset = dt.offset
128
+ packer.write(offset.numerator)
129
+ packer.write(offset.denominator)
130
+ },
131
+ unpacker: lambda { |unpacker|
132
+ ::DateTime.new(
133
+ unpacker.read, # year
134
+ unpacker.read, # month
135
+ unpacker.read, # day
136
+ unpacker.read, # hour
137
+ unpacker.read, # minute
138
+ Rational(unpacker.read, unpacker.read), # sec fraction
139
+ Rational(unpacker.read, unpacker.read), # offset fraction
140
+ )
141
+ },
142
+ recursive: true,
143
+ )
144
+
145
+ require "msgpack/bigint"
146
+ factory.register_type(
147
+ 0x04,
148
+ Integer,
149
+ packer: MessagePack::Bigint.method(:to_msgpack_ext),
150
+ unpacker: MessagePack::Bigint.method(:from_msgpack_ext),
151
+ oversized_integer_extension: true,
152
+ )
111
153
 
112
154
  self.msgpack_factory = factory
113
155
 
@@ -116,7 +158,7 @@ module Bootsnap
116
158
  if params.include?([:key, :symbolize_names])
117
159
  supported_options << :symbolize_names
118
160
  end
119
- if params.include?([:key, :freeze]) && factory.load(factory.dump("yaml"), freeze: true).frozen?
161
+ if params.include?([:key, :freeze])
120
162
  supported_options << :freeze
121
163
  end
122
164
  supported_options.freeze
@@ -135,6 +177,14 @@ module Bootsnap
135
177
 
136
178
  NoTagsVisitor.new(scanner, loader).visit(ast)
137
179
  end
180
+
181
+ def msgpack_unpacker_options(kwargs)
182
+ return kwargs unless kwargs&.key?(:symbolize_names)
183
+
184
+ kwargs = kwargs.dup
185
+ kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
186
+ kwargs
187
+ end
138
188
  end
139
189
 
140
190
  module Psych4
@@ -164,11 +214,9 @@ module Bootsnap
164
214
  end
165
215
 
166
216
  def storage_to_output(data, kwargs)
167
- if kwargs&.key?(:symbolize_names)
168
- kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
169
- end
170
-
171
- unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
217
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(
218
+ CompileCache::YAML.msgpack_unpacker_options(kwargs),
219
+ )
172
220
  unpacker.feed(data)
173
221
  _safe_loaded = unpacker.unpack
174
222
  result = unpacker.unpack
@@ -202,11 +250,9 @@ module Bootsnap
202
250
  end
203
251
 
204
252
  def storage_to_output(data, kwargs)
205
- if kwargs&.key?(:symbolize_names)
206
- kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
207
- end
208
-
209
- unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
253
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(
254
+ CompileCache::YAML.msgpack_unpacker_options(kwargs),
255
+ )
210
256
  unpacker.feed(data)
211
257
  safe_loaded = unpacker.unpack
212
258
  if safe_loaded
@@ -282,10 +328,9 @@ module Bootsnap
282
328
  end
283
329
 
284
330
  def storage_to_output(data, kwargs)
285
- if kwargs&.key?(:symbolize_names)
286
- kwargs[:symbolize_keys] = kwargs.delete(:symbolize_names)
287
- end
288
- unpacker = CompileCache::YAML.msgpack_factory.unpacker(kwargs)
331
+ unpacker = CompileCache::YAML.msgpack_factory.unpacker(
332
+ CompileCache::YAML.msgpack_unpacker_options(kwargs),
333
+ )
289
334
  unpacker.feed(data)
290
335
  _safe_loaded = unpacker.unpack
291
336
  unpacker.unpack
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bootsnap
4
- VERSION = "1.24.6"
4
+ VERSION = "1.25.0"
5
5
  end
data/lib/bootsnap.rb CHANGED
@@ -6,6 +6,9 @@ require_relative "bootsnap/bundler"
6
6
  module Bootsnap
7
7
  InvalidConfiguration = Class.new(StandardError)
8
8
 
9
+ # JITs shouldn't change the cache key as they have no impact on iseq generation
10
+ RUBY_CACHE_KEY = RUBY_DESCRIPTION.gsub(/\s\+\wJIT/, "").freeze
11
+
9
12
  class << self
10
13
  attr_reader :cache_dir, :logger
11
14
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.6
4
+ version: 1.25.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Burke Libbey
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: '1.2'
18
+ version: '1.5'
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: '1.2'
25
+ version: '1.5'
26
26
  description: Boot large ruby/rails apps faster
27
27
  email:
28
28
  - burke.libbey@shopify.com
@@ -81,7 +81,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  requirements: []
84
- rubygems_version: 3.6.9
84
+ rubygems_version: 4.0.16
85
85
  specification_version: 4
86
86
  summary: Boot large ruby/rails apps faster
87
87
  test_files: []