bootsnap 1.1.0.pre-java → 1.1.1-java

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
  SHA1:
3
- metadata.gz: 40ed6de82125b74db129cadfca1d981483cda326
4
- data.tar.gz: 3a71063dc3ba38f604718aca731933029a984465
3
+ metadata.gz: 622dbeab469dbcd40ec9e8c93d73e6ff01aa2d6c
4
+ data.tar.gz: 1f50bce28e945662a13ad63592352d64d77273be
5
5
  SHA512:
6
- metadata.gz: e8834a384a8c48454521b0186aa023e5ece9227383b24624b88620c4732fb8466fddf7bdd8ecd19494cf52d6a64fd9d3c0a09af93274ede44f07928c5338bf2f
7
- data.tar.gz: 631c6b34200beba552a1fa6b49185c514182014302ce0a8c8cd0985c338d812108ebfa7dab8274d4d3a10896e909ab4eb8958c9676bda4dffb4f2cdc5abf03e9
6
+ metadata.gz: 117a042e1ccbaef389ff7e9ed121ae3c0125544400dc3678cabe7dabb1568e4650d89b17738cc2a8dfa909ed20ee5186a59fec3df83d99753a6f89343018e910
7
+ data.tar.gz: b4aac5d35a0c8eba3a238d82ec076707917373d7dfa0c0b232cef22e0d499e72a584bb937886e260fe8817ce9e003f74bf6d91b641b2cc2bdd08febf6192b235
@@ -1,7 +1,13 @@
1
+ # 1.1.1
2
+
3
+ * Fix crash in `Native.compile_option_crc32=` on 32-bit platforms.
4
+
1
5
  # 1.1.0
2
6
 
3
7
  * Add `bootsnap/setup`
4
8
  * Support jruby (without compile caching features)
9
+ * Better deoptimization when Coverage is enabled
10
+ * Consider `Bundler.bundle_path` to be stable
5
11
 
6
12
  # 1.0.0
7
13
 
data/README.md CHANGED
@@ -1,11 +1,11 @@
1
- # Bootsnap ![CI status](https://travis-ci.org/Shopify/bootsnap.svg?branch=master)
1
+ # Bootsnap [![Build Status](https://travis-ci.org/Shopify/bootsnap.svg?branch=master)](https://travis-ci.org/Shopify/bootsnap)
2
2
 
3
3
  **Beta-quality. See [the last section of this README](#trustworthiness).**
4
4
 
5
- Bootsnap is a library that plugs into a number of Ruby and (optionally) `ActiveSupport` and `YAML`
6
- methods to optimize and cache expensive computations. See [the How Does This Work section](#how-does-this-work) for more information.
5
+ Bootsnap is a library that plugs into Ruby, with optional support for `ActiveSupport` and `YAML`,
6
+ to optimize and cache expensive computations. See [How Does This Work](#how-does-this-work).
7
7
 
8
- #### Quick Performance Overview
8
+ #### Performance
9
9
  - [Discourse](https://github.com/discourse/discourse) reports a boot time reduction of approximately 50%, from roughly 6 to 3 seconds on one machine;
10
10
  - One of our smaller internal apps also sees a reduction of 50%, from 3.6 to 1.8 seconds;
11
11
  - The core Shopify platform -- a rather large monolithic application -- boots about 75% faster, dropping from around 25s to 6.5s.
@@ -32,14 +32,15 @@ this is loaded, the sooner it can start optimizing things)
32
32
 
33
33
  ```ruby
34
34
  require 'bootsnap'
35
+ env = ENV['RAILS_ENV'] || "development"
35
36
  Bootsnap.setup(
36
- cache_dir: 'tmp/cache', # Path to your cache
37
- development_mode: ENV['RAILS_ENV'] == 'development', # This should be set to whatever evaluates your current working environment, e.g. RACK_ENV, RAILS_ENV, etc
38
- load_path_cache: true, # Should we optimize the LOAD_PATH with a cache?
39
- autoload_paths_cache: true, # Should we optimize ActiveSupport autoloads with cache?
40
- disable_trace: false, # Sets `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`
41
- compile_cache_iseq: true, # Should compile Ruby code into ISeq cache?
42
- compile_cache_yaml: true # Should compile YAML into a cache?
37
+ cache_dir: 'tmp/cache', # Path to your cache
38
+ development_mode: env == 'development', # Current working environment, e.g. RACK_ENV, RAILS_ENV, etc
39
+ load_path_cache: true, # Optimize the LOAD_PATH with a cache
40
+ autoload_paths_cache: true, # Optimize ActiveSupport autoloads with cache
41
+ disable_trace: true, # (Alpha) Set `RubyVM::InstructionSequence.compile_option = { trace_instruction: false }`
42
+ compile_cache_iseq: true, # Compile Ruby code into ISeq cache, breaks coverage reporting.
43
+ compile_cache_yaml: true # Compile YAML into a cache
43
44
  )
44
45
  ```
45
46
 
@@ -49,8 +50,7 @@ will help optimize boot time further if you have an extremely large `$LOAD_PATH`
49
50
 
50
51
  ## How does this work?
51
52
 
52
- Bootsnap is a library that plugs into a number of Ruby and (optionally) `ActiveSupport` and `YAML`
53
- methods. These methods are modified to cache results of expensive computations, and can be grouped
53
+ Bootsnap optimizes methods to cache results of expensive computations, and can be grouped
54
54
  into two broad categories:
55
55
 
56
56
  * [Path Pre-Scanning](#path-pre-scanning)
@@ -110,7 +110,8 @@ entries do not expire -- once their contents has been scanned, it is assumed to
110
110
 
111
111
  The only directories considered "stable" are things under the Ruby install prefix
112
112
  (`RbConfig::CONFIG['prefix']`, e.g. `/usr/local/ruby` or `~/.rubies/x.y.z`), and things under the
113
- `Gem.path` (e.g. `~/.gem/ruby/x.y.z`). Everything else is considered "volatile".
113
+ `Gem.path` (e.g. `~/.gem/ruby/x.y.z`) or `Bundler.bundle_path`. Everything else is considered
114
+ "volatile".
114
115
 
115
116
  In addition to the [`Bootsnap::LoadPathCache::Cache`
116
117
  source](https://github.com/Shopify/bootsnap/blob/master/lib/bootsnap/load_path_cache/cache.rb),
@@ -34,7 +34,6 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency 'rake-compiler', '~> 0'
35
35
  spec.add_development_dependency "minitest", "~> 5.0"
36
36
  spec.add_development_dependency "mocha", "~> 1.2"
37
- spec.add_development_dependency "ffi-xattr", "~> 0.1.2"
38
37
 
39
38
  spec.add_runtime_dependency "msgpack", "~> 1.0"
40
39
  end
@@ -18,7 +18,9 @@
18
18
  #include <errno.h>
19
19
  #include <fcntl.h>
20
20
  #include <sys/stat.h>
21
+ #ifndef _WIN32
21
22
  #include <sys/utsname.h>
23
+ #endif
22
24
 
23
25
  /* 1000 is an arbitrary limit; FNV64 plus some slashes brings the cap down to
24
26
  * 981 for the cache dir */
@@ -109,6 +111,15 @@ struct s2o_data;
109
111
  struct i2o_data;
110
112
  struct i2s_data;
111
113
 
114
+ /* https://bugs.ruby-lang.org/issues/13667 */
115
+ extern VALUE rb_get_coverages(void);
116
+ static VALUE
117
+ bs_rb_coverage_running(VALUE self)
118
+ {
119
+ VALUE cov = rb_get_coverages();
120
+ return RTEST(cov) ? Qtrue : Qfalse;
121
+ }
122
+
112
123
  /*
113
124
  * Ruby C extensions are initialized by calling Init_<extname>.
114
125
  *
@@ -129,6 +140,7 @@ Init_bootsnap(void)
129
140
 
130
141
  uncompilable = rb_intern("__bootsnap_uncompilable__");
131
142
 
143
+ rb_define_module_function(rb_mBootsnap_CompileCache_Native, "coverage_running?", bs_rb_coverage_running, 0);
132
144
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "fetch", bs_rb_fetch, 3);
133
145
  rb_define_module_function(rb_mBootsnap_CompileCache_Native, "compile_option_crc32=", bs_compile_option_crc32_set, 1);
134
146
  }
@@ -136,12 +148,17 @@ Init_bootsnap(void)
136
148
  /*
137
149
  * Bootsnap's ruby code registers a hook that notifies us via this function
138
150
  * when compile_option changes. These changes invalidate all existing caches.
151
+ *
152
+ * Note that on 32-bit platforms, a CRC32 can't be represented in a Fixnum, but
153
+ * can be represented by a uint.
139
154
  */
140
155
  static VALUE
141
156
  bs_compile_option_crc32_set(VALUE self, VALUE crc32_v)
142
157
  {
143
- Check_Type(crc32_v, T_FIXNUM);
144
- current_compile_option_crc32 = FIX2UINT(crc32_v);
158
+ if (!RB_TYPE_P(crc32_v, T_BIGNUM) && !RB_TYPE_P(crc32_v, T_FIXNUM)) {
159
+ Check_Type(crc32_v, T_FIXNUM);
160
+ }
161
+ current_compile_option_crc32 = NUM2UINT(crc32_v);
145
162
  return Qnil;
146
163
  }
147
164
 
@@ -176,6 +193,9 @@ fnv1a_64(const char *str)
176
193
  static uint32_t
177
194
  get_os_version(void)
178
195
  {
196
+ #ifdef _WIN32
197
+ return (uint32_t)GetVersion();
198
+ #else
179
199
  uint64_t hash;
180
200
  struct utsname utsname;
181
201
 
@@ -185,6 +205,7 @@ get_os_version(void)
185
205
  hash = fnv1a_64(utsname.version);
186
206
 
187
207
  return (uint32_t)(hash >> 32);
208
+ #endif
188
209
  }
189
210
 
190
211
  /*
@@ -265,6 +286,9 @@ open_current_file(char * path, struct bs_cache_key * key)
265
286
 
266
287
  fd = open(path, O_RDONLY);
267
288
  if (fd < 0) return fd;
289
+ #ifdef _WIN32
290
+ setmode(fd, O_BINARY);
291
+ #endif
268
292
 
269
293
  if (fstat(fd, &statbuf) < 0) {
270
294
  close(fd);
@@ -321,6 +345,9 @@ open_cache_file(const char * path, struct bs_cache_key * key)
321
345
  if (errno == ENOENT) return CACHE_MISSING_OR_INVALID;
322
346
  return ERROR_WITH_ERRNO;
323
347
  }
348
+ #ifdef _WIN32
349
+ setmode(fd, O_BINARY);
350
+ #endif
324
351
 
325
352
  res = bs_read_key(fd, key);
326
353
  if (res < 0) {
@@ -393,7 +420,11 @@ mkpath(char * file_path, mode_t mode)
393
420
  char * p;
394
421
  for (p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) {
395
422
  *p = '\0';
423
+ #ifdef _WIN32
424
+ if (mkdir(file_path) == -1) {
425
+ #else
396
426
  if (mkdir(file_path, mode) == -1) {
427
+ #endif
397
428
  if (errno != EEXIST) {
398
429
  *p = '/';
399
430
  return -1;
@@ -428,6 +459,9 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data)
428
459
  fd = open(tmp_path, O_WRONLY | O_CREAT, 0644);
429
460
  if (fd < 0) return -1;
430
461
  }
462
+ #ifdef _WIN32
463
+ setmode(fd, O_BINARY);
464
+ #endif
431
465
 
432
466
  key->data_size = RSTRING_LEN(data);
433
467
  nwrite = write(fd, key, KEY_SIZE);
@@ -12,12 +12,6 @@ module Bootsnap
12
12
  RubyVM::InstructionSequence.compile_file(path).to_binary
13
13
  rescue SyntaxError
14
14
  raise Uncompilable, 'syntax error'
15
- rescue RuntimeError => e
16
- if e.message == 'should not compile with coverage'
17
- raise Uncompilable, 'coverage is enabled'
18
- else
19
- raise
20
- end
21
15
  end
22
16
 
23
17
  def self.storage_to_output(binary)
@@ -37,6 +31,9 @@ module Bootsnap
37
31
 
38
32
  module InstructionSequenceMixin
39
33
  def load_iseq(path)
34
+ # Having coverage enabled prevents iseq dumping/loading.
35
+ return nil if defined?(Coverage) && Bootsnap::CompileCache::Native.coverage_running?
36
+
40
37
  Bootsnap::CompileCache::Native.fetch(
41
38
  Bootsnap::CompileCache::ISeq.cache_dir,
42
39
  path.to_s,
@@ -47,18 +44,6 @@ module Bootsnap
47
44
  puts "unmatched platform for file #{path}"
48
45
  end
49
46
  raise
50
- rescue Errno::ERANGE
51
- STDERR.puts <<~EOF
52
- \x1b[31mError loading ISeq from cache for \x1b[1;34m#{path}\x1b[0;31m!
53
- You can likely fix this by running:
54
- \x1b[1;32mxattr -c #{path}
55
- \x1b[0;31m...but, first, please make sure \x1b[1;34m@burke\x1b[0;31m knows you ran into this bug!
56
- He will want to see the results of:
57
- \x1b[1;32m/bin/ls -l@ #{path}
58
- \x1b[0;31mand:
59
- \x1b[1;32mxattr -p user.aotcc.key #{path}\x1b[0m
60
- EOF
61
- raise
62
47
  end
63
48
 
64
49
  def compile_option=(hash)
@@ -48,7 +48,7 @@ module Bootsnap
48
48
  def find(feature)
49
49
  reinitialize if (@has_relative_paths && dir_changed?) || stale?
50
50
  feature = feature.to_s
51
- return feature if feature.start_with?(SLASH)
51
+ return feature if absolute_path?(feature)
52
52
  return File.expand_path(feature) if feature.start_with?('./')
53
53
  @mutex.synchronize do
54
54
  x = search_index(feature)
@@ -85,6 +85,16 @@ module Bootsnap
85
85
  end
86
86
  end
87
87
 
88
+ if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
89
+ def absolute_path?(path)
90
+ path[1] == ':'
91
+ end
92
+ else
93
+ def absolute_path?(path)
94
+ path.start_with?(SLASH)
95
+ end
96
+ end
97
+
88
98
  def unshift_paths(sender, *paths)
89
99
  return unless sender == @path_obj
90
100
  @mutex.synchronize { unshift_paths_locked(*paths) }
@@ -99,6 +99,8 @@ module Bootsnap
99
99
  @stability ||= begin
100
100
  if Gem.path.detect { |p| expanded_path.start_with?(p.to_s) }
101
101
  STABLE
102
+ elsif expanded_path.start_with?(Bundler.bundle_path.to_s)
103
+ STABLE
102
104
  elsif expanded_path.start_with?(RUBY_LIBDIR) && !expanded_path.start_with?(RUBY_SITEDIR)
103
105
  STABLE
104
106
  else
@@ -1,3 +1,3 @@
1
1
  module Bootsnap
2
- VERSION = "1.1.0.pre"
2
+ VERSION = "1.1.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bootsnap
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0.pre
4
+ version: 1.1.1
5
5
  platform: java
6
6
  authors:
7
7
  - Burke Libbey
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-06-12 00:00:00.000000000 Z
11
+ date: 2017-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.2'
83
- - !ruby/object:Gem::Dependency
84
- requirement: !ruby/object:Gem::Requirement
85
- requirements:
86
- - - "~>"
87
- - !ruby/object:Gem::Version
88
- version: 0.1.2
89
- name: ffi-xattr
90
- prerelease: false
91
- type: :development
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: 0.1.2
97
83
  - !ruby/object:Gem::Dependency
98
84
  requirement: !ruby/object:Gem::Requirement
99
85
  requirements:
@@ -162,9 +148,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
162
148
  version: 2.0.0
163
149
  required_rubygems_version: !ruby/object:Gem::Requirement
164
150
  requirements:
165
- - - ">"
151
+ - - ">="
166
152
  - !ruby/object:Gem::Version
167
- version: 1.3.1
153
+ version: '0'
168
154
  requirements: []
169
155
  rubyforge_project:
170
156
  rubygems_version: 2.4.8