Small Int and Char closures in GHCi

Hi, I am preparing a talk about the details of how data and programs look in memory in Haskell (well, GHC). When explaining the memory consumption of a large String, I wanted to show the effect of short-int-replacement that happens in http://hackage.haskell.org/trac/ghc/browser/rts/sm/Evac.c#L550 I use my ghc-heap-view-package to observe the heap. This programs shows the effect: import GHC.HeapView import System.Mem main = do let hallo = "hallo" mapM_ (\x -> putStrLn $ show x ++ ": " ++ show (asBox x)) hallo performGC mapM_ (\x -> putStrLn $ show x ++ ": " ++ show (asBox x)) hallo gives, as expected: $ ./SmallChar 'h': 0x00007f2811e042a8/1 'a': 0x00007f2811e08128/1 'l': 0x00007f2811e09ef0/1 'l': 0x00007f2811e0bcd8/1 'o': 0x00007f2811e0db10/1 'h': 0x00000000006d9bd0/1 'a': 0x00000000006d9b60/1 'l': 0x00000000006d9c10/1 'l': 0x00000000006d9c10/1 'o': 0x00000000006d9c40/1 but in GHCi, it does not work: $ runhaskell SmallChar.hs 'h': 0x00007f5334623d58/1 'a': 0x00007f5334626208/1 'l': 0x00007f5334627fc0/1 'l': 0x00007f5334629dc0/1 'o': 0x00007f533462bba8/1 'h': 0x00007f533381a1c8/1 'a': 0x00007f5333672e30/1 'l': 0x00007f533381a408/1 'l': 0x00007f533381a6b8/1 'o': 0x00007f533389c5d0/1 Note that the GC does evacuate the closures, as the pointers change. Why are these not replaced by the static ones here? Thanks, Joachim -- Joachim "nomeata" Breitner mail@joachim-breitner.de | nomeata@debian.org | GPG: 0x4743206C xmpp: nomeata@joachim-breitner.de | http://www.joachim-breitner.de/

On 30/08/2012 12:29, Joachim Breitner wrote:
Hi,
I am preparing a talk about the details of how data and programs look in memory in Haskell (well, GHC). When explaining the memory consumption of a large String, I wanted to show the effect of short-int-replacement that happens in http://hackage.haskell.org/trac/ghc/browser/rts/sm/Evac.c#L550
I use my ghc-heap-view-package to observe the heap. This programs shows the effect:
import GHC.HeapView import System.Mem
main = do let hallo = "hallo" mapM_ (\x -> putStrLn $ show x ++ ": " ++ show (asBox x)) hallo performGC mapM_ (\x -> putStrLn $ show x ++ ": " ++ show (asBox x)) hallo
gives, as expected:
$ ./SmallChar 'h': 0x00007f2811e042a8/1 'a': 0x00007f2811e08128/1 'l': 0x00007f2811e09ef0/1 'l': 0x00007f2811e0bcd8/1 'o': 0x00007f2811e0db10/1 'h': 0x00000000006d9bd0/1 'a': 0x00000000006d9b60/1 'l': 0x00000000006d9c10/1 'l': 0x00000000006d9c10/1 'o': 0x00000000006d9c40/1
but in GHCi, it does not work:
$ runhaskell SmallChar.hs 'h': 0x00007f5334623d58/1 'a': 0x00007f5334626208/1 'l': 0x00007f5334627fc0/1 'l': 0x00007f5334629dc0/1 'o': 0x00007f533462bba8/1 'h': 0x00007f533381a1c8/1 'a': 0x00007f5333672e30/1 'l': 0x00007f533381a408/1 'l': 0x00007f533381a6b8/1 'o': 0x00007f533389c5d0/1
Note that the GC does evacuate the closures, as the pointers change. Why are these not replaced by the static ones here?
Probably because GHCi has a dynamically loaded copy of the base package, so the pointer comparisons that the GC is doing do not match the dynamically-loaded I# and C# constructors. Cheers, Simon

Hi, Am Freitag, den 31.08.2012, 13:14 +0100 schrieb Simon Marlow:
Note that the GC does evacuate the closures, as the pointers change. Why are these not replaced by the static ones here?
Probably because GHCi has a dynamically loaded copy of the base package, so the pointer comparisons that the GC is doing do not match the dynamically-loaded I# and C# constructors.
could be; I could not find a way to verify it. I tried comparing the info pointers of a "1::Int" that I generated in ghci and one that comes from a statically compiled module loaded into ghci, but that is probably also linked against GHHi’s dynamically loaded base. But if it is really the case that the RTS has different copies of base, wouldn’t code like this then break? if (i == &stg_TSO_info || i == &stg_WHITEHOLE_info || i == &stg_BLOCKING_QUEUE_CLEAN_info || i == &stg_BLOCKING_QUEUE_DIRTY_info) { copy(p,info,q,sizeofW(StgInd),gen_no); return; } (http://hackage.haskell.org/trac/ghc/browser/rts/sm/Evac.c#L635) Or is it, by accident or careful design, the case that all the instances where the RTS compares info pointers with well known pointers are not relevant when running in GHCi? Thanks, Joachim -- Joachim "nomeata" Breitner mail@joachim-breitner.de | nomeata@debian.org | GPG: 0x4743206C xmpp: nomeata@joachim-breitner.de | http://www.joachim-breitner.de/
participants (2)
-
Joachim Breitner
-
Simon Marlow