diff --git a/src/dict.jl b/src/dict.jl index 5899cf6..b28d93e 100644 --- a/src/dict.jl +++ b/src/dict.jl @@ -348,22 +348,24 @@ end @inline value_ref(ref::RefSlotRef) = ImmutableRef(ref.ref[].value.x) -allocate_slot(::AbstractVector{Slot}) where {Slot<:Ref} = forceheap(Slot()) +allocate_slot(::AbstractVector{Slot}) where {Slot<:Ref} = Ref(Slot()) +# One indirection to force heap allocation @inline function cas_slot!( slotref::RefSlotRef{Slot}, - new_slot::Slot, + new_slot_ref::Ref{Slot}, root, key, value, ) where {P,Slot<:Ref{P}} ptr = slotref.ptr + new_slot = new_slot_ref[] new_slot[] = value isa NoValue ? P(key) : P(key, value) - ou = UInt(pointer_from_objref(slotref.ref)) - nu = UInt(pointer_from_objref(new_slot)) - julia_write_barrier(new_slot) - julia_write_barrier(root, new_slot) - GC.@preserve new_slot begin + GC.@preserve new_slot_ref begin + ou = UInt(pointer_from_objref(slotref.ref)) + nu = UInt(unsafe_load(Ptr{Ptr{Cvoid}}(pointer_from_objref(new_slot_ref)))) + julia_write_barrier(new_slot) + julia_write_barrier(root, new_slot) fu = UnsafeAtomics.cas!(Ptr{typeof(nu)}(ptr), ou, nu) end return fu == ou diff --git a/src/utils.jl b/src/utils.jl index 0f0afea..fd5b397 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -166,16 +166,6 @@ end end end -const _FALSE_ = Ref(false) - -# TODO: a teribble hack to force heap-allocation of `x`; can we get rid of it? -@inline function forceheap(x) - if _FALSE_[] - global SINK = x - end - return x -end - @generated function julia_write_barrier(args::Vararg{Any,N}) where {N} pointer_exprs = map(1:N) do i :(_pointer_from_objref(args[$i])) @@ -183,7 +173,7 @@ end jlp = "{} addrspace(10)*" llvm_args = string.("%", 0:N-1) word = "i$(Base.Sys.WORD_SIZE)" - entry_sig = join(word .* llvm_args, ", ") + entry_sig = join(word .* " " .* llvm_args, ", ") ptrs = string.("%ptr", 0:N-1) wb_sig = join("$jlp " .* ptrs, ", ") inttoptr = join(