From b66fee5c9991330aa8256b9bf7ba3cc967775aef Mon Sep 17 00:00:00 2001 From: Tim Holy Date: Wed, 24 Jun 2020 09:04:16 -0500 Subject: [PATCH] Ensure string-hashing is defined before it gets used An analysis of invalidations during bootstrap revealed that `log_record_id` calls `hash` on strings, and in principle it is used before the specialized methods are defined. Since the new methods change the value of the hash is expected to change, this could cause subtle bugs. It seems safer to define the hash methods at around the first time they could conceivably be defined. --- base/hashing.jl | 10 ++++++++++ base/hashing2.jl | 11 ----------- base/strings/basic.jl | 4 ++++ base/strings/substring.jl | 5 +++++ 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/base/hashing.jl b/base/hashing.jl index 7b962a58ad5ad..f40ccb50f0f5b 100644 --- a/base/hashing.jl +++ b/base/hashing.jl @@ -75,3 +75,13 @@ else hash(x::Expr, h::UInt) = hash(x.args, hash(x.head, h + 0x96d26dc6)) hash(x::QuoteNode, h::UInt) = hash(x.value, h + 0x469d72af) end + +## hashing strings ## + +const memhash = UInt === UInt64 ? :memhash_seed : :memhash32_seed +const memhash_seed = UInt === UInt64 ? 0x71e729fd56419c81 : 0x56419c81 + +function hash(s::String, h::UInt) + h += memhash_seed + ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), s, sizeof(s), h % UInt32) + h +end diff --git a/base/hashing2.jl b/base/hashing2.jl index ec670759ca6bd..f7ea3838aa096 100644 --- a/base/hashing2.jl +++ b/base/hashing2.jl @@ -230,14 +230,3 @@ end ## hashing Float16s ## hash(x::Float16, h::UInt) = hash(Float64(x), h) - -## hashing strings ## - -const memhash = UInt === UInt64 ? :memhash_seed : :memhash32_seed -const memhash_seed = UInt === UInt64 ? 0x71e729fd56419c81 : 0x56419c81 - -function hash(s::Union{String,SubString{String}}, h::UInt) - h += memhash_seed - ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), s, sizeof(s), h % UInt32) + h -end -hash(s::AbstractString, h::UInt) = hash(String(s), h) diff --git a/base/strings/basic.jl b/base/strings/basic.jl index ccbb2ef16cfbc..0fde8bd1ffcd4 100644 --- a/base/strings/basic.jl +++ b/base/strings/basic.jl @@ -347,6 +347,10 @@ cmp(a::Symbol, b::Symbol) = Int(sign(ccall(:strcmp, Int32, (Cstring, Cstring), a isless(a::Symbol, b::Symbol) = cmp(a, b) < 0 +# hashing + +hash(s::AbstractString, h::UInt) = hash(String(s), h) + ## character index arithmetic ## """ diff --git a/base/strings/substring.jl b/base/strings/substring.jl index 73288ea363046..abb22b412f993 100644 --- a/base/strings/substring.jl +++ b/base/strings/substring.jl @@ -122,6 +122,11 @@ end pointer(x::SubString{String}) = pointer(x.string) + x.offset pointer(x::SubString{String}, i::Integer) = pointer(x.string) + x.offset + (i-1) +function hash(s::SubString{String}, h::UInt) + h += memhash_seed + ccall(memhash, UInt, (Ptr{UInt8}, Csize_t, UInt32), s, sizeof(s), h % UInt32) + h +end + """ reverse(s::AbstractString) -> AbstractString