From 7ae7ee1ab8d714d28b752068c7c0443a82109180 Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Mon, 17 Nov 2025 19:31:09 +0100 Subject: [PATCH 1/6] Make `allocatedinline` public and give it a docstring --- base/array.jl | 26 ++++++++++++++++++++++++++ base/public.jl | 1 + 2 files changed, 27 insertions(+) diff --git a/base/array.jl b/base/array.jl index b973b0765f0c7..cbe36a4e13dd0 100644 --- a/base/array.jl +++ b/base/array.jl @@ -187,6 +187,32 @@ end asize_from(a::Array, n) = n > ndims(a) ? () : (size(a,n), asize_from(a, n+1)...) +""" + allocatedinline(::Type{T}) :: Bool + +Returns whether an object of type `T` is able to be inline allocated inside of enclosing structres or arrays, +of if it must be allocated as a reference. Generally, types which are immutable and whose instances have a +finite, statically determinable size can be allocated inline, whereas everything else is allocated using +reference pointers. + +# Examples +```jldoctest +julia> Base.allocatedinline(Int) +true + +julia> Base.allocatedinline(Union{Int, Float64}) +true + +julia> Base.allocatedinline(Real) +true + +julia> Base.allocatedinline(Complex) +false + +julia> Base.allocatedinline(Complex{Int}) +true +``` +""" allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0)) """ diff --git a/base/public.jl b/base/public.jl index 413c859106240..bc9910704487b 100644 --- a/base/public.jl +++ b/base/public.jl @@ -69,6 +69,7 @@ public isexported, ispublic, remove_linenums!, + allocatedinline, # AST handling IR, From f11d8d1715216fe3eb865d5c30a35555ff79b6e1 Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Mon, 17 Nov 2025 19:38:09 +0100 Subject: [PATCH 2/6] elaborate on docstring --- base/array.jl | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/base/array.jl b/base/array.jl index cbe36a4e13dd0..57d1d3c54d45b 100644 --- a/base/array.jl +++ b/base/array.jl @@ -212,6 +212,31 @@ false julia> Base.allocatedinline(Complex{Int}) true ``` + +Whether or not a type is `allocatedinline` determines whether or not objects of that type can be undefined +in arrays or as fields of enclosing types, or if it will be replaced with garbage bits read from memory. +``` +julia> Vector{Int}(undef, 1) +1-element Vector{Int64}: + 8 + +julia> Vector{Union{Int, Float64}}(undef, 1) +1-element Vector{Union{Float64, Int64}}: + 0.0 + +julia> Vector{Real}(undef, 1) +1-element Vector{Real}: + #undef + +julia> Vector{Complex}(undef, 1) +1-element Vector{Complex}: + #undef + +julia> Vector{Complex{Int}}(undef, 1) +1-element Vector{Complex{Int64}}: + 139934851180016 + 7957332965790215680im +``` +See also [`isdefined`](@ref), [`isassigned`](@ref) """ allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0)) From a3fc620c040950e8defa28bc4bfcaa8c81806ded Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Mon, 17 Nov 2025 19:55:31 +0100 Subject: [PATCH 3/6] fix typo --- base/array.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/array.jl b/base/array.jl index 57d1d3c54d45b..3c61f0bc69e98 100644 --- a/base/array.jl +++ b/base/array.jl @@ -190,7 +190,7 @@ asize_from(a::Array, n) = n > ndims(a) ? () : (size(a,n), asize_from(a, n+1)...) """ allocatedinline(::Type{T}) :: Bool -Returns whether an object of type `T` is able to be inline allocated inside of enclosing structres or arrays, +Returns whether an object of type `T` is able to be inline allocated inside of enclosing structs or arrays, of if it must be allocated as a reference. Generally, types which are immutable and whose instances have a finite, statically determinable size can be allocated inline, whereas everything else is allocated using reference pointers. From 5e509aeba87d6fa56a30a8c68d58ee72ee7a165c Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Mon, 17 Nov 2025 20:20:19 +0100 Subject: [PATCH 4/6] move `allocatedinline` and `isbitsunion` to genericmemory.jl --- base/array.jl | 69 ------------------------------------------- base/genericmemory.jl | 69 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/base/array.jl b/base/array.jl index 3c61f0bc69e98..7467ecacd282e 100644 --- a/base/array.jl +++ b/base/array.jl @@ -187,75 +187,6 @@ end asize_from(a::Array, n) = n > ndims(a) ? () : (size(a,n), asize_from(a, n+1)...) -""" - allocatedinline(::Type{T}) :: Bool - -Returns whether an object of type `T` is able to be inline allocated inside of enclosing structs or arrays, -of if it must be allocated as a reference. Generally, types which are immutable and whose instances have a -finite, statically determinable size can be allocated inline, whereas everything else is allocated using -reference pointers. - -# Examples -```jldoctest -julia> Base.allocatedinline(Int) -true - -julia> Base.allocatedinline(Union{Int, Float64}) -true - -julia> Base.allocatedinline(Real) -true - -julia> Base.allocatedinline(Complex) -false - -julia> Base.allocatedinline(Complex{Int}) -true -``` - -Whether or not a type is `allocatedinline` determines whether or not objects of that type can be undefined -in arrays or as fields of enclosing types, or if it will be replaced with garbage bits read from memory. -``` -julia> Vector{Int}(undef, 1) -1-element Vector{Int64}: - 8 - -julia> Vector{Union{Int, Float64}}(undef, 1) -1-element Vector{Union{Float64, Int64}}: - 0.0 - -julia> Vector{Real}(undef, 1) -1-element Vector{Real}: - #undef - -julia> Vector{Complex}(undef, 1) -1-element Vector{Complex}: - #undef - -julia> Vector{Complex{Int}}(undef, 1) -1-element Vector{Complex{Int64}}: - 139934851180016 + 7957332965790215680im -``` -See also [`isdefined`](@ref), [`isassigned`](@ref) -""" -allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0)) - -""" - Base.isbitsunion(::Type{T}) - -Return whether a type is an "is-bits" Union type, meaning each type included in a Union is [`isbitstype`](@ref). - -# Examples -```jldoctest -julia> Base.isbitsunion(Union{Float64, UInt8}) -true - -julia> Base.isbitsunion(Union{Float64, String}) -false -``` -""" -isbitsunion(u::Type) = u isa Union && allocatedinline(u) - function _unsetindex!(A::Array, i::Int) @inline @boundscheck checkbounds(A, i) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index b34095ea37d48..e24b9ca10f545 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -422,3 +422,72 @@ function replaceindex_atomic!( @_boundscheck, ) end + +""" + allocatedinline(::Type{T}) :: Bool + +Returns whether an object of type `T` is able to be inline allocated inside of enclosing structs or arrays, +of if it must be allocated as a reference. Generally, types which are immutable and whose instances have a +finite, statically determinable size can be allocated inline, whereas everything else is allocated using +reference pointers. + +# Examples +```jldoctest +julia> Base.allocatedinline(Int) +true + +julia> Base.allocatedinline(Union{Int, Float64}) +true + +julia> Base.allocatedinline(Real) +true + +julia> Base.allocatedinline(Complex) +false + +julia> Base.allocatedinline(Complex{Int}) +true +``` + +Whether or not a type is `allocatedinline` determines whether or not objects of that type can be undefined +in arrays or as fields of enclosing types, or if it will be replaced with garbage bits read from memory. +``` +julia> Vector{Int}(undef, 1) +1-element Vector{Int64}: + 8 + +julia> Vector{Union{Int, Float64}}(undef, 1) +1-element Vector{Union{Float64, Int64}}: + 0.0 + +julia> Vector{Real}(undef, 1) +1-element Vector{Real}: + #undef + +julia> Vector{Complex}(undef, 1) +1-element Vector{Complex}: + #undef + +julia> Vector{Complex{Int}}(undef, 1) +1-element Vector{Complex{Int64}}: + 139934851180016 + 7957332965790215680im +``` +See also [`isdefined`](@ref), [`isassigned`](@ref) +""" +allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, Cint, (Any,), T) != Cint(0)) + +""" + Base.isbitsunion(::Type{T}) + +Return whether a type is an "is-bits" Union type, meaning each type included in a Union is [`isbitstype`](@ref). + +# Examples +```jldoctest +julia> Base.isbitsunion(Union{Float64, UInt8}) +true + +julia> Base.isbitsunion(Union{Float64, String}) +false +``` +""" +isbitsunion(u::Type) = u isa Union && allocatedinline(u) From beecc70f2c4b2101a0757c6b88206e100a2d2ba9 Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Mon, 17 Nov 2025 20:38:36 +0100 Subject: [PATCH 5/6] fix dumb typo, remove `Real` examples --- base/genericmemory.jl | 7 ------- 1 file changed, 7 deletions(-) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index e24b9ca10f545..4ce9df2ce2bd6 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -439,9 +439,6 @@ true julia> Base.allocatedinline(Union{Int, Float64}) true -julia> Base.allocatedinline(Real) -true - julia> Base.allocatedinline(Complex) false @@ -460,10 +457,6 @@ julia> Vector{Union{Int, Float64}}(undef, 1) 1-element Vector{Union{Float64, Int64}}: 0.0 -julia> Vector{Real}(undef, 1) -1-element Vector{Real}: - #undef - julia> Vector{Complex}(undef, 1) 1-element Vector{Complex}: #undef From 1782399b20b2eabf9679cbb97a130c49f71e8f1b Mon Sep 17 00:00:00 2001 From: Mason Protter Date: Fri, 21 Nov 2025 22:55:01 +0100 Subject: [PATCH 6/6] typo --- base/genericmemory.jl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/base/genericmemory.jl b/base/genericmemory.jl index 4ce9df2ce2bd6..0bb911061e7c5 100644 --- a/base/genericmemory.jl +++ b/base/genericmemory.jl @@ -426,8 +426,8 @@ end """ allocatedinline(::Type{T}) :: Bool -Returns whether an object of type `T` is able to be inline allocated inside of enclosing structs or arrays, -of if it must be allocated as a reference. Generally, types which are immutable and whose instances have a +Returns whether an object of type `T` is able to be stored inline inside of enclosing structs or arrays, +or if it must be allocated as a reference. Generally, types which are immutable and whose instances have a finite, statically determinable size can be allocated inline, whereas everything else is allocated using reference pointers. @@ -472,7 +472,7 @@ allocatedinline(@nospecialize T::Type) = (@_total_meta; ccall(:jl_stored_inline, """ Base.isbitsunion(::Type{T}) -Return whether a type is an "is-bits" Union type, meaning each type included in a Union is [`isbitstype`](@ref). +Returns whether a type is an "is-bits" Union type, meaning each type included in a Union is [`isbitstype`](@ref). # Examples ```jldoctest