z, ? | toggle help (this) |
space, → | next slide |
shift-space, ← | previous slide |
d | toggle debug mode |
## <ret> | go to slide # |
r | reload slides |
n | toggle notes |
COUNTS = {}
def objects_allocated
ObjectSpace.count_objects(COUNTS)
arrays = COUNTS[:T_ARRAY]
hashes = COUNTS[:T_HASH]
yield
ObjectSpace.count_objects(COUNTS)
arrays -= COUNTS[:T_ARRAY]
hashes -= COUNTS[:T_HASH]
puts "Allocates: #{-arrays} arrays, #{-hashes} hashes"
end
GC.start
GC.disable
objects_allocated do
# nothing
end
# Allocates: 0 arrays, 0 hashes
COUNTS = {}
def objects_allocated
ObjectSpace.count_objects(COUNTS)
arrays = COUNTS[:T_ARRAY]
hashes = COUNTS[:T_HASH]
yield
ObjectSpace.count_objects(COUNTS)
arrays -= COUNTS[:T_ARRAY]
hashes -= COUNTS[:T_HASH]
puts "Allocates: #{-arrays} arrays, #{-hashes} hashes"
end
GC.start
GC.disable
objects_allocated do
# nothing
end
# Allocates: 0 arrays, 0 hashes
method
COUNTS = {}
def objects_allocated
ObjectSpace.count_objects(COUNTS)
arrays = COUNTS[:T_ARRAY]
hashes = COUNTS[:T_HASH]
yield
ObjectSpace.count_objects(COUNTS)
arrays -= COUNTS[:T_ARRAY]
hashes -= COUNTS[:T_HASH]
puts "Allocates: #{-arrays} arrays, #{-hashes} hashes"
end
GC.start
GC.disable
objects_allocated do
# nothing
end
# Allocates: 0 arrays, 0 hashes
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
# Ruby 3.2: Allocates: 4 arrays, 1 hashes
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
# Ruby 3.2: Allocates: 4 arrays, 1 hashes
# Ruby 3.3: Allocates: 0 arrays, 0 hashes
def a
end
ary = []
kw = {}
objects_allocated do
a(*ary, **kw)
end
# Ruby 3.2: Allocates: 4 arrays, 1 hashes
# Ruby 3.3: Allocates: 0 arrays, 0 hashes
$ ruby32 --dump=insns -e '
ary = []
kw = {}
a(*ary, **kw)
'
$ ruby32 --dump=insns -e '
ary = []
kw = {}
a(*ary, **kw)
'
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray true
putspecialobject 1
newhash 0
getlocal_WC_0 kw@1
opt_send_without_block core#hash_merge_kwd, 2, ARGS_SIMPLE
newarray 1
concatarray
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
a(*ary, **kw)
a(*[*ary, **kw])
$ ruby33 --dump=insns -e '
ary = []
kw = {}
a(*ary, **kw)
'
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray false
getlocal_WC_0 kw@1
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray false
getlocal_WC_0 kw@1
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
newarray 0
setlocal_WC_0 ary@0
newhash 0
setlocal_WC_0 kw@1
putself
getlocal_WC_0 ary@0
splatarray false
getlocal_WC_0 kw@1
opt_send_without_block a, 1, ARGS_SPLAT|FCALL|KW_SPLAT
leave
splatarray true
def a(b=nil)
end
ary = []
objects_allocated do
a(*ary)
end
def a(b=nil)
end
ary = []
objects_allocated do
a(*ary)
end
def a(b=nil)
end
ary = []
objects_allocated do
a(*ary)
end
def a(b=nil)
end
ary = []
objects_allocated do
a(*ary)
end
# Ruby 3.2: Allocates: 0 arrays, 0 hashes
def a(b=nil)
end
ary = []
objects_allocated do
a(1, *ary)
end
# Ruby 3.2: Allocates: 0 arrays, 0 hashes
def a(b=nil)
end
ary = []
objects_allocated do
a(1, *ary)
end
# Ruby 3.2: Allocates: 1 arrays, 0 hashes
def a(b=nil)
end
ary = []
objects_allocated do
a(1, *ary)
end
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject_INT2FIX_1_
getlocal_WC_0 ary@0
splatarray true
opt_send_without_block a, argc:2, ARGS_SPLAT|FCALL
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
$ ruby32 --dump=insns_without_opt -e '
ary = []
a(1, *ary)
'
$ ruby34 --dump=insns,-opt -e '
ary = []
a(1, *ary)
'
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray true
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
putself
putobject 1
getlocal ary@0, 0
splatarray false
send a, argc:2, ARGS_SPLAT|FCALL, nil
if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == Qtrue) {
if (IS_NEXT_INSN_ID(niobj, send)) {
niobj = niobj->next;
unsigned int flag = vm_ci_flag((const struct rb_callinfo *)OPERAND_AT(niobj, 0));
if ((flag & VM_CALL_ARGS_SPLAT) && !(flag & (VM_CALL_KW_SPLAT|VM_CALL_ARGS_BLOCKARG))) {
OPERAND_AT(iobj, 0) = Qfalse;
}
}
}
a(1, *ary)
a(1, *ary)
a(1, *ary, &block)
a(1, *ary)
a(1, *ary, &block)
putself
putobject 1
getlocal a@0, 0
splatarray true
getlocal block@0, 0
send a, argc:2, ARGS_SPLAT|ARGS_BLOCKARG|FCALL, nil
a(1, *ary)
a(1, *ary, &block)
putself
putobject 1
getlocal a@0, 0
splatarray true
getlocal block@0, 0
send a, argc:2, ARGS_SPLAT|ARGS_BLOCKARG|FCALL, nil
a(1, *ary)
a(1, *ary, &block)
putself
putobject 1
getlocal a@0, 0
splatarray true
getlocal block@0, 0
send a, argc:2, ARGS_SPLAT|ARGS_BLOCKARG|FCALL, nil
a(1, *ary)
a(1, *ary, &block)
a(1, *ary)
a(1, *ary, &block)
a(1, *ary)
a(1, *ary, &block)
a(1, *ary)
a(1, *ary, &block)
a(*ary, **kw)
a(1, *ary)
a(1, *ary, &block)
a(*ary, **kw)
a(*ary, **kw, &block)
a(1, *ary)
a(1, *ary, &block)
a(*ary, **kw)
a(*ary, **kw, &block)
a(*ary, kw: 1)
a(1, *ary)
a(1, *ary, &block)
a(*ary, **kw)
a(*ary, **kw, &block)
a(*ary, kw: 1)
a(*ary, kw: 1, &block)
a(1, *ary)
a(1, *ary, &block)
a(*ary, **kw)
a(*ary, **kw, &block)
a(*ary, kw: 1)
a(*ary, kw: 1, &block)
def a(*ary)
end
a(*ary, kw: 1)
def a(*ary)
end
a(*ary, kw: 1)
def a(*ary)
end
a(*ary, kw: 1)
a(1, *ary, &block)
a(1, *ary, &block)
a(**kw, &block)
a(**kw, &block)
putself
getlocal_WC_0 kw@0
getlocal_WC_0 block@1
send a, argc:1, ARGS_BLOCKARG|FCALL|KW_SPLAT, nil
a(**kw, &block)
putself
getlocal_WC_0 kw@0
getlocal_WC_0 block@1
send a, argc:1, ARGS_BLOCKARG|FCALL|KW_SPLAT, nil
a(**kw, &block)
putself
getlocal_WC_0 kw@0
getlocal_WC_0 block@1
splatkw
send a, argc:1, ARGS_BLOCKARG|FCALL|KW_SPLAT, nil
a(**kw, &block)
super(**kw, &block)
obj[**kw, &block] += 1
obj[**kw, &block] += 1
obj[**kw] += 1
obj[**kw, &block] += 1
obj[**kw] += 1
obj[kw: 1] += 1
obj[**kw, &block] += 1
obj[**kw] += 1
obj[kw: 1] += 1
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw
end
f(*[], **o)
o = Object.new
def o.to_hash
{a: 1}
end
def f(*a, **kw)
kw # => o !!!
end
f(*[], **o)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
f(**kw)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
f(**kw)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
f(**kw)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
# => kw.dup
f(**kw)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
# => kw.dup
f(**kw)
def f(obj)
obj
end
ary = []
kw = {a: 1}
f(*ary, **kw)
# => kw.dup
f(**kw)
# => kw
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
# Ruby 3.3: Allocates: 3 arrays, 0 hashes
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*[*ary, *ary])
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*[*ary, *ary])
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concatarray false
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, *ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
splatarray false
concattoarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
# Ruby 3.3: Allocates: 3 arrays, 0 hashes
# Ruby 3.4: Allocates: 1 arrays, 0 hashes
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, *ary)
end
# Ruby 3.3: Allocates: 3 arrays, 0 hashes
# Ruby 3.4: Allocates: 1 arrays, 0 hashes
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, ary)
end
# Ruby 3.3: Allocates:
# Ruby 3.4: Allocates:
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, ary)
end
# Ruby 3.3: Allocates: 4 arrays, 0 hashes
# Ruby 3.4: Allocates:
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*[*ary, *[ary]])
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concattoarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concattoarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
newarray 1
concatarray
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
pushtoarray 1
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
pushtoarray 1
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
a(*ary, ary)
putself
getlocal_WC_0 ary@0
splatarray true
getlocal_WC_0 ary@0
pushtoarray 1
opt_send_without_block a, argc:1, ARGS_SPLAT|ARGS_SPLAT_MUT|FCALL
def a(*ary)
end
ary = []
objects_allocated do
a(*ary, ary)
end
# Ruby 3.3: Allocates: 4 arrays, 0 hashes
# Ruby 3.4: Allocates: 1 arrays, 0 hashes
def a(*c)
# ...
end
def a(*c)
# ...
end
def a(*c)
# ...
end
def a(*)
# ...
end
def a(*)
p(*)
end
def a(*, **)
p(*, **)
end
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:)
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **)
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(a, *, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(a, *, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(a, *, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
g(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 1 arrays, 1 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(*, **) = g(*, **)
def f(*, **) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(*, **)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(...) = g(...)
def f(...) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(...)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 2 arrays, 2 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(...) = g(...)
def f(...) # has_rest, has_kwrest, anon_rest, anon_kwrest
h(...)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 3 arrays, 3 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(...) = g(...)
def f(...) # def f(*, &); ruby2_keywords :f
h(...)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 3 arrays, 3 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(...) = g(...)
def f(...) # def f(*, **, &)
h(...)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 3 arrays, 3 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes
def g(a, b:) # has_lead, has_kw
a + b
end
def h(...) = g(...)
def f(...) # def f(*, **, &)
h(...)
end
a = [1]
kw = {b: 2}
objects_allocated do
f(*a, **kw)
end
# Ruby 3.3: Allocates: 3 arrays, 3 hashes
# Ruby 3.4: Allocates: 0 arrays, 0 hashes