Skip to content

Commit 82bcb4b

Browse files
TheNumbatmshinwell
andauthored
Runtime 5 forward & backward porting (#2027)
* Resolve sigprocmask cr * Backport amd64 backend changes * Fix systhreads5 install * Forward port ft relative retaddr * Backport cmm changes * Ignore nnp link config in 5 * Fix ocamltest build with 5 runtime * Forward port unboxed int64 in closure * Forward port is_last closinfo flag * Backport lazy implementation * Forward port fl2 root scanning fix * Make atomics compatible with 4 and 5 Once the atomic primitives are backported, switch to them. * Backport marshal change * Implement more of the domain API using DLS * Backport filename change * Backport format changes * Ignore backport gc change * Backport hashtbl change * Add stubs that runtime5 needs for linking with stdlib * CR for SIMD register save * Address code review comments * Don't align for runtime5 --------- Co-authored-by: Mark Shinwell <[email protected]>
1 parent 04d3a14 commit 82bcb4b

Some content is hidden

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

58 files changed

+946
-907
lines changed

backend/amd64/emit.mlp

Lines changed: 59 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ let cfi_endproc () =
7474
let cfi_adjust_cfa_offset n =
7575
if Config.asm_cfi_supported then D.cfi_adjust_cfa_offset n
7676

77-
let _cfi_remember_state () =
77+
let cfi_remember_state () =
7878
if Config.asm_cfi_supported then D.cfi_remember_state ()
7979

80-
let _cfi_restore_state () =
80+
let cfi_restore_state () =
8181
if Config.asm_cfi_supported then D.cfi_restore_state ()
8282

83-
let _cfi_def_cfa_register reg =
83+
let cfi_def_cfa_register reg =
8484
if Config.asm_cfi_supported then D.cfi_def_cfa_register reg
8585

8686
let emit_debug_info ?discriminator dbg =
@@ -94,7 +94,7 @@ let emit_debug_info_linear i =
9494

9595
let fp = Config.with_frame_pointers
9696

97-
let _stack_threshold_size = Config.stack_threshold * 8 (* bytes *)
97+
let stack_threshold_size = Config.stack_threshold * 8 (* bytes *)
9898

9999
(* Tradeoff between code size and code speed *)
100100

@@ -1269,25 +1269,19 @@ let emit_instr fallthrough i =
12691269
end
12701270
end
12711271
end
1272-
| Lop(Iextcall { func; alloc; stack_ofs
1273-
(* BACKPORT BEGIN *)
1274-
= _
1275-
(* BACKPORT END *)
1276-
}) ->
1272+
| Lop(Iextcall { func; alloc; stack_ofs }) ->
12771273
add_used_symbol func;
1278-
(* BEGIN BACKPORT
1279-
if stack_ofs > 0 then begin
1274+
if Config.runtime5 && stack_ofs > 0 then begin
12801275
I.mov rsp r13;
12811276
I.lea (mem64 QWORD stack_ofs RSP) r12;
1282-
load_symbol_addr func rax;
1283-
emit_call "caml_c_call_stack_args";
1284-
record_frame env i.live (Dbg_other i.dbg);
1285-
end else *) if alloc then begin
1277+
load_symbol_addr (Cmm.global_symbol func) rax;
1278+
emit_call (Cmm.global_symbol "caml_c_call_stack_args");
1279+
record_frame i.live (Dbg_other i.dbg);
1280+
end else if alloc then begin
12861281
load_symbol_addr (Cmm.global_symbol func) rax;
12871282
emit_call (Cmm.global_symbol "caml_c_call");
12881283
record_frame i.live (Dbg_other i.dbg);
1289-
(* BEGIN BACKPORT *)
1290-
if system <> S_win64 then begin
1284+
if not Config.runtime5 && system <> S_win64 then begin
12911285

12921286
(* In amd64.S, "caml_c_call" tail-calls the C function (in order to
12931287
produce nicer backtraces), so we need to restore r15 manually after
@@ -1299,24 +1293,21 @@ let emit_instr fallthrough i =
12991293

13001294
I.mov (domain_field Domainstate.Domain_young_ptr) r15
13011295
end
1302-
(* END BACKPORT *)
13031296
end else begin
1304-
(* BEGIN BACKPORT
1305-
I.mov rsp rbx;
1306-
cfi_remember_state ();
1307-
cfi_def_cfa_register "rbx";
1308-
(* NB: gdb has asserts on contiguous stacks that mean it
1309-
will not unwind through this unless we were to tag this
1310-
calling frame with cfi_signal_frame in it's definition. *)
1311-
I.mov (domain_field Domainstate.Domain_c_stack) rsp; *)
1312-
(* END BACKPORT *)
1313-
emit_call (Cmm.global_symbol func)
1314-
(* BEGIN BACKPORT
1315-
;
1316-
I.mov rbx rsp;
1317-
cfi_restore_state ();
1318-
*)
1319-
(* END BACKPORT *)
1297+
if Config.runtime5 then begin
1298+
I.mov rsp rbx;
1299+
cfi_remember_state ();
1300+
cfi_def_cfa_register "rbx";
1301+
(* NB: gdb has asserts on contiguous stacks that mean it
1302+
will not unwind through this unless we were to tag this
1303+
calling frame with cfi_signal_frame in it's definition. *)
1304+
I.mov (domain_field Domainstate.Domain_c_stack) rsp;
1305+
end;
1306+
emit_call (Cmm.global_symbol func);
1307+
if Config.runtime5 then begin
1308+
I.mov rbx rsp;
1309+
cfi_restore_state ();
1310+
end;
13201311
end
13211312
| Lop(Istackoffset n) ->
13221313
emit_stack_offset n
@@ -1690,8 +1681,9 @@ let emit_instr fallthrough i =
16901681
I.set (cond (Iunsigned Cne)) (res8 i 0);
16911682
I.movzx (res8 i 0) (res i 0)
16921683
| Lop (Idls_get) ->
1693-
Misc.fatal_error "Dls is currently not supported";
1694-
(* I.mov (domain_field Domainstate.Domain_dls_root) (res i 0) *)
1684+
if Config.runtime5
1685+
then I.mov (domain_field Domainstate.Domain_dls_root) (res i 0)
1686+
else Misc.fatal_error "Dls is not supported in runtime4.";
16951687
| Lreloadretaddr ->
16961688
()
16971689
| Lreturn ->
@@ -1775,16 +1767,12 @@ let emit_instr fallthrough i =
17751767
| Lraise k ->
17761768
begin match k with
17771769
| Lambda.Raise_regular ->
1778-
(* BACKPORT BEGIN *)
17791770
I.mov (int 0) (domain_field Domainstate.Domain_backtrace_pos);
1780-
(* BACKPORT END *)
17811771
emit_call (Cmm.global_symbol "caml_raise_exn");
17821772
record_frame Reg.Set.empty (Dbg_raise i.dbg)
17831773
| Lambda.Raise_reraise ->
1784-
(* BACKPORT BEGIN *)
1785-
(* emit_call (Cmm.global_symbol "caml_reraise_exn"); *)
1786-
emit_call (Cmm.global_symbol "caml_raise_exn");
1787-
(* BACKPORT END *)
1774+
emit_call (Cmm.global_symbol
1775+
(if Config.runtime5 then "caml_reraise_exn" else "caml_raise_exn"));
17881776
record_frame Reg.Set.empty (Dbg_raise i.dbg)
17891777
| Lambda.Raise_notrace ->
17901778
I.mov (domain_field Domainstate.Domain_exn_handler) rsp;
@@ -1853,33 +1841,40 @@ let fundecl fundecl =
18531841
D.label (label_name (emit_symbol fundecl.fun_name));
18541842
emit_debug_info fundecl.fun_dbg;
18551843
cfi_startproc ();
1856-
(* BACKPORT BEGIN *)
1857-
(* if !Clflags.runtime_variant = "d" then
1858-
emit_call (Cmm.global_symbol "caml_assert_stack_invariants");
1859-
let { max_frame_size; contains_nontail_calls} =
1860-
preproc_stack_check
1861-
~fun_body:fundecl.fun_body ~frame_size:(frame_size ()) ~trap_size:16
1844+
let handle_overflow_and_max_frame_size =
1845+
(* CR mshinwell: this should be conditionalized on a specific
1846+
"stack checks enabled" config option, so we can backport to 4.x *)
1847+
if not Config.runtime5 then None
1848+
else (
1849+
if !Clflags.runtime_variant = "d" then
1850+
emit_call (Cmm.global_symbol "caml_assert_stack_invariants");
1851+
let { max_frame_size; contains_nontail_calls} =
1852+
preproc_stack_check
1853+
~fun_body:fundecl.fun_body ~frame_size:(frame_size ()) ~trap_size:16
1854+
in
1855+
let handle_overflow =
1856+
if contains_nontail_calls || max_frame_size >= stack_threshold_size then begin
1857+
let overflow = new_label () and ret = new_label () in
1858+
let threshold_offset = Domainstate.stack_ctx_words * 8 + stack_threshold_size in
1859+
I.lea (mem64 NONE (-(max_frame_size + threshold_offset)) RSP) r10;
1860+
I.cmp (domain_field Domainstate.Domain_current_stack) r10;
1861+
I.jb (label overflow);
1862+
def_label ret;
1863+
Some (overflow, ret)
1864+
end else None
1865+
in
1866+
match handle_overflow with
1867+
| None -> None
1868+
| Some handle_overflow -> Some (handle_overflow, max_frame_size)
1869+
)
18621870
in
1863-
let handle_overflow =
1864-
if contains_nontail_calls || max_frame_size >= stack_threshold_size then begin
1865-
let overflow = new_label () and ret = new_label () in
1866-
let threshold_offset = Domainstate.stack_ctx_words * 8 + stack_threshold_size in
1867-
I.lea (mem64 NONE (-(max_frame_size + threshold_offset)) RSP) r10;
1868-
I.cmp (domain_field Domainstate.Domain_current_stack) r10;
1869-
I.jb (label overflow);
1870-
def_label ret;
1871-
Some (overflow, ret)
1872-
end else None
1873-
in*)
1874-
(* BACKPORT END *)
18751871
emit_all true fundecl.fun_body;
18761872
List.iter emit_call_gc !call_gc_sites;
18771873
List.iter emit_local_realloc !local_realloc_sites;
18781874
emit_call_safety_errors ();
1879-
(* BACKPORT BEGIN *)
1880-
(*begin match handle_overflow with
1875+
begin match handle_overflow_and_max_frame_size with
18811876
| None -> ()
1882-
| Some (overflow,ret) -> begin
1877+
| Some ((overflow,ret), max_frame_size) -> begin
18831878
def_label overflow;
18841879
(* Pass the desired frame size on the stack, since all of the
18851880
argument-passing registers may be in use.
@@ -1892,8 +1887,7 @@ let fundecl fundecl =
18921887
cfi_adjust_cfa_offset (-8);
18931888
I.jmp (label ret)
18941889
end
1895-
end;*)
1896-
(* BACKPORT END *)
1890+
end;
18971891
if !frame_required then begin
18981892
let n = frame_size() - 8 - (if fp then 8 else 0) in
18991893
if n <> 0

backend/amd64/proc.ml

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -309,10 +309,7 @@ let win64_float_external_arguments =
309309
let win64_loc_external_arguments arg =
310310
let loc = Array.make (Array.length arg) Reg.dummy in
311311
let reg = ref 0
312-
(* BACKPORT BEGIN *)
313-
(* and ofs = ref 0 in *)
314-
and ofs = ref 32 in
315-
(* BACKPORT END *)
312+
and ofs = ref (if Config.runtime5 then 0 else 32) in
316313
for i = 0 to Array.length arg - 1 do
317314
match arg.(i) with
318315
| Val | Int | Addr as ty ->
@@ -374,10 +371,16 @@ let domainstate_ptr_dwarf_register_number = 14
374371

375372
(* Registers destroyed by operations *)
376373

374+
let int_regs_destroyed_at_c_call_win64 =
375+
if Config.runtime5 then [|0;1;4;5;6;7;10;11;12|] else [|0;4;5;6;7;10;11|]
376+
377+
let int_regs_destroyed_at_c_call =
378+
if Config.runtime5 then [|0;1;2;3;4;5;6;7;10;11|] else [|0;2;3;4;5;6;7;10;11|]
379+
377380
let destroyed_at_c_call_win64 =
378381
(* Win64: rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15 preserved *)
379382
let basic_regs = Array.append
380-
(Array.map (phys_reg Int) [|0;4;5;6;7;10;11|] )
383+
(Array.map (phys_reg Int) int_regs_destroyed_at_c_call_win64)
381384
(Array.sub hard_float_reg 0 6)
382385
in
383386
fun () -> if simd_regalloc_disabled ()
@@ -387,7 +390,7 @@ let destroyed_at_c_call_win64 =
387390
let destroyed_at_c_call_unix =
388391
(* Unix: rbx, rbp, r12-r15 preserved *)
389392
let basic_regs = Array.append
390-
(Array.map (phys_reg Int) [|0;2;3;4;5;6;7;10;11|])
393+
(Array.map (phys_reg Int) int_regs_destroyed_at_c_call)
391394
hard_float_reg
392395
in
393396
fun () -> if simd_regalloc_disabled ()

backend/asmlink.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,11 @@ let add_ccobjs origin l =
141141
end
142142

143143
let runtime_lib () =
144-
let libname = "libasmrun" ^ !Clflags.runtime_variant ^ ext_lib in
144+
let variant =
145+
if Config.runtime5 && !Clflags.runtime_variant = "nnp" then ""
146+
else !Clflags.runtime_variant
147+
in
148+
let libname = "libasmrun" ^ variant ^ ext_lib in
145149
try
146150
if !Clflags.nopervasives || not !Clflags.with_runtime then []
147151
else [ Load_path.find libname ]

backend/cmm_helpers.ml

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -826,9 +826,7 @@ let get_header ptr dbg =
826826
data race on headers. This saves performance with ThreadSanitizer
827827
instrumentation by avoiding to instrument header loads. *)
828828
Cop
829-
( (* BACKPORT BEGIN mk_load_immut Word_int, *)
830-
mk_load_mut Word_int,
831-
(* BACKPORT END *)
829+
( (if Config.runtime5 then mk_load_immut Word_int else mk_load_mut Word_int),
832830
[Cop (Cadda, [ptr; Cconst_int (-size_int, dbg)], dbg)],
833831
dbg )
834832

@@ -850,9 +848,9 @@ let get_tag ptr dbg =
850848
(* If byte loads are efficient *)
851849
(* Same comment as [get_header] above *)
852850
Cop
853-
( (* BACKPORT BEGIN mk_load_immut Byte_unsigned, *)
854-
mk_load_mut Byte_unsigned,
855-
(* BACKPORT END *)
851+
( (if Config.runtime5
852+
then mk_load_immut Byte_unsigned
853+
else mk_load_mut Byte_unsigned),
856854
[Cop (Cadda, [ptr; Cconst_int (tag_offset, dbg)], dbg)],
857855
dbg )
858856

@@ -1235,9 +1233,9 @@ let make_alloc_generic ~mode set_fn dbg tag wordsize args =
12351233
Cop
12361234
( Cextcall
12371235
{ func =
1238-
(* BACKPORT BEGIN "caml_alloc_shr_check_gc" *)
1239-
"caml_alloc"
1240-
(* BACKPORT END *);
1236+
(if Config.runtime5
1237+
then "caml_alloc_shr_check_gc"
1238+
else "caml_alloc");
12411239
ty = typ_val;
12421240
alloc = true;
12431241
builtin = false;
@@ -3124,10 +3122,9 @@ let assignment_kind (ptr : Lambda.immediate_or_pointer)
31243122
| Assignment Modify_maybe_stack, Pointer ->
31253123
assert Config.stack_allocation;
31263124
Caml_modify_local
3127-
(* BACKPORT BEGIN | Heap_initialization, Pointer | Root_initialization,
3128-
Pointer -> Caml_initialize *)
31293125
| Heap_initialization, Pointer -> Caml_initialize
3130-
| Root_initialization, Pointer -> Simple Initialization (* BACKPORT END *)
3126+
| Root_initialization, Pointer ->
3127+
if Config.runtime5 then Caml_initialize else Simple Initialization
31313128
| Assignment _, Immediate -> Simple Assignment
31323129
| Heap_initialization, Immediate | Root_initialization, Immediate ->
31333130
Simple Initialization

backend/cmmgen.ml

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -155,21 +155,22 @@ let mut_from_env env ptr =
155155
else Asttypes.Mutable
156156
| _ -> Asttypes.Mutable
157157

158-
(* BACKPORT
159158
(* Minimum of two [mutable_flag] values, assuming [Immutable < Mutable]. *)
160159
let min_mut x y =
161160
match x,y with
162-
| Immutable,_ | _,Immutable -> Immutable
163-
| Mutable,Mutable -> Mutable
164-
*)
165-
166-
(* BACKPORT BEGIN
167-
let get_field env mut ptr n dbg =
168-
let mut = min_mut mut (mut_from_env env ptr) in
169-
*)
170-
let get_field env layout ptr n dbg =
171-
let mut = mut_from_env env ptr in
172-
(* BACKPORT END *)
161+
| Asttypes.Immutable, _
162+
| _, Asttypes.Immutable -> Asttypes.Immutable
163+
| Asttypes.Mutable, Asttypes.Mutable -> Asttypes.Mutable
164+
165+
let mut_from_lambda = function
166+
| Lambda.Immutable -> Asttypes.Immutable
167+
| Lambda.Immutable_unique -> Asttypes.Immutable
168+
| Lambda.Mutable -> Asttypes.Mutable
169+
170+
let get_field env mut layout ptr n dbg =
171+
let mut = if Config.runtime5
172+
then min_mut (mut_from_lambda mut) (mut_from_env env ptr)
173+
else mut_from_env env ptr in
173174
let memory_chunk =
174175
match layout with
175176
| Pvalue Pintval | Punboxed_int _ -> Word_int
@@ -1002,13 +1003,13 @@ and transl_prim_1 env p arg dbg =
10021003
Popaque ->
10031004
opaque (transl env arg) dbg
10041005
(* Heap operations *)
1005-
| Pfield (n, layout, _, _) ->
1006-
get_field env layout (transl env arg) n dbg
1006+
| Pfield (n, layout, _, mut) ->
1007+
get_field env mut layout (transl env arg) n dbg
10071008
| Pfloatfield (n,mode) ->
10081009
let ptr = transl env arg in
10091010
box_float dbg mode (floatfield n ptr dbg)
10101011
| Pufloatfield n ->
1011-
get_field env Punboxed_float (transl env arg) n dbg
1012+
get_field env Mutable Punboxed_float (transl env arg) n dbg
10121013
| Pint_as_pointer _ ->
10131014
int_as_pointer (transl env arg) dbg
10141015
(* Exceptions *)

backend/emitaux.ml

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -534,8 +534,7 @@ let report_error ppf = function
534534
name Debuginfo.print_compact dbg
535535

536536

537-
(* BACKPORT BEGIN *)
538-
(*type preproc_stack_check_result =
537+
type preproc_stack_check_result =
539538
{ max_frame_size : int;
540539
contains_nontail_calls : bool }
541540

@@ -562,5 +561,4 @@ let preproc_stack_check ~fun_body ~frame_size ~trap_size =
562561
| Lentertrap | Lraise _ ->
563562
loop i.next fs max_fs nontail_flag
564563
in
565-
loop fun_body frame_size frame_size false*)
566-
(* BACKPORT END *)
564+
loop fun_body frame_size frame_size false

backend/emitaux.mli

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,12 @@ end
128128
exception Error of error
129129
val report_error: Format.formatter -> error -> unit
130130

131-
(* BACKPORT BEGIN *)
132-
(*type preproc_stack_check_result =
131+
type preproc_stack_check_result =
133132
{ max_frame_size : int;
134133
contains_nontail_calls : bool }
135134

136135
val preproc_stack_check:
137136
fun_body:Linear.instruction ->
138137
frame_size:int ->
139138
trap_size:int ->
140-
preproc_stack_check_result*)
141-
(* BACKPORT END *)
139+
preproc_stack_check_result

0 commit comments

Comments
 (0)