reorganized the tracker to be a bit more modular

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40121
This commit is contained in:
David Anderson 2006-10-15 20:57:14 +00:00
parent 6f2ebd8da7
commit 2c65e42379
4 changed files with 152 additions and 96 deletions

View File

@ -66,6 +66,7 @@
#include "lstring.h" #include "lstring.h"
#include "sc.h" #include "sc.h"
#include "svnrev.h" #include "svnrev.h"
#include "sctracker.h"
#define VERSION_STR "3.2." SVN_REVSTR #define VERSION_STR "3.2." SVN_REVSTR
#define VERSION_INT 0x0302 #define VERSION_INT 0x0302

View File

@ -1056,13 +1056,13 @@ static int hier14(value *lval1)
* (a() ? return_array() : return_array()) ? return_array() : return_array() * (a() ? return_array() : return_array()) ? return_array() : return_array()
*/ */
void dynarray_from_heaplist(heapuse_list_t *heap) void dynarray_from_heaplist(memuse_list_t *heap)
{ {
heapuse_t *use=heap->head; memuse_t *use=heap->head;
heapuse_t *tmp; memuse_t *tmp;
long total=0; long total=0;
while (use) { while (use) {
assert(use->type==HEAPUSE_STATIC); assert(use->type==MEMUSE_STATIC);
total+=use->size; total+=use->size;
tmp=use->prev; tmp=use->prev;
free(use); free(use);
@ -1081,7 +1081,7 @@ static int hier13(value *lval)
int flab2=getlabel(); int flab2=getlabel();
value lval2={0}; value lval2={0};
int array1,array2; int array1,array2;
heapuse_list_t *heap; memuse_list_t *heap;
pushheaplist(); pushheaplist();
if (lvalue) { if (lvalue) {
@ -1124,7 +1124,7 @@ static int hier13(value *lval)
dynarray_from_heaplist(heap); dynarray_from_heaplist(heap);
setlabel(flab2); setlabel(flab2);
if (array1 && array2) { if (array1 && array2) {
markheap(HEAPUSE_DYNAMIC, 0); markheap(MEMUSE_DYNAMIC, 0);
} }
if (lval->ident==iARRAY) if (lval->ident==iARRAY)
lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */ lval->ident=iREFARRAY; /* iARRAY becomes iREFARRAY */
@ -1907,7 +1907,7 @@ static void setdefarray(cell *string,cell size,cell array_sz,cell *dataaddr,int
*/ */
assert(array_sz>=size); assert(array_sz>=size);
modheap((int)array_sz*sizeof(cell)); modheap((int)array_sz*sizeof(cell));
markheap(HEAPUSE_STATIC, array_sz); markheap(MEMUSE_STATIC, array_sz);
/* ??? should perhaps fill with zeros first */ /* ??? should perhaps fill with zeros first */
memcopy(size*sizeof(cell)); memcopy(size*sizeof(cell));
moveto1(); moveto1();
@ -1982,7 +1982,7 @@ static int nesting=0;
assert(retsize>0); assert(retsize>0);
modheap(retsize*sizeof(cell));/* address is in ALT */ modheap(retsize*sizeof(cell));/* address is in ALT */
pushreg(sALT); /* pass ALT as the last (hidden) parameter */ pushreg(sALT); /* pass ALT as the last (hidden) parameter */
markheap(HEAPUSE_STATIC, retsize); markheap(MEMUSE_STATIC, retsize);
/* also mark the ident of the result as "array" */ /* also mark the ident of the result as "array" */
lval_result->ident=iREFARRAY; lval_result->ident=iREFARRAY;
lval_result->sym=symret; lval_result->sym=symret;
@ -2090,14 +2090,14 @@ static int nesting=0;
} else { } else {
rvalue(&lval); /* get value in PRI */ rvalue(&lval); /* get value in PRI */
setheap_pri(); /* address of the value on the heap in PRI */ setheap_pri(); /* address of the value on the heap in PRI */
heapalloc+=markheap(HEAPUSE_STATIC, 1); heapalloc+=markheap(MEMUSE_STATIC, 1);
nest_stkusage++; nest_stkusage++;
} /* if */ } /* if */
} else if (lvalue) { } else if (lvalue) {
address(lval.sym,sPRI); address(lval.sym,sPRI);
} else { } else {
setheap_pri(); /* address of the value on the heap in PRI */ setheap_pri(); /* address of the value on the heap in PRI */
heapalloc+=markheap(HEAPUSE_STATIC, 1); heapalloc+=markheap(MEMUSE_STATIC, 1);
nest_stkusage++; nest_stkusage++;
} /* if */ } /* if */
} else if (lval.ident==iCONSTEXPR || lval.ident==iEXPRESSION } else if (lval.ident==iCONSTEXPR || lval.ident==iEXPRESSION
@ -2109,7 +2109,7 @@ static int nesting=0;
/* allocate a cell on the heap and store the /* allocate a cell on the heap and store the
* value (already in PRI) there */ * value (already in PRI) there */
setheap_pri(); /* address of the value on the heap in PRI */ setheap_pri(); /* address of the value on the heap in PRI */
heapalloc+=markheap(HEAPUSE_STATIC, 1); heapalloc+=markheap(MEMUSE_STATIC, 1);
nest_stkusage++; nest_stkusage++;
} /* if */ } /* if */
/* ??? handle const array passed by reference */ /* ??? handle const array passed by reference */
@ -2147,7 +2147,7 @@ static int nesting=0;
address(lval.sym,sPRI); address(lval.sym,sPRI);
} else { } else {
setheap_pri(); /* address of the value on the heap in PRI */ setheap_pri(); /* address of the value on the heap in PRI */
heapalloc+=markheap(HEAPUSE_STATIC, 1); heapalloc+=markheap(MEMUSE_STATIC, 1);
nest_stkusage++; nest_stkusage++;
} /* if */ } /* if */
} /* if */ } /* if */
@ -2294,7 +2294,7 @@ static int nesting=0;
} else if (arg[argidx].ident==iREFERENCE) { } else if (arg[argidx].ident==iREFERENCE) {
setheap(arg[argidx].defvalue.val); setheap(arg[argidx].defvalue.val);
/* address of the value on the heap in PRI */ /* address of the value on the heap in PRI */
heapalloc+=markheap(HEAPUSE_STATIC, 1); heapalloc+=markheap(MEMUSE_STATIC, 1);
nest_stkusage++; nest_stkusage++;
} else { } else {
int dummytag=arg[argidx].tags[0]; int dummytag=arg[argidx].tags[0];

View File

@ -3,28 +3,104 @@
#include "sc.h" #include "sc.h"
#include "sctracker.h" #include "sctracker.h"
heapuse_list_t *heapusage = NULL; memuse_list_t *heapusage = NULL;
memuse_list_t *stackusage = NULL;
/** /**
* Creates a new heap allocation tracker entry * Creates a new mem usage tracker entry
*/
void _push_memlist(memuse_list_t **head)
{
memuse_list_t *newlist = (memuse_list_t *)malloc(sizeof(memuse_list_t));
(*head)->prev = *head;
(*head)->head = NULL;
*head = newlist;
}
/**
* Pops a heap list but does not free it.
*/
memuse_list_t *_pop_save_memlist(memuse_list_t **head)
{
memuse_list_t *oldlist = *head;
*head = (*head)->prev;
return oldlist;
}
/**
* Marks a memory usage on a memory list
*/
int _mark_memlist(memuse_list_t *head, int type, int size)
{
memuse_t *use;
if (type==MEMUSE_STATIC && size==0)
{
return 0;
}
use=head->head;
if (use && (type==MEMUSE_STATIC)
&& (use->type == type))
{
use->size += size;
} else {
use=(memuse_t *)malloc(sizeof(memuse_t));
use->type=type;
use->size=size;
use->prev=head->head;
head->head=use;
}
return size;
}
/**
* Wrapper for pushing the heap list
*/ */
void pushheaplist() void pushheaplist()
{ {
heapuse_list_t *newlist=(heapuse_list_t *)malloc(sizeof(heapuse_list_t)); _push_memlist(&heapusage);
newlist->prev=heapusage; }
newlist->head=NULL;
heapusage=newlist; /**
* Wrapper for popping and saving the heap list
*/
memuse_list_t *popsaveheaplist()
{
return _pop_save_memlist(&heapusage);
}
/**
* Wrapper for marking the heap
*/
int markheap(int type, int size)
{
return _mark_memlist(heapusage, type, size);
}
/**
* Wrapper for pushing the stack list
*/
void pushstacklist()
{
_push_memlist(&stackusage);
}
/**
* Wrapper for marking the stack
*/
int markstack(int type, int size)
{
return _mark_memlist(stackusage, type, size);
} }
/** /**
* Generates code to free all heap allocations on a tracker * Generates code to free all heap allocations on a tracker
*/ */
void freeheapusage(heapuse_list_t *heap) void _heap_freeusage(memuse_list_t *heap)
{ {
heapuse_t *cur=heap->head; memuse_t *cur=heap->head;
heapuse_t *tmp; memuse_t *tmp;
while (cur) { while (cur) {
if (cur->type == HEAPUSE_STATIC) { if (cur->type == MEMUSE_STATIC) {
modheap((-1)*cur->size*sizeof(cell)); modheap((-1)*cur->size*sizeof(cell));
} else { } else {
modheap_i(); modheap_i();
@ -36,25 +112,15 @@ void freeheapusage(heapuse_list_t *heap)
heap->head=NULL; heap->head=NULL;
} }
/**
* Pops a heap list but does not free it.
*/
heapuse_list_t *popsaveheaplist()
{
heapuse_list_t *oldlist=heapusage;
heapusage=heapusage->prev;
return oldlist;
}
/** /**
* Pops a heap list and frees it. * Pops a heap list and frees it.
*/ */
void popheaplist() void popheaplist()
{ {
heapuse_list_t *oldlist; memuse_list_t *oldlist;
assert(heapusage!=NULL); assert(heapusage!=NULL);
freeheapusage(heapusage); _heap_freeusage(heapusage);
assert(heapusage->head==NULL); assert(heapusage->head==NULL);
oldlist=heapusage->prev; oldlist=heapusage->prev;
@ -62,25 +128,4 @@ void popheaplist()
heapusage=oldlist; heapusage=oldlist;
} }
/*
* Returns the size passed in
*/
int markheap(int type, int size)
{
heapuse_t *use;
if (type==HEAPUSE_STATIC && size==0)
return 0;
use=heapusage->head;
if (use && (type==HEAPUSE_STATIC)
&& (use->type == type))
{
use->size += size;
} else {
use=(heapuse_t *)malloc(sizeof(heapuse_t));
use->type=type;
use->size=size;
use->prev=heapusage->head;
heapusage->head=use;
}
return size;
}

View File

@ -1,26 +1,36 @@
#ifndef _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_ #ifndef _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_
#define _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_ #define _INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_
#define HEAPUSE_STATIC 0 #define MEMUSE_STATIC 0
#define HEAPUSE_DYNAMIC 1 #define MEMUSE_DYNAMIC 1
typedef struct heapuse_s { typedef struct memuse_s {
int type; /* HEAPUSE_STATIC or HEAPUSE_DYNAMIC */ int type; /* MEMUSE_STATIC or MEMUSE_DYNAMIC */
int size; /* size of array for static (0 for dynamic) */ int size; /* size of array for static (0 for dynamic) */
struct heapuse_s *prev; /* previous array on the list */ struct memuse_s *prev; /* previous block on the list */
} heapuse_t; } memuse_t;
typedef struct heapuse_list_s { typedef struct memuse_list_s {
struct heapuse_list_s *prev; /* last used list */ struct memuse_list_s *prev; /* last used list */
heapuse_t *head; /* head of the current list */ memuse_t *head; /* head of the current list */
} heapuse_list_t; } memuse_list_t;
extern heapuse_list_t *heapusage;
/**
* Heap functions
*/
void pushheaplist(); void pushheaplist();
void freeheapusage(heapuse_list_t *heap); memuse_list_t *popsaveheaplist();
heapuse_list_t *popsaveheaplist();
void popheaplist(); void popheaplist();
int markheap(int type, int size); int markheap(int type, int size);
/**
* Stack functions
*/
void pushstacklist();
void popstacklist();
int markstack(int type, int size);
extern memuse_list_t *heapusage;
extern memuse_list_t *stackusage;
#endif //_INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_ #endif //_INCLUDE_SOURCEPAWN_COMPILER_TRACKER_H_