committed new stack modification method

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40122
This commit is contained in:
David Anderson 2006-10-15 23:31:09 +00:00
parent 2c65e42379
commit ea6e82d79a
3 changed files with 119 additions and 16 deletions

View File

@ -1972,6 +1972,7 @@ static int declloc(int fstatic)
} /* if */ } /* if */
markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */ markexpr(sLDECL,name,-declared*sizeof(cell)); /* mark for better optimization */
modstk(-(int)size*sizeof(cell)); modstk(-(int)size*sizeof(cell));
markstack(MEMUSE_STATIC, size);
assert(curfunc!=NULL); assert(curfunc!=NULL);
assert((curfunc->usage & uNATIVE)==0); assert((curfunc->usage & uNATIVE)==0);
if (curfunc->x.stacksize<declared+1) if (curfunc->x.stacksize<declared+1)
@ -3334,6 +3335,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
sc_alignnext=FALSE; sc_alignnext=FALSE;
} /* if */ } /* if */
declared=0; /* number of local cells */ declared=0; /* number of local cells */
resetstacklist();
rettype=(sym->usage & uRETVALUE); /* set "return type" variable */ rettype=(sym->usage & uRETVALUE); /* set "return type" variable */
curfunc=sym; curfunc=sym;
define_args(); /* add the symbolic info for the function arguments */ define_args(); /* add the symbolic info for the function arguments */
@ -3361,7 +3363,7 @@ static int newfunc(char *firstname,int firsttag,int fpublic,int fstatic,int stoc
* has only a single statement in its body (no compound block) and that * has only a single statement in its body (no compound block) and that
* statement declares a new variable * statement declares a new variable
*/ */
modstk((int)declared*sizeof(cell)); /* remove all local variables */ popstacklist();
declared=0; declared=0;
} /* if */ } /* if */
if ((lastst!=tRETURN) && (lastst!=tGOTO)){ if ((lastst!=tRETURN) && (lastst!=tGOTO)){
@ -4770,6 +4772,7 @@ static void compound(int stmt_sameline,int starttok)
int block_start=fline; /* save line where the compound block started */ int block_start=fline; /* save line where the compound block started */
int endtok; int endtok;
pushstacklist();
/* if there is more text on this line, we should adjust the statement indent */ /* if there is more text on this line, we should adjust the statement indent */
if (stmt_sameline) { if (stmt_sameline) {
int i; int i;
@ -4808,8 +4811,9 @@ static void compound(int stmt_sameline,int starttok)
} /* while */ } /* while */
if (lastst!=tRETURN) if (lastst!=tRETURN)
destructsymbols(&loctab,nestlevel); destructsymbols(&loctab,nestlevel);
if (lastst!=tRETURN && lastst!=tGOTO) if (lastst!=tRETURN && lastst!=tGOTO) {
modstk((int)(declared-save_decl)*sizeof(cell)); /* delete local variable space */ popstacklist();
}
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */ testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
declared=save_decl; declared=save_decl;
delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but delete_symbols(&loctab,nestlevel,FALSE,TRUE); /* erase local symbols, but
@ -5069,6 +5073,7 @@ static int dofor(void)
save_decl=declared; save_decl=declared;
save_nestlevel=nestlevel; save_nestlevel=nestlevel;
save_endlessloop=endlessloop; save_endlessloop=endlessloop;
pushstacklist();
addwhile(wq); addwhile(wq);
skiplab=getlabel(); skiplab=getlabel();
@ -5094,8 +5099,11 @@ static int dofor(void)
*/ */
ptr=readwhile(); ptr=readwhile();
assert(ptr!=NULL); assert(ptr!=NULL);
ptr[wqBRK]=(int)declared; /*ptr[wqBRK]=(int)declared;
ptr[wqCONT]=(int)declared; *ptr[wqCONT]=(int)declared;
*/
ptr[wqBRK] = stackusage->list_id;
ptr[wqCONT] = stackusage->list_id;
jumplabel(skiplab); /* skip expression 3 1st time */ jumplabel(skiplab); /* skip expression 3 1st time */
setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */ setlabel(wq[wqLOOP]); /* "continue" goes to this label: expr3 */
setline(TRUE); setline(TRUE);
@ -5135,7 +5143,7 @@ static int dofor(void)
* variable in "expr1". * variable in "expr1".
*/ */
destructsymbols(&loctab,nestlevel); destructsymbols(&loctab,nestlevel);
modstk((int)(declared-save_decl)*sizeof(cell)); popstacklist();
testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */ testsymbols(&loctab,nestlevel,FALSE,TRUE); /* look for unused block locals */
declared=save_decl; declared=save_decl;
delete_symbols(&loctab,nestlevel,FALSE,TRUE); delete_symbols(&loctab,nestlevel,FALSE,TRUE);
@ -5152,7 +5160,7 @@ static int dofor(void)
* 2. only one instruction may appear below each case, use a compound * 2. only one instruction may appear below each case, use a compound
* instruction to execute multiple instructions * instruction to execute multiple instructions
* 3. the "case" keyword accepts a comma separated list of values to * 3. the "case" keyword accepts a comma separated list of values to
* match, it also accepts a range using the syntax "1 .. 4" * match
* *
* SWITCH param * SWITCH param
* PRI = expression result * PRI = expression result
@ -5349,6 +5357,8 @@ static void dolabel(void)
/* since one can jump around variable declarations or out of compound /* since one can jump around variable declarations or out of compound
* blocks, the stack must be manually adjusted * blocks, the stack must be manually adjusted
*/ */
//:TODO: This is actually generated, egads!
//We have to support this and LCTRL/SCTRL
setstk(-declared*sizeof(cell)); setstk(-declared*sizeof(cell));
sym->usage|=uDEFINE; /* label is now defined */ sym->usage|=uDEFINE; /* label is now defined */
} }
@ -5496,8 +5506,7 @@ static void doreturn(void)
rettype|=uRETNONE; /* function does not return anything */ rettype|=uRETNONE; /* function does not return anything */
} /* if */ } /* if */
destructsymbols(&loctab,0); /* call destructor for *all* locals */ destructsymbols(&loctab,0); /* call destructor for *all* locals */
modstk((int)declared*sizeof(cell)); /* end of function, remove *all* genstackfree(-1); /* free everything on the stack */
* local variables */
ffret(strcmp(curfunc->name,uENTRYFUNC)!=0); ffret(strcmp(curfunc->name,uENTRYFUNC)!=0);
} }
@ -5511,7 +5520,7 @@ static void dobreak(void)
if (ptr==NULL) if (ptr==NULL)
return; return;
destructsymbols(&loctab,nestlevel); destructsymbols(&loctab,nestlevel);
modstk(((int)declared-ptr[wqBRK])*sizeof(cell)); genstackfree(ptr[wqBRK]);
jumplabel(ptr[wqEXIT]); jumplabel(ptr[wqEXIT]);
} }
@ -5524,7 +5533,7 @@ static void docont(void)
if (ptr==NULL) if (ptr==NULL)
return; return;
destructsymbols(&loctab,nestlevel); destructsymbols(&loctab,nestlevel);
modstk(((int)declared-ptr[wqCONT])*sizeof(cell)); genstackfree(ptr[wqCONT]);
jumplabel(ptr[wqLOOP]); jumplabel(ptr[wqLOOP]);
} }

View File

@ -12,8 +12,14 @@ memuse_list_t *stackusage = NULL;
void _push_memlist(memuse_list_t **head) void _push_memlist(memuse_list_t **head)
{ {
memuse_list_t *newlist = (memuse_list_t *)malloc(sizeof(memuse_list_t)); memuse_list_t *newlist = (memuse_list_t *)malloc(sizeof(memuse_list_t));
(*head)->prev = *head; if (*head != NULL)
(*head)->head = NULL; {
newlist->list_id = (*head)->list_id + 1;
} else {
newlist->list_id = 0;
}
newlist->prev = *head;
newlist->head = NULL;
*head = newlist; *head = newlist;
} }
@ -52,6 +58,26 @@ int _mark_memlist(memuse_list_t *head, int type, int size)
return size; return size;
} }
void _reset_memlist(memuse_list_t **head)
{
memuse_list_t *curlist = *head;
memuse_list_t *tmplist;
while (curlist) {
memuse_t *curuse = curlist->head;
memuse_t *tmpuse;
while (curuse) {
tmpuse = curuse->prev;
free(curuse);
curuse = tmpuse;
}
tmplist = curlist->prev;
free(curlist);
curlist = tmplist;
}
*head = NULL;
}
/** /**
* Wrapper for pushing the heap list * Wrapper for pushing the heap list
*/ */
@ -99,8 +125,10 @@ void _heap_freeusage(memuse_list_t *heap)
{ {
memuse_t *cur=heap->head; memuse_t *cur=heap->head;
memuse_t *tmp; memuse_t *tmp;
while (cur) { while (cur)
if (cur->type == MEMUSE_STATIC) { {
if (cur->type == MEMUSE_STATIC)
{
modheap((-1)*cur->size*sizeof(cell)); modheap((-1)*cur->size*sizeof(cell));
} else { } else {
modheap_i(); modheap_i();
@ -112,6 +140,34 @@ void _heap_freeusage(memuse_list_t *heap)
heap->head=NULL; heap->head=NULL;
} }
void _stack_genusage(memuse_list_t *stack, int dofree)
{
memuse_t *cur = stack->head;
memuse_t *tmp;
while (cur)
{
if (cur->type == MEMUSE_DYNAMIC)
{
/* no idea yet */
assert(0);
} else {
modstk(cur->size * sizeof(cell));
}
if (dofree)
{
tmp = cur->prev;
free(cur);
cur = tmp;
} else {
cur = cur->prev;
}
}
if (dofree)
{
stack->head = NULL;
}
}
/** /**
* Pops a heap list and frees it. * Pops a heap list and frees it.
*/ */
@ -128,4 +184,30 @@ void popheaplist()
heapusage=oldlist; heapusage=oldlist;
} }
void genstackfree(int stop_id)
{
memuse_list_t *curlist = stackusage;
while (curlist && curlist->list_id > stop_id)
{
_stack_genusage(curlist, 0);
curlist = curlist->prev;
}
}
void popstacklist()
{
memuse_list_t *oldlist;
assert(stackusage != NULL);
_stack_genusage(stackusage, 1);
assert(stackusage->head==NULL);
oldlist = stackusage->prev;
free(stackusage);
stackusage = oldlist;
}
void resetstacklist()
{
_reset_memlist(&stackusage);
}

View File

@ -12,6 +12,7 @@ typedef struct memuse_s {
typedef struct memuse_list_s { typedef struct memuse_list_s {
struct memuse_list_s *prev; /* last used list */ struct memuse_list_s *prev; /* last used list */
int list_id;
memuse_t *head; /* head of the current list */ memuse_t *head; /* head of the current list */
} memuse_list_t; } memuse_list_t;
@ -29,6 +30,17 @@ int markheap(int type, int size);
void pushstacklist(); void pushstacklist();
void popstacklist(); void popstacklist();
int markstack(int type, int size); int markstack(int type, int size);
/**
* Generates code to free stack usage, but does not pop the list.
* This is used for code like dobreak()/docont()/doreturn().
* stop_id is the list at which to stop generating.
*/
void genstackfree(int stop_id);
/**
* Resets the stack list by freeing everything
*/
void resetstacklist();
extern memuse_list_t *heapusage; extern memuse_list_t *heapusage;
extern memuse_list_t *stackusage; extern memuse_list_t *stackusage;