Dynamic version, working.
[virt-mem.git] / extract / codegen / minimizer.ml
diff --git a/extract/codegen/minimizer.ml b/extract/codegen/minimizer.ml
new file mode 100644 (file)
index 0000000..ede6a47
--- /dev/null
@@ -0,0 +1,87 @@
+(* Memory info command for virtual domains.
+   (C) Copyright 2008 Richard W.M. Jones, Red Hat Inc.
+   http://libvirt.org/
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *)
+
+open ExtList
+open ExtString
+
+open Printf
+
+module PP = Pahole_parser
+
+type parser_ = {
+  pa_i : int;
+  pa_name : string;
+  pa_endian : Bitstring.endian;
+  pa_structure : Pahole_parser.structure;
+}
+
+and pahash = (string, parser_) Hashtbl.t
+
+let endian_of_architecture arch =
+  if String.starts_with arch "i386" ||
+    String.starts_with arch "i486" ||
+    String.starts_with arch "i586" ||
+    String.starts_with arch "i686" ||
+    String.starts_with arch "x86_64" ||
+    String.starts_with arch "x86-64" then
+      Bitstring.LittleEndian
+  else if String.starts_with arch "ia64" then
+    Bitstring.LittleEndian (* XXX usually? *)
+  else if String.starts_with arch "ppc" then
+    Bitstring.BigEndian
+  else if String.starts_with arch "sparc" then
+    Bitstring.BigEndian
+  else
+    failwith (sprintf "endian_of_architecture: cannot parse %S" arch)
+
+let unique =
+  let i = ref 0 in
+  fun () ->
+    incr i; !i
+
+let hash_values h = Hashtbl.fold (fun _ v vs -> v :: vs) h []
+
+let minimize_parsers struct_name kernels =
+  let h = Hashtbl.create 13 in
+  let rh = Hashtbl.create 13 in
+
+  (* Do not change - see Code_generation.re_subst. *)
+  let name_of i = sprintf "%s_parser_%d" struct_name i in
+
+  List.iter (
+    fun ({ PP.kernel_version = version; arch = arch },
+        ({ PP.struct_fields = fields; struct_name = name_check }
+           as structure)) ->
+      assert (struct_name = name_check);
+      let endian = endian_of_architecture arch in
+      let key = endian, fields in
+      let pa =
+       try Hashtbl.find h key
+       with Not_found ->
+         let i = unique () in
+         let pa = { pa_i = i; pa_name = name_of i;
+                    pa_endian = endian;
+                    pa_structure = structure } in
+         Hashtbl.add h key pa;
+         pa in
+      Hashtbl.add rh version pa
+  ) kernels;
+
+  let pas = hash_values h in
+  pas, rh