Skip to content

Commit f631597

Browse files
authored
minor cleanups to MemoryRef (JuliaLang#51937)
1 parent 69a4ecb commit f631597

File tree

5 files changed

+33
-24
lines changed

5 files changed

+33
-24
lines changed

base/abstractarray.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,8 @@ the other elements are left untouched.
10341034
10351035
See also [`copy!`](@ref Base.copy!), [`copy`](@ref).
10361036
1037+
$(_DOCS_ALIASING_WARNING)
1038+
10371039
# Examples
10381040
```jldoctest
10391041
julia> x = [1., 0., 3., 0., 5.];

base/array.jl

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,6 @@ source and `do` in the destination (1-indexed).
276276
The `unsafe` prefix on this function indicates that no validation is performed to ensure
277277
that N is inbounds on either array. Incorrect usage may corrupt or segfault your program, in
278278
the same manner as C.
279-
280-
$(_DOCS_ALIASING_WARNING)
281279
"""
282280
function unsafe_copyto!(dest::Array, doffs, src::Array, soffs, n)
283281
n == 0 && return dest
@@ -291,24 +289,26 @@ end
291289
Copy `N` elements from collection `src` starting at the linear index `so`, to array `dest` starting at
292290
the index `do`. Return `dest`.
293291
"""
294-
function copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
295-
return _copyto_impl!(dest, doffs, src, soffs, n)
296-
end
292+
copyto!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
293+
copyto!(dest::Array, doffs::Integer, src::Memory, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
294+
copyto!(dest::Memory, doffs::Integer, src::Array, soffs::Integer, n::Integer) = _copyto_impl!(dest, doffs, src, soffs, n)
297295

298296
# this is only needed to avoid possible ambiguities with methods added in some packages
299-
function copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where T
300-
return _copyto_impl!(dest, doffs, src, soffs, n)
301-
end
297+
copyto!(dest::Array{T}, doffs::Integer, src::Array{T}, soffs::Integer, n::Integer) where {T} = _copyto_impl!(dest, doffs, src, soffs, n)
302298

303-
function _copyto_impl!(dest::Array, doffs::Integer, src::Array, soffs::Integer, n::Integer)
299+
function _copyto_impl!(dest::Union{Array,Memory}, doffs::Integer, src::Union{Array,Memory}, soffs::Integer, n::Integer)
304300
n == 0 && return dest
305301
n > 0 || _throw_argerror("Number of elements to copy must be non-negative.")
306302
@boundscheck checkbounds(dest, doffs:doffs+n-1)
307303
@boundscheck checkbounds(src, soffs:soffs+n-1)
308-
unsafe_copyto!(dest, doffs, src, soffs, n)
304+
@inbounds let dest = GenericMemoryRef(dest isa Array ? getfield(dest, :ref) : dest, doffs)
305+
src = GenericMemoryRef(src isa Array ? getfield(src, :ref) : src, soffs)
306+
unsafe_copyto!(dest, src, n)
307+
end
309308
return dest
310309
end
311310

311+
312312
# Outlining this because otherwise a catastrophic inference slowdown
313313
# occurs, see discussion in #27874.
314314
# It is also mitigated by using a constant string.

base/genericmemory.jl

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ end
6868
@eval isassigned(a::GenericMemoryRef) = memoryref_isassigned(a, :not_atomic, $(Expr(:boundscheck)))
6969

7070
## copy ##
71-
@eval function unsafe_copyto!(dest::MemoryRef{T}, src::MemoryRef{T}, n) where {T}
71+
function unsafe_copyto!(dest::MemoryRef{T}, src::MemoryRef{T}, n) where {T}
7272
@_terminates_globally_meta
7373
n == 0 && return dest
7474
@boundscheck GenericMemoryRef(dest, n), GenericMemoryRef(src, n)
@@ -118,6 +118,13 @@ end
118118

119119
copy(a::T) where {T<:Memory} = ccall(:jl_genericmemory_copy, Ref{T}, (Any,), a)
120120

121+
function copyto!(dest::Memory, doffs::Integer, src::Memory, soffs::Integer, n::Integer)
122+
n < 0 && _throw_argerror("Number of elements to copy must be non-negative.")
123+
unsafe_copyto!(dest, doffs, src, soffs, n)
124+
return dest
125+
end
126+
127+
121128
## Constructors ##
122129

123130
similar(a::Memory{T}) where {T} = Memory{T}(undef, length(a))

doc/src/manual/embedding.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,14 +432,14 @@ object has just been allocated and no garbage collection has run since then. Not
432432
`jl_...` functions can sometimes invoke garbage collection.
433433

434434
The write barrier is also necessary for arrays of pointers when updating their data directly.
435-
For example:
435+
Calling `jl_array_ptr_set` is usually much preferred. But direct updates can be done. For example:
436436

437437
```c
438438
jl_array_t *some_array = ...; // e.g. a Vector{Any}
439439
void **data = jl_array_data(some_array, void*);
440440
jl_value_t *some_value = ...;
441441
data[0] = some_value;
442-
jl_gc_wb(some_array, some_value);
442+
jl_gc_wb(jl_array_owner(some_array), some_value);
443443
```
444444
445445
### Controlling the Garbage Collector

stdlib/Base64/src/buffer.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,37 @@
22

33
# Data buffer for pipes.
44
mutable struct Buffer
5-
data::Memory{UInt8}
6-
ptr::Ptr{UInt8}
5+
const data::Memory{UInt8}
6+
offset::Int
77
size::Int
88

99
function Buffer(bufsize)
1010
data = Memory{UInt8}(undef, bufsize)
11-
return new(data, pointer(data), 0)
11+
return new(data, 0, 0)
1212
end
1313
end
1414

1515
Base.empty!(buffer::Buffer) = buffer.size = 0
16-
Base.getindex(buffer::Buffer, i::Integer) = unsafe_load(buffer.ptr, i)
17-
Base.setindex!(buffer::Buffer, v::UInt8, i::Integer) = unsafe_store!(buffer.ptr, v, i)
16+
Base.getindex(buffer::Buffer, i::Integer) = buffer.data[buffer.offset + i]
17+
Base.setindex!(buffer::Buffer, v::UInt8, i::Integer) = buffer.data[buffer.offset + i] = v
1818
Base.firstindex(buffer::Buffer) = 1
1919
Base.lastindex(buffer::Buffer) = buffer.size
20-
Base.pointer(buffer::Buffer) = buffer.ptr
21-
capacity(buffer::Buffer) = Int(pointer(buffer.data, lastindex(buffer.data)) - buffer.ptr) + 1
20+
Base.pointer(buffer::Buffer) = pointer(buffer.data) + buffer.offset
21+
capacity(buffer::Buffer) = length(buffer.data) - buffer.offset
2222

2323
function consumed!(buffer::Buffer, n::Integer)
2424
@assert n buffer.size
25-
buffer.ptr += n
25+
buffer.offset += n
2626
buffer.size -= n
2727
end
2828

2929
function read_to_buffer(io::IO, buffer::Buffer)
30-
offset = buffer.ptr - pointer(buffer.data)
30+
offset = buffer.offset
3131
copyto!(buffer.data, 1, buffer.data, offset + 1, buffer.size)
32-
buffer.ptr = pointer(buffer.data)
32+
buffer.offset = 0
3333
if !eof(io)
3434
n = min(bytesavailable(io), capacity(buffer) - buffer.size)
35-
unsafe_read(io, buffer.ptr + buffer.size, n)
35+
unsafe_read(io, pointer(buffer) + buffer.size, n)
3636
buffer.size += n
3737
end
3838
return

0 commit comments

Comments
 (0)