Skip to content

Commit 2e18cd6

Browse files
authored
Statically enabled probes (#1388)
* Support [~enabled_at_init] argument of %probe The following new constructs are accepted: [%probe "name" ~enabled_at_init:true handler] [%probe "name" ~enabled_at_init:false handler] The default is [%probe "name" handler] and implies [~enabled_at_init:false] * Propagate [enabled_at_init] to Emit * emit call instead of jmp opcode for enabled_at_init probes * Add test * Initialize semaphore according to enabled_at_init Check that all probes with the same name in the current compilation unit have consistent [enabled_at_init]. * Improve error message * Add a test for inconsistent enabled_at_init for %probe * Refactor parsing * Add a module for Probe in Flambda2 * Rename variables [probe_name] to [probe] in middle_end/flambda2 code * Improve code style and make [desc] private
1 parent 8ab5a75 commit 2e18cd6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+281
-111
lines changed

backend/amd64/emit.mlp

Lines changed: 44 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -732,15 +732,32 @@ let reset_probes () =
732732
probes := [];
733733
probe_semaphores := String.Map.empty
734734

735-
let find_or_add_semaphore name =
735+
let find_or_add_semaphore name enabled_at_init dbg =
736736
match String.Map.find_opt name !probe_semaphores with
737-
| Some label -> label
737+
| Some (label, e) ->
738+
(match e, enabled_at_init with
739+
| None, None -> ()
740+
| None, Some _ ->
741+
let d = (label, enabled_at_init) in
742+
probe_semaphores :=
743+
String.Map.remove name !probe_semaphores |>
744+
String.Map.add name d
745+
| Some _, None ->
746+
(* [find_or_add_semaphore] is called with None for Iprobe_is_enabled
747+
during code emission only. [find_or_add_semaphore] us called with
748+
Some to emit probe notes only after all code is emitted. *)
749+
assert false
750+
| Some b, Some b' ->
751+
if not (Bool.equal b b') then
752+
raise (Error (Inconsistent_probe_init (name,dbg))));
753+
label
738754
| None ->
739755
let sym = "caml_probes_semaphore_"^name in
740-
probe_semaphores := String.Map.add name sym !probe_semaphores;
756+
let d = (sym, enabled_at_init) in
757+
probe_semaphores := String.Map.add name d !probe_semaphores;
741758
sym
742759

743-
let emit_call_probe_handler_wrapper i ~probe_label =
760+
let emit_call_probe_handler_wrapper i ~enabled_at_init ~probe_label =
744761
assert !frame_required;
745762
let wrap_label = probe_handler_wrapper_name probe_label in
746763
(* We emit a cmp instruction that is effectively a nop:
@@ -756,8 +773,12 @@ let emit_call_probe_handler_wrapper i ~probe_label =
756773
result, instead of relying on an assembler that might choose a different
757774
encoding which produces an incorrect relocation and changes the meaning
758775
of the program. *)
759-
(* Emit the required encoding of "cmp $0, %eax" directly, using .byte *)
760-
D.byte (Const 0x3dL);
776+
(* Emit the required encoding of "cmp $0, %eax" or "call" directly,
777+
using .byte *)
778+
if enabled_at_init then
779+
D.byte (Const 0xe8L)
780+
else
781+
D.byte (Const 0x3dL);
761782
D.byte (Const 0L);
762783
D.byte (Const 0L);
763784
D.byte (Const 0L);
@@ -1222,7 +1243,7 @@ let emit_instr fallthrough i =
12221243
| Lop(Iendregion) ->
12231244
I.mov (arg i 0) (domain_field Domainstate.Domain_local_sp)
12241245
| Lop (Iname_for_debugger _) -> ()
1225-
| Lop (Iprobe _) ->
1246+
| Lop (Iprobe { enabled_at_init; _ }) ->
12261247
let probe_label = new_label () in
12271248
let probe =
12281249
{ probe_label;
@@ -1238,9 +1259,9 @@ let emit_instr fallthrough i =
12381259
intervening wrapper that deals with getting the arguments to the probe
12391260
in the correct place and managing the spilling/reloading of live
12401261
registers. See [emit_probe_handler_wrapper] below. *)
1241-
emit_call_probe_handler_wrapper i ~probe_label
1262+
emit_call_probe_handler_wrapper i ~enabled_at_init ~probe_label
12421263
| Lop (Iprobe_is_enabled { name; }) ->
1243-
let semaphore_sym = find_or_add_semaphore name in
1264+
let semaphore_sym = find_or_add_semaphore name None i.dbg in
12441265
(* Load unsigned 2-byte integer value of the semaphore.
12451266
According to the documentation [1],
12461267
semaphores are of type unsigned short.
@@ -1584,7 +1605,8 @@ let emit_probe_handler_wrapper p =
15841605
let wrap_label = probe_handler_wrapper_name p.probe_label in
15851606
let probe_name, handler_code_sym =
15861607
match p.probe_insn.desc with
1587-
| Lop (Iprobe { name; handler_code_sym; }) -> name, handler_code_sym
1608+
| Lop (Iprobe { name; handler_code_sym; enabled_at_init = _; }) ->
1609+
name, handler_code_sym
15881610
| _ -> assert false
15891611
in
15901612
(* Restore stack frame info as it was at the probe site, so we can easily
@@ -1739,9 +1761,10 @@ let emit_probe_notes0 () =
17391761
Printf.sprintf "%d@%s" (Reg.size_of_contents_in_bytes arg) arg_name
17401762
in
17411763
let describe_one_probe p =
1742-
let probe_name =
1764+
let probe_name, enabled_at_init =
17431765
match p.probe_insn.desc with
1744-
| Lop (Iprobe { name; _; }) -> name
1766+
| Lop (Iprobe { name; enabled_at_init; handler_code_sym=_; }) ->
1767+
name, enabled_at_init
17451768
| _ -> assert false
17461769
in
17471770
let args =
@@ -1750,7 +1773,10 @@ let emit_probe_notes0 () =
17501773
[]
17511774
|> String.concat " "
17521775
in
1753-
let semaphore_label = emit_symbol (find_or_add_semaphore probe_name) in
1776+
let semsym =
1777+
find_or_add_semaphore probe_name (Some enabled_at_init) p.probe_insn.dbg
1778+
in
1779+
let semaphore_label = emit_symbol semsym in
17541780
let emit_desc () =
17551781
D.qword (ConstLabel (emit_label p.probe_label));
17561782
(match is_macosx_system with
@@ -1771,12 +1797,15 @@ let emit_probe_notes0 () =
17711797
| true ->
17721798
D.section ["__TEXT";"__probes"] None ["regular"]);
17731799
D.align ~data:true 2;
1774-
String.Map.iter (fun _ label ->
1800+
String.Map.iter (fun _ (label, enabled_at_init) ->
1801+
(* Unresolved weak symbols have a zero value regardless
1802+
of the following initialization. *)
1803+
let enabled_at_init = Option.value enabled_at_init ~default:false in
17751804
D.weak label;
17761805
D.hidden label;
17771806
_label label;
17781807
D.word (const 0); (* for systemtap probes *)
1779-
D.word (const 0); (* for ocaml probes *)
1808+
D.word (const (Bool.to_int enabled_at_init)); (* for ocaml probes *)
17801809
add_def_symbol label)
17811810
!probe_semaphores
17821811

backend/cfg/cfg.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,8 @@ let dump_terminator' ?(print_reg = Printmach.reg) ?(res = [||]) ?(args = [||])
368368
| Alloc { bytes; dbginfo; mode } -> Mach.Ialloc { bytes; dbginfo; mode }
369369
| Checkbound { immediate = Some x } -> Mach.Iintop_imm (Icheckbound, x)
370370
| Checkbound { immediate = None } -> Mach.Iintop Icheckbound
371-
| Probe { name; handler_code_sym } ->
372-
Mach.Iprobe { name; handler_code_sym });
371+
| Probe { name; handler_code_sym; enabled_at_init } ->
372+
Mach.Iprobe { name; handler_code_sym; enabled_at_init });
373373
Format.fprintf ppf "%sgoto %d" sep label_after
374374
| Specific_can_raise { op; label_after } ->
375375
Format.fprintf ppf "%a" specific_can_raise op;

backend/cfg/cfg_equivalence.ml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -294,10 +294,18 @@ let check_prim_call_operation :
294294
when Option.equal Int.equal expected_immediate result_immediate ->
295295
()
296296
| ( Probe
297-
{ name = expected_name; handler_code_sym = expected_handler_code_sym },
298-
Probe { name = result_name; handler_code_sym = result_handler_code_sym } )
297+
{ name = expected_name;
298+
handler_code_sym = expected_handler_code_sym;
299+
enabled_at_init = expected_enabled_at_init
300+
},
301+
Probe
302+
{ name = result_name;
303+
handler_code_sym = result_handler_code_sym;
304+
enabled_at_init = result_enabled_at_init
305+
} )
299306
when String.equal expected_name result_name
300-
&& String.equal expected_handler_code_sym result_handler_code_sym ->
307+
&& String.equal expected_handler_code_sym result_handler_code_sym
308+
&& Bool.equal expected_enabled_at_init result_enabled_at_init ->
301309
()
302310
| _ -> different location "primitive call operation"
303311
[@@ocaml.warning "-4"]

backend/cfg/cfg_intf.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ module S = struct
5151
| Checkbound of { immediate : int option }
5252
| Probe of
5353
{ name : string;
54-
handler_code_sym : string
54+
handler_code_sym : string;
55+
enabled_at_init : bool
5556
}
5657

5758
type operation =

backend/cfg/cfg_to_linear.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,8 @@ let linearize_terminator cfg_with_layout (func : string) start
171171
| Checkbound { immediate = None } -> Iintop Icheckbound
172172
| Checkbound { immediate = Some i } -> Iintop_imm (Icheckbound, i)
173173
| Alloc { bytes; dbginfo; mode } -> Ialloc { bytes; dbginfo; mode }
174-
| Probe { name; handler_code_sym } -> Iprobe { name; handler_code_sym }
174+
| Probe { name; handler_code_sym; enabled_at_init } ->
175+
Iprobe { name; handler_code_sym; enabled_at_init }
175176
in
176177
branch_or_fallthrough [L.Lop op] label_after, None
177178
| Specific_can_raise { op; label_after } ->

backend/cfg/cfgize.ml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,10 +215,13 @@ let basic_or_terminator_of_operation :
215215
Misc.fatal_error
216216
"Cfgize.basic_or_terminator_of_operation: \"the Iname_for_debugger\" \
217217
instruction is currently not supported "
218-
| Iprobe { name; handler_code_sym } ->
218+
| Iprobe { name; handler_code_sym; enabled_at_init } ->
219219
With_next_label
220220
(fun label_after ->
221-
Prim { op = Probe { name; handler_code_sym }; label_after })
221+
Prim
222+
{ op = Probe { name; handler_code_sym; enabled_at_init };
223+
label_after
224+
})
222225
| Iprobe_is_enabled { name } -> Basic (Op (Probe_is_enabled { name }))
223226
| Ibeginregion -> Basic (Op Begin_region)
224227
| Iendregion -> Basic (Op End_region)

backend/cfg/linear_to_cfg.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -582,8 +582,8 @@ let rec create_blocks (t : t) (i : L.instruction) (block : C.basic_block)
582582
terminator_prim (Checkbound { immediate = Some i })
583583
| Ialloc { bytes; dbginfo; mode } ->
584584
terminator_prim (Alloc { bytes; dbginfo; mode })
585-
| Iprobe { name; handler_code_sym } ->
586-
terminator_prim (Probe { name; handler_code_sym })
585+
| Iprobe { name; handler_code_sym; enabled_at_init } ->
586+
terminator_prim (Probe { name; handler_code_sym; enabled_at_init })
587587
| Istackoffset bytes ->
588588
let desc = C.Op (C.Stackoffset bytes) in
589589
DLL.add_end block.body (create_instruction t desc i ~stack_offset);

backend/checkmach.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -699,7 +699,7 @@ end = struct
699699
assert (not (Mach.operation_can_raise op));
700700
let r = Value.transform next in
701701
check t r "heap allocation" dbg
702-
| Iprobe { name; handler_code_sym } ->
702+
| Iprobe { name; handler_code_sym; enabled_at_init = __ } ->
703703
let desc = Printf.sprintf "probe %s handler %s" name handler_code_sym in
704704
transform_call t ~next ~exn handler_code_sym ~desc dbg
705705
| Icall_ind -> transform t ~next ~exn ~effect:Value.top "indirect call" dbg

backend/cmm.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ and operation =
213213
| Ccmpf of float_comparison
214214
| Craise of Lambda.raise_kind
215215
| Ccheckbound
216-
| Cprobe of { name: string; handler_code_sym: string; }
216+
| Cprobe of { name: string; handler_code_sym: string; enabled_at_init: bool }
217217
| Cprobe_is_enabled of { name: string }
218218
| Copaque
219219
| Cbeginregion | Cendregion

backend/cmm.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ and operation =
215215
then the index.
216216
It results in a bounds error if the index is greater than
217217
or equal to the bound. *)
218-
| Cprobe of { name: string; handler_code_sym: string; }
218+
| Cprobe of { name: string; handler_code_sym: string; enabled_at_init: bool }
219219
| Cprobe_is_enabled of { name: string }
220220
| Copaque (* Sys.opaque_identity *)
221221
| Cbeginregion | Cendregion

backend/cmm_helpers.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4028,8 +4028,12 @@ let beginregion ~dbg = Cop (Cbeginregion, [], dbg)
40284028

40294029
let endregion ~dbg region = Cop (Cendregion, [region], dbg)
40304030

4031-
let probe ~dbg ~name ~handler_code_linkage_name ~args =
4032-
Cop (Cprobe { name; handler_code_sym = handler_code_linkage_name }, args, dbg)
4031+
let probe ~dbg ~name ~handler_code_linkage_name ~enabled_at_init ~args =
4032+
Cop
4033+
( Cprobe
4034+
{ name; handler_code_sym = handler_code_linkage_name; enabled_at_init },
4035+
args,
4036+
dbg )
40334037

40344038
let load ~dbg kind mut ~addr = Cop (Cload (kind, mut), [addr], dbg)
40354039

backend/cmm_helpers.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,6 +1131,7 @@ val probe :
11311131
dbg:Debuginfo.t ->
11321132
name:string ->
11331133
handler_code_linkage_name:string ->
1134+
enabled_at_init:bool ->
11341135
args:expression list ->
11351136
expression
11361137

backend/cmmgen.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -511,10 +511,10 @@ let rec transl env e =
511511
let ptr = transl env arg in
512512
let dbg = Debuginfo.none in
513513
ptr_offset ptr offset dbg
514-
| Udirect_apply(handler_code_sym, args, Some { name; }, _, _, dbg) ->
514+
| Udirect_apply(handler_code_sym, args, Some { name; enabled_at_init }, _, _, dbg) ->
515515
let args = List.map (transl env) args in
516516
return_unit dbg
517-
(Cop(Cprobe { name; handler_code_sym; }, args, dbg))
517+
(Cop(Cprobe { name; handler_code_sym; enabled_at_init }, args, dbg))
518518
| Udirect_apply(lbl, args, None, result_layout, kind, dbg) ->
519519
let args = List.map (transl env) args in
520520
let sym =

backend/emitaux.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
type error =
1919
| Stack_frame_too_large of int
2020
| Stack_frame_way_too_large of int
21+
| Inconsistent_probe_init of string * Debuginfo.t
2122

2223
exception Error of error
2324

@@ -506,3 +507,7 @@ let report_error ppf = function
506507
Use -long-frames compiler flag." n
507508
| Stack_frame_way_too_large n ->
508509
Format.fprintf ppf "stack frame too large (%d bytes)." n
510+
| Inconsistent_probe_init (name, dbg) ->
511+
Format.fprintf ppf "Inconsistent use of ~enabled_at_init in [%%probe %s ..] at %a"
512+
name Debuginfo.print_compact dbg
513+

backend/emitaux.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ val reduce_heap_size : reset:(unit -> unit) -> unit
106106
type error =
107107
| Stack_frame_too_large of int
108108
| Stack_frame_way_too_large of int
109+
| Inconsistent_probe_init of string * Debuginfo.t
109110

110111
module Dwarf_helpers : sig
111112
val init: disable_dwarf:bool -> string -> unit

backend/mach.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ type operation =
7979
| Ipoll of { return_label: Cmm.label option }
8080
| Iname_for_debugger of { ident : Backend_var.t; which_parameter : int option;
8181
provenance : unit option; is_assignment : bool; }
82-
| Iprobe of { name: string; handler_code_sym: string; }
82+
| Iprobe of { name: string; handler_code_sym: string; enabled_at_init: bool; }
8383
| Iprobe_is_enabled of { name: string }
8484
| Ibeginregion | Iendregion
8585

backend/mach.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ type operation =
8989
(b) If [is_assignment] is [true], any information about other [Reg.t]s
9090
that have been previously deemed to hold the value of that
9191
identifier is forgotten. *)
92-
| Iprobe of { name: string; handler_code_sym: string; }
92+
| Iprobe of { name: string; handler_code_sym: string; enabled_at_init: bool; }
9393
| Iprobe_is_enabled of { name: string }
9494
| Ibeginregion | Iendregion
9595

backend/printcmm.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,9 @@ let operation d = function
226226
| Ccmpf c -> Printf.sprintf "%sf" (float_comparison c)
227227
| Craise k -> Lambda.raise_kind k ^ location d
228228
| Ccheckbound -> "checkbound" ^ location d
229-
| Cprobe { name; handler_code_sym } ->
230-
Printf.sprintf "probe[%s %s]" name handler_code_sym
229+
| Cprobe { name; handler_code_sym; enabled_at_init; } ->
230+
Printf.sprintf "probe[%s %s%s]" name handler_code_sym
231+
(if enabled_at_init then " enabled_at_init" else "")
231232
| Cprobe_is_enabled {name} -> Printf.sprintf "probe_is_enabled[%s]" name
232233
| Cprefetch { is_write; locality; } ->
233234
Printf.sprintf "prefetch is_write=%b prefetch_temporal_locality_hint=%s"

backend/selectgen.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,8 +690,8 @@ method select_operation op args _dbg =
690690
(Iintop_atomic { op = Compare_and_swap; size; addr }, [compare_with; set_to; eloc])
691691
| (Ccheckbound, _) ->
692692
self#select_arith Icheckbound args
693-
| (Cprobe { name; handler_code_sym; }, _) ->
694-
Iprobe { name; handler_code_sym; }, args
693+
| (Cprobe { name; handler_code_sym; enabled_at_init; }, _) ->
694+
Iprobe { name; handler_code_sym; enabled_at_init; }, args
695695
| (Cprobe_is_enabled {name}, _) -> Iprobe_is_enabled {name}, []
696696
| (Cbeginregion, _) -> Ibeginregion, []
697697
| (Cendregion, _) -> Iendregion, args

middle_end/flambda2/compare/compare.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,8 @@ and subst_apply env apply =
438438
let args_arity = Apply_expr.args_arity apply in
439439
let return_arity = Apply_expr.return_arity apply in
440440
Apply_expr.create ~callee ~continuation exn_continuation ~args ~call_kind dbg
441-
~inlined ~inlining_state ~probe_name:None ~position ~relative_history
442-
~region ~args_arity ~return_arity
441+
~inlined ~inlining_state ~probe:None ~position ~relative_history ~region
442+
~args_arity ~return_arity
443443
|> Expr.create_apply
444444

445445
and subst_apply_cont env apply_cont =
@@ -1002,7 +1002,7 @@ let apply_exprs env apply1 apply2 : Expr.t Comparison.t =
10021002
~args:args1' ~call_kind:call_kind1' (Apply.dbg apply1)
10031003
~inlined:(Apply.inlined apply1)
10041004
~inlining_state:(Apply.inlining_state apply1)
1005-
~probe_name:None ~position:(Apply.position apply1)
1005+
~probe:None ~position:(Apply.position apply1)
10061006
~relative_history:(Apply_expr.relative_history apply1)
10071007
~region:(Apply_expr.region apply1)
10081008
~args_arity:(Apply_expr.args_arity apply1)

0 commit comments

Comments
 (0)