Issue #12403 has been updated by Yui NARUSE.


After r55102, rb_scan_args is almost statically resolved.

```
000000000051eae0 <rb_reg_match_m_p>:
 *     $&                       #=> nil
 */

static VALUE
rb_reg_match_m_p(int argc, VALUE *argv, VALUE re)
{
  51eae0:       41 57                   push   %r15
  51eae2:       41 56                   push   %r14
  51eae4:       41 55                   push   %r13
  51eae6:       41 54                   push   %r12
  51eae8:       55                      push   %rbp
  51eae9:       89 fd                   mov    %edi,%ebp
  51eaeb:       53                      push   %rbx
  51eaec:       48 81 ec 88 00 00 00    sub    $0x88,%rsp
  51eaf3:       48 8b 05 86 00 3b 00    mov    0x3b0086(%rip),%rax        # 8ceb80 <_DYNAMIC+0x240>
    VALUE str, initpos;
    long pos = 0;
    regex_t *reg;
    onig_errmsg_buffer err = "";
  51eafa:       48 c7 44 24 10 00 00    movq   $0x0,0x10(%rsp)
  51eb01:       00 00
  51eb03:       48 8d 7c 24 18          lea    0x18(%rsp),%rdi
 *     $&                       #=> nil
 */

static VALUE
rb_reg_match_m_p(int argc, VALUE *argv, VALUE re)
{
  51eb08:       48 8b 08                mov    (%rax),%rcx
  51eb0b:       48 89 4c 24 78          mov    %rcx,0x78(%rsp)
  51eb10:       31 c9                   xor    %ecx,%ecx
    VALUE str, initpos;
    long pos = 0;
    regex_t *reg;
    onig_errmsg_buffer err = "";
  51eb12:       b9 0a 00 00 00          mov    $0xa,%ecx
  51eb17:       31 c0                   xor    %eax,%eax
  51eb19:       f3 48 ab                rep stos %rax,%es:(%rdi)
  51eb1c:       31 c9                   xor    %ecx,%ecx
  51eb1e:       66 89 0f                mov    %cx,(%rdi)
    if (*p != '\0') {
        rb_fatal("bad scan arg format: %s", fmt);
    }
    n_mand = n_lead + n_trail;

    if (argc < n_mand)
  51eb21:       85 ed                   test   %ebp,%ebp
  51eb23:       0f 8e 71 02 00 00       jle    51ed9a <rb_reg_match_m_p+0x2ba>
  51eb29:       48 89 d3                mov    %rdx,%rbx
        }
    }
    /* capture leading mandatory arguments */
    for (i = n_lead; i-- > 0; ) {
        var = vars[vari++];
        if (var) *var = argv[argi];
  51eb2c:       48 8b 3e                mov    (%rsi),%rdi
        argi++;
    }
    /* capture optional arguments */
    for (i = n_opt; i-- > 0; ) {
        var = vars[vari++];
        if (argi < argc - n_trail) {
  51eb2f:       83 fd 01                cmp    $0x1,%ebp
  51eb32:       0f 84 00 01 00 00       je     51ec38 <rb_reg_match_m_p+0x158>
            if (var) *var = argv[argi];
  51eb38:       4c 8b 6e 08             mov    0x8(%rsi),%r13
        else {
            *var = Qnil;
        }
    }

    if (argi < argc) {
  51eb3c:       83 fd 02                cmp    $0x2,%ebp
  51eb3f:       0f 85 55 02 00 00       jne    51ed9a <rb_reg_match_m_p+0x2ba>
    OnigPosition result;
    const UChar *start, *end;
    int tmpreg;

    rb_scan_args(argc, argv, "11", &str, &initpos);
    if (NIL_P(str)) return Qfalse;
  51eb45:       48 83 ff 08             cmp    $0x8,%rdi
  51eb49:       0f 84 f9 00 00 00       je     51ec48 <rb_reg_match_m_p+0x168>
    str = SYMBOL_P(str) ? rb_sym2str(str) : rb_str_to_str(str);
  51eb4f:       40 80 ff 0c             cmp    $0xc,%dil
  51eb53:       0f 84 cf 01 00 00       je     51ed28 <rb_reg_match_m_p+0x248>
  51eb59:       40 f6 c7 07             test   $0x7,%dil
  51eb5d:       75 17                   jne    51eb76 <rb_reg_match_m_p+0x96>
  51eb5f:       48 f7 c7 f7 ff ff ff    test   $0xfffffffffffffff7,%rdi
  51eb66:       74 0e                   je     51eb76 <rb_reg_match_m_p+0x96>
  51eb68:       8b 07                   mov    (%rdi),%eax
  51eb6a:       83 e0 1f                and    $0x1f,%eax
  51eb6d:       83 f8 14                cmp    $0x14,%eax
  51eb70:       0f 84 b2 01 00 00       je     51ed28 <rb_reg_match_m_p+0x248>
  51eb76:       e8 05 72 04 00          callq  565d80 <rb_str_to_str>
  51eb7b:       49 89 c4                mov    %rax,%r12
```

----------------------------------------
Feature #12403: Optimise Regexp#match?
https://bugs.ruby-lang.org/issues/12403#change-58795

* Author: Sam Saffron
* Status: Open
* Priority: Normal
* Assignee: 
----------------------------------------
At the moment `#match?` is dynamically dispatched and args are walked. 

Instead

- Add 2 insns instructions for #match? with 1 param and #match? with 2 params
- Amend parser to route #match?("s") and #match?("s", 1) to insns version

Main reason for `#match?` is performance, might as well make it as fast as possible. 



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>