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

1112 Коммитов

Автор SHA1 Сообщение Дата
eileencodes 6f6aff56b1 Don't shrink array in `ary_make_shared`
This change adds back the assertions removed in #11092 and removes the
call to `ary_shrink_capa` from `ary_make_shared` when the array is
frozen.
2024-07-09 10:22:29 -07:00
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
Aaron Patterson 4c9134d2b2 Move Array#select to Ruby
This speeds up the mail benchmark by about 7% on the interpreter:

```
before: ruby 3.4.0dev (2024-07-03T17:01:41Z master f4b313f733) [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T17:45:50Z ruby-select de282cacd5) [arm64-darwin23]

-----  -----------  ----------  ----------  ----------  -------------  ------------
bench  before (ms)  stddev (%)  after (ms)  stddev (%)  after 1st itr  before/after
mail   72.9         0.8         68.2        1.0         1.02           1.07
-----  -----------  ----------  ----------  ----------  -------------  ------------
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.
```

YJIT is about 13% faster:

```
before: ruby 3.4.0dev (2024-07-03T17:01:41Z master f4b313f733) +YJIT [arm64-darwin23]
after: ruby 3.4.0dev (2024-07-03T17:45:50Z ruby-select de282cacd5) +YJIT [arm64-darwin23]

-----  -----------  ----------  ----------  ----------  -------------  ------------
bench  before (ms)  stddev (%)  after (ms)  stddev (%)  after 1st itr  before/after
mail   51.0         0.8         45.2        0.6         1.00           1.13
-----  -----------  ----------  ----------  ----------  -------------  ------------
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 11:32:40 -07: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
eileencodes d25b74b32c Resize arrays in `rb_ary_freeze` and use it for freezing arrays
While working on a separate issue we found that in some cases
`ary_heap_realloc` was being called on frozen arrays. To fix this, this
change does the following:

1) Updates `rb_ary_freeze` to assert the type is an array, return if
already frozen, and shrink the capacity if it is not embedded, shared
or a shared root.
2) Replaces `rb_obj_freeze` with `rb_ary_freeze` when the object is
always an array.
3) In `ary_heap_realloc`, ensure the new capa is set with
`ARY_SET_CAPA`. Previously the change in capa was not set.
4) Adds an assertion to `ary_heap_realloc` that the array is not frozen.

Some of this work was originally done in
https://github.com/ruby/ruby/pull/2640, referencing this issue
https://bugs.ruby-lang.org/issues/16291. There didn't appear to be any
objections to this PR, it appears to have simply lost traction.

The original PR made changes to arrays and strings at the same time,
this PR only does arrays. Also it was old enough that rather than revive
that branch I've made a new one. I added Lourens as co-author in addtion
to Aaron who helped me with this patch.

The original PR made this change for performance reasons, and while
that's still true for this PR, the goal of this PR is to avoid
calling `ary_heap_realloc` on frozen arrays. The capacity should be
shrunk _before_ the array is frozen, not after.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: methodmissing <lourens@methodmissing.com>
2024-07-02 10:34:23 -07:00
Jean Boussier 7c12169230 Eliminate internal uses of `Data_Wrap_Struct`
Ref: https://github.com/ruby/ruby/pull/10872

These should be the last internal uses of the old `Data` API
inside Ruby itself. Some use remain in a couple default gems.
2024-06-02 13:59:11 +02: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
Matt Valentine-House c59abb9999 Rename ary_heap_alloc -> ary_heap_alloc_buffer
To differentiate it from ary_alloc_heap
2024-05-02 19:28:23 +01:00
Zack Deveau c479492a67 Resize ary when `Array#sort!` block modifies embedded ary
In cases where `rb_ary_sort_bang` is called with a block and
tmp is an embedded array, we need to account for the block
potentially impacting the capacity of ary.

ex:
```
var_0 = (1..70).to_a
var_0.sort! do |var_0_block_129, var_1_block_129|
  var_0.pop
  var_1_block_129 <=> var_0_block_129
end.shift(3)
```

The above example can put the array into a corrupted state
resulting in a heap buffer overflow and possible segfault:
```
ERROR: AddressSanitizer: heap-buffer-overflow on address [...]
WRITE of size 560 at 0x60b0000034f0 thread T0 [...]
```

This commit adds a conditional to determine when the capacity
of ary has been modified by the provided block. If this is
the case, ensure that the capacity of ary is adjusted to
handle at minimum the len of tmp.
2024-04-14 08:41:47 +09:00
KJ Tsanaktsidis 9d0a5148ae Add missing RB_GC_GUARDs related to DATA_PTR
I discovered the problem in `compile.c` from a failing
TestIseqLoad#test_stressful_roundtrip test with ASAN enabled. The other
two changes in array.c and string.c I found by auditing similar usages
of DATA_PTR in the codebase.

[Bug #20402]
2024-03-31 20:33:38 +11:00
Burdette Lamar 76f9cfd0b9
[DOC] Array doc (#10199) 2024-03-13 14:50:18 -04:00
BurdetteLamar cc757f4a61 Add 'In brief' for Array#[] 2024-03-06 16:42:29 -05:00
Peter Zhu df5b8ea4db Remove unneeded RUBY_FUNC_EXPORTED 2024-02-23 10:24:21 -05:00
Burdette Lamar 65f5435540
[DOC] Doc compliance (#9955) 2024-02-14 10:47:42 -05:00
BurdetteLamar f41d8f38b4 Comply with doc guide 2024-02-12 16:52:14 -05:00
Peter Zhu 1228751af6 Replace assert with RUBY_ASSERT in array.c
assert does not print the bug report, only the file and line number of
the assertion that failed. RUBY_ASSERT prints the full bug report, which
makes it much easier to debug.
2024-02-12 15:07:47 -05:00
Takashi Kokubun c84237f953
Rewrite Array#each in Ruby using Primitive (#9533) 2024-01-23 20:09:57 +00:00
Edwing123 a660e1de18
[DOC] correct doc comment for rb_ary_aset
Signed-off-by: Edwin Garcia <egarciavalle2014@gmail.com>
2024-01-18 06:56:42 +00:00
Akshay Birajdar c06745fec9 [DOC] Enhance documentation for `Array#zip` 2024-01-09 14:13:20 -05:00
Peter Zhu 26172c9701 [DOC] Add parentheses to Array#eql?
Makes the call-seq and code more consistent in format.
2023-12-27 11:11:42 -05:00
Peter Zhu ca886cd253 [DOC] Link to Array#eql? from Array#hash 2023-12-25 13:56:15 -05:00
Peter Zhu 47f33c3848 Remove useless `#if 1` in array.c 2023-12-23 09:51:30 -05:00
Peter Zhu e191bf42d2 Fix ary_make_partial_step for compaction
ary could change embeddedness due to compaction, so we should only get
the pointer after allocations.

The included test was crashing with:

    TestArray#test_slice_gc_compact_stress
    ruby/lib/pp.rb:192: [BUG] Segmentation fault at 0x0000000000000038
2023-12-21 10:39:03 -05:00
Nobuyoshi Nakada 40fc9b070c
[DOC] No document for internal or debug methods 2023-12-18 20:17:45 +09:00
Tema Bolshakov e4a11a1283 Array#rassoc should try to convert to array implicitly. Fixes #20003 2023-11-29 09:39:15 +09:00
Peter Zhu 150ed44d87 Fix compaction during ary_make_partial
The ary_make_shared call may allocate, which can trigger a GC
compaction. This can cause the array to be embedded because it has a
length of 0.
2023-11-27 12:40:26 -05:00
Jean Boussier 9691532428 Get rid of flatten_memo_data_type
We can use an hidden Hash instead, it's simpler, triggers
write barriers, handle compaction, etc.
2023-11-22 17:10:03 +01:00
Peter Zhu 4cc5659293 Keep write-barrier status after splicing array
We don't need to remove the write-barrier protected status after
splicing an array. We can simply add it to the rememberset for marking
during the next GC.

The benchmark illustrates the performance impact on minor GC:

```
require "benchmark"

arys = 1_000_000.times.map do
  ary = Array.new(50)
  ary.insert(1, 3)
  ary
end

4.times { GC.start }

puts(Benchmark.measure do
  1000.times do
    GC.start(full_mark: false)
  end
end)
```

This branch:

```
  1.309910   0.004342   1.314252 (  1.314580)
```

Master branch:

```
 54.376091   0.219037  54.595128 ( 54.742996)
```
2023-09-04 08:50:27 -04:00
Nobuyoshi Nakada 247fa3ca76
[DOC] Remove typo 2023-08-29 19:40:52 +09:00
Kouhei Yanagita a28c5151f5 Fix Array#bsearch when block returns a non-integer numeric value 2023-08-29 18:00:44 +09:00
Peter Zhu c8d6419985 Refactor ary_make_partial 2023-08-18 10:25:36 -04:00
Burdette Lamar 6ccc660d85
[DOC] Don't suppress autolinks (#8207) 2023-08-11 17:53:53 -04:00
Kunshan Wang aeff31168a No computing embed_capa_max in ary_make_partial
ary_make_partial now uses the actual embed_capa of an allocated heap
array to guide whether make an embedded copy or a slice view.
2023-08-03 08:34:24 -04:00
Peter Zhu 62ecf78b87 Don't pass array into ary_heap_alloc
We no longer need a reference to the array when allocating the buffer
because we no longer allocate through the transient heap.
2023-07-13 14:48:14 -04:00
Peter Zhu 87e1486d31 Remove unused references to the transient heap 2023-07-13 14:48:14 -04:00
Peter Zhu 3223181284 Remove RARRAY_CONST_PTR_TRANSIENT
RARRAY_CONST_PTR now does the same things as RARRAY_CONST_PTR_TRANSIENT.
2023-07-13 14:48:14 -04:00
Peter Zhu de327ccb63 Remove RARRAY_PTR_USE_TRANSIENT
RARRAY_PTR_USE now does the same things as RARRAY_PTR_USE_TRANSIENT.
2023-07-13 14:48:14 -04:00
Peter Zhu 1e7b67f733 [Feature #19730] Remove transient heap 2023-07-13 09:27:33 -04:00
Nobuyoshi Nakada a5e1d549b5 [DOC] Mention the edge case of `any?`/`all?` 2023-06-01 21:44:53 +09:00
Peter Zhu 0938964ba1 Implement Hash ST tables on VWA 2023-05-17 09:19:40 -04:00
Nobuyoshi Nakada 0e5aecea11
[DOC] Move docs of `Array#first` and `Array#last` to array.rb 2023-05-10 15:47:39 +09:00
Jeremy Evans 986268afae Document that Array#{&,intersection,intersect?} use hash method [ci skip]
Fixes [Bug #19622]
2023-05-09 02:25:56 -07:00
git 21082eac50 * expand tabs. [ci skip]
Please consider using misc/expand_tabs.rb as a pre-commit hook.
2023-04-19 00:16:36 +00:00
Aaron Patterson c5fc1ce975 Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is
used when there is an array literal followed by either the `hash`,
`min`, or `max` method.

```
[a, b, c].hash
```

Will emit an `opt_newarray_send` instruction.  This instruction falls
back to a method call if the "interested" method has been monkey
patched.

Here are some examples of the instructions generated:

```
$ ./miniruby --dump=insns -e '[@a, @b].max'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :max
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].min'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :min
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].hash'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :hash
0009 leave
```

[Feature #18897] [ruby-core:109147]

Co-authored-by: John Hawthorn <jhawthorn@github.com>
2023-04-18 17:16:22 -07:00
Matt Valentine-House 026321c5b9 [Feature #19474] Refactor NEWOBJ macros
NEWOBJ_OF is now our canonical newobj macro. It takes an optional ec
2023-04-06 11:07:16 +01:00
Peter Zhu 1da2e7fca3
[Feature #19579] Remove !USE_RVARGC code (#7655)
Remove !USE_RVARGC code

[Feature #19579]

The Variable Width Allocation feature was turned on by default in Ruby
3.2. Since then, we haven't received bug reports or backports to the
non-Variable Width Allocation code paths, so we assume that nobody is
using it. We also don't plan on maintaining the non-Variable Width
Allocation code, so we are going to remove it.
2023-04-04 17:30:06 -04:00
Takashi Kokubun 1b475fcd10 Remove an unneeded function copy 2023-04-01 23:09:05 -07:00
Koichi Sasada 0112a5b342 `Array#first` and `Array#last` in Ruby 2023-03-23 14:03:12 +09:00
Jean Boussier ca437aeb39 rb_ary_sum: don't enter fast path if initial isn't a native numeric type.
[Bug #19530]

If the initial value isn't one of the special cased types, we directly
jump to the slow path.
2023-03-15 09:12:59 +00:00
Nobuyoshi Nakada 00d6772e40
Adjust styles [ci skip] 2023-03-08 14:02:46 +09:00