Skip to content

Commit b063f6e

Browse files
committed
Support kwargs, splatting, and other forms of quote node in allocated macro optimization
Refs #58057
1 parent ccef01a commit b063f6e

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

base/timing.jl

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -472,32 +472,40 @@ function gc_bytes()
472472
b[]
473473
end
474474

475-
function allocated(f, args::Vararg{Any,N}) where {N}
475+
function allocated(f, args::Vararg{Any,N}; kwargs...) where {N}
476476
b0 = Ref{Int64}(0)
477477
b1 = Ref{Int64}(0)
478478
Base.gc_bytes(b0)
479-
f(args...)
479+
f(args...; kwargs...)
480480
Base.gc_bytes(b1)
481481
return b1[] - b0[]
482482
end
483483
only(methods(allocated)).called = 0xff
484484

485-
function allocations(f, args::Vararg{Any,N}) where {N}
485+
function allocations(f, args::Vararg{Any,N}; kwargs...) where {N}
486486
stats = Base.gc_num()
487-
f(args...)
487+
f(args...; kwargs...)
488488
diff = Base.GC_Diff(Base.gc_num(), stats)
489489
return Base.gc_alloc_count(diff)
490490
end
491491
only(methods(allocations)).called = 0xff
492492

493493
function is_simply_call(@nospecialize ex)
494494
Meta.isexpr(ex, :call) || return false
495-
for a in ex.args
496-
a isa QuoteNode && continue
497-
a isa Symbol && continue
498-
Base.is_self_quoting(a) && continue
495+
function is_simple_arg(@nospecialize a)
496+
a isa Symbol && return true
497+
is_self_quoting(a) && return true
498+
is_quoted(a) && return true
499+
if a isa Expr
500+
a.head === :(kw) && return is_simple_arg(a.args[2])
501+
a.head === :(...) && return is_simple_arg(a.args[1])
502+
a.head === :parameters && return all(is_simple_arg, a.args)
503+
end
499504
return false
500505
end
506+
for a in ex.args
507+
is_simple_arg(a) || return false
508+
end
501509
return true
502510
end
503511

@@ -518,6 +526,8 @@ julia> @allocated rand(10^6)
518526
macro allocated(ex)
519527
if !is_simply_call(ex)
520528
ex = :((() -> $ex)())
529+
else
530+
length(ex.args) >= 2 && isexpr(ex.args[2], :parameters) && ((ex.args[1], ex.args[2]) = (ex.args[2], ex.args[1]))
521531
end
522532
pushfirst!(ex.args, GlobalRef(Base, :allocated))
523533
return esc(ex)
@@ -543,6 +553,8 @@ julia> @allocations rand(10^6)
543553
macro allocations(ex)
544554
if !is_simply_call(ex)
545555
ex = :((() -> $ex)())
556+
else
557+
length(ex.args) >= 2 && isexpr(ex.args[2], :parameters) && ((ex.args[1], ex.args[2]) = (ex.args[2], ex.args[1]))
546558
end
547559
pushfirst!(ex.args, GlobalRef(Base, :allocations))
548560
return esc(ex)

0 commit comments

Comments
 (0)