1
Fork 0
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:
Andy Wingo 2012-03-07 10:27:16 +01:00
parent 3c12fc3595
commit 9d381ba478
11 changed files with 148 additions and 178 deletions

View file

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