bootsnap 1.1.0.pre-java → 1.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
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