Skip to content

unsafePerformIO prevents space leak?

Sadly, I don't have a concrete testcase for this, but I've fixed this issue in the Bluespec compiler more than once, so I have a strong suspicion that there's a GHC bug (or lack of optimization) going on here.

The basic situation is that I have a deeply nested structures of IORefs (I once measured one particular instance as including chains over 300 IORefs deep). I want to walk this structure recursively (it does not contain loops) without mutating it to compute a property of this structure. Generally speaking I'm either looking to accumulate certain kinds of nodes or I'm looking to detect the presence or absence of a certain kind of node.

If I traverse this structure in the IO monad (using readIORef directly and recursing and combining using things like mapM and foldM) I see a huge space leak (which can be confirmed with profiling). If I take the same traversal and wrap up the readIORef inside an unsafePerformIO (and change mapM to map and the like) the space leak disappears. This surprised me because I thought it would be the sort of thing GHC could figure out.

I'm sorry I can't easily give you a testcase, but I hope I've included enough detail that you have a fighting chance of reproducing it. Please let me know if you have any questions.

Trac metadata
Trac field Value
Version 6.8.2
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component Compiler
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture Multiple
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information