Skip to content

Commit 383923b

Browse files
authored
Emit stack checks for probes (#2539)
1 parent 0235e45 commit 383923b

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

backend/amd64/emit.mlp

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -470,31 +470,44 @@ let emit_call_safety_errors () =
470470
type stack_realloc = {
471471
sc_label : Label.t; (* Label of the reallocation code. *)
472472
sc_return : Label.t; (* Label to return to after reallocation. *)
473-
sc_max_frame_size_in_bytes : int; (* Size for reallocation. *)
473+
sc_size_in_bytes : int; (* Size for reallocation. *)
474474
}
475475

476-
let stack_realloc = ref (None : stack_realloc option)
476+
let stack_realloc = ref ([] : stack_realloc list)
477477

478478
let clear_stack_realloc () =
479-
stack_realloc := None
479+
stack_realloc := []
480480

481481
let emit_stack_realloc () =
482-
begin match !stack_realloc with
483-
| None -> ()
484-
| Some { sc_label; sc_return; sc_max_frame_size_in_bytes; } -> begin
485-
def_label sc_label;
486-
(* Pass the desired frame size on the stack, since all of the
487-
argument-passing registers may be in use.
488-
Also serves to align the stack properly before the call *)
489-
I.push (int (Config.stack_threshold + sc_max_frame_size_in_bytes / 8));
490-
cfi_adjust_cfa_offset 8;
491-
(* measured in words *)
492-
emit_call (Cmm.global_symbol "caml_call_realloc_stack");
493-
I.add (int 8) rsp;
494-
cfi_adjust_cfa_offset (-8);
495-
I.jmp (label sc_return)
496-
end
497-
end
482+
List.iter
483+
(fun { sc_label; sc_return; sc_size_in_bytes; } ->
484+
def_label sc_label;
485+
(* Pass the desired frame size on the stack, since all of the
486+
argument-passing registers may be in use.
487+
Also serves to align the stack properly before the call *)
488+
I.push (int (Config.stack_threshold + sc_size_in_bytes / 8));
489+
cfi_adjust_cfa_offset 8;
490+
(* measured in words *)
491+
emit_call (Cmm.global_symbol "caml_call_realloc_stack");
492+
I.add (int 8) rsp;
493+
cfi_adjust_cfa_offset (-8);
494+
I.jmp (label sc_return))
495+
!stack_realloc
496+
497+
let emit_stack_check ~size_in_bytes ~save_registers =
498+
let overflow = new_label () and ret = new_label () in
499+
let threshold_offset = Domainstate.stack_ctx_words * 8 + Stack_check.stack_threshold_size in
500+
if save_registers then I.push r10;
501+
I.lea (mem64 NONE (-(size_in_bytes + threshold_offset)) RSP) r10;
502+
I.cmp (domain_field Domainstate.Domain_current_stack) r10;
503+
if save_registers then I.pop r10;
504+
I.jb (label overflow);
505+
def_label ret;
506+
stack_realloc := {
507+
sc_label = overflow;
508+
sc_return = ret;
509+
sc_size_in_bytes = size_in_bytes;
510+
} :: !stack_realloc
498511

499512
(* Record jump tables *)
500513
type jump_table =
@@ -1828,20 +1841,7 @@ let emit_instr ~first ~fallthrough i =
18281841
I.jmp r11
18291842
end
18301843
| Lstackcheck { max_frame_size_bytes; } ->
1831-
let save_registers = not first in
1832-
let overflow = new_label () and ret = new_label () in
1833-
let threshold_offset = Domainstate.stack_ctx_words * 8 + Stack_check.stack_threshold_size in
1834-
if save_registers then I.push r10;
1835-
I.lea (mem64 NONE (-(max_frame_size_bytes + threshold_offset)) RSP) r10;
1836-
I.cmp (domain_field Domainstate.Domain_current_stack) r10;
1837-
if save_registers then I.pop r10;
1838-
I.jb (label overflow);
1839-
def_label ret;
1840-
stack_realloc := Some {
1841-
sc_label = overflow;
1842-
sc_return = ret;
1843-
sc_max_frame_size_in_bytes = max_frame_size_bytes;
1844-
}
1844+
emit_stack_check ~size_in_bytes:max_frame_size_bytes ~save_registers:(not first)
18451845

18461846
let rec emit_all ~first ~fallthrough i =
18471847
match i.desc with
@@ -2164,6 +2164,8 @@ let emit_probe_handler_wrapper p =
21642164
let padding = if ((wrapper_frame_size k) mod 16) = 0 then 0 else 8 in
21652165
let n = k + padding in
21662166
(* Allocate stack space *)
2167+
if Config.runtime5 && (not Config.no_stack_checks) && (n >= Stack_check.stack_threshold_size) then
2168+
emit_stack_check ~size_in_bytes:n ~save_registers:true;
21672169
emit_stack_offset n;
21682170
(* Save all live hard registers *)
21692171
let offset = aux_offset + tmp_offset + loc_offset in

0 commit comments

Comments
 (0)