
#14789: GHCi fails to garbage collect declaration `l = length [1..10^8]` entered at prompt -------------------------------------+------------------------------------- Reporter: kabuhr | Owner: (none) Type: bug | Status: new Priority: normal | Milestone: Component: GHCi | Version: 8.2.2 Resolution: | Keywords: Operating System: Unknown/Multiple | Architecture: Type of failure: Runtime | Unknown/Multiple performance bug | Test Case: Blocked By: | Blocking: Related Tickets: | Differential Rev(s): Wiki Page: | -------------------------------------+------------------------------------- Comment (by bgamari): Here is the code produced (from `-ddump-rn -ddump-simpl -ddump-bcos`) by the `let l` form, {{{ λ> let l = length [1..10^8] ==================== Renamer ==================== let l_a2bl = length [1 .. 10 ^ 8] ==================== Simplified expression ==================== GHC.Base.returnIO @ [()] (GHC.Types.: @ () ((Data.Foldable.length @ [] Data.Foldable.$fFoldable[] @ GHC.Integer.Type.Integer (GHC.Enum.enumFromTo @ GHC.Integer.Type.Integer GHC.Enum.$fEnumInteger 1 (GHC.Real.^ @ GHC.Integer.Type.Integer @ GHC.Integer.Type.Integer GHC.Num.$fNumInteger GHC.Real.$fIntegralInteger 10 8))) `cast` (UnsafeCo representational GHC.Types.Int () :: (GHC.Types.Int :: *) ~R# (() :: *))) (GHC.Types.[] @ ())) ==================== Proto-BCOs ==================== ProtoBCO ExprTopLevel_E0#0 []: let sat_s3Wi = ... in ... bitmap: 0 [] ALLOC_AP 0 PUSH_BCO ProtoBCO sat_s3Wi#0 []: let sat_s3Wh = ... in ... bitmap: 0 [] ALLOC_AP 0 PUSH_BCO ProtoBCO sat_s3Wh#0 []: let sat_s3Wg = ... in ... bitmap: 0 [] ALLOC_AP 0 PUSH_BCO ProtoBCO sat_s3Wg#0 []: let sat_s3Wf = ... in ... bitmap: 0 [] PUSH_UBX (1) 8# PACK GHC.Integer.Type.S# 1 PUSH_UBX (1) 10# PACK GHC.Integer.Type.S# 1 PUSH_LL 1 0 PUSH_G GHC.Real.$fIntegralInteger PUSH_G GHC.Num.$fNumInteger PUSH_APPLY_PPPP PUSH_G GHC.Real.^ SLIDE 6 2 ENTER MKAP 0 words, 1 stkoff PUSH_UBX (1) 1# PACK GHC.Integer.Type.S# 1 PUSH_LL 1 0 PUSH_G GHC.Enum.$fEnumInteger PUSH_APPLY_PPP PUSH_G GHC.Enum.enumFromTo SLIDE 5 2 ENTER MKAP 0 words, 1 stkoff PUSH_L 0 PUSH_G Data.Foldable.$fFoldable[] PUSH_APPLY_PP PUSH_G Data.Foldable.length SLIDE 4 1 ENTER MKAP 0 words, 1 stkoff PUSH_G GHC.Types.[] PUSH_L 1 PACK : 2 PUSH_L 0 PUSH_APPLY_P PUSH_G GHC.Base.returnIO SLIDE 3 2 ENTER }}} Here is the same output for the `let`-less form, {{{ λ> l = length [1..10^8] ==================== Renamer ==================== interactive:Ghci2.l = length [1 .. 10 ^ 8] ==================== Tidy Core ==================== Result size of Tidy Core = {terms: 25, types: 11, coercions: 0, joins: 0/0} -- RHS size: {terms: 10, types: 5, coercions: 0, joins: 0/0} l :: Int [GblId] l = length @ [] Data.Foldable.$fFoldable[] @ Integer (enumFromTo @ Integer GHC.Enum.$fEnumInteger 1 (^ @ Integer @ Integer GHC.Num.$fNumInteger GHC.Real.$fIntegralInteger 10 8)) -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule1_r3XB :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule1_r3XB = "interactive"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule2_r3XM :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule2_r3XM = GHC.Types.TrNameS $trModule1_r3XB -- RHS size: {terms: 1, types: 0, coercions: 0, joins: 0/0} $trModule3_r3XN :: GHC.Prim.Addr# [GblId, Caf=NoCafRefs] $trModule3_r3XN = "Ghci2"# -- RHS size: {terms: 2, types: 0, coercions: 0, joins: 0/0} $trModule4_r3XO :: GHC.Types.TrName [GblId, Caf=NoCafRefs] $trModule4_r3XO = GHC.Types.TrNameS $trModule3_r3XN -- RHS size: {terms: 3, types: 0, coercions: 0, joins: 0/0} interactive:Ghci2.$trModule :: GHC.Types.Module [GblId, Caf=NoCafRefs] interactive:Ghci2.$trModule = GHC.Types.Module $trModule2_r3XM $trModule4_r3XO ==================== Proto-BCOs ==================== ProtoBCO sat_s3XU#0 []: let sat_s3XT = ... in ... bitmap: 0 [] ALLOC_AP 0 PUSH_BCO ProtoBCO sat_s3XT#0 []: let sat_s3XS = ... in ... bitmap: 0 [] PUSH_UBX (1) 8# PACK GHC.Integer.Type.S# 1 PUSH_UBX (1) 10# PACK GHC.Integer.Type.S# 1 PUSH_LL 1 0 PUSH_G GHC.Real.$fIntegralInteger PUSH_G GHC.Num.$fNumInteger PUSH_APPLY_PPPP PUSH_G GHC.Real.^ SLIDE 6 2 ENTER MKAP 0 words, 1 stkoff PUSH_UBX (1) 1# PACK GHC.Integer.Type.S# 1 PUSH_LL 1 0 PUSH_G GHC.Enum.$fEnumInteger PUSH_APPLY_PPP PUSH_G GHC.Enum.enumFromTo SLIDE 5 2 ENTER ProtoBCO Ghci2.l#0 []: Data.Foldable.length @ [] Data.Foldable.$fFoldable[] @ GHC.Integer.Type.Integer sat_s3XU bitmap: 0 [] PUSH_G sat_s3XU PUSH_G Data.Foldable.$fFoldable[] PUSH_APPLY_PP PUSH_G Data.Foldable.length ENTER ProtoBCO $trModule2_r3XM#0 []: GHC.Types.TrNameS $trModule1_r3XB bitmap: 0 [] PUSH_UBX (1) 26770624## PACK GHC.Types.TrNameS 1 ENTER ProtoBCO $trModule4_r3XO#0 []: GHC.Types.TrNameS $trModule3_r3XN bitmap: 0 [] PUSH_UBX (1) 26770592## PACK GHC.Types.TrNameS 1 ENTER ProtoBCO Ghci2.$trModule#0 []: GHC.Types.Module $trModule2_r3XM $trModule4_r3XO bitmap: 0 [] PUSH_G $trModule4_r3XO PUSH_G $trModule2_r3XM PACK GHC.Types.Module 2 ENTER }}} It looks to me like the BCO pass is somehow floating out the `enumFromTo` application, which then gets retained. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/14789#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler