Visitar URL original
Implement #[] optimization as in CRuby · Issue #9732 · jruby/jruby · GitHub
Skip to content

Implement #[] optimization as in CRuby #9732

Description

@headius

CRuby introduced a new instruction to make calls to [] (as on Array or Hash) that elides the call and does an optimized version of it directly in the caller.

For code like this:

def foo(h)
  h[:foo]
end

The CRuby 4.0 instruction sequence looks like this:

== disasm: #<ISeq:foo@-e:1 (1,0)-(1,24)>
local table (size: 1, argc: 1 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1])
[ 1] h@0<Arg>
0000 getlocal_WC_0                          h@0                       (   1)[LiCa]
0002 putobject                              :foo
0004 opt_aref                               <calldata!mid:[], argc:1, ARGS_SIMPLE>[CcCr]
0006 leave                                  [Re]

Only if the [] method is unrecognized does the invocation actually happen; for known cases like Array and Hash, the operations are performed within the instruction (later optimized by the JIT).

We should explore introducing the same optimization in JRuby's compiler.

Current JRuby IR for the same code:

block #1 (out: exit, 3↓): LBL_0:-1
  0:         push_backref_frame

block #2 (out: exit, 3!): LBL_1:-1
  0: %v_0 := recv_kw(hasRestArg: false, acceptsKeywords: false)
  1:         check_arity(%v_0, required: 1, opt: 0, rest: false, restKey: -1)
  2:    h := recv_pre_reqd_arg(%v_0, argIndex: 0)
  3:         line_num(lineNumber: 0, coverage: false, oneshot: false)
  4: %v_1 := call_1o(h, sym<foo>, callType: NORMAL, name: [], potentiallyRefined: false, flags: 0)
  5:         pop_backref_frame
  6:         return(%v_1)

block #4 (out: exit): _GLOBAL_ENSURE_BLOCK__0:-1
  0: %v_3 := recv_jruby_exc
  1:         pop_backref_frame
  2:         throw(%v_3)

Note also that this is pushing and popping a frame in case the [] is String#[] called with a regexp.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions