Commit Graph

18273 Commits

Author SHA1 Message Date
Yukihiro "Matz" Matsumoto c68e97bf3c NEWS.md: add commit SHA for OP_RETTRUE/OP_RETFALSE entry
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto 7f13422f2f vm: add OP_RETTRUE and OP_RETFALSE for returning boolean literals
Add single-byte opcodes for returning true/false directly, completing
the set of literal return opcodes (RETSELF, RETNIL, RETTRUE, RETFALSE).

Codegen applies peephole optimization to fuse LOADTRUE/LOADFALSE + RETURN.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:27 +09:00
Yukihiro "Matz" Matsumoto a1567be5da ops.h: rename OP_LOADT/OP_LOADF to OP_LOADTRUE/OP_LOADFALSE
Rename boolean load opcodes for consistency with LOADNIL/LOADSELF.
Backward compatibility aliases are provided in opcode.h.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 60d981dbc8 NEWS.md: add commit SHA for OP_BLKCALL and OP_RETNIL entries
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 0b1af858e2 vm: add OP_RETNIL for returning nil directly
Add a new opcode that returns nil without requiring LOADNIL + RETURN.
This avoids loading nil into a register by setting the return value (v)
directly. The implementation uses a separate label (L_RETURN_NIL) to
bypass v = regs[a], preserving self in regs[0] for ensure blocks.

Codegen applies peephole optimization to fuse LOADNIL + RETURN -> RETNIL.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto a6bf08847a vm.c: refactor OP_TDEF/OP_SDEF to share method definition code
Both opcodes had nearly identical code for creating procs and
defining methods. Now they share a common L_DEF_METHOD label,
reducing code duplication by ~10 lines.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 13bc858dff mrblib: use yield instead of block.call for iteration methods
Replace block.call(x) with yield x in core iteration methods to take
advantage of the new OP_BLKCALL optimization. This improves Integer#times
by 13% and Array#each by 7%.

Methods updated:
- Integer#times, Integer#upto, Integer#downto
- Array#each, Array#each_index

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 52bee49ad2 vm: add OP_BLKCALL for direct block call without method dispatch
Bypass method dispatch when calling blocks via yield. The new OP_BLKCALL
instruction directly invokes the proc without looking up Proc#call,
resulting in 13-17% faster yield performance.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:26 +09:00
Yukihiro "Matz" Matsumoto 44f6cf4b4e vm.c: add branch prediction hints for hot paths
Add mrb_likely/mrb_unlikely hints to help CPU branch predictor:
- stack overflow checks (mrb_unlikely)
- exception checks (mrb_unlikely)
- integer type checks in arithmetic (mrb_likely)
- method dispatch fast path (mrb_likely)
- argument validation errors (mrb_unlikely)
- target class checks in method definition (mrb_unlikely)

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 7e3447b29a NEWS.md: document new VM super-instructions
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 7f2e6c190b class.c: make singleton methods always public
Singleton methods should always be public regardless of the
enclosing scope's visibility setting.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 48a88ed79b vm: add OP_TDEF/OP_SDEF for fused method definition
TDEF fuses TCLASS+METHOD+DEF for normal method definitions.
SDEF fuses SCLASS+METHOD+DEF for singleton method definitions.
Saves 4 bytes per method definition (8 bytes -> 4 bytes).
Falls back to unfused instructions if irep index exceeds 255.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 51e8da6614 vm: add OP_GETIDX0 for fast array[0] access
Fuses MOVE+LOADI_0+GETIDX pattern into single instruction.
Saves 4 bytes per arr[0] access (7 bytes -> 3 bytes).

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 5475ea573a vm: add OP_ADDILV/OP_SUBILV for local variable increment
fuse MOVE+ADDI+MOVE and MOVE+SUBI+MOVE patterns into single instructions.
ADDILV/SUBILV add/subtract an immediate to a local variable in-place.
BBB format: a=local, b=working space for method call, c=immediate.

saves 5 bytes per instance (9->4 bytes), 40 occurrences in stdlib.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto 724a2e2638 vm: add OP_RETSELF instruction for returning self
Fuse LOADSELF + RETURN sequence into single RETSELF instruction.
Saves 2 bytes per occurrence (3 bytes -> 1 byte).

Found 25 occurrences in mrblib, saving 50 bytes total.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:25 +09:00
Yukihiro "Matz" Matsumoto dece8cb343 vm: fuse JMPIF and MATCHERR into conditional MATCHERR
Change OP_MATCHERR from Z format (unconditional) to B format
(conditional on register). This allows fusing JMPIF + MATCHERR
sequence into a single MATCHERR instruction for simple patterns.

Before: JMPIF R2 target (4 bytes) + MATCHERR (1 byte) = 5 bytes
After:  MATCHERR R2 (2 bytes)

Saves 3 bytes per pattern match with raise_on_fail.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 2fa99a73c2 vm: add OP_MATCHERR instruction for pattern matching errors
Replace 4-instruction sequence (GETCONST + STRING + SEND + RAISEIF)
with single OP_MATCHERR instruction that raises NoMatchingPatternError
with "pattern not matched" message.

Bump RITE binary format version from 0300 to 0400 due to opcode
number shift.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 8c99e3dd29 AUTHORS: update entries [ci skip] 2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto a07d9fb62c vm.c: optimize OP_GETIDX with branch hints and reduced checks
- Add mrb_likely/mrb_unlikely macros to common.h for branch prediction
- Optimize OP_GETIDX array fast path:
  - Cache RArray pointer to avoid repeated RARRAY() calls
  - Single ARY_EMBED_P check instead of two (via RARRAY_LEN + RARRAY_PTR)
  - Use unsigned comparison for bounds check
  - Add branch prediction hints for common cases
- Convert switch statement to if-else chain for better branch prediction

Benchmark shows ~3% improvement for array read operations.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto ed84649fbd benchmark: add VM optimization benchmarks
Add comprehensive benchmarks for measuring VM performance:
- vm_optimization_bench.rb: Ruby-level benchmarks covering dispatch,
  arithmetic, method calls, array/hash access, loops, and recursion
- vm_dispatch_bench.c: C-level micro-benchmarks for precise measurement

These benchmarks are designed to measure the effect of potential VM
optimizations such as tail-call threading, register variables,
fused opcodes, and inline caching.

Usage:
  # Ruby benchmark
  ./build/host/bin/mruby benchmark/vm_optimization_bench.rb

  # C benchmark
  cc -O2 -I include -I build/host/include \
     benchmark/vm_dispatch_bench.c \
     build/host/lib/libmruby.a -lm -o vm_dispatch_bench
  ./vm_dispatch_bench

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-27 14:57:24 +09:00
Yukihiro "Matz" Matsumoto 92010e9fe4 Merge pull request #6709 from dearblue/mrb_ensure 2026-01-27 13:49:48 +09:00
Yukihiro "Matz" Matsumoto d690a49112 Merge pull request #6711 from Asmod4n/patch-4 2026-01-27 13:47:13 +09:00
Hendrik c836b096af Add error handling for fdset size limit
This should fix it for Windows.
2026-01-25 16:04:23 +01:00
Hendrik 8769f37868 Improve error handling for file descriptor range 2026-01-25 15:46:56 +01:00
Hendrik 44831711fc Fix out of bounds read and write in IO.select
Added error handling for file descriptors larger than FD_SETSIZE in mrb_hal_io_fdset_set and mrb_hal_io_fdset_isset functions, for posix hal.

I actually don't know how to fix this on windows, or if it needs fixing.
2026-01-25 15:42:17 +01:00
dearblue 5bc08befae Use the specialized MRB_ENSURE() instead of mrb_protect_error() 2026-01-24 11:34:02 +09:00
dearblue da75e4b049 Use MRB_ENSURE() instead of mrb_ensure()
The purpose is to avoid using the `MRB_TT_CPTR` object.
The reasons are as follows:
  - The `MRB_WORD_BOXING` setting involves object creation.
  - If object creation fails, the `ary_set_t` data leaks memory.
2026-01-24 11:32:57 +09:00
dearblue 3ac682b2de Add the MRB_ENSURE() macro 2026-01-24 11:31:32 +09:00
Yukihiro "Matz" Matsumoto c25b562256 Merge pull request #6706 from Asmod4n/patch-4 2026-01-20 13:28:25 +09:00
Yukihiro "Matz" Matsumoto aadd23cc70 Merge pull request #6699 from hasumikin/fix/mruby-task 2026-01-20 12:37:29 +09:00
Yukihiro "Matz" Matsumoto 26c38bd8ba Merge pull request #6708 from dearblue/private-methods 2026-01-19 18:08:28 +09:00
dearblue 8a8e2ddad9 Define the initialize_copy and respond_to_missing? methods as private
It is preferable for them to be private even when defined via `mrb_define_method()`.
This mimics CRuby's behavior.

ref: https://github.com/ruby/ruby/blob/v4.0.0/vm_method.c#L1329-L1336
2026-01-18 20:56:51 +09:00
Hendrik 3d5bb929ab Refactor task class to use symbol IDs 2026-01-17 19:31:24 +01:00
Yukihiro "Matz" Matsumoto 3a1b771cc6 class.h: add mrb_class_outer() API to get the outer class/module
expose the previously internal outer_class() function as a public API
for mrbgems to retrieve the enclosing class/module of a given class.
closes #6705.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-17 14:17:29 +09:00
Yukihiro "Matz" Matsumoto 0ba48a2a5b mruby-set: fix memory leak in khash rebuild using mrb_protect_error()
wrap hash and eql callbacks with mrb_protect_error() to catch exceptions
during khash table rebuild. when an exception occurs (e.g., SystemStackError
from infinite recursion), return a safe default value and store the exception
in mrb->exc for later processing. this prevents memory leaks from orphaned
allocations when exceptions propagate through khash rebuild.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-17 13:00:45 +09:00
Yukihiro "Matz" Matsumoto 27c9356f99 Revert "mruby-set: fix memory leak caused by recursive hash computation"
This reverts commit c9e3af60e1.
2026-01-17 12:55:50 +09:00
Yukihiro "Matz" Matsumoto a9f02eb6a4 bigint.c: add inline to limb_popcount()
Small helper called in a loop from mpz_popcount().

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-17 11:13:59 +09:00
Yukihiro "Matz" Matsumoto 8d15caec14 bigint.c: add inline to mpn_add_n() and mpn_sub_n()
Both functions are small helpers called only from mpn_add()
and mpn_sub() respectively.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-17 11:07:14 +09:00
Yukihiro "Matz" Matsumoto 632391fba2 bigint.c: add inline to mpn_div_batch()
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 18:06:46 +09:00
Yukihiro "Matz" Matsumoto 6ebb6f3f4e bigint.c: use mpn_cmp() in ucmp()
Move mpn_cmp() before ucmp() and simplify ucmp() to use it
instead of duplicating the comparison loop.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 17:17:18 +09:00
Yukihiro "Matz" Matsumoto 2a415f1640 bigint.c: remove unused mpn_submul_1()
Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 17:14:43 +09:00
Yukihiro "Matz" Matsumoto 8089fdadf0 bigint.c: inline usub_inplace() at call site
Function was only called once and contained just 2 lines of code.
Inlining directly reduces code size and improves clarity.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 17:11:43 +09:00
Yukihiro "Matz" Matsumoto ad1254e3cc bigint.c: optimize decimal string parsing with chunked conversion
Add CPython-style parsing for base-10 string to integer conversion:
- Parse 9 digits at a time into decimal-base array
- Convert decimal-base to binary in single pass
- Use memory pool for temporary decimal buffer
- Use realloc for result buffer to reduce allocations

Also add digit_pairs lookup table for faster to_s output.

Performance: 2-5x faster for to_i, 60% fewer allocations.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 16:59:27 +09:00
HASUMI Hitoshi 219588091b Improve task.c code clarity and fix potential GC issue
- Add mrb_gc_protect() after arena_restore to prevent result from being collected before returning to caller
- Add comment to suspend_task_internal explaining why WAITING and DORMANT tasks can also be suspended
- Move argc/argv cast at the beginning of function with comment
2026-01-16 08:56:49 +09:00
Yukihiro "Matz" Matsumoto 9e6f2809ce bigint.c: optimize decimal string conversion with base conversion algorithm
Replace the repeated-division approach with Knuth's base conversion
algorithm for decimal string conversion. This processes each input
limb once (MSB to LSB) and builds the decimal representation
incrementally, which is faster than dividing the entire number
repeatedly.

Performance improvement for to_s on numbers under D&C threshold:
- 128 bits:  2.5x faster (0.80 -> 0.32 us)
- 256 bits:  3.6x faster (1.47 -> 0.41 us)
- 512 bits:  5.0x faster (3.47 -> 0.69 us)
- 1024 bits: 6.1x faster (9.37 -> 1.55 us)
- 2048 bits: 6.4x faster (31.0 -> 4.82 us)

Also includes:
- Montgomery reduction for modular exponentiation (powm)
- Adjusted Barrett reduction threshold to >= 4 limbs

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-16 08:46:11 +09:00
Yukihiro "Matz" Matsumoto 27816e7482 bigint.c: lower DC_GET_STR_THRESHOLD from 1000 to 700
This improves to_s performance for medium-sized bigints (40-50 limbs,
~800-1000 digits) by approximately 5x by enabling the divide-and-conquer
algorithm earlier.

Benchmark results:
  40 limbs (772 digits): 88 us -> 18 us (5x faster)
  50 limbs (964 digits): 134 us -> 25 us (5.4x faster)

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 16:52:57 +09:00
Yukihiro "Matz" Matsumoto 85e81072cf mruby-bigint: add Karatsuba multiplication for medium-sized numbers
Implement Karatsuba algorithm for operands with 32-99 limbs, providing
~10-25% speedup over schoolbook multiplication in this range.

Algorithm hierarchy is now:
  - Schoolbook: < 32 limbs
  - Karatsuba:  32-99 limbs
  - Toom-3:     >= 100 limbs

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 16:12:45 +09:00
Yukihiro "Matz" Matsumoto b0c1a31961 mruby-bigint: raise Toom-3 threshold from 50 to 100 limbs
Benchmarks show the previous threshold of 50 was too low, causing
Toom-3's setup overhead to outweigh its asymptotic benefits for
medium-sized numbers. Raising to 100 limbs provides:

- 2x faster at 300 limbs (192 -> 96 us)
- 2.5x faster at 120 limbs (42 -> 17 us)
- 2.6x faster at 80 limbs (31 -> 12 us)

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 14:46:00 +09:00
Yukihiro "Matz" Matsumoto 0220ec2b62 mruby-bigint: add balance multiplication for asymmetric operands
When multiplying numbers where one is significantly larger than the other
(at least 2x size difference), split the larger number into chunks matching
the smaller number's size, multiply each chunk, and combine results. This
avoids pathological performance when Toom-3 pads asymmetric operands with
zeros.

Benchmarks show 6-16x speedup for size ratios from 10:1 to 40:1, with no
regression for symmetric cases.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 14:37:18 +09:00
Yukihiro "Matz" Matsumoto 1fd4cd989b bigint.c: remove redundant mpz_realloc() calls after mpz_init_heap()
mpz_init_heap() already allocates the requested size, so immediately
calling mpz_realloc() with the same size is a no-op. Remove these
redundant calls from mpz_and, mpz_or, mpz_xor, mpz_mod_2exp, and
mpz_abs.

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-15 11:51:17 +09:00