summaryrefslogtreecommitdiff
path: root/test/ruby
AgeCommit message (Collapse)Author
2025-05-13[Bug #21331] Prohibit modification during stlike loopNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/13317
2025-05-13Make `waiting_fd` behaviour per-IO. (#13127)Samuel Williams
- `rb_thread_fd_close` is deprecated and now a no-op. - IO operations (including close) no longer take a vm-wide lock. Notes: Merged-By: ioquatix <[email protected]>
2025-05-13variable.c: Refactor rb_obj_field_* to take shape_id_tJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13314
2025-05-12Remove respond_to check from Class#bind_callJohn Hawthorn
Notes: Merged: https://github.com/ruby/ruby/pull/13116
2025-05-12test_object_id.rb: use better randomnessJean Boussier
When the test is repeated 20 or more times in the same process it's not that unlikely for `rand(100_000)` to return the same thing twice, causing `TestObjectIdTooComplexClass` to fail. ``` 1) Failure: TestObjectIdTooComplexClass#test_dup_with_id_and_ivar [/tmp/ruby/src/trunk-repeat20-asserts/test/ruby/test_object_id.rb:172]: Expected #<struct RubyVM::Shape id=6783, parent_id=6774, edge_name=:@___26417, next_field_index=2, heap_index=0, type=1, capacity=7> to be too_complex?. ```
2025-05-11Allow T_CLASS and generic types to be too_complexJean Boussier
The intial complex shape implementation never allowed objects other than T_OBJECT to become too complex, unless we run out of shapes. I don't see any reason to prevent that. Ref: https://github.com/ruby/ruby/pull/6931 Notes: Merged: https://github.com/ruby/ruby/pull/13301
2025-05-11Skip mmtk/i686 tests for a whileSatoshi Tagomori
2025-05-11avoid calling ZALLOC after NEWOBJ_OF for RClass: need to return RClass not ↵Satoshi Tagomori
promoted
2025-05-11namespace on readSatoshi Tagomori
2025-05-09Fix warnings in tests for ObjectSpace._id2refPeter Zhu
There's a lot of warnings when running test_objectspace.rb because of ObjectSpace._id2ref. For example: test_objectspace.rb:19: warning: ObjectSpace._id2ref is deprecated Notes: Merged: https://github.com/ruby/ruby/pull/13293
2025-05-09ZJIT: Fix a splitting condition for LHSTakashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/13279
2025-05-08Fix `remove_instance_variable` on complex objectsJean Boussier
Introduced in: https://github.com/ruby/ruby/pull/13159 Now that there is no longer a unique TOO_COMPLEX shape with no children, checking `shape->type == TOO_COMPLEX` is incorrect. Notes: Merged: https://github.com/ruby/ruby/pull/13280
2025-05-08Make test/ruby/test_env.rb#test_delete_if_in_ractor easier to debugJean Boussier
2025-05-08Move `object_id` in object fields.Jean Boussier
And get rid of the `obj_to_id_tbl` It's no longer needed, the `object_id` is now stored inline in the object alongside instance variables. We still need the inverse table in case `_id2ref` is invoked, but we lazily build it by walking the heap if that happens. The `object_id` concern is also no longer a GC implementation concern, but a generic implementation. Co-Authored-By: Matt Valentine-House <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-08Rename `ivptr` -> `fields`, `next_iv_index` -> `next_field_index`Jean Boussier
Ivars will longer be the only thing stored inline via shapes, so keeping the `iv_index` and `ivptr` names would be confusing. Instance variables won't be the only thing stored inline via shapes, so keeping the `ivptr` name would be confusing. `field` encompass anything that can be stored in a VALUE array. Similarly, `gen_ivtbl` becomes `gen_fields_tbl`. Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-04Handle mutating of array passed to Set.new during iterationJeremy Evans
This avoids a heap-use-after-free. Fixes [Bug #21306] Notes: Merged: https://github.com/ruby/ruby/pull/13253
2025-05-04Handle mutation of array being merged into setJeremy Evans
Check length of array during every iteration, as a #hash method could truncate the array, resulting in heap-use-after-free. Fixes [Bug #21305] Notes: Merged: https://github.com/ruby/ruby/pull/13253
2025-05-01Omit tests using ISeq#to_binary under coverage measurementYusuke Endoh
... because ISeq#to_binary does not work Notes: Merged: https://github.com/ruby/ruby/pull/13225
2025-04-29test/ruby/test_set.rb: mmtk doesn't have GC.compactJean Boussier
2025-04-29opt_new needs to happen after safe navigationAaron Patterson
If safe navigation instructions happen first, we get a stack inconsistency error. Notes: Merged: https://github.com/ruby/ruby/pull/13205
2025-04-29Don't call hash tombstone compaction from GC compactionAaron Patterson
Tombstone removal may possibly require allocation, and we're not allowed to allocate during GC. This commit also renames `set_compact` to `set_update_references` to differentiate tombstone removal compaction with GC object compaction. Co-Authored-By: Max Bernstein <[email protected]> Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13206
2025-04-29ZJIT: Disable ZJIT instructions when USE_ZJIT is 0 (#13199)Takashi Kokubun
* ZJIT: Disable ZJIT instructions when USE_ZJIT is 0 * Test the order of ZJIT instructions * Add more jobs that disable JITs * Show instruction names in the message Notes: Merged-By: k0kubun <[email protected]>
2025-04-29Add testsMax Bernstein
Notes: Merged: https://github.com/ruby/ruby/pull/13198
2025-04-28Support Marshal.{dump,load} for core SetJeremy Evans
This was missed when adding core Set, because it's handled implicitly for T_OBJECT. Keep marshal compatibility between core Set and stdlib Set, so you can unmarshal core Set with stdlib Set and vice versa. Co-authored-by: Nobuyoshi Nakada <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13185 Merged-By: jeremyevans <[email protected]>
2025-04-28Fix nondeterministic failure in test_latest_gc_info_weak_references_countJeremy Evans
Clear the ary variable before setting it to nil. Otherwise, if the previous ary value was somewhere on the stack, all references in it would be considered live, and the wmap size would be 10000.
2025-04-26Implement Set as a core classJeremy Evans
Set has been an autoloaded standard library since Ruby 3.2. The standard library Set is less efficient than it could be, as it uses Hash for storage, which stores unnecessary values for each key. Implementation details: * Core Set uses a modified version of `st_table`, named `set_table`. than `s/st_/set_/`, the main difference is that the stored records do not have values, making them 1/3 smaller. `st_table_entry` stores `hash`, `key`, and `record` (value), while `set_table_entry` only stores `hash` and `key`. This results in large sets using ~33% less memory compared to stdlib Set. For small sets, core Set uses 12% more memory (160 byte object slot and 64 malloc bytes, while stdlib set uses 40 for Set and 160 for Hash). More memory is used because the set_table is embedded and 72 bytes in the object slot are currently wasted. Hopefully we can make this more efficient and have it stored in an 80 byte object slot in the future. * All methods are implemented as cfuncs, except the pretty_print methods, which were moved to `lib/pp.rb` (which is where the pretty_print methods for other core classes are defined). As is typical for core classes, internal calls call C functions and not Ruby methods. For example, to check if something is a Set, `rb_obj_is_kind_of` is used, instead of calling `is_a?(Set)` on the related object. * Almost all methods use the same algorithm that the pure-Ruby implementation used. The exception is when calling `Set#divide` with a block with 2-arity. The pure-Ruby method used tsort to implement this. I developed an algorithm that only allocates a single intermediate hash and does not need tsort. * The `flatten_merge` protected method is no longer necessary, so it is not implemented (it could be). * Similar to Hash/Array, subclasses of Set are no longer reflected in `inspect` output. * RDoc from stdlib Set was moved to core Set, with minor updates. This includes a comprehensive benchmark suite for all public Set methods. As you would expect, the native version is faster in the vast majority of cases, and multiple times faster in many cases. There are a few cases where it is significantly slower: * Set.new with no arguments (~1.6x) * Set#compare_by_identity for small sets (~1.3x) * Set#clone for small sets (~1.5x) * Set#dup for small sets (~1.7x) These are slower as Set does not currently use the AR table optimization that Hash does, so a new set_table is initialized for each call. I'm not sure it's worth the complexity to have an AR table-like optimization for small sets (for hashes it makes sense, as small hashes are used everywhere in Ruby). The rbs and repl_type_completor bundled gems will need updates to support core Set. The pull request marks them as allowed failures. This passes all set tests with no changes. The following specs needed modification: * Modifying frozen set error message (changed for the better) * `Set#divide` when passed a 2-arity block no longer yields the same object as both the first and second argument (this seems like an issue with the previous implementation). * Set-like objects that override `is_a?` such that `is_a?(Set)` return `true` are no longer treated as Set instances. * `Set.allocate.hash` is no longer the same as `nil.hash` * `Set#join` no longer calls `Set#to_a` (it calls the underlying C function). * `Set#flatten_merge` protected method is not implemented. Previously, `set.rb` added a `SortedSet` autoload, which loads `set/sorted_set.rb`. This replaces the `Set` autoload in `prelude.rb` with a `SortedSet` autoload, but I recommend removing it and `set/sorted_set.rb`. This moves `test/set/test_set.rb` to `test/ruby/test_set.rb`, reflecting that switch to a core class. This does not move the spec files, as I'm not sure how they should be handled. Internally, this uses the st_* types and functions as much as possible, and only adds set_* types and functions as needed. The underlying set_table implementation is stored in st.c, but there is no public C-API for it, nor is there one planned, in order to keep the ability to change the internals going forward. For internal uses of st_table with Qtrue values, those can probably be replaced with set_table. To do that, include internal/set_table.h. To handle symbol visibility (rb_ prefix), internal/set_table.h uses the same macro approach that include/ruby/st.h uses. The Set class (rb_cSet) and all methods are defined in set.c. There isn't currently a C-API for the Set class, though C-API functions can be added as needed going forward. Implements [Feature #21216] Co-authored-by: Jean Boussier <[email protected]> Co-authored-by: Oliver Nutter <[email protected]>
2025-04-25Deopt if iseq trace events are enabledAaron Patterson
2025-04-25Inline Class#new.Aaron Patterson
This commit inlines instructions for Class#new. To make this work, we added a new YARV instructions, `opt_new`. `opt_new` checks whether or not the `new` method is the default allocator method. If it is, it allocates the object, and pushes the instance on the stack. If not, the instruction jumps to the "slow path" method call instructions. Old instructions: ``` > ruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0004 leave ``` New instructions: ``` > ./miniruby --dump=insns -e'Object.new' == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,10)> 0000 opt_getconstant_path <ic:0 Object> ( 1)[Li] 0002 putnil 0003 swap 0004 opt_new <calldata!mid:new, argc:0, ARGS_SIMPLE>, 11 0007 opt_send_without_block <calldata!mid:initialize, argc:0, FCALL|ARGS_SIMPLE> 0009 jump 14 0011 opt_send_without_block <calldata!mid:new, argc:0, ARGS_SIMPLE> 0013 swap 0014 pop 0015 leave ``` This commit speeds up basic object allocation (`Foo.new`) by 60%, but classes that take keyword parameters see an even bigger benefit because no hash is allocated when instantiating the object (3x to 6x faster). Here is an example that uses `Hash.new(capacity: 0)`: ``` > hyperfine "ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" "./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end'" Benchmark 1: ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 1.082 s ± 0.004 s [User: 1.074 s, System: 0.008 s] Range (min … max): 1.076 s … 1.088 s 10 runs Benchmark 2: ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' Time (mean ± σ): 627.9 ms ± 3.5 ms [User: 622.7 ms, System: 4.8 ms] Range (min … max): 622.7 ms … 633.2 ms 10 runs Summary ./ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ran 1.72 ± 0.01 times faster than ruby --disable-gems -e'i = 0; while i < 10_000_000; Hash.new(capacity: 0); i += 1; end' ``` This commit changes the backtrace for `initialize`: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb class Foo def initialize puts caller end end def hello Foo.new end hello aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] test.rb:8:in 'Class#new' test.rb:8:in 'Object#hello' test.rb:11:in '<main>' aaron@tc ~/g/ruby (inline-new)> ./miniruby -v test.rb ruby 3.5.0dev (2025-03-28T23:59:40Z inline-new c4157884e4) +PRISM [arm64-darwin24] test.rb:8:in 'Object#hello' test.rb:11:in '<main>' ``` It also increases memory usage for calls to `new` by 122 bytes: ``` aaron@tc ~/g/ruby (inline-new)> cat test.rb require "objspace" class Foo def initialize puts caller end end def hello Foo.new end puts ObjectSpace.memsize_of(RubyVM::InstructionSequence.of(method(:hello))) aaron@tc ~/g/ruby (inline-new)> make runruby RUBY_ON_BUG='gdb -x ./.gdbinit -p' ./miniruby -I./lib -I. -I.ext/common ./tool/runruby.rb --extout=.ext -- --disable-gems ./test.rb 656 aaron@tc ~/g/ruby (inline-new)> ruby -v test.rb ruby 3.4.2 (2025-02-15 revision d2930f8e7a) +PRISM [arm64-darwin24] 544 ``` Thanks to @ko1 for coming up with this idea! Co-Authored-By: John Hawthorn <[email protected]>
2025-04-24Fix a flaky test by making sure that a test thread stopsYusuke Endoh
``` 1) Failure: TestThread#test_join_argument_conversion [D:/a/ruby/ruby/src/test/ruby/test_thread.rb:249]: Expected nil (oid=4) to be the same as #<TestThread::Thread:0x000001e9e13bbc18 D:/a/ruby/ruby/src/test/ruby/test_thread.rb:245 run> (oid=3856). ``` https://github.com/ruby/ruby/actions/runs/14636019219/job/41067199813?pr=13169 Notes: Merged: https://github.com/ruby/ruby/pull/13170
2025-04-18Add codegen for NewArray instruction (https://github.com/Shopify/zjit/pull/110)Aiden Fox Ivey
* Show failing test * Add second test case * Add empty NewArray setup * Update opt_tests and fix NewArray instantiation * Add code generation for NewArray * Add NewArray ordering test Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Implement JIT-to-JIT calls (https://github.com/Shopify/zjit/pull/109)Takashi Kokubun
* Implement JIT-to-JIT calls * Use a closer dummy address for Arm64 * Revert an obsoleted change * Revert a few more obsoleted changes * Fix outdated comments * Explain PosMarkers for CCall * s/JIT code/machine code/ * Get rid of ParallelMov Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add codegen support for ArrayDupAiden Fox Ivey
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Strength reduce to `CCall` for sends landing in simple C methodsAlan Wu
A new optimization pass. Also: - Printing for `Insn::CCall` - Wrap `ID` and add convenience method for printing, replacing calls to rb_id2name() Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Split LHS of CMP if it's an immediate (https://github.com/Shopify/zjit/pull/94)Takashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Fix opt_neq HIR codegenMax Bernstein
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Compile Param into VReg and ParallelMov ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/87) Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add recursive factorial and fibonacci functions to test_zjit.rbMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Compile IfFalse, IfTrue, and Jump instructions ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/72) * Compile IfFalse instruction * Add a TODO comment * Rename *s_len to num_*s * Run only gen_param() against block.params * Add a few more tests * Wrap label indexes with Label * Compile blocks in reverse post-order * Simplify a nested test * s/get_block/block/ * Return a number instead of an iterator * Clarify the allocator uses disjoint sets of registers * Use Display for Block and Insn * Compile IfTrue and Jump * Avoid resolving Param instructions * Always compile Insn::Param as basic block arguments * Remove an obsoleted variable * Change it back to use find * Use find for params too * Use Display more * Add more tests * nested if * if after if * if elsif else * loop after loop * nested loops * if in loop * loop in if Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Implement dynamic dispatch for opt_send_without_block ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/63) * Implement dynamic dispatch for opt_send_without_block * Rename stack methods * Fix typos * More clarification on gen_save_sp() * Update a comment * Update a comment about spills * Rename name to method_name * Test no-arg and 2-arg method calls Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Implement codegen for Test insn (https://github.com/Shopify/zjit/pull/57)Maxime Chevalier-Boisvert
* Implement codegen for Test insn * Update zjit/src/codegen.rs Co-authored-by: Alan Wu <[email protected]> --------- Co-authored-by: Alan Wu <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Reorder two tests, update commentMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add a skipped test case for opt_mult overflowTakashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Implement all basic Fixnum instructions ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/50) * Implement all basic Fixnum instructions * Use opnd! macro for other instructions as well Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Compile FixnumLt (https://github.com/Shopify/zjit/pull/48)Max Bernstein
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add comments to testsMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add commented out if-else test to test_zjit.rbMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add while loop test to test_zjit.rbMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Add small test for setlocalMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Set a return value before popping registers ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/41) Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Implement Insn::FixnumSub (https://github.com/Shopify/zjit/pull/42)Takashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/13131