Граф коммитов

19417 Коммитов

Автор SHA1 Сообщение Дата
Aaron Patterson b974c84606 Move Array#map to Ruby
Improves activerecord by about 1% on the interpreter:

```
before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) [arm64-darwin23]

------------  -----------  ----------  ----------  ----------  -------------  ------------
bench         before (ms)  stddev (%)  after (ms)  stddev (%)  after 1st itr  before/after
activerecord  235.2        0.8         233.6       0.7         1.01           1.01
------------  -----------  ----------  ----------  ----------  -------------  ------------
Legend:
- after 1st itr: ratio of before/after time for the first benchmarking iteration.
- before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup.
```

Improves YJIT by about 4%:

```
before: ruby 3.4.0dev (2024-07-03T18:40:10Z master f88841b8f3) +YJIT [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T18:41:14Z ruby-map 6c0df4eb32) +YJIT [arm64-darwin23]

------------  -----------  ----------  ----------  ----------  -------------  ------------
bench         before (ms)  stddev (%)  after (ms)  stddev (%)  after 1st itr  before/after
activerecord  142.1        1.2         137.0       0.6         1.00           1.04
------------  -----------  ----------  ----------  ----------  -------------  ------------
Legend:
- after 1st itr: ratio of before/after time for the first benchmarking iteration.
- before/after: ratio of before/after time. Higher is better for after. Above 1 represents a speedup.
```
2024-07-03 12:32:53 -07:00
Stan Lo 7fe5f0a1d0 [ruby/irb] Introduce cd command
(https://github.com/ruby/irb/pull/971)

It's essentially a combination of pushws and popws commands that are
easier to use.

Help message:

```
Usage: cd ([target]|..)

IRB uses a stack of workspaces to keep track of context(s), with `pushws` and `popws` commands to manipulate the stack.
The `cd` command is an attempt to simplify the operation and will be subject to change.

When given:
- an object, cd will use that object as the new context by pushing it onto the workspace stack.
- "..", cd will leave the current context by popping the top workspace off the stack.
- no arguments, cd will move to the top workspace on the stack by popping off all workspaces.

Examples:

  cd Foo
  cd Foo.new
  cd @ivar
  cd ..
  cd
```

https://github.com/ruby/irb/commit/4a0e0e89b7
2024-07-03 17:17:42 +00:00
Jean Boussier 786cf9db48 array.c: Remove outdated assertions
Following [Feature #20589] it can happen that we change the
capacity of a frozen array, so these assertions no longer make
sense.

Normally we don't hit them because `Array#freeze` shrinks the
array, but if somehow the Array was frozen using `Object#freeze`
then we may shrink it after it was frozen.
2024-07-03 17:16:17 +02:00
Peter Zhu 51bd816517 [Feature #20470] Split GC into gc_impl.c
This commit splits gc.c into two files:

- gc.c now only contains code not specific to Ruby GC. This includes
  code to mark objects (which the GC implementation may choose not to
  use) and wrappers for internal APIs that the implementation may need
  to use (e.g. locking the VM).

- gc_impl.c now contains the implementation of Ruby's GC. This includes
  marking, sweeping, compaction, and statistics. Most importantly,
  gc_impl.c only uses public APIs in Ruby and a limited set of functions
  exposed in gc.c. This allows us to build gc_impl.c independently of
  Ruby and plug Ruby's GC into itself.
2024-07-03 09:03:40 -04:00
Grant Gardner 4d4ac00123 [ruby/openssl] Add SSLSocket#readbyte
Companion to getbyte but raise EOFError
Similar to https://github.com/ruby/openssl/pull/438

https://github.com/ruby/openssl/commit/c40f70711a
2024-07-03 08:54:18 +00:00
Aaron Patterson 93b19d56de Add regression test for mutating pack's format string
It doesn't look like there was a test added for this bug, so I'm adding
it.

Code is from here:

  https://web.archive.org/web/20160908192307/http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/24445
2024-07-02 17:59:48 -07:00
Hiroshi SHIBATA 1ab31eb429 [ruby/fiddle] Pick ruby/ruby changes for
`test/fiddle/test_function.rb`
(https://github.com/ruby/fiddle/pull/141)

https://github.com/ruby/ruby/pull/11048#issuecomment-2185630854

---------

https://github.com/ruby/fiddle/commit/a245f19763

Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
2024-07-02 18:33:39 +09:00
Yudai Takada 15ceb95d78 [ruby/rdoc] Fix some typos (https://github.com/ruby/rdoc/pull/1129)
* constist ==> consist

* Tidyness ==> Tidiness

* Currentry ==> Currently

* valus ==> values

https://github.com/ruby/rdoc/commit/8412705721
2024-07-01 11:08:37 +09:00
tomoya ishida de2d9c8e22 [ruby/irb] Allow assigning and using local variable name conflicting
with command
(https://github.com/ruby/irb/pull/961)

https://github.com/ruby/irb/commit/00603d470f
2024-06-30 17:13:27 +00:00
Peter Zhu 176c4bb3c7 Fix corruption of internal encoding string
[Bug #20598]

Just like [Bug #20595], Encoding#name_list and Encoding#aliases can have
their strings corrupted when Encoding.default_internal is set to nil.

Co-authored-by: Matthew Valentine-House <matt@eightbitraptor.com>
2024-06-27 14:06:40 -04:00
Peter Zhu c6a0d03649 Fix corruption of encoding name string
[Bug #20595]

enc_set_default_encoding will free the C string if the encoding is nil,
but the C string can be used by the encoding name string. This will cause
the encoding name string to be corrupted.

Consider the following code:

    Encoding.default_internal = Encoding::ASCII_8BIT
    names = Encoding.default_internal.names
    p names
    Encoding.default_internal = nil
    p names

It outputs:

    ["ASCII-8BIT", "BINARY", "internal"]
    ["ASCII-8BIT", "BINARY", "\x00\x00\x00\x00\x00\x00\x00\x00"]

Co-authored-by: Matthew Valentine-House <matt@eightbitraptor.com>
2024-06-27 09:47:22 -04:00
Kevin Newton ce7299d09a [ruby/prism] Handle block exits under modifiers
https://github.com/ruby/prism/commit/6b78f5309b
2024-06-26 20:46:27 +00:00
David Rodríguez 403413e1f1 [rubygems/rubygems] Don't print warning about nil versions being discouraged during tests
https://github.com/rubygems/rubygems/commit/39a47c264e
2024-06-26 16:11:44 +00:00
Thomas Marshall 39951293b4 [rubygems/rubygems] Add Specification#validate_for_resolution
This method validates only what is required for resolution, skipping any
irrelevant metadata validation. This will be used by Bundler instead of
doing a full validation, allowing gem authors to use `bundle` commands
immediately in newly created gems without first having to fix invalid
metafata fields in the default gemspec.

https://github.com/rubygems/rubygems/commit/da7704cfc0
2024-06-25 14:32:19 +00:00
Nobuyoshi Nakada 3b4ff810d2
Move to test/.excludes-prism 2024-06-25 12:42:16 +09:00
Nobuyoshi Nakada a7f33c99c6
Pending `EVENT_RETURN` settracefunc tests with Prism 2024-06-25 12:37:50 +09:00
Nobuyoshi Nakada 250fc1223c [Bug #20457] Do not remove final `return` node
This was an optimization for versions prior to 1.9 that traverse the
AST at runtime.
2024-06-25 11:07:58 +09:00
tomoya ishida 691d85d342 [ruby/reline] Rerender and enter raw mode again by SIGCONT
(https://github.com/ruby/reline/pull/727)

https://github.com/ruby/reline/commit/be45660c83
2024-06-25 00:55:07 +00:00
Jeremy Evans ae0c7faa79
Handle hash and splat nodes in defined?
This supports the nodes in both in the parse.y and prism compilers.

Fixes [Bug #20043]

Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2024-06-24 11:32:58 -07:00
Jean Boussier 95ffcd3f9f Fix `--debug-frozen-string-literal` to not apply `--disable-frozen-string-literal`
[Feature #20205]

This was an undesired side effect. Now that this value is a triplet, we can't
assume it's disabled by default.
2024-06-24 12:43:39 +02:00
Yusuke Endoh 9cfc1362aa Extend the timeout of test_try_ldflag_invalid_opt and test_try_cppflag_invalid_opt 2024-06-24 18:14:34 +09:00
Yusuke Endoh 96b45e61ca Introduce retry to the setup of test files with TestFile#test_stat
GitHub Actions macos-arm-oss is often too slow and does not timestamp as
expected.
2024-06-24 13:18:21 +09:00
Yusuke Endoh ace17ba3cd Extend the timeout of Fiddle::TestFunction#test_nogvl_poll 2024-06-24 13:11:45 +09:00
Yusuke Endoh 3a323c6b12 Extend the timeout of TestVMDump#test_darwin_invalid_call, etc. 2024-06-24 11:54:10 +09:00
Yusuke Endoh 47364c147d Apply EnvUtil.apply_timeout_scale for TestFile#test_stat
... to respect RUBY_TEST_TIMEOUT_SCALE. This test somehow fails
frequently on macos-arm-oss with --repeat-count=2

https://app.launchableinc.com/organizations/ruby/workspaces/ruby/data/test-paths/file%3Dtest%2Fruby%2Ftest_file.rb%23%23%23class%3DTestFile%23%23%23testcase%3Dtest_stat?organizationId=ruby&workspaceId=ruby&testPathId=file%3Dtest%2Fruby%2Ftest_file.rb%23%23%23class%3DTestFile%23%23%23testcase%3Dtest_stat&testSessionStatus=flake
2024-06-21 13:57:07 +09:00
Kevin Newton 9bd5995b40 [PRISM] Remove duplicated tests
These tests are flaky and are duplicative of other tests that are
run in CI when parser=prism.
2024-06-20 09:24:19 -04:00
David Rodríguez 0a9f1ecc37 [rubygems/rubygems] Add a regression test for previous `bundler update --bundler` fix
https://github.com/rubygems/rubygems/commit/c392593dc3
2024-06-20 09:26:33 +00:00
Nobuyoshi Nakada 92ab2dac22 [rubygems/rubygems] Check if failed with the expected error
https://github.com/rubygems/rubygems/commit/3f22e9df8d
2024-06-20 07:16:56 +00:00
Nobuyoshi Nakada e345970707 [rubygems/rubygems] Revert "Workaround for TruffleRuby that set `nil` to LIBRUBY_RELATIVE"
This reverts commit https://github.com/rubygems/rubygems/commit/06fd39997348, for a
bug that is fixed by https://github.com/rubygems/rubygems/commit/0148cce153a5.

https://github.com/rubygems/rubygems/commit/907e51e521
2024-06-20 07:16:55 +00:00
Jean Boussier 83f57ca3d2 String.new(capacity:) don't substract termlen
[Bug #20585]

This was changed in 36a06efdd9f0604093dccbaf96d4e2cb17874dc8 because
`String.new(1024)` would end up allocating `1025` bytes, but the problem
with this change is that the caller may be trying to right size a String.

So instead, we should just better document the behavior of `capacity:`.
2024-06-19 15:11:07 +02:00
Nobuyoshi Nakada 321ed86e93 [rubygems/rubygems] Do not set previously unset value
https://github.com/rubygems/rubygems/commit/0148cce153
2024-06-19 11:42:35 +00:00
Nobuyoshi Nakada 57e15074fe [rubygems/rubygems] Workaround for TruffleRuby that set `nil` to LIBRUBY_RELATIVE
https://github.com/rubygems/rubygems/commit/06fd399973
2024-06-19 11:42:35 +00:00
Nobuyoshi Nakada 378e65af9a [rubygems/rubygems] Dump `RbConfig` elements to escape special characters
Naively embed strings do not work if special characters (newline,
backslahes and so on) are contained.

https://github.com/rubygems/rubygems/commit/ac2c4c4af1
2024-06-19 11:42:34 +00:00
Kevin Newton dfb67a4433 [ruby/prism] (parser) Print when token tests are now passing
https://github.com/ruby/prism/commit/9e4fb665ee
2024-06-18 21:18:39 -04:00
Kevin Newton 24f48382bc [ruby/prism] (parser) Fix up tokens for empty symbol
https://github.com/ruby/prism/commit/5985ab7687
2024-06-18 21:18:39 -04:00
Peter Zhu eb215c8dc6 Fix flaky TestWeakMap#test_inspect_garbage
If a GC is ran before the assert_match, then the WeakMap would be empty
and would not have any objects, so the regular expression match would
fail. This changes the regular expression to work even if the WeakMap
is empty.
2024-06-18 14:21:37 -04:00
Aaron Patterson cfc5646cdc fix allocation assertions 2024-06-18 09:28:25 -07: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
Stan Lo 921f22e563 [ruby/irb] Improve how command calls' return value is handled
(https://github.com/ruby/irb/pull/972)

In #934, we changed command calls to return nil only. This PR improves
the behaviour even further by:

- Not echoing the `nil` returned by command calls
- Not overriding previous return value stored in `_` with the
  `nil` from commands

https://github.com/ruby/irb/commit/c844176842
2024-06-18 15:15:23 +00:00
tomoya ishida c2e2c5975d [ruby/reline] Fix vi_yank or vi_delete_meta copies nil bug
(https://github.com/ruby/reline/pull/726)

https://github.com/ruby/reline/commit/46b30b07c9
2024-06-18 14:57:19 +00:00
Alexey Schepin a3930db275 [rubygems/rubygems] Delete extra spaces left after rubocop autofix
https://github.com/rubygems/rubygems/commit/a552732bed
2024-06-18 01:52:04 +00:00
Yuta Saito 97a23db5ac [rubygems/rubygems] Disable `install_extension_in_lib` when cross-compiling
https://github.com/rubygems/rubygems/commit/643e154f32
2024-06-18 00:59:36 +00:00
Yuta Saito 273d41b9e3 [rubygems/rubygems] Add `--target-rbconfig` option to `gem install` and `gem update` commands
This patch adds `--target-rbconfig` option to specify the rbconfig.rb file
for the deployment target platform. This is useful when cross-compiling
gems. At the moment, this option is only available for `extconf.rb`-based
extensions.

https://github.com/rubygems/rubygems/commit/cf2843f7a2
2024-06-18 00:59:35 +00:00
Kevin Newton 7529591df1 [ruby/prism] Ensure ranges are non-associative
https://github.com/ruby/prism/commit/f59295938b
2024-06-14 19:22:54 +00:00
Nobuyoshi Nakada a1f72a563b [Bug #20579] ripper: Dispatch spaces at END-OF-INPUT without newline 2024-06-14 17:54:02 +09:00
David Rodríguez 62fc473224 [rubygems/rubygems] Never remove executables that may belong to a default gem
https://github.com/rubygems/rubygems/commit/ed585f2fca
2024-06-14 08:02:38 +00:00
David Rodríguez 7767b60ff2 [rubygems/rubygems] Reuse `write_file` helper
https://github.com/rubygems/rubygems/commit/339f099870
2024-06-14 08:02:38 +00:00
Nobuyoshi Nakada 2e59cf00cc [Bug #20578] ripper: Fix dispatching part at invalid escapes 2024-06-14 15:02:15 +09:00
Kevin Newton 0321f2c8fe [ruby/prism] Handle implicit array precedence
When an implicit array is used in a write, is causes the whole
expression to become a statement. For example:

```ruby
a = *b
a = 1, 2, 3
```

Even though these expressions are exactly equivalent to their
explicit array counterparts:

```ruby
a = [*b]
a = [1, 2, 3]
```

As such, these expressions cannot be joined with other expressions
by operators or modifiers except if, unless, while, until, or
rescue.

https://github.com/ruby/prism/commit/7cd2407272
2024-06-13 18:46:02 +00:00
tompng 04467218ce Add rb_str_resize coderange test 2024-06-13 18:27:02 +02:00