let ram = 100 let memory = Array.make ram 0Un bloc de taille n situé à l'adresse p est représenté de la manière suivante : memory.(p) contient n (la taille du bloc) et memory.(p+1), ..., memory.(p+n) contiennent les n champs. On note en particulier que n+1 éléments du tableau memory sont donc utilisés.
Les racines sont déclarées dans un tableau à part, roots :
let max_roots = 10 let roots = Array.make max_roots (-1)
Les valeurs contenues dans les champs et dans les racines sont interprétées de la manière suivante : tout entier compris entre 0 (au sens large) et ram au sens strict est considéré comme un pointeur ; tout autre entier est considéré comme autre chose.
val stop_and_copy : int -> int -> intqui prend comme argument le début de la zone from_space et le début de la zone to_space et déplace les blocs vivants de from_space vers to_space. (On pourra supposer que les deux zones ont chacune la taille ram/2.) La valeur renvoyée est le premier emplacement libre dans to_space à l'issue de la copie.
Pour visualiser l'effet de la collection (en particulier dans les tests proposés plus loin), on pourra afficher un message du type
mémoire occupée après collection = 15 motsjuste avant de renvoyer le résultat.
val alloc : int -> intqui prend en argument une taille de bloc et renvoie l'emplacement du bloc alloué. Si le bloc ne peut être alloué directement, cette fonction doit appeler stop_and_copy pour libérer de la mémoire. Si le bloc ne peut toujours pas être alloué à l'issue de la collection, on lèvera l'exception Failure "out of memory".
Bien entendu, une ou deux références sont nécessaires pour contenir l'état du GC ; à vous de les choisir et de les déclarer. Pour les besoins des tests qui suivent, on écrira également une fonction
val reset : unit -> unitqui réinitialise le GC.
Compiler avec
ocamlopt stop_and_copy.ml tri.ml -o td11et lancer le programme obtenu (avec ./td11). On doit obtenir quelque chose comme
tri 3 -515,-148,-235, -515,-235,-148, tri 10 -898,-429,-588,-976,-77,-759,-196,-857,-751,-674, mémoire occupée après collection = 9 mots mémoire occupée après collection = 15 mots mémoire occupée après collection = 27 mots -976,-898,-857,-759,-751,-674,-588,-429,-196,-77, tri 17 mémoire occupée après collection = 48 mots Exception: Failure "out of memory".On pourra bien entendu augmenter la valeur de ram pour des tests plus poussés.
tri 16 -674,-68,-543,-616,-974,-733,-452,-796,-886,-938,-206,-979,-477,-434,-455,-791, mémoire occupée après collection = 0 mots mémoire occupée après collection = 18 mots mémoire occupée après collection = 12 mots mémoire occupée après collection = 30 mots mémoire occupée après collection = 27 mots mémoire occupée après collection = 24 mots mémoire occupée après collection = 6 mots mémoire occupée après collection = 27 mots -979,-974,-938,-886,-796,-791,-733,-674,-616,-543,-477,-455,-452,-434,-206,-68,Comment explique-t-on ce phénomène et pourquoi la liste n'est-elle pas perdue ? (Il faut regarder le code tri.ml pour comprendre.)