File tree 4 files changed +54
-4
lines changed
4 files changed +54
-4
lines changed Original file line number Diff line number Diff line change @@ -365,13 +365,23 @@ let record_frame_label live dbg =
365
365
let live_offset = ref [] in
366
366
Reg.Set.iter
367
367
(function
368
- | {typ = Val; loc = Reg r} ->
368
+ | {typ = Val; loc = Reg r} as reg ->
369
+ assert (Proc.gc_regs_offset reg = r);
369
370
live_offset := ((r lsl 1) + 1) :: !live_offset
370
371
| {typ = Val; loc = Stack s} as reg ->
371
372
live_offset := slot_offset s (stack_slot_class reg.typ) :: !live_offset
373
+ | {typ = Valx2; loc = Reg r} as reg ->
374
+ let n = Proc.gc_regs_offset reg in
375
+ let encode n = ((n lsl 1) + 1) in
376
+ live_offset := encode n :: encode (n + 1) :: !live_offset
377
+ | {typ = Valx2; loc = Stack s} as reg ->
378
+ let n = slot_offset s (stack_slot_class reg.typ) in
379
+ live_offset := n :: n + 1 :: !live_offset
372
380
| {typ = Addr} as r ->
373
381
Misc.fatal_error ("bad GC root " ^ Reg.name r)
374
- | _ -> ()
382
+ | { typ = (Val | Valx2); loc = Unknown ; } as r ->
383
+ Misc.fatal_error ("Unknown location " ^ Reg.name r)
384
+ | { typ = Int | Float | Float32 | Vec128; _ } -> ()
375
385
)
376
386
live;
377
387
record_frame_descr ~label:lbl ~frame_size:(frame_size())
@@ -2243,6 +2253,7 @@ let emit_probe_handler_wrapper p =
2243
2253
(match r.typ with
2244
2254
| Val -> k::acc
2245
2255
| Int | Float | Vec128 | Float32 -> acc
2256
+ | Valx2 -> k::k+1::acc
2246
2257
| Addr -> Misc.fatal_error ("bad GC root " ^ Reg.name r))
2247
2258
| _ -> assert false)
2248
2259
saved_live
Original file line number Diff line number Diff line change @@ -165,7 +165,40 @@ let phys_reg ty n =
165
165
| Int | Addr | Val -> hard_int_reg.(n)
166
166
| Float -> hard_float_reg.(n - 100 )
167
167
| Float32 -> hard_float32_reg.(n - 100 )
168
- | Vec128 -> hard_vec128_reg.(n - 100 )
168
+ | Vec128 | Valx2 -> hard_vec128_reg.(n - 100 )
169
+
170
+ let gc_regs_offset reg =
171
+ (* Given register [r], return the offset (the number of [value] slots,
172
+ not their size in bytes) of the register from the
173
+ [gc_regs] pointer during GC at runtime. Keep in sync with [amd64.S]. *)
174
+ let r =
175
+ match reg.loc with
176
+ | Reg r -> r
177
+ | Stack _ | Unknown ->
178
+ Misc. fatal_errorf " Unexpected register location for %d" reg.stamp
179
+ in
180
+ let reg_class = register_class reg in
181
+ let index = (r - first_available_register.(reg_class)) in
182
+ match reg_class with
183
+ | 0 -> index
184
+ | 1 ->
185
+ let slot_size_in_vals = 2 in
186
+ assert (Arch. size_vec128 / Arch. size_int = slot_size_in_vals);
187
+ if Config. runtime5
188
+ then
189
+ (* xmm slots are above regular slots based at [gc_regs_bucket] *)
190
+ let num_regular_slots =
191
+ (* rbp is always spilled even without frame pointers *)
192
+ 13
193
+ in
194
+ num_regular_slots + (index * slot_size_in_vals)
195
+ else
196
+ (* xmm slots are below [gc_regs] pointer *)
197
+ let num_xmm_slots = 16 in
198
+ let offset = Int. neg (num_xmm_slots * slot_size_in_vals) in
199
+ offset + (index * slot_size_in_vals)
200
+ | _ -> assert false
201
+
169
202
170
203
let rax = phys_reg Int 0
171
204
let rdx = phys_reg Int 4
Original file line number Diff line number Diff line change @@ -143,14 +143,19 @@ let is_long n =
143
143
if n > 0x3FFF_FFFF then raise (Error (Stack_frame_way_too_large n));
144
144
n > = ! Flambda_backend_flags. long_frames_threshold
145
145
146
+ let is_long_stack_index n =
147
+ let is_reg n = n land 1 = 1 in
148
+ (* allows negative reg offsets in runtime4 *)
149
+ if is_reg n && not Config. runtime5 then false else is_long n
150
+
146
151
let record_frame_descr ~label ~frame_size ~live_offset debuginfo =
147
152
assert (frame_size land 3 = 0 );
148
153
let fd_long =
149
154
is_long (frame_size + get_flags debuginfo)
150
155
(* The checks below are redundant (if they fail, then frame size check above
151
156
should have failed), but they make the safety of [emit_frame] clear. *)
152
157
|| is_long (List. length live_offset)
153
- || List. exists is_long live_offset
158
+ || List. exists is_long_stack_index live_offset
154
159
in
155
160
if fd_long && not ! Flambda_backend_flags. allow_long_frames
156
161
then raise (Error (Stack_frame_too_large frame_size));
Original file line number Diff line number Diff line change @@ -25,6 +25,7 @@ val num_available_registers: int array
25
25
val first_available_register : int array
26
26
val register_name : Cmm .machtype_component -> int -> string
27
27
val phys_reg : Cmm .machtype_component -> int -> Reg .t
28
+ val gc_regs_offset : Reg .t -> int
28
29
val rotate_registers : bool
29
30
val precolored_regs : unit -> Reg.Set .t
30
31
You can’t perform that action at this time.
0 commit comments