Skip to content

Commit eb66785

Browse files
committed
Support local allocations in i386 and fix amd64 bug (#31)
* i386 local allocation support * Bugfix for local alloc counting logic on amd64
1 parent c936b19 commit eb66785

File tree

4 files changed

+80
-2
lines changed

4 files changed

+80
-2
lines changed

asmcomp/amd64/emit.mlp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,8 @@ let emit_instr fallthrough i =
758758
I.mov (arg i 0) r11;
759759
I.sub (domain_field Domainstate.Domain_local_sp) r11;
760760
I.add r11 (domain_field Domainstate.Domain_local_total);
761-
I.mov (arg i 0) (domain_field Domainstate.Domain_local_sp)
761+
I.add (domain_field Domainstate.Domain_local_sp) r11;
762+
I.mov r11 (domain_field Domainstate.Domain_local_sp)
762763
| Lop (Iname_for_debugger _) -> ()
763764
| Lreloadretaddr ->
764765
()

asmcomp/i386/emit.mlp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,19 @@ let emit_call_gc gc =
236236
def_label gc.gc_frame;
237237
I.jmp (label gc.gc_return_lbl)
238238

239+
(* Record calls to local stack reallocation *)
240+
241+
type local_realloc_call =
242+
{ lr_lbl: label;
243+
lr_return_lbl: label; }
244+
245+
let local_realloc_sites = ref ([] : local_realloc_call list)
246+
247+
let emit_local_realloc lr =
248+
def_label lr.lr_lbl;
249+
emit_call "caml_call_local_realloc";
250+
I.jmp (label lr.lr_return_lbl)
251+
239252
(* Record calls to caml_ml_array_bound_error.
240253
In -g mode, we maintain one call to caml_ml_array_bound_error
241254
per bound check site. Without -g, we can share a single call. *)
@@ -608,7 +621,7 @@ let emit_instr fallthrough i =
608621
I.fstp (addressing addr REAL8 i 1)
609622
end
610623
end
611-
| Lop(Ialloc { bytes = n; dbginfo }) ->
624+
| Lop(Ialloc { bytes = n; dbginfo; mode = Alloc_heap }) ->
612625
if !fastcode_flag then begin
613626
load_domain_state ebx;
614627
I.mov (domain_field Domain_young_ptr RBX) eax;
@@ -643,6 +656,21 @@ let emit_instr fallthrough i =
643656
def_label label;
644657
I.lea (mem32 NONE 4 RAX) (reg i.res.(0))
645658
end
659+
| Lop(Ialloc {bytes = n; dbginfo=_; mode = Alloc_local }) ->
660+
load_domain_state ebx;
661+
I.mov (domain_field Domainstate.Domain_local_sp RBX) eax;
662+
I.sub (int n) eax;
663+
I.mov eax (domain_field Domainstate.Domain_local_sp RBX);
664+
I.cmp (domain_field Domainstate.Domain_local_limit RBX) eax;
665+
let lbl_call = new_label () in
666+
I.j L (label lbl_call);
667+
let lbl_after_alloc = new_label () in
668+
def_label lbl_after_alloc;
669+
I.add (domain_field Domainstate.Domain_local_top RBX) eax;
670+
I.lea (mem32 NONE 4 RAX) (reg i.res.(0));
671+
local_realloc_sites :=
672+
{ lr_lbl = lbl_call;
673+
lr_return_lbl = lbl_after_alloc } :: !local_realloc_sites
646674
| Lop(Iintop(Icomp cmp)) ->
647675
I.cmp (reg i.arg.(1)) (reg i.arg.(0));
648676
I.set (cond cmp) al;
@@ -799,6 +827,16 @@ let emit_instr fallthrough i =
799827
if Array.length i.arg = 2 && is_tos i.arg.(1) then
800828
I.fxch st1;
801829
emit_floatspecial s
830+
| Lop (Ibeginregion) ->
831+
load_domain_state ebx;
832+
I.mov (domain_field Domainstate.Domain_local_sp RBX) (reg i.res.(0))
833+
| Lop (Iendregion) ->
834+
I.mov (reg i.arg.(0)) eax;
835+
load_domain_state ebx;
836+
I.sub (domain_field Domainstate.Domain_local_sp RBX) eax;
837+
I.add eax (domain_field Domainstate.Domain_local_total RBX);
838+
I.add (domain_field Domainstate.Domain_local_sp RBX) eax;
839+
I.mov eax (domain_field Domainstate.Domain_local_sp RBX)
802840
| Lop (Iname_for_debugger _) -> ()
803841
| Lreloadretaddr ->
804842
()
@@ -922,6 +960,7 @@ let fundecl fundecl =
922960
tailrec_entry_point := fundecl.fun_tailrec_entry_point_label;
923961
stack_offset := 0;
924962
call_gc_sites := [];
963+
local_realloc_sites := [];
925964
bound_error_sites := [];
926965
bound_error_call := 0;
927966
for i = 0 to Proc.num_register_classes - 1 do
@@ -937,6 +976,7 @@ let fundecl fundecl =
937976
cfi_startproc ();
938977
emit_all true fundecl.fun_body;
939978
List.iter emit_call_gc !call_gc_sites;
979+
List.iter emit_local_realloc !local_realloc_sites;
940980
emit_call_bound_errors ();
941981
cfi_endproc ();
942982
begin match system with

asmcomp/i386/proc.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ let destroyed_at_oper = function
207207
| Iop(Iintop Imulh) -> [| eax |]
208208
| Iop(Iintop(Icomp _) | Iintop_imm(Icomp _, _)) -> [| eax |]
209209
| Iop(Iintoffloat) -> [| eax |]
210+
| Iop(Ibeginregion|Iendregion) -> [| eax; ebx |]
210211
| Iifthenelse(Ifloattest _, _, _) -> [| eax |]
211212
| Itrywith _ -> [| edx |]
212213
| _ -> [||]
@@ -235,6 +236,7 @@ let op_is_pure = function
235236
| Iintop(Icheckbound) | Iintop_imm(Icheckbound, _) -> false
236237
| Ispecific(Ilea _) -> true
237238
| Ispecific _ -> false
239+
| Ibeginregion | Iendregion -> false
238240
| _ -> true
239241

240242
(* Layout of the stack frame *)

runtime/i386.S

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,41 @@ FUNCTION(caml_allocN)
203203
CFI_ENDPROC
204204
ENDFUNCTION(caml_allocN)
205205

206+
FUNCTION(caml_call_local_realloc)
207+
CFI_STARTPROC
208+
movl G(Caml_state), %ebx
209+
#if !defined(SYS_mingw) && !defined(SYS_cygwin)
210+
/* Touch the stack to trigger a recoverable segfault
211+
if insufficient space remains */
212+
subl $(STACK_PROBE_SIZE), %esp; CFI_ADJUST(STACK_PROBE_SIZE);
213+
movl %eax, 0(%esp)
214+
addl $(STACK_PROBE_SIZE), %esp; CFI_ADJUST(-STACK_PROBE_SIZE);
215+
#endif
216+
/* Build array of registers, save it into Caml_state->gc_regs */
217+
pushl %ebp; CFI_ADJUST(4)
218+
pushl %edi; CFI_ADJUST(4)
219+
pushl %esi; CFI_ADJUST(4)
220+
pushl %edx; CFI_ADJUST(4)
221+
pushl %ecx; CFI_ADJUST(4)
222+
pushl %ebx; CFI_ADJUST(4)
223+
pushl %eax; CFI_ADJUST(4)
224+
movl %esp, CAML_STATE(gc_regs, %ebx)
225+
/* MacOSX note: 16-alignment of stack preserved at this point */
226+
/* Call the garbage collector */
227+
call G(caml_local_realloc)
228+
/* Restore all regs used by the code generator */
229+
popl %eax; CFI_ADJUST(-4)
230+
popl %ebx; CFI_ADJUST(-4)
231+
popl %ecx; CFI_ADJUST(-4)
232+
popl %edx; CFI_ADJUST(-4)
233+
popl %esi; CFI_ADJUST(-4)
234+
popl %edi; CFI_ADJUST(-4)
235+
popl %ebp; CFI_ADJUST(-4)
236+
ret
237+
CFI_ENDPROC
238+
ENDFUNCTION(caml_call_local_realloc)
239+
240+
206241
/* Call a C function from OCaml */
207242

208243
FUNCTION(caml_c_call)

0 commit comments

Comments
 (0)