From 53d55f252204f8537ed5014e1896328df5652049 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Wed, 3 Jun 2020 16:38:02 +0200 Subject: [PATCH] Revised linking of trap frames in bytecode interpreter stack Rather than storing a pointer to the previous frame in the Trap_link field of the current frame, store the distance (pointer difference) between the current frame and the previous frame, tagged as an OCaml integer. Using a tagged integer instead of a raw pointer means fever problems later with strict no-naked-pointer support. Using a distance rather than an absolute address simplifies the code that resizes the stack. --- runtime/backtrace_byt.c | 2 +- runtime/caml/stacks.h | 2 +- runtime/interp.c | 6 +++--- runtime/stacks.c | 3 --- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/backtrace_byt.c b/runtime/backtrace_byt.c index 28fe44c75..2641daedd 100644 --- a/runtime/backtrace_byt.c +++ b/runtime/backtrace_byt.c @@ -304,7 +304,7 @@ code_t caml_next_frame_pointer(value ** sp, value ** trsp) if (Is_long(*spv)) continue; p = (code_t*) spv; if(&Trap_pc(*trsp) == p) { - *trsp = Trap_link(*trsp); + *trsp = *trsp + Long_val(Trap_link_offset(*trsp)); continue; } diff --git a/runtime/caml/stacks.h b/runtime/caml/stacks.h index 8cbb02a83..d309141f9 100644 --- a/runtime/caml/stacks.h +++ b/runtime/caml/stacks.h @@ -33,7 +33,7 @@ #define caml_trap_barrier (Caml_state_field(trap_barrier)) #define Trap_pc(tp) (((code_t *)(tp))[0]) -#define Trap_link(tp) (((value **)(tp))[1]) +#define Trap_link_offset(tp) (((value *)(tp))[1]) void caml_init_stack (uintnat init_max_size); void caml_realloc_stack (asize_t required_size); diff --git a/runtime/interp.c b/runtime/interp.c index 146c8346e..e5c110812 100644 --- a/runtime/interp.c +++ b/runtime/interp.c @@ -850,7 +850,7 @@ value caml_interprete(code_t prog, asize_t prog_size) Instruct(PUSHTRAP): sp -= 4; Trap_pc(sp) = pc + *pc; - Trap_link(sp) = Caml_state->trapsp; + Trap_link_offset(sp) = Val_long(Caml_state->trapsp - sp); sp[2] = env; sp[3] = Val_long(extra_args); Caml_state->trapsp = sp; @@ -865,7 +865,7 @@ value caml_interprete(code_t prog, asize_t prog_size) pc--; /* restart the POPTRAP after processing the signal */ goto process_actions; } - Caml_state->trapsp = Trap_link(sp); + Caml_state->trapsp = sp + Long_val(Trap_link_offset(sp)); sp += 4; Next; @@ -898,7 +898,7 @@ value caml_interprete(code_t prog, asize_t prog_size) } sp = Caml_state->trapsp; pc = Trap_pc(sp); - Caml_state->trapsp = Trap_link(sp); + Caml_state->trapsp = sp + Long_val(Trap_link_offset(sp)); env = sp[2]; extra_args = Long_val(sp[3]); sp += 4; diff --git a/runtime/stacks.c b/runtime/stacks.c index 2e3be6a0f..a1409b2ab 100644 --- a/runtime/stacks.c +++ b/runtime/stacks.c @@ -47,7 +47,6 @@ void caml_realloc_stack(asize_t required_space) { asize_t size; value * new_low, * new_high, * new_sp; - value * p; CAMLassert(Caml_state->extern_sp >= Caml_state->stack_low); size = Caml_state->stack_high - Caml_state->stack_low; @@ -72,8 +71,6 @@ void caml_realloc_stack(asize_t required_space) caml_stat_free(Caml_state->stack_low); Caml_state->trapsp = (value *) shift(Caml_state->trapsp); Caml_state->trap_barrier = (value *) shift(Caml_state->trap_barrier); - for (p = Caml_state->trapsp; p < new_high; p = Trap_link(p)) - Trap_link(p) = (value *) shift(Trap_link(p)); Caml_state->stack_low = new_low; Caml_state->stack_high = new_high; Caml_state->stack_threshold =