Commit graph

3437 commits

Author SHA1 Message Date
Nobuyoshi Nakada
b61e3a6218 Write rbinc files at once
Unexpected error can make empty files which result in unclear
compilation errors.
2024-07-18 19:34:10 +09:00
Hiroshi SHIBATA
7a0e6f1d12
Follow-up resolv and win32 integration
https://github.com/ruby/resolv/pull/54
2024-07-16 12:12:40 +09:00
Kevin Newton
0006fb1e9e [PRISM] Revert incorrectly merged gemfile 2024-07-11 14:25:54 -04:00
Kevin Newton
aa473489a2 [ruby/prism] Various cleanup for initializers and typechecks
86cf82794a
2024-07-11 14:25:54 -04:00
Hiroshi SHIBATA
9a5e3a4007 Removed WEBrick and that tests
We can handle uri, time and others without `make test-all` dependencies now.
2024-07-11 09:23:16 +09:00
Peter Zhu
c1ff8d519f Fix grammar of ruby_shared_gc.m4 2024-07-09 13:14:28 -04:00
Peter Zhu
a9f6bd028a Add make target shared-gc
Allows building shared GC using `make shared-gc SHARED_GC=gc_impl`
2024-07-08 16:47:25 -04:00
Naoto Ono
8ede84aa95 Move the file location of launchable.rb 2024-07-08 10:15:04 +09:00
Naoto Ono
5b78925455 Integrate Launchable into make btest 2024-07-08 10:15:04 +09:00
Peter Zhu
e2ceded2c6 Change external GC to use directory at configure
This commit changes the external GC API to use `--with-shared-gc=DIR` at
configure time with a directory of the external GC and uses
`RUBY_GC_LIBRARY` environment variable to load the external GC at
runtime.
2024-07-05 14:05:58 -04:00
Hiroshi SHIBATA
01eb5c0f18
Skip to copy .so/.bundle files generated by rake-compiler 2024-07-01 11:07:49 +09:00
Nobuyoshi Nakada
1213623e5c
Use gperf 3.1 to generate ANSI-C code 2024-06-24 23:43:45 +09:00
Nobuyoshi Nakada
65d3eacc80 No longer needs sigsetjmp
Since signal handlers just set flag and return now, `sigsetjmp` and
`siglongjmp` will not be needed.
2024-06-24 17:38:01 +09:00
Yusuke Endoh
ac9e84df3d Support LCOV 2.0
LCOV 2.0, a GCOV frontend, seems to have stricter error checking
2024-06-21 14:48:44 +09:00
Aaron Patterson
cdf33ed5f3 Optimized forwarding callers and callees
This patch optimizes forwarding callers and callees. It only optimizes methods that only take `...` as their parameter, and then pass `...` to other calls.

Calls it optimizes look like this:

```ruby
def bar(a) = a
def foo(...) = bar(...) # optimized
foo(123)
```

```ruby
def bar(a) = a
def foo(...) = bar(1, 2, ...) # optimized
foo(123)
```

```ruby
def bar(*a) = a

def foo(...)
  list = [1, 2]
  bar(*list, ...) # optimized
end
foo(123)
```

All variants of the above but using `super` are also optimized, including a bare super like this:

```ruby
def foo(...)
  super
end
```

This patch eliminates intermediate allocations made when calling methods that accept `...`.
We can observe allocation elimination like this:

```ruby
def m
  x = GC.stat(:total_allocated_objects)
  yield
  GC.stat(:total_allocated_objects) - x
end

def bar(a) = a
def foo(...) = bar(...)

def test
  m { foo(123) }
end

test
p test # allocates 1 object on master, but 0 objects with this patch
```

```ruby
def bar(a, b:) = a + b
def foo(...) = bar(...)

def test
  m { foo(1, b: 2) }
end

test
p test # allocates 2 objects on master, but 0 objects with this patch
```

How does it work?
-----------------

This patch works by using a dynamic stack size when passing forwarded parameters to callees.
The caller's info object (known as the "CI") contains the stack size of the
parameters, so we pass the CI object itself as a parameter to the callee.
When forwarding parameters, the forwarding ISeq uses the caller's CI to determine how much stack to copy, then copies the caller's stack before calling the callee.
The CI at the forwarded call site is adjusted using information from the caller's CI.

I think this description is kind of confusing, so let's walk through an example with code.

```ruby
def delegatee(a, b) = a + b

def delegator(...)
  delegatee(...)  # CI2 (FORWARDING)
end

def caller
  delegator(1, 2) # CI1 (argc: 2)
end
```

Before we call the delegator method, the stack looks like this:

```
Executing Line | Code                                  | Stack
---------------+---------------------------------------+--------
              1| def delegatee(a, b) = a + b           | self
              2|                                       | 1
              3| def delegator(...)                    | 2
              4|   #                                   |
              5|   delegatee(...)  # CI2 (FORWARDING)  |
              6| end                                   |
              7|                                       |
              8| def caller                            |
          ->  9|   delegator(1, 2) # CI1 (argc: 2)     |
             10| end                                   |
```

The ISeq for `delegator` is tagged as "forwardable", so when `caller` calls in
to `delegator`, it writes `CI1` on to the stack as a local variable for the
`delegator` method.  The `delegator` method has a special local called `...`
that holds the caller's CI object.

Here is the ISeq disasm fo `delegator`:

```
== disasm: #<ISeq:delegator@-e:1 (1,0)-(1,39)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] "..."@0
0000 putself                                                          (   1)[LiCa]
0001 getlocal_WC_0                          "..."@0
0003 send                                   <calldata!mid:delegatee, argc:0, FCALL|FORWARDING>, nil
0006 leave                                  [Re]
```

The local called `...` will contain the caller's CI: CI1.

Here is the stack when we enter `delegator`:

```
Executing Line | Code                                  | Stack
---------------+---------------------------------------+--------
              1| def delegatee(a, b) = a + b           | self
              2|                                       | 1
              3| def delegator(...)                    | 2
           -> 4|   #                                   | CI1 (argc: 2)
              5|   delegatee(...)  # CI2 (FORWARDING)  | cref_or_me
              6| end                                   | specval
              7|                                       | type
              8| def caller                            |
              9|   delegator(1, 2) # CI1 (argc: 2)     |
             10| end                                   |
```

The CI at `delegatee` on line 5 is tagged as "FORWARDING", so it knows to
memcopy the caller's stack before calling `delegatee`.  In this case, it will
memcopy self, 1, and 2 to the stack before calling `delegatee`.  It knows how much
memory to copy from the caller because `CI1` contains stack size information
(argc: 2).

Before executing the `send` instruction, we push `...` on the stack.  The
`send` instruction pops `...`, and because it is tagged with `FORWARDING`, it
knows to memcopy (using the information in the CI it just popped):

```
== disasm: #<ISeq:delegator@-e:1 (1,0)-(1,39)>
local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] "..."@0
0000 putself                                                          (   1)[LiCa]
0001 getlocal_WC_0                          "..."@0
0003 send                                   <calldata!mid:delegatee, argc:0, FCALL|FORWARDING>, nil
0006 leave                                  [Re]
```

Instruction 001 puts the caller's CI on the stack.  `send` is tagged with
FORWARDING, so it reads the CI and _copies_ the callers stack to this stack:

```
Executing Line | Code                                  | Stack
---------------+---------------------------------------+--------
              1| def delegatee(a, b) = a + b           | self
              2|                                       | 1
              3| def delegator(...)                    | 2
              4|   #                                   | CI1 (argc: 2)
           -> 5|   delegatee(...)  # CI2 (FORWARDING)  | cref_or_me
              6| end                                   | specval
              7|                                       | type
              8| def caller                            | self
              9|   delegator(1, 2) # CI1 (argc: 2)     | 1
             10| end                                   | 2
```

The "FORWARDING" call site combines information from CI1 with CI2 in order
to support passing other values in addition to the `...` value, as well as
perfectly forward splat args, kwargs, etc.

Since we're able to copy the stack from `caller` in to `delegator`'s stack, we
can avoid allocating objects.

I want to do this to eliminate object allocations for delegate methods.
My long term goal is to implement `Class#new` in Ruby and it uses `...`.

I was able to implement `Class#new` in Ruby
[here](https://github.com/ruby/ruby/pull/9289).
If we adopt the technique in this patch, then we can optimize allocating
objects that take keyword parameters for `initialize`.

For example, this code will allocate 2 objects: one for `SomeObject`, and one
for the kwargs:

```ruby
SomeObject.new(foo: 1)
```

If we combine this technique, plus implement `Class#new` in Ruby, then we can
reduce allocations for this common operation.

Co-Authored-By: John Hawthorn <john@hawthorn.email>
Co-Authored-By: Alan Wu <XrXr@users.noreply.github.com>
2024-06-18 09:28:25 -07:00
Alan Wu
0dcb0fdfcd
Enable LeakChecker for RJIT previously disabled for MJIT (#10998)
RJIT doesn't spawn subprocesses so there should now be no need to
special case it.
2024-06-14 00:05:38 -07:00
Takashi Kokubun
0a6b1a4d9d redmine-backporter.rb: Prepend commit: to shorter revs
Some of the places in Redmine (e.g. Associated revisions) print
revisions using only 8 characters. Even when I copied a revision from
there, I want to prepend commit: in the message.
2024-06-11 11:28:04 -07:00
KJ Tsanaktsidis
0ccb80d6bf Extract hardening CFLAGS to a special $hardenflags variable
This changes the automatic detection of -fstack-protector,
-D_FORTIFY_SOURCE, and -mbranch-protection to write to $hardenflags
instead of $XCFLAGS. The definition of $cflags is changed to
"$hardenflags $orig_cflags $optflags $debugflags $warnflags" to match.

Furthermore, these flags are _prepended_ to $hardenflags, rather than
appended.

The implications of doing this are as follows:

* If a CRuby builder specifies cflags="-mbranch-protection=foobar" at
  the ./configure script, and the configure script detects that
  -mbranch-protection=pac-ret is accepted, then GCC will be invoked as
  "gcc -mbranch-protection=pac-ret -mbranch-protection=foobar". Since
  the last flags take precedence, that means that user-supplied values
  of these flags in $cflags will take priority.
* Likewise, if a CRuby builder explicitly specifies
  "hardenflags=-mbranch-protection=foobar", because we _prepend_ to
  $hardenflags in our autoconf script, we will still invoke GCC as
  "gcc -mbranch-protection=pac-ret -mbranch-protection=foobar".
* If a CRuby builder specifies CFLAGS="..." at the configure line,
  automatic detection of hardening flags is ignored as before.
* C extensions will _also_ be built with hardening flags now as well
  (this was not the case by default before because the detected flags
  went into $XCFLAGS).

Additionally, as part of this work, I changed how the detection of
PAC/BTI in Context.S works. Rather than appending the autodetected
option to ASFLAGS, we simply compile a set of test programs with the
actual CFLAGS in use to determine what PAC/BTI settings were actually
chosen by the builder. Context.S is made aware of these choices through
some custom macros.

The result of this work is that:

* Ruby will continue to choose some sensible defaults for hardening
  options for the C compiler
* Distributors are able to specify CFLAGS that are consistent with their
  distribution and override these defaults
* Context.S will react to whatever -mbranch-protection is actually in
  use, not what was autodetected
* Extensions get built with hardening flags too.

[Bug #20154]
[Bug #20520]
2024-06-11 20:48:55 +10:00
Jeremy Evans
ac429df64f Ignore retguard symbols when looking for leaked symbols
retguard symbols are added on OpenBSD as part of stack protection.
They should be ignored by the leaked symbols checker, just as we
ignore asan symbols.
2024-06-04 13:04:41 -07:00
Takashi Kokubun
40a9e806f2 merger.rb: Put spaces in between revisions
so that they are linked correctly on GitHub
2024-06-04 11:31:20 -07:00
Hiroshi SHIBATA
3eda59e975
Sync strscan HEAD again.
https://github.com/ruby/strscan/pull/99 split document with multi-byte
chars.
2024-06-04 12:40:08 +09:00
Hiroshi SHIBATA
d50404d6fe
Revert "Sync strscan document files to under the doc directory"
This reverts commit 5611e249e1.

Followed up with 78bfde5d9f
2024-06-03 14:20:23 +09:00
Nobuyoshi Nakada
733c72e6f0
Show destination directory after installation
Due to the length of the list of gems to install, the message at the
beginning of the installation scrolls out.
2024-06-02 17:21:22 +09:00
Sorah Fukumori
1ab7c412d2
RUBY_CHECK_HEADER didn't define HAVE_{header-file} (#10876)
--with-gmp is not working at all because HAVE_GMP_H
was missing since 18eaf0be90. [Bug #20515]

bug: https://bugs.ruby-lang.org/issues/20515
follow-up: https://bugs.ruby-lang.org/issues/20494
follow-up: 18eaf0be90
follow-up: https://github.com/ruby/ruby/pull/10805
2024-05-30 18:52:26 +00:00
Hiroshi SHIBATA
5611e249e1
Sync strscan document files to under the doc directory 2024-05-30 12:34:18 +09:00
Takashi Kokubun
53150b18de release.sh: Explain example usages 2024-05-29 20:25:41 -07:00
Takashi Kokubun
8a9d8a0ef6 release.sh: We don't release tar.bz2 anymore 2024-05-29 20:22:25 -07:00
Hiroshi SHIBATA
f1702261d7
Suppress warnings about frozen string literal feature
```
tool/redmine-backporter.rb:69: warning: literal string will be frozen in the future
```
2024-05-30 10:32:33 +09:00
Takashi Kokubun
a760e21bc1 Sort backport revisions by commit timestamps 2024-05-29 10:39:32 -07:00
Takashi Kokubun
d9d7ae7830 merger.rb: Don't ask "conflicts resolved?" if not needed 2024-05-28 17:46:58 -07:00
Takashi Kokubun
7e95efdafa redmine-backporter.rb: Prepend commit: to every revision 2024-05-28 17:17:16 -07:00
Takashi Kokubun
d0cde43a33 redmine-backporter.rb: Remove an unneeded space
from #backport_command_string

I don't want to leave unneeded spaces in the command history by
copy-pasting the entire line.
2024-05-28 17:00:47 -07:00
Takashi Kokubun
2eded6cc5d merger.rb: Auto-detect tickets when --ticket is not given 2024-05-28 16:30:22 -07:00
Takashi Kokubun
24c56ed516 merger.rb: Drop an obsoleted command from help
It was needed only for SVN, and we dropped SVN support.
2024-05-28 15:43:24 -07:00
Takashi Kokubun
b0ebad51e5 merger.rb: Use commit: prefix in more places 2024-05-28 14:28:50 -07:00
Takashi Kokubun
d1265d6172 merger.rb: Improve the help message
It wasn't clear whether the backport command takes a commit hash or a
ticket number.
2024-05-28 14:05:51 -07:00
Takashi Kokubun
7a860bacee merger.rb: Drop SVN support 2024-05-28 13:51:45 -07:00
Takashi Kokubun
7873275326 redmine-backporter.rb: Use commit: prefix 2024-05-28 13:37:53 -07:00
Takashi Kokubun
13307cd944 redmine-backporter.rb: Highlight closed tickets 2024-05-28 11:46:15 -07:00
Takashi Kokubun
2608f2a23b redmine-backporter.rb: Fix #color for Ruby 3 splat
color(*PRIORITIES['Immediate']) didn't work with Ruby 3.
2024-05-28 11:41:31 -07:00
Takashi Kokubun
3f256dc66a redmine-backporter.rb: Drop SVN support 2024-05-28 10:47:51 -07:00
Takashi Kokubun
450e9d2495 redmine-backporter.rb: Migrate Readline to Reline
instead of using a local Readline port as a fallback
2024-05-28 10:42:47 -07:00
Takashi Kokubun
db7c385897 redmine-backporter.rb: Get rid of VERSION
that has never been utilized
2024-05-28 10:39:39 -07:00
Takashi Kokubun
e5759e4126 redmine-backporter.rb: Print help on wrong usage 2024-05-28 10:34:16 -07:00
Nobuyoshi Nakada
49fcd33e13 Introduce a specialize instruction for Array#pack
Instructions for this code:

```ruby
  # frozen_string_literal: true

[a].pack("C")
```

Before this commit:

```
== disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)>
0000 putself                                                          (   3)[Li]
0001 opt_send_without_block                 <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 newarray                               1
0005 putobject                              "C"
0007 opt_send_without_block                 <calldata!mid:pack, argc:1, ARGS_SIMPLE>
0009 leave
```

After this commit:

```
== disasm: #<ISeq:<main>@test.rb:1 (1,0)-(3,13)>
0000 putself                                                          (   3)[Li]
0001 opt_send_without_block                 <calldata!mid:a, argc:0, FCALL|VCALL|ARGS_SIMPLE>
0003 putobject                              "C"
0005 opt_newarray_send                      2, :pack
0008 leave
```

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2024-05-23 12:11:50 -07:00
Hiroshi SHIBATA
7f0e26b7f9 Re-use strscan with ruby repo 2024-05-20 18:10:09 +09:00
Nobuyoshi Nakada
18eaf0be90 [Bug #20494] Search non-default directories for GMP
Co-Authored-by: lish82 (Hiroki Katagiri)
2024-05-20 13:54:08 +09:00
Nobuyoshi Nakada
e937878883
Revert "Update revision.h if branch unmatch not only revision"
This reverts commit 5a332940ed.
Something does not work well on Github Actions.
2024-05-09 01:02:59 +09:00
Nobuyoshi Nakada
5a332940ed
Update revision.h if branch unmatch not only revision [ci skip] 2024-05-08 21:39:32 +09:00
Nobuyoshi Nakada
aabe718e64
Show the caller location of assertion methods
Not only defined in `Test::Unit` or `CoreAssertions`, also show the
caller location of assertion methods defined in the current class or
ancestors.
2024-05-08 17:24:36 +09:00