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:
parent
6f2ebd8da7
commit
2c65e42379
@ -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
|
||||||
|
|
||||||
|
@ -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];
|
||||||
|
@ -3,84 +3,129 @@
|
|||||||
#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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates code to free all heap allocations on a tracker
|
* Wrapper for popping and saving the heap list
|
||||||
*/
|
*/
|
||||||
void freeheapusage(heapuse_list_t *heap)
|
memuse_list_t *popsaveheaplist()
|
||||||
{
|
{
|
||||||
heapuse_t *cur=heap->head;
|
return _pop_save_memlist(&heapusage);
|
||||||
heapuse_t *tmp;
|
|
||||||
while (cur) {
|
|
||||||
if (cur->type == HEAPUSE_STATIC) {
|
|
||||||
modheap((-1)*cur->size*sizeof(cell));
|
|
||||||
} else {
|
|
||||||
modheap_i();
|
|
||||||
}
|
|
||||||
tmp=cur->prev;
|
|
||||||
free(cur);
|
|
||||||
cur=tmp;
|
|
||||||
}
|
|
||||||
heap->head=NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pops a heap list but does not free it.
|
* Wrapper for marking the heap
|
||||||
*/
|
*/
|
||||||
heapuse_list_t *popsaveheaplist()
|
|
||||||
{
|
|
||||||
heapuse_list_t *oldlist=heapusage;
|
|
||||||
heapusage=heapusage->prev;
|
|
||||||
return oldlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pops a heap list and frees it.
|
|
||||||
*/
|
|
||||||
void popheaplist()
|
|
||||||
{
|
|
||||||
heapuse_list_t *oldlist;
|
|
||||||
assert(heapusage!=NULL);
|
|
||||||
|
|
||||||
freeheapusage(heapusage);
|
|
||||||
assert(heapusage->head==NULL);
|
|
||||||
|
|
||||||
oldlist=heapusage->prev;
|
|
||||||
free(heapusage);
|
|
||||||
heapusage=oldlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Returns the size passed in
|
|
||||||
*/
|
|
||||||
int markheap(int type, int size)
|
int markheap(int type, int size)
|
||||||
{
|
{
|
||||||
heapuse_t *use;
|
return _mark_memlist(heapusage, type, size);
|
||||||
if (type==HEAPUSE_STATIC && size==0)
|
}
|
||||||
return 0;
|
|
||||||
use=heapusage->head;
|
/**
|
||||||
if (use && (type==HEAPUSE_STATIC)
|
* Wrapper for pushing the stack list
|
||||||
&& (use->type == type))
|
*/
|
||||||
{
|
void pushstacklist()
|
||||||
use->size += size;
|
{
|
||||||
} else {
|
_push_memlist(&stackusage);
|
||||||
use=(heapuse_t *)malloc(sizeof(heapuse_t));
|
}
|
||||||
use->type=type;
|
|
||||||
use->size=size;
|
/**
|
||||||
use->prev=heapusage->head;
|
* Wrapper for marking the stack
|
||||||
heapusage->head=use;
|
*/
|
||||||
}
|
int markstack(int type, int size)
|
||||||
return size;
|
{
|
||||||
}
|
return _mark_memlist(stackusage, type, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates code to free all heap allocations on a tracker
|
||||||
|
*/
|
||||||
|
void _heap_freeusage(memuse_list_t *heap)
|
||||||
|
{
|
||||||
|
memuse_t *cur=heap->head;
|
||||||
|
memuse_t *tmp;
|
||||||
|
while (cur) {
|
||||||
|
if (cur->type == MEMUSE_STATIC) {
|
||||||
|
modheap((-1)*cur->size*sizeof(cell));
|
||||||
|
} else {
|
||||||
|
modheap_i();
|
||||||
|
}
|
||||||
|
tmp=cur->prev;
|
||||||
|
free(cur);
|
||||||
|
cur=tmp;
|
||||||
|
}
|
||||||
|
heap->head=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pops a heap list and frees it.
|
||||||
|
*/
|
||||||
|
void popheaplist()
|
||||||
|
{
|
||||||
|
memuse_list_t *oldlist;
|
||||||
|
assert(heapusage!=NULL);
|
||||||
|
|
||||||
|
_heap_freeusage(heapusage);
|
||||||
|
assert(heapusage->head==NULL);
|
||||||
|
|
||||||
|
oldlist=heapusage->prev;
|
||||||
|
free(heapusage);
|
||||||
|
heapusage=oldlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -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_
|
||||||
|
Loading…
Reference in New Issue
Block a user