cobbpg/elerea — pull request #5 by takano-akio (2012-03-26 08:07:43+00:00)
Title: Aggressive inlining can make elerea misbehave

The following program works correctly when compiled with GHC 7.0.4 and '-O2'. However, when it is compiled with '-O2 -funfolding-use-threshold=100', it prints "0 1 2 2 2" instead of "0 1 2 3 4".

```haskell
import FRP.Elerea.Simple
import System.Mem

main :: IO ()
main = do
sample <- start $ listToSignal [0..]
sample >>= print
sample >>= print
performGC
sample >>= print
sample >>= print
sample >>= print

listToSignal :: [a] -> SignalGen (Signal a)
listToSignal xs = fmap (fmap head) $ stateful xs tail
```

I believe this problem is caused by a bad interaction between inlining and weak pointers. In Simple.hs, addSignal calls mkWeak to create a weak pointer whose key is the new signal, but if sig gets inlined into the call to mkWeak, it ends up creating a weak pointer whose key is a lambda. Since the lambda is referenced from nowhere else, it will soon get garbage-collected, causing the weak pointer to be invalidated prematurely.

My commit tries to fix the problem by marking sig NOINLINE. It makes the above example work, but I'm not 100% sure that this is the correct fix.