Skip to content

Commit b658812

Browse files
JamesWrigleyaviatesk
authored andcommitted
Type-assert DataType.layout in some Base functions (#59886)
This prevents a bunch of invalidations, specifically these ones in Julia 1.12 with UnsafePointers.jl (CC @cjdoris): ```julia inserting convert(P::Type{<:Ptr}, p::UnsafePointers.UnsafePtr) @ UnsafePointers ~/git/UnsafePointers.jl/src/UnsafePointers.jl:66 invalidated: mt_backedges: 1: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_npointers(::Type{T} where T<:(NamedTuple{names, T} where {T<:Tuple, names})) (4 children) 2: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_npointers(::Type{T} where T<:AbstractString) (4 children) 3: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_npointers(::Type{T} where T<:Tuple{Symbol, Any}) (4 children) 4: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_npointers(::Type{T} where T<:(NamedTuple{(:message, :position, :hint), _A} where _A)) (4 children) 5: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_npointers(::Type{T} where T<:(SubString{_A} where _A)) (4 children) 6: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:(NamedTuple{(:message, :position, :hint), _A} where _A)) (15 children) 7: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:(SubString{_A} where _A)) (19 children) 8: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:Tuple{Any, Symbol, Symbol}) (21 children) 9: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:Tuple{Symbol, Any}) (23 children) 10: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:AbstractString) (52 children) 11: signature Tuple{typeof(convert), Type{Ptr{Base.DataTypeLayout}}, Any} triggered MethodInstance for Base.datatype_alignment(::Type{T} where T<:(NamedTuple{names, T} where {T<:Tuple, names})) (1739 children) ``` Using Cthulhu to look at the last invalidation with 1739 children showed this: ```julia datatype_alignment(dt::DataType) @ Base ~/.julia/juliaup/julia-1.12.1+0.x64.linux.gnu/share/julia/base/runtime_internals.jl:544 544 function datatype_alignment(dt::Type{T} where T<:(NamedTuple{names, T} where {T<:Tuple, names})::DataType)::Any 545 @_foldable_meta 546 (dt::Type{T} where T<:(NamedTuple{names, T} where {T<:Tuple, names}).layout::Any == C_NULL::Core.Const(Ptr{Nothing}(0x0000000000000000)))::Any && throw(UndefRefError()::Core.Const(UndefRefError())) 547 alignment::Any = unsafe_load(convert(Ptr{DataTypeLayout}::Type{Ptr{Base.DataTypeLayout}}, dt::Type{T} where T<:(NamedTuple{names, T} where {T<:Tuple, names}).layout::Any)::Any)::Any.alignment::Any 548 return Int::Type{Int64}(alignment::Any)::Any 549 end ``` The `.layout` field was getting inferred as `Any` which caused that method to be invalidated when UnsafePointers.jl defined a new `convert()` method. Would it be possible to backport this to 1.12? UnsafePointers is a dependency of PythonCall so it's quite widely used. --------- Co-authored-by: Shuhei Kadowaki <[email protected]> (cherry picked from commit 90f4289)
1 parent ce95997 commit b658812

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

base/runtime_internals.jl

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,9 @@ alignment of the elements, not the whole object.
543543
"""
544544
function datatype_alignment(dt::DataType)
545545
@_foldable_meta
546-
dt.layout == C_NULL && throw(UndefRefError())
547-
alignment = unsafe_load(convert(Ptr{DataTypeLayout}, dt.layout)).alignment
546+
layout = dt.layout::Ptr{Cvoid}
547+
layout == C_NULL && throw(UndefRefError())
548+
alignment = unsafe_load(convert(Ptr{DataTypeLayout}, layout)).alignment
548549
return Int(alignment)
549550
end
550551

@@ -627,8 +628,9 @@ Return the number of pointers in the layout of a datatype.
627628
"""
628629
function datatype_npointers(dt::DataType)
629630
@_foldable_meta
630-
dt.layout == C_NULL && throw(UndefRefError())
631-
return unsafe_load(convert(Ptr{DataTypeLayout}, dt.layout)).npointers
631+
layout = dt.layout::Ptr{Cvoid}
632+
layout == C_NULL && throw(UndefRefError())
633+
return unsafe_load(convert(Ptr{DataTypeLayout}, layout)).npointers
632634
end
633635

634636
"""

0 commit comments

Comments
 (0)