diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-09-19 09:59:03 +0000 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2008-09-19 09:59:03 +0000 |
commit | 16dedfd3996a3077ce9ee93ab4dd7b9e47d05cfb (patch) | |
tree | a5ad50dd3d492d6479f1a39a4ebadc61059f927e /mfd/prog.c | |
parent | f7db7631f4df8c6dcca5c1fef060634e8c62a6eb (diff) | |
download | mailfromd-16dedfd3996a3077ce9ee93ab4dd7b9e47d05cfb.tar.gz mailfromd-16dedfd3996a3077ce9ee93ab4dd7b9e47d05cfb.tar.bz2 |
Implement two stack growth policies.
* mfd/gram.y (pragma_stacksize): Implement two stack growth
policies.
* mfd/mailfromd.h (enum stack_expand_policy): New enum.
(stack_expand_incr, stack_expand_policy): New global variables.
* mfd/prog.c (stack_expand_incr)
(stack_expand_policy): New global variables.
* NEWS: Update.
* doc/mailfromd.texi (stacksize): Document changes to pragma
stacksize.
* doc/values.texi (STACK-INCR): New value.
git-svn-id: file:///svnroot/mailfromd/trunk@1676 7a8a7f39-df28-0410-adc6-e0d955640f24
Diffstat (limited to 'mfd/prog.c')
-rw-r--r-- | mfd/prog.c | 46 |
1 files changed, 35 insertions, 11 deletions
@@ -46,6 +46,8 @@ static prog_counter_t pc, pmax; instr_t *prog; size_t stack_size = 4096; +size_t stack_expand_incr = 4096; +enum stack_expand_policy stack_expand_policy = stack_expand_add; /* Data segment */ STKVAL *dataseg; @@ -384,32 +386,54 @@ env_fixup_autos(eval_environ_t env, ptrdiff_t offset) } -#define STACK_EXPAND_BLOCK 64 - static int expand_dataseg(eval_environ_t env, size_t count, const char *errtext) { STKVAL *newds; ptrdiff_t offset; + size_t new_stack_size; + size_t diff; + + switch (stack_expand_policy) { + case stack_expand_add: + diff = ((count + stack_expand_incr - 1) / stack_expand_incr) + * stack_expand_incr; + new_stack_size = env->stack_size + diff; + break; + + case stack_expand_twice: + new_stack_size = 2 * env->stack_size; + if (new_stack_size < env->stack_size) { + if (errtext) + runtime_error(env, errtext); + else + return 1; + } + diff = new_stack_size - env->stack_size; + if (diff < count) { + if (errtext) + runtime_error(env, errtext); + else + return 1; + } + } - count = ((count + STACK_EXPAND_BLOCK - 1) / STACK_EXPAND_BLOCK) - * STACK_EXPAND_BLOCK; newds = realloc(env->dataseg, - (env->stack_size + datasize + count) - * sizeof env->dataseg[0]); + (new_stack_size + datasize) * sizeof env->dataseg[0]); + if (!newds) { if (errtext) runtime_error(env, errtext); else return 1; } - + offset = (char*)newds - (char*)env->dataseg; env->dataseg = newds; - env->stack_size += count; - env->tos += count; - env->base += count; - memmove(newds + env->tos, newds + env->tos - count, + env->stack_size = new_stack_size; + env->tos += diff; + env->base += diff; + memmove(newds + env->tos, newds + env->tos - diff, (datasize + env->stack_size - env->tos) * sizeof newds[0]); env_fixup_autos(env, offset); |