From 39a4466f4d3bf5bb41aa417e39da94c9749fe7b4 Mon Sep 17 00:00:00 2001 From: Neven Sajko Date: Mon, 15 Sep 2025 06:08:44 +0200 Subject: [PATCH 1/2] `ReadOnly`: do not add single-argument methods to `eachindex`, etc Do not add single-argument methods to: * `eachindex` * `firstindex` * `lastindex` The above have fallbacks that work as intended as long as the two two-argument methods of `eachindex` are defined. So add the two-argument methods of `eachindex` instead of adding single-argument methods of the three functions. On nightly Julia, together with PR #652, this PR decreases the amount of sysimage invalidations that happen when loading SparseArrays from $26$ to $17$. Without PR #652, this PR happens to increase the amount of invalidations, to $28$. --- src/readonly.jl | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/readonly.jl b/src/readonly.jl index 00eacc3c..a1096a2d 100644 --- a/src/readonly.jl +++ b/src/readonly.jl @@ -13,13 +13,20 @@ ReadOnly(x::ReadOnly) = x Base.getproperty(x::ReadOnly, s::Symbol) = Base.getproperty(parent(x), s) @inline Base.parent(x::ReadOnly) = getfield(x, :parent) -for i in [:length, :first, :last, :eachindex, :firstindex, :lastindex, :axes, :size] +for i in [:length, :first, :last, :axes, :size] @eval Base.@propagate_inbounds @inline Base.$i(x::ReadOnly) = Base.$i(parent(x)) end for i in [:iterate, :getindex, :strides] @eval(Base.@propagate_inbounds @inline Base.$i(x::ReadOnly, y...) = Base.$i(parent(x), y...)) end +function Base.eachindex(i::IndexLinear, x::ReadOnly) + eachindex(i, parent(x)) +end +function Base.eachindex(i::IndexCartesian, x::ReadOnly) + eachindex(i, parent(x)) +end + Base.unsafe_convert(x::Type{Ptr{T}}, A::ReadOnly) where T = Base.unsafe_convert(x, parent(A)) Base.elsize(::Type{ReadOnly{T,N,V}}) where {T,N,V} = Base.elsize(V) Base.@propagate_inbounds @inline Base.setindex!(x::ReadOnly, v, ind...) = if v == getindex(parent(x), ind...) From 14976eca3788043909ee2838f2ce592939832aaa Mon Sep 17 00:00:00 2001 From: Neven Sajko <4944410+nsajko@users.noreply.github.com> Date: Mon, 15 Sep 2025 17:47:11 +0200 Subject: [PATCH 2/2] make the methods one liners Co-authored-by: Daniel Karrasch --- src/readonly.jl | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/readonly.jl b/src/readonly.jl index a1096a2d..8d219f0c 100644 --- a/src/readonly.jl +++ b/src/readonly.jl @@ -20,12 +20,8 @@ for i in [:iterate, :getindex, :strides] @eval(Base.@propagate_inbounds @inline Base.$i(x::ReadOnly, y...) = Base.$i(parent(x), y...)) end -function Base.eachindex(i::IndexLinear, x::ReadOnly) - eachindex(i, parent(x)) -end -function Base.eachindex(i::IndexCartesian, x::ReadOnly) - eachindex(i, parent(x)) -end +Base.eachindex(i::IndexLinear, x::ReadOnly) = eachindex(i, parent(x)) +Base.eachindex(i::IndexCartesian, x::ReadOnly) = eachindex(i, parent(x)) Base.unsafe_convert(x::Type{Ptr{T}}, A::ReadOnly) where T = Base.unsafe_convert(x, parent(A)) Base.elsize(::Type{ReadOnly{T,N,V}}) where {T,N,V} = Base.elsize(V)