From acb976fa578b2a8bb8d2ba60fdd857f7d5f63e85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Fri, 7 Jun 2024 09:35:48 +0200 Subject: [PATCH] [region] Ivette memory diagram --- .../src/frama-c/plugins/region/api/index.ts | 38 ++-- ivette/src/frama-c/plugins/region/memory.tsx | 37 +++- src/plugins/region/analysis.ml | 4 +- src/plugins/region/code.ml | 6 +- src/plugins/region/memory.ml | 190 +++++++++++------- src/plugins/region/memory.mli | 39 ++-- src/plugins/region/services.ml | 28 +-- src/plugins/region/services.mli | 2 +- 8 files changed, 224 insertions(+), 120 deletions(-) diff --git a/ivette/src/frama-c/plugins/region/api/index.ts b/ivette/src/frama-c/plugins/region/api/index.ts index f2264c6eb57..2e05e72283f 100644 --- a/ivette/src/frama-c/plugins/region/api/index.ts +++ b/ivette/src/frama-c/plugins/region/api/index.ts @@ -65,38 +65,46 @@ export const byNode: Compare.Order<node> = Compare.number; /** Default value for `node` */ export const nodeDefault: node = Json.jIndex<'#node'>('#node')(-1); -export type range = { offset: number, length: number, data: node }; +export type range = + { offset: number, length: number, cells: number, data: node }; /** Decoder for `range` */ export const jRange: Json.Decoder<range> = - Json.jObject({ offset: Json.jNumber, length: Json.jNumber, data: jNode,}); + Json.jObject({ + offset: Json.jNumber, + length: Json.jNumber, + cells: Json.jNumber, + data: jNode, + }); /** Natural order for `range` */ export const byRange: Compare.Order<range> = Compare.byFields - <{ offset: number, length: number, data: node }>({ + <{ offset: number, length: number, cells: number, data: node }>({ offset: Compare.number, length: Compare.number, + cells: Compare.number, data: byNode, }); /** Default value for `range` */ export const rangeDefault: range = - { offset: 0, length: 0, data: nodeDefault }; + { offset: 0, length: 0, cells: 0, data: nodeDefault }; export type region = - { roots: string[], parents: node[], sizeof: number, ranges: range[], - pointsTo?: node, reads: boolean, writes: boolean, shifts: boolean, - types: marker[] }; + { node: node, roots: string[], parents: node[], sizeof: number, + ranges: range[], pointed?: node, reads: boolean, writes: boolean, + shifts: boolean, types: marker[] }; /** Decoder for `region` */ export const jRegion: Json.Decoder<region> = Json.jObject({ + node: jNode, roots: Json.jArray(Json.jString), parents: Json.jArray(jNode), sizeof: Json.jNumber, ranges: Json.jArray(jRange), - pointsTo: Json.jOption(jNode), + pointed: Json.jOption(jNode), reads: Json.jBoolean, writes: Json.jBoolean, shifts: Json.jBoolean, @@ -106,14 +114,15 @@ export const jRegion: Json.Decoder<region> = /** Natural order for `region` */ export const byRegion: Compare.Order<region> = Compare.byFields - <{ roots: string[], parents: node[], sizeof: number, ranges: range[], - pointsTo?: node, reads: boolean, writes: boolean, shifts: boolean, - types: marker[] }>({ + <{ node: node, roots: string[], parents: node[], sizeof: number, + ranges: range[], pointed?: node, reads: boolean, writes: boolean, + shifts: boolean, types: marker[] }>({ + node: byNode, roots: Compare.array(Compare.alpha), parents: Compare.array(byNode), sizeof: Compare.number, ranges: Compare.array(byRange), - pointsTo: Compare.defined(byNode), + pointed: Compare.defined(byNode), reads: Compare.boolean, writes: Compare.boolean, shifts: Compare.boolean, @@ -122,8 +131,9 @@ export const byRegion: Compare.Order<region> = /** Default value for `region` */ export const regionDefault: region = - { roots: [], parents: [], sizeof: 0, ranges: [], pointsTo: undefined, - reads: false, writes: false, shifts: false, types: [] }; + { node: nodeDefault, roots: [], parents: [], sizeof: 0, ranges: [], + pointed: undefined, reads: false, writes: false, shifts: false, types: [] + }; const compute_internal: Server.ExecRequest<decl,null> = { kind: Server.RqKind.EXEC, diff --git a/ivette/src/frama-c/plugins/region/memory.tsx b/ivette/src/frama-c/plugins/region/memory.tsx index 2a7b1f3fa98..30373baf677 100644 --- a/ivette/src/frama-c/plugins/region/memory.tsx +++ b/ivette/src/frama-c/plugins/region/memory.tsx @@ -29,14 +29,49 @@ import * as Dot from 'dome/graph/diagram'; import * as States from 'frama-c/states'; import * as Region from './api'; -function makeDiagram(_regions: Region.region[]) : Dot.DiagramProps { +function makeDiagram(regions: Region.region[]): Dot.DiagramProps { const nodes: Dot.Node[] = []; const edges: Dot.Edge[] = []; + regions.forEach(r => { + const id = `n${r.node}`; + const ht = r.types.length; + const color = + ht > 1 ? 'red' : + r.pointed !== undefined + ? (r.writes ? 'orange' : 'yellow') + : (r.writes && r.reads) ? 'green' : + r.writes ? 'pink' : r.reads ? 'grey' : 'white'; + const label = + (r.reads ? 'R' : '') + (r.writes ? 'W' : '') + + (r.pointed !== undefined ? '*' : ''); + const cells = + r.ranges.map((rg, i): Dot.Cell => { + const port = `r${i}`; + const target = `n${rg.data}`; + edges.push({ source: id, sourcePort: port, target }); + return ({ + label: `${rg.offset}..${rg.offset + rg.length - 1} [${rg.cells}]`, + port, + }); + }); + const shape = cells.length > 0 ? cells : undefined; + nodes.push({ id: id, color, label, shape }); + r.roots.forEach(x => { + const xid = `X${x}`; + nodes.push({ id: xid, label: x, shape: 'folder', color: 'blue' }); + edges.push({ source: xid, target: id }); + }); + if (r.pointed !== undefined) { + const pid = `n${r.pointed}`; + edges.push({ source: id, target: pid, head: 'dot', color: 'orange' }); + } + }); return { nodes, edges }; } export function MemoryView(): JSX.Element { const scope = States.useCurrentScope(); + // eslint-disable-next-line react-hooks/exhaustive-deps const regions = States.useRequest(Region.regions, scope) ?? []; const diagram = React.useMemo(() => makeDiagram(regions), [regions]); return <Dot.Diagram display={regions.length > 0} {...diagram} />; diff --git a/src/plugins/region/analysis.ml b/src/plugins/region/analysis.ml index 58d131f5b4f..ae65c3fdca9 100644 --- a/src/plugins/region/analysis.ml +++ b/src/plugins/region/analysis.ml @@ -60,9 +60,9 @@ let get kf = Kernel_function.pretty kf begin fun fmt -> Memory.iter domain.map - begin fun r m -> + begin fun r -> Format.pp_print_newline fmt () ; - Memory.pp_region fmt r m ; + Memory.pp_region fmt r ; end end ; domain diff --git a/src/plugins/region/code.ml b/src/plugins/region/code.ml index b2fd6328fb5..c7f3e43ccf4 100644 --- a/src/plugins/region/code.ml +++ b/src/plugins/region/code.ml @@ -72,7 +72,7 @@ and exp (m: map) (s:stmt) (e:exp) : node option = Memory.read m rv (Lval(s,lv)) ; if Cil.isPointerType @@ Cil.typeOfLval lv then let rp = cell m () in - Memory.pointer m rv rp ; + Memory.points_to m rv rp ; Some rp else None @@ -113,7 +113,7 @@ let rec init (m:map) (s:stmt) (acs:Access.acs) (lv:lval) (iv:init) = | SingleInit e -> let r = lval m s lv in Memory.write m r acs ; - Option.iter (Memory.pointer m r) (exp m s e) + Option.iter (Memory.points_to m r) (exp m s e) | CompoundInit(_,fvs) -> List.iter @@ -134,7 +134,7 @@ let instr (m:map) (s:stmt) (instr:instr) = let r = lval m s lv in let v = exp m s e in Memory.write m r (Lval(s,lv)) ; - Option.iter (Memory.pointer m r) v + Option.iter (Memory.points_to m r) v | Local_init(x,AssignInit iv,_) -> let acs = Access.Init(s,x) in diff --git a/src/plugins/region/memory.ml b/src/plugins/region/memory.ml index ae480509a44..2ac7d0d25ef 100644 --- a/src/plugins/region/memory.ml +++ b/src/plugins/region/memory.ml @@ -31,26 +31,26 @@ module Vmap = Varinfo.Map (* All offsets in bits *) -type node = region Ufind.rref +type node = chunk Ufind.rref and layout = | Blob | Cell of int * node option | Compound of int * node Ranges.t -and region = { - parents: node list ; - roots: varinfo list ; - reads: Access.Set.t ; - writes: Access.Set.t ; - shifts: Access.Set.t ; - layout: layout ; +and chunk = { + cparents: node list ; + croots: varinfo list ; + creads: Access.Set.t ; + cwrites: Access.Set.t ; + cshifts: Access.Set.t ; + clayout: layout ; } -type range = node Ranges.range +type rg = node Ranges.range type map = { - store: region Ufind.store ; + store: chunk Ufind.store ; mutable index: node Vmap.t ; } @@ -59,15 +59,15 @@ type map = { (* -------------------------------------------------------------------------- *) let sizeof = function Blob -> 0 | Cell(s,_) | Compound(s,_) -> s -let points_to = function Blob | Compound _ -> None | Cell(_,p) -> p let ranges = function Blob | Cell _ -> [] | Compound(_,R rs) -> rs +let pointed = function Blob | Compound _ -> None | Cell(_,p) -> p -let types (m : region) : typ list = +let types (m : chunk) : typ list = let pool = ref Typ.Set.empty in let add acs = pool := Typ.Set.add (Cil.unrollType @@ Access.typeof acs) !pool in - Access.Set.iter add m.reads ; - Access.Set.iter add m.writes ; + Access.Set.iter add m.creads ; + Access.Set.iter add m.cwrites ; Typ.Set.elements !pool (* -------------------------------------------------------------------------- *) @@ -83,29 +83,30 @@ let pp_layout fmt = function | Compound(s,rg) -> Format.fprintf fmt "@[<hv 0>{%04d" s ; Ranges.iteri - (fun (rg : range) -> + (fun (rg : rg) -> Format.fprintf fmt "@ | %a: %a" Ranges.pp_range rg pp_node rg.data ) rg ; Format.fprintf fmt "@ }@]" -let pp_region fmt (n: node) (m: region) = +let pp_chunk fmt (n: node) (m: chunk) = begin let acs r s = if Access.Set.is_empty s then '-' else r in Format.fprintf fmt "@[<hov 2>%a: %c%c%c" pp_node n - (acs 'R' m.reads) (acs 'W' m.writes) (acs 'A' m.shifts) ; + (acs 'R' m.creads) (acs 'W' m.cwrites) (acs 'A' m.cshifts) ; List.iter (Format.fprintf fmt "@ (%a)" Typ.pretty) (types m) ; - List.iter (Format.fprintf fmt "@ %a" Varinfo.pretty) m.roots ; + List.iter (Format.fprintf fmt "@ %a" Varinfo.pretty) m.croots ; if Options.debug_atleast 1 then begin - Access.Set.iter (Format.fprintf fmt "@ R:%a" Access.pretty) m.reads ; - Access.Set.iter (Format.fprintf fmt "@ W:%a" Access.pretty) m.writes ; - Access.Set.iter (Format.fprintf fmt "@ A:%a" Access.pretty) m.shifts ; + Access.Set.iter (Format.fprintf fmt "@ R:%a" Access.pretty) m.creads ; + Access.Set.iter (Format.fprintf fmt "@ W:%a" Access.pretty) m.cwrites ; + Access.Set.iter (Format.fprintf fmt "@ A:%a" Access.pretty) m.cshifts ; end ; - Format.fprintf fmt "@ %a ;@]" pp_layout m.layout ; + Format.fprintf fmt "@ %a ;@]" pp_layout m.clayout ; end +[@@ warning "-32"] (* -------------------------------------------------------------------------- *) -(* --- Constructors --- *) +(* --- Map Constructors --- *) (* -------------------------------------------------------------------------- *) let create () = { @@ -119,12 +120,12 @@ let copy m = { } let empty = { - parents = [] ; - roots = [] ; - reads = Access.Set.empty ; - writes = Access.Set.empty ; - shifts = Access.Set.empty ; - layout = Blob ; + cparents = [] ; + croots = [] ; + creads = Access.Set.empty ; + cwrites = Access.Set.empty ; + cshifts = Access.Set.empty ; + clayout = Blob ; } (* -------------------------------------------------------------------------- *) @@ -145,18 +146,18 @@ let get map node = with Not_found -> empty (* -------------------------------------------------------------------------- *) -(* --- Constructors --- *) +(* --- Chunk Constructors --- *) (* -------------------------------------------------------------------------- *) let cell (m: map) ?size ?ptr ?root () = - let layout = match size, ptr with + let clayout = match size, ptr with | None, None -> Blob | None, Some _ -> Cell(Cil.bitsSizeOf Cil.voidPtrType,ptr) | Some s, _ -> Cell(s,ptr) in - let roots = match root with None -> [] | Some v -> [v] in - Ufind.make m.store { empty with layout ; roots } + let croots = match root with None -> [] | Some v -> [v] in + Ufind.make m.store { empty with clayout ; croots } -let update (m: map) (n: node) (f: region -> region) = +let update (m: map) (n: node) (f: chunk -> chunk) = let r = get m n in Ufind.set m.store n (f r) @@ -164,9 +165,9 @@ let range (m: map) ~size ~offset ~length ~data : node = let last = offset + length in if not (0 <= offset && offset < last && last <= size) then raise (Invalid_argument "Region.Memory.range") ; - let layout = Compound(size, Ranges.singleton { offset ; length ; data }) in - let n = Ufind.make m.store { empty with layout } in - update m data (fun r -> { r with parents = nodes m @@ n :: r.parents }) ; n + let clayout = Compound(size, Ranges.singleton { offset ; length ; data }) in + let n = Ufind.make m.store { empty with clayout } in + update m data (fun r -> { r with cparents = nodes m @@ n :: r.cparents }) ; n let root (m: map) v = try Vmap.find v m.index with Not_found -> @@ -177,20 +178,73 @@ let root (m: map) v = (* --- Iterator --- *) (* -------------------------------------------------------------------------- *) -let normalize map r = { - parents = nodes map r.parents ; - roots = r.roots ; - reads = r.reads ; - writes = r.writes ; - shifts = r.shifts ; - layout = - match r.layout with - | Blob -> Blob - | Cell(s,p) -> Cell(s,Option.map (node map) p) - | Compound(s,rg) -> Compound(s,Ranges.map (node map) rg) +type range = { + offset: int ; + length: int ; + cells: int ; + data: node ; +} + +type region = { + node: node ; + parents: node list ; + roots: varinfo list ; + types: typ list ; + reads: Access.acs list ; + writes: Access.acs list ; + shifts: Access.acs list ; + sizeof: int ; + ranges: range list ; + pointed: node option ; +} + +let pp_range fmt (r: range) = + Format.fprintf fmt "%d..%d [%d]: %a" + r.offset (r.offset + r.length) r.cells pp_node r.data + +let pp_region fmt (m: region) = + begin + let acs r s = if s = [] then '-' else r in + Format.fprintf fmt "@[<hov 2>%a: %c%c%c" + pp_node m.node + (acs 'R' m.reads) (acs 'W' m.writes) (acs 'A' m.shifts) ; + List.iter (Format.fprintf fmt "@ (%a)" Typ.pretty) m.types ; + List.iter (Format.fprintf fmt "@ %a" Varinfo.pretty) m.roots ; + Format.fprintf fmt "@ %db" m.sizeof ; + Option.iter (Format.fprintf fmt "@ (*%a)" pp_node) m.pointed ; + Format.fprintf fmt "@[<hv 0>]" ; + List.iter (Format.fprintf fmt "@ %a" pp_range) m.ranges ; + Format.fprintf fmt "@]" ; + if Options.debug_atleast 1 then + begin + List.iter (Format.fprintf fmt "@ R:%a" Access.pretty) m.reads ; + List.iter (Format.fprintf fmt "@ W:%a" Access.pretty) m.writes ; + List.iter (Format.fprintf fmt "@ A:%a" Access.pretty) m.shifts ; + end ; + Format.fprintf fmt " ;@]" ; + end + +let make_range (m: map) (rg: rg) : range = { + offset = rg.offset ; + length = rg.length ; + cells = rg.length / sizeof (get m rg.data).clayout ; + data = node m rg.data ; +} + +let make_region (m: map) (n: node) (r: chunk) : region = { + node = n ; + parents = nodes m r.cparents ; + roots = r.croots ; + reads = Access.Set.elements r.creads ; + writes = Access.Set.elements r.cwrites ; + shifts = Access.Set.elements r.cshifts ; + types = types r ; + sizeof = sizeof r.clayout ; + ranges = List.map (make_range m) @@ ranges r.clayout ; + pointed = Option.map (node m) (pointed r.clayout) ; } -let region map n = normalize map (get map n) +let region map n = make_region map n (get map n) let rec walk h m f n = let n = Ufind.find m.store n in @@ -198,15 +252,15 @@ let rec walk h m f n = try Hashtbl.find h id with Not_found -> Hashtbl.add h id () ; let r = Ufind.get m.store n in - f n (normalize m r) ; - match r.layout with + f (make_region m n r) ; + match r.clayout with | Blob -> () | Cell(_,p) -> Option.iter (walk h m f) p | Compound(_,rg) -> Ranges.iter (walk h m f) rg -let iter (m:map) (f: node -> region -> unit) = +let iter (m:map) (f: region -> unit) = let h = Hashtbl.create 0 in - Vmap.iter (fun _ n -> walk h m f n) m.index + Vmap.iter (fun _x n -> walk h m f n) m.index (* -------------------------------------------------------------------------- *) (* --- Merge --- *) @@ -228,15 +282,15 @@ let merge_opt (m: map) (q: queue) | None, p | p, None -> p | Some pa, Some pb -> Some (merge_node m q pa pb) -let merge_range (m: map) (q: queue) (ra : range) (rb : range) : node = +let merge_range (m: map) (q: queue) (ra : rg) (rb : rg) : node = let na = ra.data in let nb = rb.data in let ma = ra.offset + ra.length in let mb = rb.offset + rb.length in let dp = ra.offset - rb.offset in let dq = ma - mb in - let sa = sizeof (get m na).layout in - let sb = sizeof (get m nb).layout in + let sa = sizeof (get m na).clayout in + let sb = sizeof (get m nb).clayout in let size = Ranges.(sa %. sb %. dp %. dq) in let data = merge_node m q na nb in if size = sa && size = sb then data else @@ -271,13 +325,13 @@ let merge_layout (m: map) (q: queue) (a : layout) (b : layout) : layout = let wx = Ranges.range ~length:sx rp in merge_ranges m q sx wx sr wr -let merge_region (m: map) (q: queue) (a : region) (b : region) : region = { - parents = nodes m @@ Store.bag a.parents b.parents ; - roots = List.sort_uniq Varinfo.compare @@ Store.bag a.roots b.roots ; - reads = Access.Set.union a.reads b.reads ; - writes = Access.Set.union a.writes b.writes ; - shifts = Access.Set.union a.shifts b.shifts ; - layout = merge_layout m q a.layout b.layout ; +let merge_region (m: map) (q: queue) (a : chunk) (b : chunk) : chunk = { + cparents = nodes m @@ Store.bag a.cparents b.cparents ; + croots = List.sort_uniq Varinfo.compare @@ Store.bag a.croots b.croots ; + creads = Access.Set.union a.creads b.creads ; + cwrites = Access.Set.union a.cwrites b.cwrites ; + cshifts = Access.Set.union a.cshifts b.cshifts ; + clayout = merge_layout m q a.clayout b.clayout ; } let do_merge (m: map) (q: queue) (a: node) (b: node): unit = @@ -304,26 +358,26 @@ let merge (m: map) (a: node) (b: node) : node = (* -------------------------------------------------------------------------- *) let access (m:map) (a:node) (ty: typ) = - let sr = sizeof (get m a).layout in + let sr = sizeof (get m a).clayout in let size = Ranges.gcd sr (Cil.bitsSizeOf ty) in if sr <> size then ignore (merge m a (cell m ~size ())) -let pointer (m: map) (a: node) (b : node) = +let points_to (m: map) (a: node) (b : node) = ignore @@ merge m a @@ cell m ~ptr:b () let read (m: map) (a: node) from = let r = get m a in - Ufind.set m.store a { r with reads = Access.Set.add from r.reads } ; + Ufind.set m.store a { r with creads = Access.Set.add from r.creads } ; access m a (Access.typeof from) let write (m: map) (a: node) from = let r = get m a in - Ufind.set m.store a { r with writes = Access.Set.add from r.writes } ; + Ufind.set m.store a { r with cwrites = Access.Set.add from r.cwrites } ; access m a (Access.typeof from) let shift (m: map) (a: node) from = let r = get m a in - Ufind.set m.store a { r with shifts = Access.Set.add from r.shifts } + Ufind.set m.store a { r with cshifts = Access.Set.add from r.cshifts } (* no access *) (* -------------------------------------------------------------------------- *) diff --git a/src/plugins/region/memory.mli b/src/plugins/region/memory.mli index f3a03a5417c..f1a3bc95e8c 100644 --- a/src/plugins/region/memory.mli +++ b/src/plugins/region/memory.mli @@ -24,30 +24,31 @@ open Cil_types type node -and layout = - | Blob - | Cell of int * node option - | Compound of int * node Ranges.t +type range = { + offset: int ; + length: int ; + cells: int ; + data: node ; +} -type region = private { +type region = { + node: node ; parents: node list ; roots: varinfo list ; - reads: Access.Set.t ; - writes: Access.Set.t ; - shifts: Access.Set.t ; - layout: layout ; + types: typ list ; + reads: Access.acs list ; + writes: Access.acs list ; + shifts: Access.acs list ; + sizeof: int ; + ranges: range list ; + pointed: node option ; } -val sizeof : layout -> int -val points_to : layout -> node option -val ranges : layout -> node Ranges.range list -val types : region -> typ list +type map val pp_node : Format.formatter -> node -> unit -val pp_layout : Format.formatter -> layout -> unit -val pp_region : Format.formatter -> node -> region -> unit - -type map +val pp_range : Format.formatter -> range -> unit +val pp_region : Format.formatter -> region -> unit val create : unit -> map val copy : map -> map @@ -61,10 +62,10 @@ val forge : int -> node val node : map -> node -> node val nodes : map -> node list -> node list val region : map -> node -> region -val iter : map -> (node -> region -> unit) -> unit +val iter : map -> (region -> unit) -> unit val merge : map -> node -> node -> node val read : map -> node -> Access.acs -> unit val write : map -> node -> Access.acs -> unit val shift : map -> node -> Access.acs -> unit -val pointer : map -> node -> node -> unit +val points_to : map -> node -> node -> unit diff --git a/src/plugins/region/services.ml b/src/plugins/region/services.ml index b14918e442d..afc4a530676 100644 --- a/src/plugins/region/services.ml +++ b/src/plugins/region/services.ml @@ -41,19 +41,21 @@ end module NodeOpt = Data.Joption(Node) module NodeList = Data.Jlist(Node) -module Range : Data.S with type t = Memory.node Ranges.range = +module Range : Data.S with type t = Memory.range = struct - type t = Memory.node Ranges.range + type t = Memory.range let jtype = Data.declare ~package ~name:"range" @@ Jrecord [ "offset", Jnumber ; "length", Jnumber ; + "cells", Jnumber ; "data", Node.jtype ; ] - let to_json (rg : Memory.node Ranges.range) = + let to_json (rg : Memory.range) = Json.of_fields [ "offset", Json.of_int rg.offset ; "length", Json.of_int rg.length ; + "cells", Json.of_int rg.cells ; "data", Node.to_json rg.data ; ] let of_json _ = failwith "Region.Range.of_json" @@ -66,11 +68,12 @@ struct type t = Memory.region let jtype = Data.declare ~package ~name:"region" @@ Jrecord [ + "node", Node.jtype ; "roots", Jarray Jalpha ; "parents", NodeList.jtype ; "sizeof", Jnumber ; "ranges", Ranges.jtype ; - "pointsTo", NodeOpt.jtype ; + "pointed", NodeOpt.jtype ; "reads", Jboolean ; "writes", Jboolean ; "shifts", Jboolean ; @@ -86,15 +89,16 @@ struct let to_json (m: Memory.region) = Json.of_fields [ + "node", Node.to_json m.node ; "roots", roots_to_json m.roots ; "parents", NodeList.to_json m.parents ; - "sizeof", Json.of_int @@ Memory.sizeof m.layout ; - "ranges", Ranges.to_json @@ Memory.ranges m.layout ; - "pointsTo", NodeOpt.to_json @@ Memory.points_to m.layout ; - "reads", Json.of_bool @@ not @@ Access.Set.is_empty m.reads ; - "writes", Json.of_bool @@ not @@ Access.Set.is_empty m.writes ; - "shifts", Json.of_bool @@ not @@ Access.Set.is_empty m.shifts ; - "types", Json.of_list @@ List.map typ_to_json @@ Memory.types m ; + "sizeof", Json.of_int @@ m.sizeof ; + "ranges", Ranges.to_json @@ m.ranges ; + "pointed", NodeOpt.to_json @@ m.pointed ; + "reads", Json.of_bool (m.reads <> []) ; + "writes", Json.of_bool (m.writes <> []) ; + "shifts", Json.of_bool (m.shifts <> []) ; + "types", Json.of_list @@ List.map typ_to_json @@ m.types ; ] let of_json _ = failwith "Region.Layout.of_json" end @@ -107,7 +111,7 @@ module Regions = Data.Jlist(Region) let regions map = let pool = ref [] in - Memory.iter map (fun _ r -> pool := r :: !pool) ; + Memory.iter map (fun r -> pool := r :: !pool) ; List.rev !pool let map_of_localizable (loc : Printer_tag.localizable) = diff --git a/src/plugins/region/services.mli b/src/plugins/region/services.mli index 1e8c1893803..d694a69647e 100644 --- a/src/plugins/region/services.mli +++ b/src/plugins/region/services.mli @@ -26,7 +26,7 @@ open Request val package : Package.package module Node : Data.S with type t = Memory.node -module Range : Output with type t = Memory.node Ranges.range +module Range : Output with type t = Memory.range module Region : Output with type t = Memory.region (** @raises Not_found *) -- GitLab