Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: [Caml-list] Native compiler support for m68k?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Xavier Leroy <xavier.leroy@i...>
Subject: Re: [Caml-list] GC Question
> in the following kind code :
> 
> let l = ... a function building a long list ... in
> let l' = List.map fn l in (* or fold or anything similar *)
> ... no more reference to l ...
> 
> Once the beginning of l has been read to compute l' (assuming List.map 
> starts from the beginning of l) is the GC able to collect the beginning 
> of l ?

Short answer: with ocamlc, no.  With ocamlopt, yes.

Longer answer: in the bytecoded implementation, every value in the VM
stack is a GC root.  "let x = e in e'" pushes the value of e on the
stack just before evaluating e', and pops it at the end of e'.  So,
the value of e remains a live GC root throughout the evaluation of e'.

In the native-code implementation, not all machine stack entries are
GC roots, but only the stack slots that hold a variable of type
address that is live at the point where the GC is called.  ("Live"
here is in the sense of liveness analysis of local variables.)
In your example, "l" is not live across the call to "List.map fn l".

> If not how to write the code to ensure this behaviour of the GC ?

As other mentioned, removing the outer "let" gives the desired GC
behavior even in bytecode:

        List.map fn l (... list builder ...)

In the OCaml sources, you can find this strange-looking idiom:

      let (++) x f = f x

      Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number
      ++ print_if ppf Clflags.dump_parsetree Printast.implementation
      ++ Typemod.type_implementation sourcefile prefixname modulename env
      ++ Translmod.transl_implementation modulename
      ++ print_if ppf Clflags.dump_rawlambda Printlambda.lambda
      ++ Simplif.simplify_lambda
      ++ print_if ppf Clflags.dump_lambda Printlambda.lambda
      ++ Bytegen.compile_implementation modulename
      ++ print_if ppf Clflags.dump_instr Printinstr.instrlist
      ++ Emitcode.to_file oc modulename;

which is a nicer way of writing

      Emitcode.to_file oc modulename
        (print_if ....
          (Bytegen.compile_implementation ...
             (print_if ...
                (...
                ))))

and gives better GC behavior than the obvious:

      let x1 = Pparse.file ppf inputfile Parse.implementation ast_impl_magic_number in
      let x2 = print_if ppf Clflags.dump_parsetree Printast.implementation p x1 in
      let x3 = Typemod.type_implementation sourcefile prefixname modulename env x2 in
      ...

- Xavier Leroy

-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners