-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathobject_stats.ml
More file actions
138 lines (132 loc) · 4.31 KB
/
Copy pathobject_stats.ml
File metadata and controls
138 lines (132 loc) · 4.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
[@@@ocaml.warning "+a-4-9-30-40-41-42"]
let printf = Printf.printf
module String = struct
include String
module Set = Misc.StringSet
end
type stats = {
mutable direct_calls : String.Set.t;
mutable c_calls : String.Set.t;
mutable indirect_calls : int;
mutable allocation_points : int;
mutable may_allocate : bool;
mutable may_raise : bool;
mutable bounded_stack_space : bool;
}
let analyse ~(fundecl : Linearize.fundecl) =
let stats : stats = {
direct_calls = String.Set.empty;
c_calls = String.Set.empty;
indirect_calls = 0;
allocation_points = 0;
may_allocate = false;
may_raise = false;
bounded_stack_space = true;
}
in
let insn = ref fundecl.fun_body in
while not ((!insn).next == !insn) do
begin match (!insn).desc with
| Lop op ->
begin match op with
| Icall_ind ->
stats.indirect_calls <- stats.indirect_calls + 1;
stats.may_allocate <- true;
stats.may_raise <- true;
stats.bounded_stack_space <- false
| Icall_imm func ->
stats.direct_calls <- String.Set.add func stats.direct_calls;
stats.bounded_stack_space <- false;
if not (func == fundecl.fun_name) then begin
stats.may_allocate <- true;
stats.may_raise <- true
end
| Itailcall_ind ->
stats.indirect_calls <- stats.indirect_calls + 1;
stats.may_allocate <- true;
stats.may_raise <- true;
stats.bounded_stack_space <- false
| Itailcall_imm func ->
stats.direct_calls <- String.Set.add func stats.direct_calls;
if not (func == fundecl.fun_name) then begin
stats.may_allocate <- true;
stats.may_raise <- true;
stats.bounded_stack_space <- false
end
| Iextcall (func, false) ->
stats.c_calls <- String.Set.add func stats.c_calls;
stats.bounded_stack_space <- false
| Iextcall (func, true) ->
stats.c_calls <- String.Set.add func stats.c_calls;
stats.may_allocate <- true;
stats.may_raise <- true;
stats.bounded_stack_space <- false
| Ialloc _ ->
stats.allocation_points <- stats.allocation_points + 1;
stats.may_allocate <- true;
(* Allocation points may unfortunately raise or run finalizers. *)
stats.may_raise <- true;
stats.bounded_stack_space <- false
| Imove
| Ispill
| Ireload
| Iconst_int _
| Iconst_float _
| Iconst_symbol _
| Iconst_blockheader _
| Istackoffset _ | Iload _ | Istore _ -> ()
| Iintop op | Iintop_imm (op, _) ->
begin match op with
| Iadd | Isub | Imul | Imulh | Idiv | Imod
| Iand | Ior | Ixor | Ilsl | Ilsr | Iasr
| Icomp _ -> ()
| Icheckbound -> stats.may_raise <- true
end
| Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf
| Ifloatofint | Iintoffloat -> ()
| Ispecific _ ->
(* For x86-64, these don't raise, allocate or call. *)
()
end
| Lend
| Lreloadretaddr
| Lreturn
| Llabel _
| Lbranch _
| Lcondbranch _
| Lcondbranch3 _
| Lswitch _
| Lsetuptrap _
| Lpushtrap
| Lpoptrap -> ()
| Lraise _ -> stats.may_raise <- true
end;
insn := (!insn).next
done;
let print_string_set set =
String.Set.iter (fun str -> printf " %S\n" str) set
in
printf "((function %S)\n" fundecl.fun_name;
printf " (location %S)\n" (Debuginfo.to_string fundecl.fun_dbg);
printf " (direct_calls_to_ocaml_code (\n";
print_string_set stats.direct_calls;
printf " )\n (direct_calls_to_c_code (\n";
print_string_set stats.c_calls;
printf " )\n (num_indirect_calls_to_ocaml_code %d)\n" stats.indirect_calls;
printf " (may_allocate %b)\n" stats.may_allocate;
printf " (num_inline_allocation_points %d)\n" stats.allocation_points;
printf " (may_raise_exception %b)\n" stats.may_raise;
printf " (definitely_bounded_stack_space %b)\n)\n\n" stats.bounded_stack_space
let () =
if Array.length Sys.argv <> 2 then begin
failwith "Syntax: object_stats <LINEARIZE FILE>"
end;
let filename = Sys.argv.(1) in
let chan = open_in filename in
let finished = ref false in
while not !finished do
match ((Marshal.from_channel chan) : Linearize.fundecl) with
| fundecl -> analyse ~fundecl
| exception _ -> finished := true
done;
close_in chan