aboutsummaryrefslogtreecommitdiff
path: root/mfd/prog.c
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2008-09-19 09:59:03 +0000
committerSergey Poznyakoff <gray@gnu.org.ua>2008-09-19 09:59:03 +0000
commit16dedfd3996a3077ce9ee93ab4dd7b9e47d05cfb (patch)
treea5ad50dd3d492d6479f1a39a4ebadc61059f927e /mfd/prog.c
parentf7db7631f4df8c6dcca5c1fef060634e8c62a6eb (diff)
downloadmailfromd-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.c46
1 files changed, 35 insertions, 11 deletions
diff --git a/mfd/prog.c b/mfd/prog.c
index 4a363072..25f9f220 100644
--- a/mfd/prog.c
+++ b/mfd/prog.c
@@ -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);

Return to:

Send suggestions and report system problems to the System administrator.