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.
master
Xavier Leroy 2020-06-03 16:38:02 +02:00
parent f8970c4b15
commit 53d55f2522
4 changed files with 5 additions and 8 deletions

View File

@ -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;
}

View File

@ -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);

View File

@ -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;

View File

@ -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 =