Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions test/alloc_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ using Test
# `@allocated` picks up on newer Julia versions, so it directly tests the intended
# invariant (the operation never allocates) rather than a single runtime sample.

# On aarch64 (e.g. Apple Silicon) the per-task GC stack pointer is fetched through
# `jl_get_pgcstack_fallback` rather than a TLS/register fast path. AllocCheck already
# treats the fast-path variants `jl_get_pgcstack`/`jl_get_pgcstack_static` as
# non-allocating, but its whitelist omits the `_fallback` variant, so it conservatively
# reports it as an `AllocatingRuntimeCall`. That call does not allocate, so we drop it
# before asserting; every other (genuinely allocating) result is still caught.
real_allocs(results) = filter(results) do r
!(r isa AllocCheck.AllocatingRuntimeCall && r.name == "jl_get_pgcstack_fallback")
end

getidx(A, i...) = A[i...]
setidx!(A, v, i...) = (A[i...] = v; nothing)
function sumiter(d)
Expand All @@ -26,11 +36,11 @@ end
r2 = 10:15
dr = DisjointRange(r1, r2)

@test isempty(check_allocs(length, (typeof(dr),)))
@test isempty(check_allocs(getidx, (typeof(dr), Int)))
@test isempty(check_allocs(first, (typeof(dr),)))
@test isempty(check_allocs(last, (typeof(dr),)))
@test isempty(check_allocs(sumiter, (typeof(dr),)))
@test isempty(real_allocs(check_allocs(length, (typeof(dr),))))
@test isempty(real_allocs(check_allocs(getidx, (typeof(dr), Int))))
@test isempty(real_allocs(check_allocs(first, (typeof(dr),))))
@test isempty(real_allocs(check_allocs(last, (typeof(dr),))))
@test isempty(real_allocs(check_allocs(sumiter, (typeof(dr),))))
end

@testset "colsupport - Zero Allocations" begin
Expand All @@ -42,7 +52,7 @@ end

# colsupport returns OneTo for j <= l+u and a DisjointRange otherwise; both
# branches must be allocation-free.
@test isempty(check_allocs(colsupport, (typeof(A), Int)))
@test isempty(real_allocs(check_allocs(colsupport, (typeof(A), Int))))
end

@testset "rowsupport - Zero Allocations" begin
Expand All @@ -52,7 +62,7 @@ end
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

@test isempty(check_allocs(rowsupport, (typeof(A), Int)))
@test isempty(real_allocs(check_allocs(rowsupport, (typeof(A), Int))))
end

@testset "getindex/setindex! - Zero Allocations" begin
Expand All @@ -62,8 +72,8 @@ end
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

@test isempty(check_allocs(getidx, (typeof(A), Int, Int)))
@test isempty(check_allocs(setidx!, (typeof(A), Float64, Int, Int)))
@test isempty(real_allocs(check_allocs(getidx, (typeof(A), Int, Int))))
@test isempty(real_allocs(check_allocs(setidx!, (typeof(A), Float64, Int, Int))))
end

@testset "bandpart/fillpart - Zero Allocations" begin
Expand All @@ -73,7 +83,7 @@ end
F = rand(Float64, m, n)
A = AlmostBandedMatrix(B, F)

@test isempty(check_allocs(bandpart, (typeof(A),)))
@test isempty(check_allocs(fillpart, (typeof(A),)))
@test isempty(real_allocs(check_allocs(bandpart, (typeof(A),))))
@test isempty(real_allocs(check_allocs(fillpart, (typeof(A),))))
end
end
Loading