[project @ 1999-01-23 18:10:00 by sof]
[ghc-hetmet.git] / ghc / tests / codeGen / should_run / cg021.hs
1 -- !!! Tests garbage collection in the branch of a case
2 -- !!!  alternative where the constructor is returned in the heap.
3
4 {- This is also a rather stressful test for another reason.
5    The mutual recursion between munch and f causes lots of
6    closures to be built, of the form (munch n s), for some n and s.
7    Now, all of these closures are entered and each has as its value
8    the result delivere by the next; so the result is that there is
9    a massive chain of identical updates.
10
11    As it turns out, they are mostly garbage, so the GC could eliminate
12    them (though this isn't implemented at present), but that isn't
13    necessarily the case.  
14
15    The only correct solution is to spot that the updates are all
16    updating with the same value (update frames stacked on top of each
17    other), and update all but one with indirections to the last
18    remaining one.  This could be done by GC, or at the moment the
19    frame is pushed.
20
21    Incidentally, hbc won't have this particular problem, because it
22    updates immediately.
23
24    NOTE: [March 97]  Now that stack squeezing happens when GC happens,
25    the stack is squished at GC.  So this program uses a small stack
26    in a small heap (eg 4m heap 2m stack), but in a big heap (no GC)
27    it needs a much bigger stack (10m)!  It would be better to try GC/stack
28    squeezing on stack oflo.
29 -}
30
31 module Main where
32
33 main = munch 100000 (inf 3)
34
35 data Stream a
36   = MkStream a a a a a a a a a (Stream a)
37   | Empty
38
39 inf :: Int -> Stream Int
40 inf n = MkStream n n n n n n n n n (inf n)
41
42 munch :: Int -> Stream a -> IO ()
43
44 munch n Empty = return () -- error "this never happens!\n"
45     -- this first equation mks it non-strict in "n"
46     -- (NB: call the "error" makes it strict)
47
48 munch 0 _ = putStr "I succeeded!\n"
49 munch n s = case (f n s) of
50               (True, rest) -> rest
51               (False, _)   -> error "this never happens either\n"
52
53 --f :: Int -> Stream a -> (Bool, [Request])
54
55 f n (MkStream _ _ _ _ _ _ _ _ _ rest)
56   = -- garbage collection *HERE*, please!
57     -- (forced by the closure for n-1)
58     (True, munch (n - 1) rest)
59
60 -- munch and f are mutually recursive, just to be nasty