summaryrefslogtreecommitdiff
path: root/test/ruby
AgeCommit message (Collapse)Author
2025-08-14Skip an unstable Ractor test for macOS (#14231)Takashi Kokubun
https://github.com/ruby/ruby/actions/runs/16977094733/job/48128667252?pr=14229
2025-08-14Increase timeout for a flaky test (#14228)Takashi Kokubun
https://github.com/ruby/ruby/actions/runs/16974964229/job/48121382131
2025-08-14ZJIT: Look for RUBY_ZJIT_ENABLE in combo build with YJITAlan Wu
2025-08-14Skip an unstable test for s390x and windowsTakashi Kokubun
https://github.com/ruby/ruby/actions/runs/16971197634/job/48108366805?pr=14223 https://github.com/ruby/ruby/actions/runs/16971558478/job/48109641049?pr=14223
2025-08-14Increase timeout for failing testsTakashi Kokubun
https://github.com/ruby/ruby/actions/runs/16969921157/job/48103809963 https://github.com/ruby/ruby/actions/runs/16969655024/job/48102876839
2025-08-14Extract `ruby_api_version_name`Nobuyoshi Nakada
2025-08-13ZJIT: Implement `StringIntern` codegen (#14207)Stan Lo
* ZJIT: Add test and implement display for StringIntern HIR Co-authored-by: Emily Samp <emily.samp@shopify.com> * ZJIT: Implement StringIntern codegen Co-authored-by: Emily Samp <emily.samp@shopify.com> * ZJIT: Fix StringIntern's return type --------- Co-authored-by: Emily Samp <emily.samp@shopify.com>
2025-08-13ZJIT: Fix `ObjToString` rewrite (#14196)Stan Lo
ZJIT: Fix ObjToString rewrite Currently, the rewrite for `ObjToString` always replaces it with a `SendWithoutBlock(to_s)` instruction when the receiver is not a string literal. This is incorrect because it calls `to_s` on the receiver even if it's already a string. This change fixes it by: - Avoiding the `SendWithoutBlock(to_s)` rewrite - Implement codegen for `ObjToString`
2025-08-13imemo_fields: store owner object in RBasic.klassJean Boussier
It is much more convenient than storing the klass, especially when dealing with `object_id` as it allows to update the id2ref table without having to dereference the owner, which may be garbage at that point.
2025-08-13Add link to Ruby options doc in help textPeter Zhu
Adds link to https://docs.ruby-lang.org/en/master/ruby/options_md.html in Ruby help text (-h and --help).
2025-08-12ZJIT: Prepare non-leaf calls for SetGlobal (#14197)Stan Lo
When trace_var is used, setting a global variable can cause exceptions to be raised. We need to prepare for that.
2025-08-12Allow encodings to be autoloaded through transcoding functionsLuke Gruber
Make sure VM lock is not held when calling `load_transcoder_entry`, as that causes deadlock inside ractors. `String#encode` now works inside ractors, among others. Atomic load the rb_encoding_list Without this, wbcheck would sometimes hit a missing write barrier. Co-authored-by: John Hawthorn <john.hawthorn@shopify.com> Hold VM lock when iterating over global_enc_table.names This st_table can be inserted into at runtime when autoloading encodings. minor optimization when calling Encoding.list
2025-08-12set.c: Store `set_table->bins` at the end of `set_table->entries`Jean Boussier
This saves one pointer in `struct set_table`, which would allow `Set` objects to still fit in 80B TypedData slots even if RTypedData goes from 32B to 40B large. The existing set benchmark seem to show this doesn't have a very significant impact. Smaller sets are a bit faster, larger sets a bit slower. It seem consistent over multiple runs, but it's unclear how much of that is just error margin. ``` compare-ruby: ruby 3.5.0dev (2025-08-12T02:14:57Z master 428937a536) +YJIT +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-08-12T07:22:26Z set-entries-bounds da30024fdc) +YJIT +PRISM [arm64-darwin24] warming up........ | |compare-ruby|built-ruby| |:------------------------|-----------:|---------:| |new_0 | 15.459M| 15.823M| | | -| 1.02x| |new_10 | 3.484M| 3.574M| | | -| 1.03x| |new_100 | 546.992k| 564.679k| | | -| 1.03x| |new_1000 | 49.391k| 48.169k| | | 1.03x| -| |aref_0 | 18.643M| 19.350M| | | -| 1.04x| |aref_10 | 5.941M| 6.006M| | | -| 1.01x| |aref_100 | 822.197k| 814.219k| | | 1.01x| -| |aref_1000 | 83.230k| 79.411k| | | 1.05x| -| ```
2025-08-11ZJIT: Implement `concatstrings` insn (#14154)Stan Lo
Co-authored-by: Alexander Momchilov <alexander.momchilov@shopify.com>
2025-08-11ZJIT: Add RubyVM::ZJIT.enabled? (#14159)Takashi Kokubun
Co-authored-by: Max Bernstein <tekknolagi@gmail.com>
2025-08-11Fix return value of setting in GC.configPeter Zhu
gc_config_set returned rb_gc_impl_config_get, but gc_config_get also added the implementation key to the return value. This caused the return value of GC.config to differ depending on whether the optional hash argument is provided or not.
2025-08-11Add NODE IN locationsS-H-GAMELINKS
Add locations to struct `RNode_IN`. memo: ```bash > ruby -e 'case 1; in 2 then 3; end' --parser=prism --dump=parsetree @ ProgramNode (location: (1,0)-(1,24)) +-- locals: [] +-- statements: @ StatementsNode (location: (1,0)-(1,24)) +-- body: (length: 1) +-- @ CaseMatchNode (location: (1,0)-(1,24)) +-- predicate: | @ IntegerNode (location: (1,5)-(1,6)) | +-- IntegerBaseFlags: decimal | +-- value: 1 +-- conditions: (length: 1) | +-- @ InNode (location: (1,8)-(1,19)) | +-- pattern: | | @ IntegerNode (location: (1,11)-(1,12)) | | +-- IntegerBaseFlags: decimal | | +-- value: 2 | +-- statements: | | @ StatementsNode (location: (1,18)-(1,19)) | | +-- body: (length: 1) | | +-- @ IntegerNode (location: (1,18)-(1,19)) | | +-- IntegerBaseFlags: decimal | | +-- value: 3 | +-- in_loc: (1,8)-(1,10) = "in" | +-- then_loc: (1,13)-(1,17) = "then" +-- else_clause: nil +-- case_keyword_loc: (1,0)-(1,4) = "case" +-- end_keyword_loc: (1,21)-(1,24) = "end" ```
2025-08-11Update test_string.rbErim Icel
2025-08-11Optimize `str_casecmp` length check using pointer endErim Icel
2025-08-08Fix id2ref table build when GC in progressJohn Hawthorn
Previously, if GC was in progress when we're initially building the id2ref table, it could see the empty table and then crash when trying to remove ids from it. This commit fixes the bug by only publishing the table after GC is done. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2025-08-08Fix lock ordering issue for rb_ractor_sched_wait() and rb_ractor_sched_wakeup()Luke Gruber
In rb_ractor_sched_wait() (ex: Ractor.receive), we acquire RACTOR_LOCK(cr) and then thread_sched_lock(cur_th). However, on wakeup if we're a dnt, in thread_sched_wait_running_turn() we acquire thread_sched_lock(cur_th) after condvar wakeup and then RACTOR_LOCK(cr). This lock inversion can cause a deadlock with rb_ractor_wakeup_all() (ex: port.send(obj)), where we acquire RACTOR_LOCK(other_r) and then thread_sched_lock(other_th). So, the error happens: nt 1: Ractor.receive rb_ractor_sched_wait() after condvar wakeup in thread_sched_wait_running_turn(): - thread_sched_lock(cur_th) (condvar) # acquires lock - rb_ractor_lock_self(cr) # deadlock here: tries to acquire, HANGS nt 2: port.send ractor_wakeup_all() - RACTOR_LOCK(port_r) # acquires lock - thread_sched_lock # tries to acquire, HANGS To fix it, we now unlock the thread_sched_lock before acquiring the ractor_lock in rb_ractor_sched_wait(). Script that reproduces issue: ```ruby require "async" class RactorWrapper def initialize @ractor = Ractor.new do Ractor.recv # Ractor doesn't start until explicitly told to # Do some calculations fib = ->(x) { x < 2 ? 1 : fib.call(x - 1) + fib.call(x - 2) } fib.call(20) end end def take_async @ractor.send(nil) Thread.new { @ractor.value }.value end end Async do |task| 10_000.times do |i| task.async do RactorWrapper.new.take_async puts i end end end exit 0 ``` Fixes [Bug #21398] Co-authored-by: John Hawthorn <john.hawthorn@shopify.com>
2025-08-08ZJIT: Avoid compiling and direct sends to forwardable ISEQsAlan Wu
These `...` ISEQs have a special calling convention in the interpreter and our stubs and JIT calling convention don't deal well. Reject for now. Debugged with help from `@tekknolagi` and `tool/zjit_bisect.rb`. Merely avoiding direct sends is enough to pass the attached test, but also avoid compiling ISEQs with `...` parameter to limit exposure for now. `SendWithoutBlock`, which does dynamic dispatch using interpreter code, seems to handle calling into forwardable ISEQs correctly, so they are fine -- we can't predict where these dynamic sends land anyways.
2025-08-08ZJIT: Fix "memory operand with non-register base" (#14153)Takashi Kokubun
2025-08-07ZJIT: Implement `defined?` codegen for non-yield calls (#14101)Stan Lo
2025-08-07ZJIT: Optimize class guards by directly reading klass field (#14136)Stan Lo
Replace `rb_yarv_class_of` call with: - a constant check for special constants (nil, fixnums, symbols, etc) - a check for false - direct memory read at offset 8 for regular heap objects for the class check
2025-08-06ZJIT: Inline attr_reader/attr_accessor (#14126)Max Bernstein
We can rewrite SendWithoutBlock to GetIvar.
2025-08-06ZJIT: Implement SingleRactorMode invalidation (#14121)Stan Lo
* ZJIT: Implement SingleRactorMode invalidation * ZJIT: Add macro for compiling jumps * ZJIT: Fix typo in comment * YJIT: Fix typo in comment * ZJIT: Avoid using unexported types in zjit.h `enum ruby_vminsn_type` is declared in `insns.inc` and is not exported. Using it in `zjit.h` would cause build errors when the file including it doesn't include `insns.inc`.
2025-08-06ZJIT: Fix "immediate value too large" on cmp for x86_64 (#14125)Takashi Kokubun
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2025-08-07Add MODULE NODE locationsS-H-GAMELINKS
Add `keyword_module` amd `keyword_end` locations to struct `RNode_MODULE`. memo: ``` >ruby --dump=parsetree -e 'module A end' @ ProgramNode (location: (1,0)-(1,12)) +-- locals: [] +-- statements: @ StatementsNode (location: (1,0)-(1,12)) +-- body: (length: 1) +-- @ ModuleNode (location: (1,0)-(1,12)) +-- locals: [] +-- module_keyword_loc: (1,0)-(1,6) = "module" +-- constant_path: | @ ConstantReadNode (location: (1,7)-(1,8)) | +-- name: :A +-- body: nil +-- end_keyword_loc: (1,9)-(1,12) = "end" +-- name: :A ```
2025-08-06Struct: keep direct reference to IMEMO/fields when space allowsJean Boussier
It's not rare for structs to have additional ivars, hence are one of the most common, if not the most common type in the `gen_fields_tbl`. This can cause Ractor contention, but even in single ractor mode means having to do a hash lookup to access the ivars, and increase GC work. Instead, unless the struct is perfectly right sized, we can store a reference to the associated IMEMO/fields object right after the last struct member. ``` compare-ruby: ruby 3.5.0dev (2025-08-06T12:50:36Z struct-ivar-fields-2 9a30d141a1) +PRISM [arm64-darwin24] built-ruby: ruby 3.5.0dev (2025-08-06T12:57:59Z struct-ivar-fields-2 2ff3ec237f) +PRISM [arm64-darwin24] warming up..... | |compare-ruby|built-ruby| |:---------------------|-----------:|---------:| |member_reader | 590.317k| 579.246k| | | 1.02x| -| |member_writer | 543.963k| 527.104k| | | 1.03x| -| |member_reader_method | 213.540k| 213.004k| | | 1.00x| -| |member_writer_method | 192.657k| 191.491k| | | 1.01x| -| |ivar_reader | 403.993k| 569.915k| | | -| 1.41x| ``` Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2025-08-01ZJIT: Enable IncrCounter for arm64 (#14086)Takashi Kokubun
2025-08-01variable.c: Fix `rb_ivar_foreach` to not yield `object_id` of complex objectsJean Boussier
Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
2025-08-01Fix rb_shape_transition_object_id transition to TOO_COMPLEXJean Boussier
If `get_next_shape_internal` fail to return a shape, we must transitiont to a complex shape. `shape_transition_object_id` mistakenly didn't. Co-Authored-By: Peter Zhu <peter@peterzhu.ca>
2025-07-31ZJIT: A64: Fix splitting for large memory displacementsAlan Wu
On the ruby side, this fixes a crash for methods with 39 or more parameters. We used to miscomp those entry points due to Insn::Lea picking ADDS which cannot reference SP: # set method params: 40 mov x0, #0xfee8 movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 adds x0, xzr, x0 Have Lea work for all i32 displacements and avoid involving the split pass. Previously, direct use of Insn::Lea directly from the user (as opposed to generated by the split pass for some memory operations) wasn't split, so being able to handle the whole range in arm64_emit() was implicitly required. Also, not going through split reduces register pressure.
2025-07-30ZJIT: Prepare for sharing JIT hooks with ZJIT (#14044)Takashi Kokubun
2025-07-29Improve performance of bignum[beg, len] (#14007)tomoya ishida
Implement rb_big_aref2. Taking a small slice from large bignum was slow in rb_int_aref2.
2025-07-29[Bug #21513] Raise on converting endless range to setviralpraxis
ref: https://bugs.ruby-lang.org/issues/21513 Before this patch, trying to convert endless range (e.g. `(1..)`) to set (using `to_set`) would hang
2025-07-28ZJIT: Support invalidating constant patch points (#13998)Stan Lo
2025-07-28ZJIT: Keep a frame pointer and use it for memory paramsAlan Wu
Previously, ZJIT miscompiled the following because of native SP interference. def a(n1,n2,n3,n4,n5,n6,n7,n8) = [n8] a(0,0,0,0,0,0,0, :ok) Commented problematic disassembly: ; call rb_ary_new_capa mov x0, #1 mov x16, #0x1278 movk x16, #0x4bc, lsl #16 movk x16, #1, lsl #32 blr x16 ; call rb_ary_push mov x1, x0 str x1, [sp, #-0x10]! ; c_push() from alloc_regs() mov x0, x1 ; arg0, the array ldur x1, [sp] ; meant to be arg1=n8, but sp just moved! mov x16, #0x3968 movk x16, #0x4bc, lsl #16 movk x16, #1, lsl #32 blr x16 Since the frame pointer stays constant in the body of the function, static offsets based on it don't run the risk of being invalidated by SP movements. Pass the registers to preserve through Insn::FrameSetup. This allows ARM to use STP and waste no gaps between EC, SP, and CFP. x86 now preserves and restores RBP since we use it as the frame pointer. Since all arches now have a frame pointer, remove offset based SP movement in the epilogue and restore registers using the frame pointer.
2025-07-28Update comments for pack/unpack tests [ci skip]Nobuyoshi Nakada
More comprehensive pack/unpack tests are in test_pack.rb.
2025-07-27Add test for `String#byteslice` with multibyte charactersErim Icel
2025-07-25Add NODE_DEFINED tests for cases with parentheses to test_ast.rbydah
2025-07-24Add DEFINED NODE locationsS-H-GAMELINKS
Add keyword_defined locations to struct RNode_DEFINED
2025-07-23ZJIT: Fix clobbering register for `self` in gen_entry_params()Alan Wu
Previously, for 8+ params we wound up clobbering the self param when putting the last param in memory in the JIT entry point: # ZJIT entry point: a@../test.rb:5 <snip> ldur x0, [x19, #0x18] # set method params: 8 ldur x1, [x21, #-0x58] ldur x2, [x21, #-0x50] ldur x3, [x21, #-0x48] ldur x4, [x21, #-0x40] ldur x5, [x21, #-0x38] ldur x11, [x21, #-0x30] ldur x12, [x21, #-0x28] ldur x0, [x21, #-0x20] stur x0, [sp, #-0x20] bl #0x11e17018c Doing the memcpys for parameters in memory first avoids this clobbering. # set method params: 8 ldur x0, [x21, #-0x20] stur x0, [sp, #-0x20] ldur x12, [x21, #-0x28] ldur x11, [x21, #-0x30] ldur x5, [x21, #-0x38] ldur x4, [x21, #-0x40] ldur x3, [x21, #-0x48] ldur x2, [x21, #-0x50] ldur x1, [x21, #-0x58] ldur x0, [x19, #0x18]
2025-07-21ZJIT: Load return value before frame teardownAlan Wu
Or else the following returns garbage since it loads after moving SP. Prior bad disassembly: def a(n1,n2,n3,n4,n5,n6,n7,n8) = n8 a(1,1,1,1,1,1,1,0) # Block: bb0(v0, v1, v2, v3, v4, v5, v6, v7, v8) stp x29, x30, [sp, #-0x10]! mov x29, sp # bump C stack pointer sub sp, sp, #0x10 # Insn: v10 Return v8 # pop stack frame adds x19, x19, #0x38 stur x19, [x20, #0x10] # restore C stack pointer add sp, sp, #0x10 mov sp, x29 ldp x29, x30, [sp], #0x10 ldur x0, [sp] ret
2025-07-18ZJIT: Support invalidating on method redefinition (#13875)Stan Lo
ZJIT: Support invalidating method redefinition This commit adds support for the MethodRedefined invariant to be invalidated when a method is redefined. Changes: - Added CME pointer to the MethodRedefined invariant in HIR - Updated all places where MethodRedefined invariants are created to include the CME pointer - Added handling for MethodRedefined invariants in gen_patch_point to call track_cme_assumption, which registers the patch point for invalidation when rb_zjit_cme_invalidate is called This ensures that when a method is redefined, all JIT code that depends on that method will be properly invalidated.
2025-07-18Revert "[Bug #21256] Fix `it` parameter when splatting and `define_method` ↵Yusuke Endoh
is…" This reverts commit 265059603c3aa6a13f90096c71b32046a17938f3.
2025-07-17Fix compilation for forwarding params in PrismAaron Patterson
[Bug #21326]
2025-07-17[Bug #21256] Fix `it` parameter when splatting and `define_method` is usedEarlopain
It was failing to set the leads, like numblocks do, causing the result to be wrapped in an array
2025-07-17ZJIT: Give up JIT-to-JIT calls for 6+ args (#13939)Takashi Kokubun