Skip to content

Commit

Permalink
fix a couple missing GC.at-preserve (JuliaLang#35046)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet authored Mar 9, 2020
1 parent 16bbb40 commit 026b965
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 47 deletions.
4 changes: 4 additions & 0 deletions base/bitset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,11 @@ function ==(s1::BitSet, s2::BitSet)

# compare overlap values
if overlap > 0
t1 = @_gc_preserve_begin a1
t2 = @_gc_preserve_begin a2
_memcmp(pointer(a1, b2-b1+1), pointer(a2), overlap<<3) == 0 || return false
@_gc_preserve_end t2
@_gc_preserve_end t1
end

return true
Expand Down
97 changes: 50 additions & 47 deletions base/hashing2.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ end
if GMP.Limb === UInt
# used e.g. for Rational{BigInt}
function hash_integer(n::BigInt, h::UInt)
s = n.size
s == 0 && return hash_integer(0, h)
p = convert(Ptr{UInt}, n.d)
b = unsafe_load(p)
h ⊻= hash_uint(ifelse(s < 0, -b, b) h)
for k = 2:abs(s)
h ⊻= hash_uint(unsafe_load(p, k) h)
GC.@preserve n begin
s = n.size
s == 0 && return hash_integer(0, h)
p = convert(Ptr{UInt}, n.d)
b = unsafe_load(p)
h ⊻= hash_uint(ifelse(s < 0, -b, b) h)
for k = 2:abs(s)
h ⊻= hash_uint(unsafe_load(p, k) h)
end
return h
end
return h
end
end

Expand Down Expand Up @@ -84,50 +86,52 @@ if GMP.Limb === UInt
_modLimb(n) = UInt === UInt64 ? n & 63 : n & 31

function hash(x::BigInt, h::UInt)
sz = x.size
sz == 0 && return hash(0, h)
ptr = Ptr{UInt}(x.d)
if sz == 1
return hash(unsafe_load(ptr), h)
elseif sz == -1
limb = unsafe_load(ptr)
limb <= typemin(Int) % UInt && return hash(-(limb % Int), h)
end
pow = trailing_zeros(x)
nd = ndigits0z(x, 2)
idx = _divLimb(pow) + 1
shift = _modLimb(pow) % UInt
upshift = GMP.BITS_PER_LIMB - shift
asz = abs(sz)
if shift == 0
limb = unsafe_load(ptr, idx)
else
limb1 = unsafe_load(ptr, idx)
limb2 = idx < asz ? unsafe_load(ptr, idx+1) : UInt(0)
limb = limb2 << upshift | limb1 >> shift
end
if nd <= 1024 && nd - pow <= 53
return hash(ldexp(flipsign(Float64(limb), sz), pow), h)
end
h = hash_integer(1, h)
h = hash_integer(pow, h)
h ⊻= hash_uint(flipsign(limb, sz) h)
for idx = idx+1:asz
GC.@preserve x begin
sz = x.size
sz == 0 && return hash(0, h)
ptr = Ptr{UInt}(x.d)
if sz == 1
return hash(unsafe_load(ptr), h)
elseif sz == -1
limb = unsafe_load(ptr)
limb <= typemin(Int) % UInt && return hash(-(limb % Int), h)
end
pow = trailing_zeros(x)
nd = ndigits0z(x, 2)
idx = _divLimb(pow) + 1
shift = _modLimb(pow) % UInt
upshift = GMP.BITS_PER_LIMB - shift
asz = abs(sz)
if shift == 0
limb = unsafe_load(ptr, idx)
else
limb1 = limb2
if idx == asz
limb = limb1 >> shift
limb == 0 && break # don't hash leading zeros
limb1 = unsafe_load(ptr, idx)
limb2 = idx < asz ? unsafe_load(ptr, idx+1) : UInt(0)
limb = limb2 << upshift | limb1 >> shift
end
if nd <= 1024 && nd - pow <= 53
return hash(ldexp(flipsign(Float64(limb), sz), pow), h)
end
h = hash_integer(1, h)
h = hash_integer(pow, h)
h ⊻= hash_uint(flipsign(limb, sz) h)
for idx = idx+1:asz
if shift == 0
limb = unsafe_load(ptr, idx)
else
limb2 = unsafe_load(ptr, idx+1)
limb = limb2 << upshift | limb1 >> shift
limb1 = limb2
if idx == asz
limb = limb1 >> shift
limb == 0 && break # don't hash leading zeros
else
limb2 = unsafe_load(ptr, idx+1)
limb = limb2 << upshift | limb1 >> shift
end
end
h ⊻= hash_uint(limb h)
end
h ⊻= hash_uint(limb h)
return h
end
return h
end
end

Expand Down Expand Up @@ -234,7 +238,6 @@ const memhash_seed = UInt === UInt64 ? 0x71e729fd56419c81 : 0x56419c81

function hash(s::Union{String,SubString{String}}, h::UInt)
h += memhash_seed
# note: use pointer(s) here (see #6058).
ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), pointer(s), sizeof(s), h % UInt32) + h
ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), s, sizeof(s), h % UInt32) + h
end
hash(s::AbstractString, h::UInt) = hash(String(s), h)

0 comments on commit 026b965

Please sign in to comment.