Skip to content

Commit d71173d

Browse files
stedolanmshinwell
andauthored
Support for locals in the 5.x runtime (#2066)
* Basic runtime support for stack allocations Follows the structure of the 4.14 implementation, except that it uses the NON_MARKABLE colour (shared by externals and statics) instead of using Caml_blue. * Stack allocation primitives for arrays, strings, etc. * Missing CAMLextern * Fix Cmm_helpers definitions of caml_local * Fix get_header test --------- Co-authored-by: Mark Shinwell <[email protected]>
1 parent d2db7bb commit d71173d

29 files changed

+558
-159
lines changed

backend/cmm_helpers.ml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,8 @@ let bind_list name args fn =
4949

5050
let caml_black = Nativeint.shift_left (Nativeint.of_int 3) 8
5151

52-
let caml_local = Nativeint.shift_left (Nativeint.of_int 2) 8
52+
let caml_local =
53+
Nativeint.shift_left (Nativeint.of_int (if Config.runtime5 then 3 else 2)) 8
5354
(* cf. runtime/caml/gc.h *)
5455

5556
(* Loads *)

ocaml/asmcomp/cmm_helpers.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ let bind_nonvar name arg fn =
3838
| _ -> let id = V.create_local name in Clet(VP.create id, arg, fn (Cvar id))
3939

4040
let caml_black = Nativeint.shift_left (Nativeint.of_int 3) 8
41-
let caml_local = Nativeint.shift_left (Nativeint.of_int 2) 8
41+
let caml_local =
42+
Nativeint.shift_left (Nativeint.of_int (if Config.runtime5 then 3 else 2)) 8
43+
(* cf. runtime/caml/gc.h *)
4244
(* cf. runtime/caml/gc.h *)
4345

4446
(* Loads *)

ocaml/configure

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ocaml/configure.ac

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2120,8 +2120,6 @@ AS_CASE([$host],
21202120

21212121
if [[ x"$enable_runtime5" = x"yes" ]]; then
21222122
runtime_suffix=
2123-
# CR ocaml 5 runtime: forward port locals
2124-
enable_stack_allocation="no"
21252123
else
21262124
runtime_suffix=4
21272125
fi

ocaml/otherlibs/systhreads/st_stubs.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ struct caml_thread_struct {
8080
/* Note: we do not save Caml_state->stack_cache, because it can
8181
safely be shared between all threads on the same domain. */
8282
struct caml__roots_block *local_roots; /* saved value of local_roots */
83+
struct caml_local_arenas *local_arenas;
8384
int backtrace_pos; /* saved value of Caml_state->backtrace_pos */
8485
backtrace_slot * backtrace_buffer;
8586
/* saved value of Caml_state->backtrace_buffer */
@@ -173,7 +174,8 @@ static void caml_thread_scan_roots(
173174
if (th != Active_thread) {
174175
if (th->current_stack != NULL)
175176
caml_do_local_roots(action, fflags, fdata,
176-
th->local_roots, th->current_stack, th->gc_regs);
177+
th->local_roots, th->current_stack, th->gc_regs,
178+
th->local_arenas);
177179
}
178180
th = th->next;
179181
} while (th != Active_thread);
@@ -198,6 +200,7 @@ static void save_runtime_state(void)
198200
this_thread->gc_regs_buckets = Caml_state->gc_regs_buckets;
199201
this_thread->exn_handler = Caml_state->exn_handler;
200202
this_thread->local_roots = Caml_state->local_roots;
203+
this_thread->local_arenas = caml_get_local_arenas(Caml_state);
201204
this_thread->backtrace_pos = Caml_state->backtrace_pos;
202205
this_thread->backtrace_buffer = Caml_state->backtrace_buffer;
203206
this_thread->backtrace_last_exn = Caml_state->backtrace_last_exn;
@@ -218,6 +221,7 @@ static void restore_runtime_state(caml_thread_t th)
218221
Caml_state->gc_regs_buckets = th->gc_regs_buckets;
219222
Caml_state->exn_handler = th->exn_handler;
220223
Caml_state->local_roots = th->local_roots;
224+
caml_set_local_arenas(Caml_state, th->local_arenas);
221225
Caml_state->backtrace_pos = th->backtrace_pos;
222226
Caml_state->backtrace_buffer = th->backtrace_buffer;
223227
Caml_state->backtrace_last_exn = th->backtrace_last_exn;
@@ -285,6 +289,7 @@ static caml_thread_t caml_thread_new_info(void)
285289
}
286290
th->c_stack = NULL;
287291
th->local_roots = NULL;
292+
th->local_arenas = NULL;
288293
th->backtrace_pos = 0;
289294
th->backtrace_buffer = NULL;
290295
th->backtrace_last_exn = Val_unit;
@@ -321,6 +326,8 @@ void caml_thread_free_info(caml_thread_t th)
321326
caml_free_stack(th->current_stack);
322327
caml_free_backtrace_buffer(th->backtrace_buffer);
323328

329+
// CR sdolan: free local arenas
330+
324331
/* Remark: we could share gc_regs_buckets between threads on a same
325332
domain, but this might break the invariant that it is always
326333
non-empty at the point where we switch from OCaml to C, so we

ocaml/runtime/alloc.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ CAMLexport value caml_alloc_string (mlsize_t len)
193193
return result;
194194
}
195195

196+
/* [len] is a number of bytes (chars) */
197+
CAMLexport value caml_alloc_local_string (mlsize_t len)
198+
{
199+
mlsize_t offset_index;
200+
mlsize_t wosize = (len + sizeof (value)) / sizeof (value);
201+
value result;
202+
203+
result = caml_alloc_local(wosize, String_tag);
204+
Field (result, wosize - 1) = 0;
205+
offset_index = Bsize_wsize (wosize) - 1;
206+
Byte (result, offset_index) = offset_index - len;
207+
return result;
208+
}
209+
196210
/* [len] is a number of bytes (chars) */
197211
CAMLexport value caml_alloc_initialized_string (mlsize_t len, const char *p)
198212
{

ocaml/runtime/amd64.S

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,20 @@ CFI_STARTPROC
581581
CFI_ENDPROC
582582
ENDFUNCTION(G(caml_allocN))
583583

584+
FUNCTION(G(caml_call_local_realloc))
585+
CFI_STARTPROC
586+
CFI_SIGNAL_FRAME
587+
ENTER_FUNCTION
588+
SAVE_ALL_REGS
589+
SWITCH_OCAML_TO_C
590+
C_call (GCALL(caml_local_realloc))
591+
SWITCH_C_TO_OCAML
592+
RESTORE_ALL_REGS
593+
LEAVE_FUNCTION
594+
ret
595+
CFI_ENDPROC
596+
ENDFUNCTION(G(caml_call_local_realloc))
597+
584598
/******************************************************************************/
585599
/* Call a C function from OCaml */
586600
/******************************************************************************/

0 commit comments

Comments
 (0)