834 Commits

Author SHA1 Message Date
Takashi Kokubun
5760f7fd3c Skip compiling at_exit without --mjit-stats 2023-03-05 22:11:20 -08:00
Takashi Kokubun
a9f4e5cc60
YJIT: Fix default call threshold in help (#7424) 2023-03-02 16:16:09 -05:00
Takashi Kokubun
526111290b Revert "reuse open(2) from rb_file_load_ok on POSIX-like system"
This reverts commit 35136e1e9c232ad7a03407b992b2e86b6df43f63.

test-spec has been failing since this revision.

.github/workflows/compilers.yml:82
https://github.com/ruby/ruby/actions/runs/4276884159/jobs/7445299562

```
env:
  # Minimal flags to pass the check.
  default_cc: 'gcc-11 -fcf-protection -Wa,--generate-missing-build-notes=yes'
  optflags: '-O2'
  LDFLAGS: '-Wl,-z,now'
  # FIXME: Drop skipping options
  # https://bugs.ruby-lang.org/issues/18061
  # https://sourceware.org/annobin/annobin.html/Test-pie.html
  TEST_ANNOCHECK_OPTS: "--skip-pie --skip-gaps"
```

Failure:

```
  1)
  An exception occurred during: Kernel#require (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:317
  Kernel#require (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.ext.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:5:in `<top (required)>'

  2)
  An exception occurred during: Kernel#require ($LOADED_FEATURES) stores an absolute path
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:330
  Kernel#require ($LOADED_FEATURES) stores an absolute path ERROR
  LeakError: Closed file descriptor: 8
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:5:in `<top (required)>'

  3)
  An exception occurred during: Kernel#require ($LOADED_FEATURES) does not load a non-canonical path for a file already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:535
  Kernel#require ($LOADED_FEATURES) does not load a non-canonical path for a file already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:5:in `<top (required)>'

  4)
  An exception occurred during: Kernel#require ($LOADED_FEATURES) does not load a ../ relative path for a file already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:551
  Kernel#require ($LOADED_FEATURES) does not load a ../ relative path for a file already loaded ERROR
  LeakError: Leaked file descriptor: 9 : #<File:../code/load_fixture.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:5:in `<top (required)>'

  5)
  An exception occurred during: Kernel#require ($LOADED_FEATURES) complex, enumerator, rational, thread, ruby2_keywords are already required
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:563
  Kernel#require ($LOADED_FEATURES) complex, enumerator, rational, thread, ruby2_keywords are already required ERROR
  LeakError: Closed file descriptor: 8
  Closed file descriptor: 9
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:5:in `<top (required)>'

  6)
  An exception occurred during: Kernel.require (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:317
  Kernel.require (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.ext.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:23:in `<top (required)>'

  7)
  An exception occurred during: Kernel.require ($LOADED_FEATURES) stores an absolute path
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:330
  Kernel.require ($LOADED_FEATURES) stores an absolute path ERROR
  LeakError: Closed file descriptor: 8
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:23:in `<top (required)>'

  8)
  An exception occurred during: Kernel.require ($LOADED_FEATURES) does not load a non-canonical path for a file already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:535
  Kernel.require ($LOADED_FEATURES) does not load a non-canonical path for a file already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:23:in `<top (required)>'

  9)
  An exception occurred during: Kernel.require ($LOADED_FEATURES) does not load a ../ relative path for a file already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:551
  Kernel.require ($LOADED_FEATURES) does not load a ../ relative path for a file already loaded ERROR
  LeakError: Leaked file descriptor: 9 : #<File:../code/load_fixture.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:23:in `<top (required)>'

  10)
  An exception occurred during: Kernel.require ($LOADED_FEATURES) complex, enumerator, rational, thread, ruby2_keywords are already required
  /__w/ruby/ruby/src/spec/ruby/core/kernel/shared/require.rb:563
  Kernel.require ($LOADED_FEATURES) complex, enumerator, rational, thread, ruby2_keywords are already required ERROR
  LeakError: Closed file descriptor: 8
  Closed file descriptor: 9
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_spec.rb:23:in `<top (required)>'

  11)
  An exception occurred during: Kernel#require_relative with a relative path (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:197
  Kernel#require_relative with a relative path (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.ext.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:4:in `<top (required)>'

  12)
  An exception occurred during: Kernel#require_relative with a relative path ($LOADED_FEATURES) stores an absolute path
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:205
  Kernel#require_relative with a relative path ($LOADED_FEATURES) stores an absolute path ERROR
  LeakError: Closed file descriptor: 8
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:4:in `<top (required)>'

  13)
  An exception occurred during: Kernel#require_relative with an absolute path (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:399
  Kernel#require_relative with an absolute path (file extensions) does not load a C-extension file if a complex-extensioned .rb file is already loaded ERROR
  LeakError: Leaked file descriptor: 8 : #<File:/__w/ruby/ruby/src/spec/ruby/fixtures/code/load_fixture.ext.rb>
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:277:in `<top (required)>'

  14)
  An exception occurred during: Kernel#require_relative with an absolute path ($LOAD_FEATURES) stores an absolute path
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:407
  Kernel#require_relative with an absolute path ($LOAD_FEATURES) stores an absolute path ERROR
  LeakError: Closed file descriptor: 8
  /__w/ruby/ruby/src/spec/ruby/core/kernel/require_relative_spec.rb:277:in `<top (required)>'
```
2023-02-27 09:24:45 -08:00
Eric Wong
35136e1e9c reuse open(2) from rb_file_load_ok on POSIX-like system
When loading Ruby source files, we can save the result of
successful opens as open(2)/openat(2) are a fairly expensive
syscalls.  This also avoids a time-of-check-to-time-of-use
(TOCTTOU) problem.

This reduces open(2) syscalls during `require'; but should be
most apparent when users have a small $LOAD_PATH.  Users with
large $LOAD_PATH will benefit less since there'll be more
open(2) failures due to ENOENT.

With `strace -c -e openat ruby -e exit' under Linux, this
results in a ~14% reduction of openat(2) syscalls
(glibc uses openat(2) to implement open(2)).

 % time     seconds  usecs/call     calls    errors syscall
 ------ ----------- ----------- --------- --------- ----------------
   0.00    0.000000           0       296       110 openat
   0.00    0.000000           0       254       110 openat

Additionally, the introduction of `struct ruby_file_load_state'
may make future optimizations more apparent.

This change cannot benefit binary (.so) loading since the
dlopen(3) API requires a filename and I'm not aware of an
alternative that takes a pre-existing FD.  In typical
situations, Ruby source files outnumber the mount of .so
files.
2023-02-26 20:39:41 +00:00
Nobuyoshi Nakada
62146d3cee
Fix a typo 2023-02-01 22:45:45 +09:00
Nobuyoshi Nakada
9445a14d31
Suppress an unused-function warning 2023-02-01 22:42:12 +09:00
Maxime Chevalier-Boisvert
4ce642620f
Make sure RUBY_YJIT_ENABLE only enables YJIT for truthy values (#7208)
* Make sure RUBY_YJIT_ENABLE only enables YJIT for truthy values

Addresses bug reported in: https://github.com/Shopify/yjit/issues/309

* Update ruby.c

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-01-31 12:18:41 -05:00
Takashi Kokubun
bcdc9cf159
YJIT: Make --yjit-stats always visible on --help (#6946) 2022-12-19 10:19:56 -05:00
Takashi Kokubun
a66a69865d
YJIT: Change the default mem size to 64MiB (#6912)
* YJIT: Change the default mem size to 64MiB

* Also update ruby --help

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2022-12-13 11:00:22 -05:00
Maxime Chevalier-Boisvert
1004d693b7
Make it so YJIT is no longer marked as experimental (#6909)
Tested on production workloads at Shopify for > 1 year and proven
to be quite stable. Enabling YJIT at run-time is still guarded
behind the --yjit command-line option for now.
2022-12-12 15:13:46 -05:00
Maxime Chevalier-Boisvert
9350c2b12f
Update YJIT warning, mention need to install rustc (#6873) 2022-12-07 15:02:45 -05:00
Nobuyoshi Nakada
b7a0ce32da [Bug #19016] SyntaxError with parser error messages
Raise a `SyntaxError` with the parser error message, in the case
reading from a file instead of the `-e` option or standard input. So
syntax_suggest can get the message from the caught error.
2022-11-22 00:33:19 +09:00
Takashi Kokubun
120b747b7d
YJIT: Lazily enable YJIT after prelude (#6597)
* YJIT: Lazily enable YJIT after prelude

* Update dependencies

* Use a bit field for opt->yjit
2022-10-24 12:20:44 -04:00
Nobuyoshi Nakada
f55212bce9 Move "special consts" so Qundef and Qnil differ just 1 bit 2022-10-20 22:05:27 +09:00
Takashi Kokubun
2e3b764ad1
Remove a leftover comment [ci skip] 2022-10-19 17:45:36 -07:00
Takashi Kokubun
d9d9005a3a
MJIT: Stop using the VM barrier for jit_cont
This solves multiple problems.

First, RB_VM_LOCK_ENTER/LEAVE is a barrier. We could at least use the
_NO_BARRIER variant.

Second, this doesn't need to interfere with GC or other GVL users when
multiple Ractors are used. This needs to be used in very few places, so
the benefit of fine-grained locking would outweigh its small maintenance
cost.

Third, it fixes a crash for YJIT. Because YJIT is never disabled until a
process exits unlike MJIT that finishes earlier, we could call jit_cont_free
when EC no longer exists, which crashes RB_VM_LOCK_ENTER.
2022-10-19 17:20:48 -07:00
Nobuyoshi Nakada
412e3c7a8d Assert for RTEST that Qnil and Qfalse differ just 1 bit 2022-10-19 22:55:42 +09:00
Takashi Kokubun
e7c71c6c92
Make mjit_cont sharable with YJIT (#6556)
* Make mjit_cont sharable with YJIT

* Update dependencies

* Update YJIT binding
2022-10-17 09:27:59 -07:00
Nobuyoshi Nakada
f178ff3933
Allow abbreviated dump options with additional options 2022-10-09 16:27:34 +09:00
yui-knk
52eaffde86 Support "+error-tolerant" as ruby option
[Feature #19013]
2022-10-08 17:59:11 +09:00
Takashi Kokubun
3767c6a90d
Ruby MJIT (#6028) 2022-09-04 21:53:46 -07:00
Takashi Kokubun
cfa40e225a
Prefer stdbool for MJIT options
same motivation as d6f21b308bcff03e82f8b3dbf11a852ce111b3b3
2022-09-03 20:01:51 -07:00
schneems
a50df1ab0e Setup SyntaxSuggest as default gem
Adds the `syntax_suggest` syntax error display tool to Ruby through the same mechanism as `error_highlight` and `did_you_mean`. Reference ticket: https://bugs.ruby-lang.org/issues/18159

close #4845

## What is syntax_suggest?

When a syntax error is raised by requiring a file, dead_end will use a combination of indentation and lexing to identify the problem.

> Note: Previously this tool was named `dead_end`. 

## Known issues

- SyntaxSearch's approach of showing syntax errors only works through integration with `require`, `load`, `autoload`, and `require_relative` (since it monkeypatches them to detect syntax errors). It does not work with direct Ruby file invocations https://github.com/zombocom/dead_end/issues/31.
  - This causes failure in the test suite (test_expected_backtrace_location_when_inheriting_from_basic_object_and_including_kernel) and confusion when inspecting backtraces if there's a different error when trying to require a file such as measuring memory (https://github.com/zombocom/syntax_suggest/issues/124#issuecomment-1006705016).
  - Discussed fix. We previously talked about opening up `SyntaxError` to be monkeypatched in the same way that other gems hook into `NoMethodError`. This is currently not possible and requires development work. When we last talked about it at RubyKaigi Nobu expressed an ability to make such a change.
2022-08-19 10:02:24 +09:00
Nobuyoshi Nakada
ee864beb7c
Simplify around USE_YJIT macro (#6240)
* Simplify around `USE_YJIT` macro

- Use `USE_YJIT` macro only instead of `YJIT_BUILD`.
- An intermediate macro `YJIT_SUPPORTED_P` is no longer used.

* Bail out if YJIT is enabled on unsupported platforms
2022-08-15 13:05:12 -04:00
Nobuyoshi Nakada
f2423be49d
Duplicate libruby self path
When LOAD_RELATIVE, as `sopath` is truncated to the prefix path, make
the duplicate before it.  Also make `rb_libruby_selfpath` frozen and
hidden.
2022-08-07 14:46:59 +09:00
Nobuyoshi Nakada
58c8b6e862
Adjust styles [ci skip] 2022-08-06 10:13:20 +09:00
Yuta Saito
00f411c58a Add -bundle_loader to mjit compilation args on macOS 2022-08-04 16:29:22 +09:00
Peter Zhu
efb91ff19b Rename rb_ary_tmp_new to rb_ary_hidden_new
rb_ary_tmp_new suggests that the array is temporary in some way, but
that's not true, it just creates an array that's hidden and not on the
transient heap. This commit renames it to rb_ary_hidden_new.
2022-07-26 09:12:09 -04:00
Takashi Kokubun
5b21e94beb Expand tabs [ci skip]
[Misc #18891]
2022-07-21 09:42:04 -07:00
Nobuyoshi Nakada
58e7205c82
See the environment variable and then check if JIT options conflict 2022-07-08 19:10:18 +09:00
Nobuyoshi Nakada
cd94842922 [Bug #18892] Reset ARGF.lineno after reading shebang 2022-07-07 11:33:07 +09:00
Nobuyoshi Nakada
829d726604 Fallback to the default JIT only when no JIT is enabled
Usually, command line options are given precedence first, environment
variables next, and fall back to configuration options at last.
2022-07-02 09:15:20 +09:00
Nobuyoshi Nakada
33100797c4
Remove redundant parentheses [ci skip] 2022-07-01 09:37:00 +09:00
Nobuyoshi Nakada
f4d70e1cd8
Make FEATURE_SET_P macro to include FEATURE_BIT 2022-06-30 16:51:39 +09:00
Nobuyoshi Nakada
bd8ed1f904
Do not call exit() directly 2022-06-29 20:10:29 +09:00
Alan Wu
eb1a84a9c3 When YJIT is not built, hide options and use MJIT for --jit
YJIT is now a build-time opt-in so on platforms that YJIT could support
it could still be unavailable due to user discretion. Use MJIT for --jit
and don't display YJIT related command line options in --help when YJIT
is not included in the build.
2022-06-23 18:12:25 -04:00
Chris Seaton
31b2cd38c5 Include JIT information in crash reports
Since enabling YJIT or MJIT drastically changes what could go wrong at
runtime, it's good to be front and center about whether they are enabled
when dumping a crash report. Previously, `RUBY_DESCRIPTION` and the
description printed when crashing can be different when a JIT is on.

Introduce a new internal data global, `rb_dynamic_description`, and set
it to be the same as `RUBY_DESCRIPTION` during initialization; use it
when crashing.

 * version.c: Init_ruby_description(): Initialize and use
       `rb_dynamic_description`.
 * error.c: Change crash reports to use `rb_dynamic_description`.
 * ruby.c: Call `Init_ruby_description()` earlier. Slightly more work
       for when we exit right after printing the description but that
       was deemed acceptable.
 * include/ruby/version.h: Talk about how JIT info is not in
      `ruby_description`.
 * test/-ext-/bug_reporter/test_bug_reporter.rb: Remove handling for
       crash description being different from `RUBY_DESCRIPTION`.
 * test/ruby/test_rubyoptions.rb: ditto

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
Co-authored-by: Alan Wu <alanwu@ruby-lang.org>
2022-06-20 17:18:29 -04:00
Alan Wu
f90549cd38 Rust YJIT
In December 2021, we opened an [issue] to solicit feedback regarding the
porting of the YJIT codebase from C99 to Rust. There were some
reservations, but this project was given the go ahead by Ruby core
developers and Matz. Since then, we have successfully completed the port
of YJIT to Rust.

The new Rust version of YJIT has reached parity with the C version, in
that it passes all the CRuby tests, is able to run all of the YJIT
benchmarks, and performs similarly to the C version (because it works
the same way and largely generates the same machine code). We've even
incorporated some design improvements, such as a more fine-grained
constant invalidation mechanism which we expect will make a big
difference in Ruby on Rails applications.

Because we want to be careful, YJIT is guarded behind a configure
option:

```shell
./configure --enable-yjit # Build YJIT in release mode
./configure --enable-yjit=dev # Build YJIT in dev/debug mode
```

By default, YJIT does not get compiled and cargo/rustc is not required.
If YJIT is built in dev mode, then `cargo` is used to fetch development
dependencies, but when building in release, `cargo` is not required,
only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer.

The YJIT command-line options remain mostly unchanged, and more details
about the build process are documented in `doc/yjit/yjit.md`.

The CI tests have been updated and do not take any more resources than
before.

The development history of the Rust port is available at the following
commit for interested parties:
1fd9573d8b

Our hope is that Rust YJIT will be compiled and included as a part of
system packages and compiled binaries of the Ruby 3.2 release. We do not
anticipate any major problems as Rust is well supported on every
platform which YJIT supports, but to make sure that this process works
smoothly, we would like to reach out to those who take care of building
systems packages before the 3.2 release is shipped and resolve any
issues that may come up.

[issue]: https://bugs.ruby-lang.org/issues/18481

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com>
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2022-04-27 11:00:22 -04:00
Yuta Saito
be1382b498 ruby.c: initialize extra optional extensions linked statically
Add a hook point to initialize extra extension libraries. The default
hook function is replaced when linking a strong `Init_extra_exts`
symbol. A builder can insert an object file that defines Init_extra_exts
by XLDFLAGS.
2022-01-19 11:19:06 +09:00
Peter Zhu
ffda21b7ba [Feature #18491] Drop support for HP-UX
IA64 support was dropped in ticket #15894, so we can drop support for
HP-UX.
2022-01-18 09:52:15 -05:00
Nobuyoshi Nakada
2dff82bfca
O_NONBLOCK is not always a preprocessor constant on all platforms 2022-01-16 23:47:10 +09:00
Nobuyoshi Nakada
c1bcfeec38
Transfer the responsibility for MJIT options to mjit.c 2022-01-15 18:57:33 +09:00
Nobuyoshi Nakada
d853a7886e Define the default JIT feature bit 2022-01-15 18:55:47 +09:00
Nobuyoshi Nakada
26b4aa853f
Show JIT options only when supported 2022-01-12 17:51:14 +09:00
Kazuhiro NISHIYAMA
b5310b8975
Fix compile errors
```
compiling ../ruby.c
../ruby.c:1547:17: error: implicit declaration of function 'setup_yjit_options' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
                setup_yjit_options(s, &opt->yjit);
                ^
../ruby.c:1547:17: note: did you mean 'setup_mjit_options'?
../ruby.c:1122:1: note: 'setup_mjit_options' declared here
setup_mjit_options(const char *s, struct mjit_options *mjit_opt)
^
../ruby.c:1547:45: error: no member named 'yjit' in 'struct ruby_cmdline_options'; did you mean 'mjit'?
                setup_yjit_options(s, &opt->yjit);
                                            ^~~~
                                            mjit
../ruby.c:192:25: note: 'mjit' declared here
    struct mjit_options mjit;
                        ^
../ruby.c:1924:28: error: no member named 'yjit' in 'struct ruby_cmdline_options'; did you mean 'mjit'?
        rb_yjit_init(&opt->yjit);
                           ^~~~
                           mjit
../ruby.c:192:25: note: 'mjit' declared here
    struct mjit_options mjit;
                        ^
3 errors generated.
```
2022-01-11 17:33:01 +09:00
Nobuyoshi Nakada
3d675c72b9
Use setup_yjit_options only when supported 2022-01-11 17:26:21 +09:00
Nobuyoshi Nakada
1c9b5d452e
Reject command line option ending with - 2022-01-11 11:49:34 +09:00
Nobuyoshi Nakada
8b585f7460
Define YJIT options only when supported 2022-01-11 10:12:40 +09:00
Kazuhiro NISHIYAMA
c764e368bd
Fix default --jit-max-cache in ruby --help
changed at 028f1887c2bfa50dcfc1b623470d6ab1b880fdde
2022-01-10 20:17:05 +09:00
Kazuhiro NISHIYAMA
a7faca51ac
Add =num to yjit options
`--yjit-call-threshold` and `--yjit-max-versions` need an argument.
2022-01-09 12:39:34 +09:00