caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] Weird GC behaviour
@ 2011-09-27 17:30 Thomas Fischbacher
  2011-09-28 11:19 ` Damien Doligez
  0 siblings, 1 reply; 7+ messages in thread
From: Thomas Fischbacher @ 2011-09-27 17:30 UTC (permalink / raw)
  To: OCaML Mailing List


Dear Camels,

The example below shows GC behaviour which in my view is somewhat
weird: I am building two very similar sorts of hash tables that map
variant types to strings. The parameter "works" (which gets passed
through from the "demo" to the "setup" function) allows one to choose,
when calling the script, whether it behaves properly or shows weird
behaviour.

For Rtag, inlining get_rtag does not make a difference, but for Ftag,
inlining the get_ftag call breaks things both with the interpreter and
compiler, but in different ways.

So... my question is: is there a documented reliable way to avoid this
sort of funny behaviour?!?

=================================
type funny_tag = Ftag of string;;

type funny_ref = Rtag of string ref;;

let get_ftag s = Ftag s;;

let get_rtag s = Rtag (ref s);;

let fin_str ht k =
   let Ftag s = k in
   let () = Printf.printf "Removing str '%s'\n%!" s in
   Hashtbl.remove ht k
;;

let fin_ref ht k =
   let Rtag rs = k in
   let () = Printf.printf "Removing ref '%s'\n%!" !rs in
   Hashtbl.remove ht k
;;


let setup works =
   let ht_str = Hashtbl.create 17 in
   let ht_ref = Hashtbl.create 17 in
   let (funny_str, funny_ref) =
   if works
     then (get_ftag "funny",get_rtag "funny")
     else (Ftag "funny", Rtag (ref "funny"))
   in
   (* Note that they keys used below are equal but not identical to the 
entities above *)
   let () = Hashtbl.add ht_str (Ftag "funny") "situation" in
   let () = Hashtbl.add ht_ref (Rtag (ref "funny")) "situation" in
   let () = Gc.finalise (fin_str ht_str) funny_str in
   let () = Gc.finalise (fin_ref ht_ref) funny_ref in
   ((ht_str,ht_ref),(funny_str,funny_ref))
;;

let left (p,q) = p;;

let demo works =
   let (ht_str,ht_ref) = left (setup works) in
   (* Note that I drop the references on the keys that have finalizers 
registered. *)
   let () = Gc.full_major () in
   let () = Gc.compact () in
   Printf.printf "ht_str entries: %d ht_ref entries: %d\n%!" 
(Hashtbl.length ht_str) (Hashtbl.length ht_ref)
;;

let () = demo (Array.length Sys.argv > 1 && Sys.argv.(1) = "magic");;


(* === Behaviour ===

$ ocaml gc_bug.ml
Removing ref 'funny'
ht_str entries: 1 ht_ref entries: 0

$ ocaml gc_bug.ml magic
Removing ref 'funny'
Removing str 'funny'
ht_str entries: 0 ht_ref entries: 0

$ ocamlopt -o gc_bug gc_bug.ml

$ ./gc_bug
Fatal error: exception Invalid_argument("Gc.finalise")

$ ./gc_bug magic
Removing ref 'funny'
Removing str 'funny'
ht_str entries: 0 ht_ref entries: 0

$ ocaml
         Objective Caml version 3.12.0

#

$ uname -prs
FreeBSD 9.0-BETA3 amd64

============ *)

=================================

-- 
best regards,
Thomas Fischbacher
t.fischbacher@soton.ac.uk

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-09-28 23:32 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-27 17:30 [Caml-list] Weird GC behaviour Thomas Fischbacher
2011-09-28 11:19 ` Damien Doligez
2011-09-28 11:53   ` Thomas Fischbacher
2011-09-28 12:12     ` Gabriel Scherer
2011-09-28 13:07     ` John Carr
2011-09-28 15:30     ` Damien Doligez
2011-09-28 23:32       ` Philippe Wang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).