summaryrefslogtreecommitdiff
path: root/libguile/dynstack.c
diff options
context:
space:
mode:
authorAndy Wingo <wingo@pobox.com>2012-03-07 10:27:16 +0100
committerAndy Wingo <wingo@pobox.com>2012-03-07 10:27:16 +0100
commit9d381ba4788b4d447acd3238c2fc8b86da4998b2 (patch)
tree5fd37ed1b9d73a20dbfadce6c4681bba8f05c75e /libguile/dynstack.c
parent3c12fc359561aedb179a524667ba03481333f482 (diff)
downloadguile-9d381ba4788b4d447acd3238c2fc8b86da4998b2.tar.gz
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.
Diffstat (limited to 'libguile/dynstack.c')
-rw-r--r--libguile/dynstack.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/libguile/dynstack.c b/libguile/dynstack.c
index 56e007c1f..ce9a2feae 100644
--- a/libguile/dynstack.c
+++ b/libguile/dynstack.c
@@ -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