@@ -528,29 +528,18 @@ let function_name = ref ""
528
528
let tailrec_entry_point = ref None
529
529
530
530
(* Emit tracing probes *)
531
- type probe_handler =
532
- {
533
- probe_stack_offset: int;
534
- probe_num_stack_slots: int array;
535
- (* Record frame info held in the corresponding mutable variables. *)
536
- probe_handler_code_sym: string;
537
- (* Probe handler function symbol. *)
538
- probe_arg: Reg.t array;
539
- probe_live: Reg.Set.t;
540
- (* Information about Iprobe instruction,
541
- recorded at probe site and used for emitting the notes and
542
- the wrapper code at the end of the compilation unit. *)
543
- }
544
531
545
532
type probe =
546
533
{
534
+ stack_offset: int;
535
+ num_stack_slots: int array;
536
+ (* Record frame info held in the corresponding mutable variables. *)
547
537
probe_label: label;
548
538
(* Probe site, recorded in .note.stapsdt section
549
539
for enabling and disabling the probes *)
550
- probe_name: string;
551
- (* User-defined name of the probe. *)
552
- probe_handler: probe_handler option;
553
- (* User-defined handler or None for dummy probes. *)
540
+ probe_insn: Linear.instruction;
541
+ (* Iprobe instruction, recorded at probe site and used for emitting
542
+ the notes and the wrapper code at the end of the compilation unit. *)
554
543
}
555
544
556
545
let probe_handler_wrapper_name probe_label =
@@ -946,20 +935,13 @@ let emit_instr fallthrough i =
946
935
in
947
936
I.prefetch is_write locality (addressing addr QWORD i 0)
948
937
| Lop (Iname_for_debugger _) -> ()
949
- | Lop (Iprobe { name; handler_code_sym } ) ->
938
+ | Lop (Iprobe _ ) ->
950
939
let probe_label = new_label () in
951
- let h =
952
- { probe_handler_code_sym = handler_code_sym;
953
- probe_arg = Array.copy i.arg;
954
- probe_live = i.live;
955
- probe_stack_offset = !stack_offset;
956
- probe_num_stack_slots = Array.copy num_stack_slots;
957
- }
958
- in
959
940
let probe =
960
941
{ probe_label;
961
- probe_name = name;
962
- probe_handler = Some h;
942
+ probe_insn = i;
943
+ stack_offset = !stack_offset;
944
+ num_stack_slots = Array.copy num_stack_slots;
963
945
}
964
946
in
965
947
probes := probe :: !probes;
@@ -1301,20 +1283,23 @@ let make_stack_loc ~offset i (r : Reg.t) =
1301
1283
1302
1284
let emit_probe_handler_wrapper p =
1303
1285
let wrap_label = probe_handler_wrapper_name p.probe_label in
1304
- let h = Option.get p.probe_handler in
1286
+ let probe_name, handler_code_sym =
1287
+ match p.probe_insn.desc with
1288
+ | Lop (Iprobe { name; handler_code_sym; }) -> name, handler_code_sym
1289
+ | _ -> assert false
1290
+ in
1305
1291
(* Restore stack frame info as it was at the probe site, so we can easily
1306
1292
refer to slots in the corresponding frame. (As per the comment above,
1307
1293
recall that the wrapper does however have its own frame.) *)
1308
1294
frame_required := true;
1309
- stack_offset := h.probe_stack_offset ;
1295
+ stack_offset := p.stack_offset ;
1310
1296
for i = 0 to Proc.num_register_classes - 1 do
1311
- num_stack_slots.(i) <- h.probe_num_stack_slots .(i);
1297
+ num_stack_slots.(i) <- p.num_stack_slots .(i);
1312
1298
done;
1313
1299
(* Account for the return address that is now pushed on the stack. *)
1314
1300
stack_offset := !stack_offset + 8;
1315
1301
(* Emit function entry code *)
1316
- D.comment (Printf.sprintf "probe %s %s" p.probe_name
1317
- h.probe_handler_code_sym);
1302
+ D.comment (Printf.sprintf "probe %s %s" probe_name handler_code_sym);
1318
1303
emit_named_text_section wrap_label;
1319
1304
D.align 16;
1320
1305
_label wrap_label;
@@ -1328,15 +1313,15 @@ let emit_probe_handler_wrapper p =
1328
1313
assert (size_addr = 8 && size_int = 8 && size_float = 8);
1329
1314
(* Compute the size of stack slots for all live hard registers. *)
1330
1315
let live =
1331
- Reg.Set.elements h.probe_live
1316
+ Reg.Set.elements p.probe_insn.live
1332
1317
|> List.filter Reg.is_reg
1333
1318
|> Array.of_list
1334
1319
in
1335
1320
let live_offset = 8 * (Array.length live) in
1336
1321
(* Compute the size of stack slots for spilling all arguments of the probe. *)
1337
1322
let aux_offset = 8 (* for saving r15 *) in
1338
- let tmp_offset = 8 * (Array.length h.probe_arg ) in
1339
- let loc_args, loc_offset = Proc.loc_arguments (Reg.typv h.probe_arg ) in
1323
+ let tmp_offset = 8 * (Array.length p.probe_insn.arg ) in
1324
+ let loc_args, loc_offset = Proc.loc_arguments (Reg.typv p.probe_insn.arg ) in
1340
1325
(* Ensure the stack is aligned.
1341
1326
Assuming that the stack at the probe site is 16-byte aligned,
1342
1327
[loc_arguments] ensures that [loc_offset] is 16-byte aligned.
@@ -1360,16 +1345,16 @@ let emit_probe_handler_wrapper p =
1360
1345
I.mov r15 (reg saved_r15);
1361
1346
(* Spill all arguments of the probe. Some of these may already be on the
1362
1347
stack, in which case a temporary is used for the move. *)
1363
- let tmp = Array.mapi (make_stack_loc ~offset:loc_offset) h.probe_arg in
1348
+ let tmp = Array.mapi (make_stack_loc ~offset:loc_offset) p.probe_insn.arg in
1364
1349
Array.iteri (fun i reg -> move_allowing_stack_to_stack reg (tmp.(i)))
1365
- h.probe_arg ;
1350
+ p.probe_insn.arg ;
1366
1351
(* Load probe arguments to correct locations for the handler *)
1367
1352
Array.iteri (fun i reg -> move_allowing_stack_to_stack tmp.(i) reg) loc_args;
1368
1353
(* Reload spilled registers used as temporaries *)
1369
1354
I.mov (reg saved_r15) r15;
1370
1355
(* Emit call to handler *)
1371
- add_used_symbol h.probe_handler_code_sym ;
1372
- emit_call h.probe_handler_code_sym ;
1356
+ add_used_symbol handler_code_sym ;
1357
+ emit_call handler_code_sym ;
1373
1358
(* Record a frame description for the wrapper *)
1374
1359
let label = new_label () in
1375
1360
let live_offset =
@@ -1398,7 +1383,7 @@ let emit_probe_handler_wrapper p =
1398
1383
cfi_endproc ();
1399
1384
emit_function_type_and_size wrap_label
1400
1385
1401
- let emit_probe_notes0 probes =
1386
+ let emit_probe_notes0 () =
1402
1387
begin match system with
1403
1388
| S_gnu | S_cygwin | S_solaris | S_win32 | S_linux_elf | S_bsd_elf
1404
1389
| S_beos | S_mingw | S_win64 | S_linux | S_mingw64 | S_unknown ->
@@ -1418,16 +1403,18 @@ let emit_probe_notes0 probes =
1418
1403
Printf.sprintf "%d@%s" (Reg.size_of_contents_in_bytes arg) arg_name
1419
1404
in
1420
1405
let describe_one_probe p =
1406
+ let probe_name =
1407
+ match p.probe_insn.desc with
1408
+ | Lop (Iprobe { name; _; }) -> name
1409
+ | _ -> assert false
1410
+ in
1421
1411
let args =
1422
- match p.probe_handler with
1423
- | None -> ""
1424
- | Some h ->
1425
- Array.fold_right (fun arg acc -> (stap_arg arg)::acc)
1426
- h.probe_arg
1427
- []
1428
- |> String.concat " "
1412
+ Array.fold_right (fun arg acc -> (stap_arg arg)::acc)
1413
+ p.probe_insn.arg
1414
+ []
1415
+ |> String.concat " "
1429
1416
in
1430
- let semaphore_label = emit_symbol (find_or_add_semaphore p. probe_name) in
1417
+ let semaphore_label = emit_symbol (find_or_add_semaphore probe_name) in
1431
1418
D.align 4;
1432
1419
let a = new_label() in
1433
1420
let b = new_label() in
@@ -1453,13 +1440,13 @@ let emit_probe_notes0 probes =
1453
1440
D.qword (const 0)
1454
1441
end;
1455
1442
D.qword (ConstLabel semaphore_label);
1456
- D.bytes "ocaml.2 \000";
1457
- D.bytes (p. probe_name ^ "\000");
1443
+ D.bytes "ocaml.1 \000";
1444
+ D.bytes (probe_name ^ "\000");
1458
1445
D.bytes (args ^ "\000");
1459
1446
def_label d;
1460
1447
D.align 4;
1461
1448
in
1462
- List.iter describe_one_probe probes;
1449
+ List.iter describe_one_probe ! probes;
1463
1450
begin match system with
1464
1451
| S_gnu | S_cygwin | S_solaris | S_win32 | S_linux_elf | S_bsd_elf
1465
1452
| S_beos | S_mingw | S_win64 | S_linux | S_mingw64 | S_unknown ->
@@ -1488,49 +1475,10 @@ let emit_probe_notes0 probes =
1488
1475
add_def_symbol label)
1489
1476
!probe_semaphores
1490
1477
1491
- let emit_probe_notes probes =
1492
- match probes, String.Map.is_empty !probe_semaphores with
1493
- | [], true -> ()
1494
- | _ -> emit_probe_notes0 probes
1495
-
1496
- let emit_dummy_probe_sites () =
1497
- let semaphores_without_probes =
1498
- List.fold_left (fun acc probe ->
1499
- String.Map.remove probe.probe_name acc)
1500
- !probe_semaphores !probes in
1501
- if (String.Map.is_empty semaphores_without_probes) then []
1502
- else begin
1503
- let fun_name = Compilenv.make_symbol (Some "___dummy_probes") in
1504
-
1505
- (* start the function (as in fundecl) *)
1506
- emit_named_text_section fun_name;
1507
- D.align 16;
1508
- add_def_symbol fun_name;
1509
- D.global (emit_symbol fun_name);
1510
- D.label (emit_symbol fun_name);
1511
- cfi_startproc ();
1512
-
1513
- (* emit dummy probe sites: labeled NOP only for stapsdt probes to work,
1514
- but no calls to probe wrapper because there is no ocaml probe handler. *)
1515
- let dummy_probes =
1516
- String.Map.fold (fun probe_name _label acc ->
1517
- let probe_label = new_label () in
1518
- def_label probe_label;
1519
- I.nop (); (* for uprobes and usdt probes as well *)
1520
- let probe = { probe_name;
1521
- probe_label;
1522
- probe_handler = None;
1523
- }
1524
- in
1525
- probe :: acc)
1526
- semaphores_without_probes []
1527
- in
1528
- I.ret ();
1529
- (* end the function (as in fundecl) *)
1530
- cfi_endproc ();
1531
- emit_function_type_and_size fun_name;
1532
- dummy_probes
1533
- end
1478
+ let emit_probe_notes () =
1479
+ match !probes with
1480
+ | [] -> ()
1481
+ | _ -> emit_probe_notes0 ()
1534
1482
1535
1483
let end_assembly() =
1536
1484
if !float_constants <> [] then begin
@@ -1547,9 +1495,6 @@ let end_assembly() =
1547
1495
(* Emit probe handler wrappers *)
1548
1496
List.iter emit_probe_handler_wrapper !probes;
1549
1497
1550
- (* Emit dummy probes for semaphores without probes in this compilation unit. *)
1551
- let dummy_probes = emit_dummy_probe_sites () in
1552
-
1553
1498
emit_named_text_section (Compilenv.make_symbol (Some "code_end"));
1554
1499
if system = S_macosx then I.nop ();
1555
1500
(* suppress "ld warning: atom sorting error" *)
@@ -1599,7 +1544,7 @@ let end_assembly() =
1599
1544
D.size frametable (ConstSub (ConstThis, ConstLabel frametable))
1600
1545
end;
1601
1546
1602
- emit_probe_notes (dummy_probes @ !probes );
1547
+ emit_probe_notes ();
1603
1548
1604
1549
if system = S_linux then
1605
1550
(* Mark stack as non-executable, PR#4564 *)
0 commit comments