bootsnap 1.1.0.pre → 1.1.0

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: eb4f1c7a20afd5550cb29063940865fa1b7cf1a6
4
- data.tar.gz: 1309c503d7c4fedbd07a30efc8fbe1cdb7fd44c7
3
+ metadata.gz: fbdf0cc19b09b396571d9d38cb037cebfcdab7b2
4
+ data.tar.gz: f07f07ec071dbffe3a48e1ae324457729a11ca61
5
5
  SHA512:
6
- metadata.gz: 712729db38aedc0316e4d2043dc3eb3f72cd6560915052ee3bf9fc19de74a5c6534716d2607ac312bb074f8df529f76a9fdfd584d746356280dc96c43fb8de3c
7
- data.tar.gz: a978d40c13d3b665910571224d378d75ec7d6c1779e8fc535bf88efc3c290e948d681f055a2ae1fcd0d6ae84df0e8ef501714c4e12c2e420357de4e7995f9dae
6
+ metadata.gz: 9db4ab87163f7c05a7b5c62fe17617149ec5acdc1caf186013c334222a4ad0a2087c5992b44fcf424201dd5b12448ce25826ccb4f99f495e450437aa90d0a0ae
7
+ data.tar.gz: 84714b27f6a3be1650807af151309dc789390944c1a317ec9c246067c2f4299184c182aa878c8eb5715da989c1c768a3d86992af02ab9d974f1d26d09bb2d170
@@ -2,6 +2,8 @@
2
2
 
3
3
  * Add `bootsnap/setup`
4
4
  * Support jruby (without compile caching features)
5
+ * Better deoptimization when Coverage is enabled
6
+ * Consider `Bundler.bundle_path` to be stable
5
7
 
6
8
  # 1.0.0
7
9
 
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
  }
@@ -176,6 +188,9 @@ fnv1a_64(const char *str)
176
188
  static uint32_t
177
189
  get_os_version(void)
178
190
  {
191
+ #ifdef _WIN32
192
+ return (uint32_t)GetVersion();
193
+ #else
179
194
  uint64_t hash;
180
195
  struct utsname utsname;
181
196
 
@@ -185,6 +200,7 @@ get_os_version(void)
185
200
  hash = fnv1a_64(utsname.version);
186
201
 
187
202
  return (uint32_t)(hash >> 32);
203
+ #endif
188
204
  }
189
205
 
190
206
  /*
@@ -265,6 +281,9 @@ open_current_file(char * path, struct bs_cache_key * key)
265
281
 
266
282
  fd = open(path, O_RDONLY);
267
283
  if (fd < 0) return fd;
284
+ #ifdef _WIN32
285
+ setmode(fd, O_BINARY);
286
+ #endif
268
287
 
269
288
  if (fstat(fd, &statbuf) < 0) {
270
289
  close(fd);
@@ -321,6 +340,9 @@ open_cache_file(const char * path, struct bs_cache_key * key)
321
340
  if (errno == ENOENT) return CACHE_MISSING_OR_INVALID;
322
341
  return ERROR_WITH_ERRNO;
323
342
  }
343
+ #ifdef _WIN32
344
+ setmode(fd, O_BINARY);
345
+ #endif
324
346
 
325
347
  res = bs_read_key(fd, key);
326
348
  if (res < 0) {
@@ -393,7 +415,11 @@ mkpath(char * file_path, mode_t mode)
393
415
  char * p;
394
416
  for (p = strchr(file_path + 1, '/'); p; p = strchr(p + 1, '/')) {
395
417
  *p = '\0';
418
+ #ifdef _WIN32
419
+ if (mkdir(file_path) == -1) {
420
+ #else
396
421
  if (mkdir(file_path, mode) == -1) {
422
+ #endif
397
423
  if (errno != EEXIST) {
398
424
  *p = '/';
399
425
  return -1;
@@ -428,6 +454,9 @@ atomic_write_cache_file(char * path, struct bs_cache_key * key, VALUE data)
428
454
  fd = open(tmp_path, O_WRONLY | O_CREAT, 0644);
429
455
  if (fd < 0) return -1;
430
456
  }
457
+ #ifdef _WIN32
458
+ setmode(fd, O_BINARY);
459
+ #endif
431
460
 
432
461
  key->data_size = RSTRING_LEN(data);
433
462
  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.0"
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.0
5
5
  platform: ruby
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-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '1.2'
83
- - !ruby/object:Gem::Dependency
84
- name: ffi-xattr
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: 0.1.2
90
- type: :development
91
- prerelease: false
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
  name: msgpack
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -163,9 +149,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
163
149
  version: 2.0.0
164
150
  required_rubygems_version: !ruby/object:Gem::Requirement
165
151
  requirements:
166
- - - ">"
152
+ - - ">="
167
153
  - !ruby/object:Gem::Version
168
- version: 1.3.1
154
+ version: '0'
169
155
  requirements: []
170
156
  rubyforge_project:
171
157
  rubygems_version: 2.6.10