#2762: Excessive heap usage
------------------------------+---------------------------------------------
 Reporter:  igloo             |          Owner:                  
     Type:  bug               |         Status:  new             
 Priority:  normal            |      Milestone:  6.10.2          
Component:  Compiler          |        Version:  6.11            
 Severity:  normal            |     Resolution:                  
 Keywords:                    |     Difficulty:  Unknown         
 Testcase:                    |   Architecture:  Unknown/Multiple
       Os:  Unknown/Multiple  |  
------------------------------+---------------------------------------------
Comment (by simonmar):

 Ok, here's what's happening.  The `input` method for `InputOutput [a]`
 gets compiled to this (STG syntax, so we can see the closures):

 {{{
 InputOutput.input1 =
     \r srt:(0,*bitmap*) [$dInputOutput_smx]
         let {
           input2_smz =
               \u srt:(0,*bitmap*) [] InputOutput.input1 $dInputOutput_smx;
 } in
         let {
           sat_snm =
               \r srt:(1,*bitmap*) [ds_smB]
               ...
         } in  sat_snm;
 }}}

 so, `sat_snm` is the function that does the work, and it has `input2_smz`
 as a free variable.

 When this function is called, it allocates closures for `sat_snm` and
 `input2_smz`, and proceeds to enter `sat_snm`.  Eventually this call
 evaluates `input2_smz`, which is another call to `input1`, which creates
 more closures, and so on.

 Normally all these closures would be GC'd immediately, but they don't in
 this example, because the `Main` module has this CAF:

 {{{
 Main.input :: GHC.Base.String -> ([GHC.Types.Char], GHC.Base.String)
 Main.input =
   InputOutput.input1
     @ GHC.Types.Char
     (InputOutput.a `cast` ...)
 }}}

 This CAF evaluates to an unbounded chain of `sat_snm` closures: remember
 `sat_snm` has `input2` as a free var, which itself evaluates to another
 `sat_snm` closure, and so on).  The CAF is retained because it is used by
 the second call to input.

 The solution seems simple: inline `input2`, then the two closures in
 `input1` disappear.  We ought to be able to tell that `input2` is a value
 - perhaps the recursion gets in the way?

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2762#comment:1>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to