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:
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.
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:
The CRuby 4.0 instruction sequence looks like this:
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:
Note also that this is pushing and popping a frame in case the
[]isString#[]called with a regexp.