When a send has ARGS_BLOCKARG and the block arg is nil (either statically known or profiled as monomorphically nil), we can strip the block arg and optimize the call to SendDirect without a block.
This reduces the param_block category in the complex argument-parameter fallback stats (34.2% of total on lobsters as of the burndown in #833).
Implementation
- Profile the block arg alongside self and regular args for
send instructions
- If the block arg type is statically
NilClass or profiled as monomorphically nil, strip it and emit SendDirect without a block
- Insert a
GuardBitEquals side exit when relying on profiled (not static) nil
- Update the frame state snapshot after stripping to keep SP consistent in codegen
Bug fix
The initial implementation had a stack consistency error (sp: N+1, bp: N) when the guard side-exited for a non-nil block. The frame state snapshot still contained the stripped block arg, causing gen_save_sp to compute the wrong SP. Fixed by creating a new snapshot with the block arg removed.
Related: #833 (lobsters perf burndown)
When a
sendhasARGS_BLOCKARGand the block arg is nil (either statically known or profiled as monomorphically nil), we can strip the block arg and optimize the call toSendDirectwithout a block.This reduces the
param_blockcategory in the complex argument-parameter fallback stats (34.2% of total on lobsters as of the burndown in #833).Implementation
sendinstructionsNilClassor profiled as monomorphically nil, strip it and emitSendDirectwithout a blockGuardBitEqualsside exit when relying on profiled (not static) nilBug fix
The initial implementation had a stack consistency error (
sp: N+1, bp: N) when the guard side-exited for a non-nil block. The frame state snapshot still contained the stripped block arg, causinggen_save_spto compute the wrong SP. Fixed by creating a new snapshot with the block arg removed.Related: #833 (lobsters perf burndown)