• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

JuliaLang / julia / #37476

pending completion
#37476

push

local

web-flow
Ensure accurate invalidation logging data (#48982)

* Ensure accurate invalidation logging data

This modifies #48841 to restore the required logging data.
By collecting at least one additional match, we retain the possibility
of identifying at least one trigger of invalidation.

* Bump number of invalidation causes

* Update src/staticdata_utils.c

Co-authored-by: Jameson Nash <vtjnash@gmail.com>

---------

Co-authored-by: Jameson Nash <vtjnash@gmail.com>

71283 of 82556 relevant lines covered (86.35%)

34551491.63 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

70.0
/base/refpointer.jl
1
# This file is a part of Julia. License is MIT: https://julialang.org/license
2

3
"""
4
    Ref{T}
5

6
An object that safely references data of type `T`. This type is guaranteed to point to
7
valid, Julia-allocated memory of the correct type. The underlying data is protected from
8
freeing by the garbage collector as long as the `Ref` itself is referenced.
9

10
In Julia, `Ref` objects are dereferenced (loaded or stored) with `[]`.
11

12
Creation of a `Ref` to a value `x` of type `T` is usually written `Ref(x)`.
13
Additionally, for creating interior pointers to containers (such as Array or Ptr),
14
it can be written `Ref(a, i)` for creating a reference to the `i`-th element of `a`.
15

16
`Ref{T}()` creates a reference to a value of type `T` without initialization.
17
For a bitstype `T`, the value will be whatever currently resides in the memory
18
allocated. For a non-bitstype `T`, the reference will be undefined and attempting to
19
dereference it will result in an error, "UndefRefError: access to undefined reference".
20

21
To check if a `Ref` is an undefined reference, use [`isassigned(ref::RefValue)`](@ref).
22
For example, `isassigned(Ref{T}())` is `false` if `T` is not a bitstype.
23
If `T` is a bitstype, `isassigned(Ref{T}())` will always be true.
24

25
When passed as a `ccall` argument (either as a `Ptr` or `Ref` type), a `Ref`
26
object will be converted to a native pointer to the data it references.
27
For most `T`, or when converted to a `Ptr{Cvoid}`, this is a pointer to the
28
object data. When `T` is an `isbits` type, this value may be safely mutated,
29
otherwise mutation is strictly undefined behavior.
30

31
As a special case, setting `T = Any` will instead cause the creation of a
32
pointer to the reference itself when converted to a `Ptr{Any}`
33
(a `jl_value_t const* const*` if T is immutable, else a `jl_value_t *const *`).
34
When converted to a `Ptr{Cvoid}`, it will still return a pointer to the data
35
region as for any other `T`.
36

37
A `C_NULL` instance of `Ptr` can be passed to a `ccall` `Ref` argument to initialize it.
38

39
# Use in broadcasting
40
`Ref` is sometimes used in broadcasting in order to treat the referenced values as a scalar.
41

42
# Examples
43

44
```jldoctest
45
julia> Ref(5)
46
Base.RefValue{Int64}(5)
47

48
julia> isa.(Ref([1,2,3]), [Array, Dict, Int]) # Treat reference values as scalar during broadcasting
49
3-element BitVector:
50
 1
51
 0
52
 0
53

54
julia> Ref{Function}()  # Undefined reference to a non-bitstype, Function
55
Base.RefValue{Function}(#undef)
56

57
julia> try
58
           Ref{Function}()[] # Dereferencing an undefined reference will result in an error
59
       catch e
60
           println(e)
61
       end
62
UndefRefError()
63

64
julia> Ref{Int64}()[]; # A reference to a bitstype refers to an undetermined value if not given
65

66
julia> isassigned(Ref{Int64}()) # A reference to a bitstype is always assigned
67
true
68

69
julia> Ref{Int64}(0)[] == 0 # Explicitly give a value for a bitstype reference
70
true
71
```
72
"""
73
Ref
74

75
# C NUL-terminated string pointers; these can be used in ccall
76
# instead of Ptr{Cchar} and Ptr{Cwchar_t}, respectively, to enforce
77
# a check for embedded NUL chars in the string (to avoid silent truncation).
78
if Int === Int64
79
    primitive type Cstring  64 end
80
    primitive type Cwstring 64 end
81
else
82
    primitive type Cstring  32 end
83
    primitive type Cwstring 32 end
84
end
85

86
### General Methods for Ref{T} type
87

88
eltype(x::Type{<:Ref{T}}) where {T} = @isdefined(T) ? T : Any
1,575,818✔
89
convert(::Type{Ref{T}}, x::Ref{T}) where {T} = x
1,197✔
90
size(x::Ref) = ()
1✔
91
axes(x::Ref) = ()
1,575,932✔
92
length(x::Ref) = 1
×
93
isempty(x::Ref) = false
×
94
ndims(x::Ref) = 0
1✔
95
ndims(::Type{<:Ref}) = 0
1,576,001✔
96
iterate(r::Ref) = (r[], nothing)
2✔
97
iterate(r::Ref, s) = nothing
2✔
98
IteratorSize(::Type{<:Ref}) = HasShape{0}()
2✔
99

100
# create Ref objects for general object conversion
101
unsafe_convert(::Type{Ref{T}}, x::Ref{T}) where {T} = unsafe_convert(Ptr{T}, x)
83,273,243✔
102
unsafe_convert(::Type{Ref{T}}, x) where {T} = unsafe_convert(Ptr{T}, x)
×
103

104
convert(::Type{Ref{T}}, x) where {T} = RefValue{T}(x)::RefValue{T}
1,795,628✔
105

106
### Methods for a Ref object that is backed by an array at index i
107
struct RefArray{T,A<:AbstractArray{T},R} <: Ref{T}
108
    x::A
109
    i::Int
110
    roots::R # should be either ::Nothing or ::Any
111
    RefArray{T,A,R}(x,i,roots=nothing) where {T,A<:AbstractArray{T},R} = new(x,i,roots)
2,030✔
112
end
113
RefArray(x::AbstractArray{T}, i::Int, roots::Any) where {T} = RefArray{T,typeof(x),Any}(x, i, roots)
2,001✔
114
RefArray(x::AbstractArray{T}, i::Int=1, roots::Nothing=nothing) where {T} = RefArray{T,typeof(x),Nothing}(x, i, nothing)
58✔
115
RefArray(x::AbstractArray{T}, i::Integer, roots::Any) where {T} = RefArray{T,typeof(x),Any}(x, Int(i), roots)
×
116
RefArray(x::AbstractArray{T}, i::Integer, roots::Nothing=nothing) where {T} = RefArray{T,typeof(x),Nothing}(x, Int(i), nothing)
×
117
convert(::Type{Ref{T}}, x::AbstractArray{T}) where {T} = RefArray(x, 1)
7✔
118

119
function unsafe_convert(P::Union{Type{Ptr{T}},Type{Ptr{Cvoid}}}, b::RefArray{T})::P where T
28✔
120
    if allocatedinline(T)
28✔
121
        p = pointer(b.x, b.i)
2,035✔
122
    elseif isconcretetype(T) && ismutabletype(T)
×
123
        p = pointer_from_objref(b.x[b.i])
×
124
    else
125
        # see comment on equivalent branch for RefValue
126
        p = pointerref(Ptr{Ptr{Cvoid}}(pointer(b.x, b.i)), 1, Core.sizeof(Ptr{Cvoid}))
×
127
    end
128
    return p
28✔
129
end
130
function unsafe_convert(::Type{Ptr{Any}}, b::RefArray{Any})::Ptr{Any}
×
131
    return pointer(b.x, b.i)
×
132
end
133

134
###
135
if is_primary_base_module
136
    Ref(x::Any) = RefValue(x)
11,229,827✔
137
    Ref{T}() where {T} = RefValue{T}() # Ref{T}()
39,096,999✔
138
    Ref{T}(x) where {T} = RefValue{T}(x) # Ref{T}(x)
41,096,773✔
139

140
    Ref(x::Ref, i::Integer) = (i != 1 && error("Ref only has one element"); x)
×
141
    Ref(x::Ptr{T}, i::Integer) where {T} = x + (i - 1) * Core.sizeof(T)
×
142

143
    # convert Arrays to pointer arrays for ccall
144
    function Ref{P}(a::Array{<:Union{Ptr,Cwstring,Cstring}}) where P<:Union{Ptr,Cwstring,Cstring}
×
145
        return RefArray(a) # effectively a no-op
×
146
    end
147
    function Ref{P}(a::Array{T}) where P<:Union{Ptr,Cwstring,Cstring} where T
2,001✔
148
        if (!isbitstype(T) && T <: eltype(P))
2,001✔
149
            # this Array already has the right memory layout for the requested Ref
150
            return RefArray(a,1,false) # root something, so that this function is type-stable
×
151
        else
152
            ptrs = Vector{P}(undef, length(a)+1)
2,001✔
153
            roots = Vector{Any}(undef, length(a))
2,001✔
154
            for i = 1:length(a)
4,002✔
155
                root = cconvert(P, a[i])
42,520✔
156
                ptrs[i] = unsafe_convert(P, root)::P
42,520✔
157
                roots[i] = root
42,520✔
158
            end
83,039✔
159
            ptrs[length(a)+1] = C_NULL
2,001✔
160
            return RefArray(ptrs,1,roots)
2,001✔
161
        end
162
    end
163
    Ref(x::AbstractArray, i::Integer) = RefArray(x, i)
22✔
164
end
165

166
cconvert(::Type{Ptr{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a
×
167
cconvert(::Type{Ref{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a
×
168
cconvert(::Type{Ptr{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)
1,958✔
169
cconvert(::Type{Ref{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)
43✔
170

171
# pass NTuple{N,T} as Ptr{T}/Ref{T}
172
cconvert(::Type{Ref{T}}, t::NTuple{N,T}) where {N,T} = Ref{NTuple{N,T}}(t)
4✔
173
cconvert(::Type{Ref{T}}, r::Ref{NTuple{N,T}}) where {N,T} = r
3✔
174
unsafe_convert(::Type{Ref{T}}, r::Ref{NTuple{N,T}}) where {N,T} =
7✔
175
    convert(Ptr{T}, unsafe_convert(Ptr{NTuple{N,T}}, r))
176
unsafe_convert(::Type{Ptr{T}}, r::Ref{NTuple{N,T}}) where {N,T} =
36,978✔
177
    convert(Ptr{T}, unsafe_convert(Ptr{NTuple{N,T}}, r))
178
unsafe_convert(::Type{Ptr{T}}, r::Ptr{NTuple{N,T}}) where {N,T} =
×
179
    convert(Ptr{T}, r)
180

181
###
182

183
getindex(b::RefArray) = b.x[b.i]
4✔
184
setindex!(b::RefArray, x) = (b.x[b.i] = x; b)
2✔
185

186
###
187

188
"""
189
    LLVMPtr{T, AS}
190

191
A pointer type that more closely resembles LLVM semantics: It includes the pointer address
192
space, and will be passed as an actual pointer instead of an integer.
193

194
This type is mainly used to interface with code that has strict requirements about pointers,
195
e.g., intrinsics that are selected based on the address space, or back-ends that require
196
pointers to be identifiable by their types.
197
"""
198
Core.LLVMPtr
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc