Repository navigation
Conversation
`SArray` and `FieldArray` gave `ccall` a pointer to their elements with
unsafe_convert(::Type{Ptr{T}}, a::Base.RefValue{SA}) where {S,T,D,L,SA<:SArray{S,T,D,L}}
and the `FieldArray` equivalent. These tie `T` through both arguments, so
type intersection cannot rule out an overlap with Base's
`unsafe_convert(::Type{Ptr{T}}, ::RefValue{T})` for an abstract `T`, and
loading StaticArrays invalidated every compiled specialization of that
method with an abstract `T`. It is the largest source of invalidations
from loading StaticArrays: on Julia 1.13, 13 of 60 method instances in a
fresh session, and 124 of 662 after using DataFrames, InlineStrings,
HTTP and JSON3. With this change, neither `cconvert` nor `unsafe_convert`
roots an invalidation.
`cconvert` now wraps the `RefValue` in a type of this package when the
argument is a pointer to the elements, and the only `unsafe_convert`
method is on that wrapper. Which arguments take that path is decided by
dispatch on a helper, whose signatures are those of the removed methods.
Everything else is the `RefValue` that `cconvert` returned before, which
Base converts as it did. The addresses are unchanged, `ccall` still does
not allocate, and no conversion that worked before fails or vice versa.
The conversions had no tests; the new ones cover `SArray` and immutable
and mutable `FieldVector`s passed as `Ptr{T}`, `Ptr{Cvoid}` and a pointer
to the array type, directly and as a `Ref`, including `Ref`s with an
abstract element type, reading and writing through the pointer.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Loading StaticArrays invalidates code that is already compiled for Base's
unsafe_convert(::Type{Ptr{T}}, ::RefValue{T}). The cause isand its
FieldArraycounterpart, which giveccalla pointer to the elements.Tappears in both arguments. Type intersection cannot rule out an overlap between that signature and Base's method for an abstractT, so every compiled specialization of Base's method with an abstractTis invalidated. This method is the largest source of invalidations from loading StaticArrays (@snoop_invalidations using StaticArrays, Julia 1.13):using StaticArraysWith this PR,
cconvertwraps theRefValuein an internal type when the argument is a pointer to the elements. The wrapper has the onlyunsafe_convertmethod, so nothing is defined onBase.RefValue. A helper decides by dispatch which arguments take this path, using the signatures of the removed methods. Every other argument keeps theRefValuethatcconvertreturned before, and Base converts it as it did. Neither new method roots an invalidation.Behavior is unchanged:
ccallpasses the same addresses as before.FieldArrayis still passed in place.ccallstill doesn't allocate: the decision is made at compile time and inlined.These conversions had no tests. The new ones pass
SArrays and immutable and mutableFieldVectors asPtr{T},Ptr{Cvoid}and a pointer to the array type, directly and as aRef, and read and write through the pointer. They also coverRefs with an abstract element type such asRef{SVector}, which Base converts. The tests pass on master and with this change, on Julia 1.10, 1.12 and nightly. The full suite passes on 1.12, with no new Aqua ambiguities or piracies.