【问题标题】:reallyUnsafePtrEquality# on constructors with no fieldsrealUnsafePtrEquality# 在没有字段的构造函数上
【发布时间】:2014-08-27 06:07:30
【问题描述】:

据我了解,没有字段的类型的构造函数是“静态分配的”和 GHC shares these between all uses,而 GC will not move these

如果这是正确的,那么我希望在 FalseNothing 这样的值上使用 reallyUnsafePtrEquality# 非常安全(没有误报或误报),因为它们只能表示为指向单个实例的相同指针那个构造函数。

我的推理正确吗?是否有任何潜在的陷阱,或者有理由怀疑这可能在不久的将来版本的 GHC 中变得不安全?

【问题讨论】:

  • 可能是真的。另一方面,对于没有字段的构造函数来说,性能胜过乏味的老 (==) 似乎是非常小的......
  • @DanielWagner 我的实际用例是在盒装引用上使用新的 CAS primops。当使用 atomic-primops 库时,我希望能够缓存 Ticket Nothing(例如)并确保它永远不会过时。
  • 您可能还需要小心插件等。
  • 不,我的意思是那些将代码加载到正在运行的 Haskell 程序中的插件最终可能会得到它们自己的那些空构造函数的副本。我不知道哪种方式,但这是我担心的事情。
  • 我很确定 nullary 构造函数指针被重写为指向 .TEXT 只有在它们幸免于 GC 之后。它们的初始分配和指针仍然指向动态分配的空间,这使得这里提出的技术不安全。

标签: haskell ghc


【解决方案1】:

我实际上设法让reallyUnsafePtrEquality 做错事。

这是我的最小代码示例

{-# LANGUAGE MagicHash #-}
import GHC.Prim

-- Package it up nicely
ptrCmp :: a -> a -> Bool
ptrCmp a b = case (reallyUnsafePtrEquality# a b) of
  0# -> False
  1# -> True

main = do
  b <- readLn
  let a  = if b then Nothing else Just ()
      a' = Nothing
  print $ a == a'     -- Normal
  print $ ptrCmp a a' -- Evil

然后做类似的事情

 $ ghc --version
   The Glorious Glasgow Haskell Compilation System, version 7.8.2
 $ ghc unsafe.hs
 $ ./unsafe
   True
   True
   False

所以...是的,reallyUnsafePtrEquality 仍然是邪恶的。

【讨论】:

  • 值得注意的是,我完全不知道为什么会发生这种情况。只是通过愚蠢的运气和尝试病理案例的结合来反驳这个猜想。如果有人能解释一下..
  • 哦,太棒了,谢谢。当我建议它可能“非常安全”时,我有点超前了,因为我们至少仍然存在将 thunk 与值进行比较的问题,以及内联可能导致的所有并发症。我猜想这里会发生类似的事情,但我看不出是什么......
  • 我认为使用if b then a' else Just () 肯定会成功。我错了。这确实很邪恶:)
  • 奇怪的是,在a 中添加一个爆炸模式会使ptrCmp 返回True。我想我明白为什么没有 bang 模式就无法工作:这是邪恶的。
  • @BenjaminHodgson 这个解释对我来说似乎并不完整; print (a == a') 不强制 aa',在调用 ptrCmp 时让它们成为非 thunk?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多