mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-24 12:20:20 +02:00
dynstack: pushing a prompt no longer allocates memory
* libguile/control.h: Remove scm_t_prompt_registers and scm_c_make_prompt_registers. (scm_c_abort): Take a pointer to a jmpbuf instead of a cookie. It will serve the same purpose. * libguile/control.c (reify_partial_continuation, scm_at_abort): Adapt to new prompt representation. * libguile/dynstack.h: * libguile/dynstack.c (scm_dynstack_push_prompt): Prompts now have 5 words instead of 2, as they now push the fp, sp, ip, and jmpbuf on the stack separately. This avoids allocation. (scm_dynstack_find_prompt): Likewise, add return values for fp, sp, etc. (scm_dynstack_wind_prompt): Replaces scm_dynstack_relocate_prompt. * libguile/eval.c (eval): * libguile/stacks.c (find_prompt): * libguile/throw.c (pre_init_catch): Adapt to the new prompt mechanism. * libguile/vm-engine.c (vm_engine): Setjmp an on-stack jmpbuf every time the VM enters. We can then re-use that jmpbuf for all prompts in that invocation. * libguile/vm-i-system.c (partial_cont_call): Adapt to change in prompt representation. We don't need to wind here any more, since we pass in the prompt's jmpbuf. (prompt): Adapt to scm_dynstack_push_prompt change. (abort): Adapt to vm_abort change. * libguile/vm.h (struct scm_vm): No more cookie. * libguile/vm.c (vm_abort): Adapt to scm_c_abort change. (vm_reinstate_partial_continuation): Rewind the dynamic stack here, now that we do have a valid jmpbuf. (make_vm): No need to initialize a cookie.
This commit is contained in:
parent
3c12fc3595
commit
9d381ba478
11 changed files with 148 additions and 178 deletions
|
@ -34,9 +34,12 @@
|
|||
|
||||
|
||||
|
||||
#define PROMPT_WORDS 2
|
||||
#define PROMPT_WORDS 5
|
||||
#define PROMPT_KEY(top) (SCM_PACK ((top)[0]))
|
||||
#define PROMPT_REGS(top) ((scm_t_prompt_registers*) ((top)[1]))
|
||||
#define PROMPT_FP(top) ((SCM *) ((top)[1]))
|
||||
#define PROMPT_SP(top) ((SCM *) ((top)[2]))
|
||||
#define PROMPT_IP(top) ((scm_t_uint8 *) ((top)[3]))
|
||||
#define PROMPT_JMPBUF(top) ((scm_i_jmp_buf *) ((top)[4]))
|
||||
|
||||
#define WINDER_WORDS 2
|
||||
#define WINDER_PROC(top) ((scm_t_guard) ((top)[0]))
|
||||
|
@ -188,13 +191,19 @@ scm_dynstack_push_fluids (scm_t_dynstack *dynstack, size_t n,
|
|||
void
|
||||
scm_dynstack_push_prompt (scm_t_dynstack *dynstack,
|
||||
scm_t_dynstack_prompt_flags flags,
|
||||
SCM key, scm_t_prompt_registers *regs)
|
||||
SCM key,
|
||||
SCM *fp, SCM *sp, scm_t_uint8 *ip,
|
||||
scm_i_jmp_buf *registers)
|
||||
{
|
||||
scm_t_bits *words;
|
||||
|
||||
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_PROMPT, flags, 2);
|
||||
words = push_dynstack_entry (dynstack, SCM_DYNSTACK_TYPE_PROMPT, flags,
|
||||
PROMPT_WORDS);
|
||||
words[0] = SCM_UNPACK (key);
|
||||
words[1] = (scm_t_bits) regs;
|
||||
words[1] = (scm_t_bits) fp;
|
||||
words[2] = (scm_t_bits) sp;
|
||||
words[3] = (scm_t_bits) ip;
|
||||
words[4] = (scm_t_bits) registers;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -439,8 +448,9 @@ scm_dynstack_unwind_fork (scm_t_dynstack *dynstack, scm_t_dynstack *branch)
|
|||
|
||||
scm_t_bits*
|
||||
scm_dynstack_find_prompt (scm_t_dynstack *dynstack, SCM key,
|
||||
scm_t_prompt_registers **regs,
|
||||
scm_t_dynstack_prompt_flags *flags)
|
||||
scm_t_dynstack_prompt_flags *flags,
|
||||
SCM **fp, SCM **sp, scm_t_uint8 **ip,
|
||||
scm_i_jmp_buf **registers)
|
||||
{
|
||||
scm_t_bits *walk;
|
||||
|
||||
|
@ -452,10 +462,16 @@ scm_dynstack_find_prompt (scm_t_dynstack *dynstack, SCM key,
|
|||
if (SCM_DYNSTACK_TAG_TYPE (tag) == SCM_DYNSTACK_TYPE_PROMPT
|
||||
&& scm_is_eq (PROMPT_KEY (walk), key))
|
||||
{
|
||||
if (regs)
|
||||
*regs = PROMPT_REGS (walk);
|
||||
if (flags)
|
||||
*flags = SCM_DYNSTACK_TAG_FLAGS (tag);
|
||||
if (fp)
|
||||
*fp = PROMPT_FP (walk);
|
||||
if (sp)
|
||||
*sp = PROMPT_SP (walk);
|
||||
if (ip)
|
||||
*ip = PROMPT_IP (walk);
|
||||
if (registers)
|
||||
*registers = PROMPT_JMPBUF (walk);
|
||||
return walk;
|
||||
}
|
||||
}
|
||||
|
@ -463,26 +479,22 @@ scm_dynstack_find_prompt (scm_t_dynstack *dynstack, SCM key,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
scm_t_prompt_registers*
|
||||
scm_dynstack_relocate_prompt (scm_t_dynstack *dynstack, scm_t_ptrdiff reloc,
|
||||
scm_t_uint64 vm_cookie)
|
||||
void
|
||||
scm_dynstack_wind_prompt (scm_t_dynstack *dynstack, scm_t_bits *item,
|
||||
scm_t_ptrdiff reloc, scm_i_jmp_buf *registers)
|
||||
{
|
||||
scm_t_bits *item;
|
||||
scm_t_prompt_registers *prev, *rewound;
|
||||
scm_t_bits tag = SCM_DYNSTACK_TAG (item);
|
||||
|
||||
item = SCM_DYNSTACK_PREV (dynstack->top);
|
||||
if (SCM_DYNSTACK_TAG_TYPE (SCM_DYNSTACK_TAG (item))
|
||||
!= SCM_DYNSTACK_TYPE_PROMPT)
|
||||
if (SCM_DYNSTACK_TAG_TYPE (tag) != SCM_DYNSTACK_TYPE_PROMPT)
|
||||
abort ();
|
||||
|
||||
prev = PROMPT_REGS (item);
|
||||
rewound = scm_c_make_prompt_registers (prev->fp + reloc,
|
||||
prev->sp + reloc,
|
||||
prev->ip,
|
||||
vm_cookie);
|
||||
item[1] = (scm_t_bits) rewound;
|
||||
|
||||
return rewound;
|
||||
scm_dynstack_push_prompt (dynstack,
|
||||
SCM_DYNSTACK_TAG_FLAGS (tag),
|
||||
PROMPT_KEY (item),
|
||||
PROMPT_FP (item) + reloc,
|
||||
PROMPT_SP (item) + reloc,
|
||||
PROMPT_IP (item),
|
||||
registers);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue