spacetrace updates (not part of build)
- use arenas for hashtable allocation - reduces spacetrace's mem usage tremendously for large files - code cleanup & wrapping - UI cleanup - headers & such - fix nsTraceMalloc to at least support long stacks, so that we don't barf if we have trouble reading the stacks git-svn-id: svn://10.0.0.236/trunk@143293 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
02c0ec9772
commit
8c9811e251
@ -708,7 +708,9 @@ static callsite *calltree(int skip)
|
||||
/*
|
||||
* Time to increase the number of stack frames?
|
||||
*/
|
||||
PR_ASSERT(framenum < MAX_STACKFRAMES);
|
||||
if (framenum >= MAX_STACKFRAMES)
|
||||
break;
|
||||
PR_ASSERT(framenum < MAX_STACKFRAMES);
|
||||
}
|
||||
|
||||
depth = framenum;
|
||||
|
||||
@ -380,9 +380,24 @@ gdImagePtr createGraph(int* aTransparencyColor)
|
||||
** This function mainly exists to simplify putitng all the pretty lace
|
||||
** around a home made graph.
|
||||
*/
|
||||
void drawGraph(gdImagePtr aImage, int aColor, const char* aGraphTitle, const char* aXAxisTitle, const char* aYAxisTitle, PRUint32 aXMarkCount, PRUint32* aXMarkPercents, const char** aXMarkTexts, PRUint32 aYMarkCount, PRUint32* aYMarkPercents, const char** aYMarkTexts, PRUint32 aLegendCount, int* aLegendColors, const char** aLegendTexts)
|
||||
void drawGraph(gdImagePtr aImage, int aColor,
|
||||
const char* aGraphTitle,
|
||||
const char* aXAxisTitle,
|
||||
const char* aYAxisTitle,
|
||||
PRUint32 aXMarkCount,
|
||||
PRUint32* aXMarkPercents,
|
||||
const char** aXMarkTexts,
|
||||
PRUint32 aYMarkCount,
|
||||
PRUint32* aYMarkPercents,
|
||||
const char** aYMarkTexts,
|
||||
PRUint32 aLegendCount,
|
||||
int* aLegendColors, const char** aLegendTexts)
|
||||
{
|
||||
if(NULL != aImage && NULL != aGraphTitle && NULL != aXAxisTitle && NULL != aYAxisTitle && (0 == aXMarkCount || (NULL != aXMarkPercents && NULL != aXMarkTexts)) && (0 == aYMarkCount || (NULL != aYMarkPercents && NULL != aYMarkTexts)) && (0 == aLegendCount || (NULL != aLegendColors && NULL != aLegendTexts)))
|
||||
if(NULL != aImage && NULL != aGraphTitle &&
|
||||
NULL != aXAxisTitle && NULL != aYAxisTitle &&
|
||||
(0 == aXMarkCount || (NULL != aXMarkPercents && NULL != aXMarkTexts)) &&
|
||||
(0 == aYMarkCount || (NULL != aYMarkPercents && NULL != aYMarkTexts)) &&
|
||||
(0 == aLegendCount || (NULL != aLegendColors && NULL != aLegendTexts)))
|
||||
{
|
||||
int margin = 1;
|
||||
PRUint32 traverse = 0;
|
||||
@ -682,8 +697,10 @@ int recalculateAllocationCost(STOptions* inOptions, STContext* inContext, STRun*
|
||||
aRun->mStats[inContext->mIndex].mCompositeCount++;
|
||||
aRun->mStats[inContext->mIndex].mHeapRuntimeCost += heapCost;
|
||||
aRun->mStats[inContext->mIndex].mSize += size;
|
||||
LL_ADD(aRun->mStats[inContext->mIndex].mTimeval64, aRun->mStats[inContext->mIndex].mTimeval64, timeval64);
|
||||
LL_ADD(aRun->mStats[inContext->mIndex].mWeight64, aRun->mStats[inContext->mIndex].mWeight64, weight64);
|
||||
LL_ADD(aRun->mStats[inContext->mIndex].mTimeval64,
|
||||
aRun->mStats[inContext->mIndex].mTimeval64, timeval64);
|
||||
LL_ADD(aRun->mStats[inContext->mIndex].mWeight64,
|
||||
aRun->mStats[inContext->mIndex].mWeight64, weight64);
|
||||
|
||||
/*
|
||||
** Use the first event of the allocation to update the parent
|
||||
@ -707,10 +724,13 @@ int recalculateAllocationCost(STOptions* inOptions, STContext* inContext, STRun*
|
||||
/*
|
||||
** Do we init it?
|
||||
*/
|
||||
if(callsiteRun->mStats[inContext->mIndex].mStamp != aRun->mStats[inContext->mIndex].mStamp)
|
||||
if(callsiteRun->mStats[inContext->mIndex].mStamp !=
|
||||
aRun->mStats[inContext->mIndex].mStamp)
|
||||
{
|
||||
memset(&callsiteRun->mStats[inContext->mIndex], 0, sizeof(STCallsiteStats));
|
||||
callsiteRun->mStats[inContext->mIndex].mStamp = aRun->mStats[inContext->mIndex].mStamp;
|
||||
memset(&callsiteRun->mStats[inContext->mIndex], 0,
|
||||
sizeof(STCallsiteStats));
|
||||
callsiteRun->mStats[inContext->mIndex].mStamp =
|
||||
aRun->mStats[inContext->mIndex].mStamp;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -730,10 +750,15 @@ int recalculateAllocationCost(STOptions* inOptions, STContext* inContext, STRun*
|
||||
** is perhaps good enough for now.
|
||||
*/
|
||||
callsiteRun->mStats[inContext->mIndex].mCompositeCount++;
|
||||
callsiteRun->mStats[inContext->mIndex].mHeapRuntimeCost += heapCost;
|
||||
callsiteRun->mStats[inContext->mIndex].mHeapRuntimeCost +=
|
||||
heapCost;
|
||||
callsiteRun->mStats[inContext->mIndex].mSize += size;
|
||||
LL_ADD(callsiteRun->mStats[inContext->mIndex].mTimeval64, callsiteRun->mStats[inContext->mIndex].mTimeval64, timeval64);
|
||||
LL_ADD(callsiteRun->mStats[inContext->mIndex].mWeight64, callsiteRun->mStats[inContext->mIndex].mWeight64, weight64);
|
||||
LL_ADD(callsiteRun->mStats[inContext->mIndex].mTimeval64,
|
||||
callsiteRun->mStats[inContext->mIndex].mTimeval64,
|
||||
timeval64);
|
||||
LL_ADD(callsiteRun->mStats[inContext->mIndex].mWeight64,
|
||||
callsiteRun->mStats[inContext->mIndex].mWeight64,
|
||||
weight64);
|
||||
}
|
||||
|
||||
callsite = callsite->parent;
|
||||
@ -756,7 +781,9 @@ int recalculateAllocationCost(STOptions* inOptions, STContext* inContext, STRun*
|
||||
** such information when it was created.
|
||||
** Returns !0 on success.
|
||||
*/
|
||||
int appendAllocation(STOptions* inOptions, STContext* inContext, STRun* aRun, STAllocation* aAllocation)
|
||||
int
|
||||
appendAllocation(STOptions* inOptions, STContext* inContext,
|
||||
STRun* aRun, STAllocation* aAllocation)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
@ -767,7 +794,8 @@ int appendAllocation(STOptions* inOptions, STContext* inContext, STRun* aRun, ST
|
||||
/*
|
||||
** Expand the size of the array if needed.
|
||||
*/
|
||||
expand = (STAllocation**)realloc(aRun->mAllocations, sizeof(STAllocation*) * (aRun->mAllocationCount + 1));
|
||||
expand = (STAllocation**)realloc(aRun->mAllocations,
|
||||
sizeof(STAllocation*) * (aRun->mAllocationCount + 1));
|
||||
if(NULL != expand)
|
||||
{
|
||||
/*
|
||||
@ -828,7 +856,8 @@ int hasCallsiteMatch(tmcallsite* aCallsite, const char* aMatch, int aDirection)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
if(NULL != aCallsite && NULL != aCallsite->method && NULL != aMatch && '\0' != *aMatch)
|
||||
if(NULL != aCallsite && NULL != aCallsite->method &&
|
||||
NULL != aMatch && '\0' != *aMatch)
|
||||
{
|
||||
const char* methodName = NULL;
|
||||
|
||||
@ -884,7 +913,9 @@ int hasCallsiteMatch(tmcallsite* aCallsite, const char* aMatch, int aDirection)
|
||||
**
|
||||
** Returns !0 on error, though aOutRun may contain a partial data set.
|
||||
*/
|
||||
int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STContext* inContext)
|
||||
int
|
||||
harvestRun(const STRun* aInRun, STRun* aOutRun,
|
||||
STOptions* aOptions, STContext* inContext)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
@ -898,7 +929,8 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
PRUint32 traverse = 0;
|
||||
STAllocation* current = NULL;
|
||||
|
||||
for(traverse = 0; 0 == retval && traverse < aInRun->mAllocationCount; traverse++)
|
||||
for(traverse = 0;
|
||||
0 == retval && traverse < aInRun->mAllocationCount; traverse++)
|
||||
{
|
||||
current = aInRun->mAllocations[traverse];
|
||||
if(NULL != current)
|
||||
@ -927,11 +959,10 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
** We have to slide the recorded timevals to be zero
|
||||
** based, so that the comparisons make sense.
|
||||
*/
|
||||
if(aOptions->mAllocationTimevalMin > (current->mMinTimeval - globals.mMinTimeval))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(aOptions->mAllocationTimevalMax < (current->mMinTimeval - globals.mMinTimeval))
|
||||
if ((aOptions->mAllocationTimevalMin >
|
||||
(current->mMinTimeval - globals.mMinTimeval)) ||
|
||||
(aOptions->mAllocationTimevalMax <
|
||||
(current->mMinTimeval - globals.mMinTimeval)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -941,11 +972,10 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
** We have to slide the recorded timevals to be zero
|
||||
** based, so that the comparisons make sense.
|
||||
*/
|
||||
if(aOptions->mTimevalMin > (current->mMaxTimeval - globals.mMinTimeval))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(aOptions->mTimevalMax < (current->mMinTimeval - globals.mMinTimeval))
|
||||
if ((aOptions->mTimevalMin >
|
||||
(current->mMinTimeval - globals.mMinTimeval)) ||
|
||||
(aOptions->mTimevalMax <
|
||||
(current->mMinTimeval - globals.mMinTimeval)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -954,11 +984,8 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
** Check lifetime restrictions.
|
||||
*/
|
||||
lifetime = current->mMaxTimeval - current->mMinTimeval;
|
||||
if(lifetime < aOptions->mLifetimeMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(lifetime > aOptions->mLifetimeMax)
|
||||
if ((lifetime < aOptions->mLifetimeMin) ||
|
||||
(lifetime > aOptions->mLifetimeMax))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -967,11 +994,8 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
** Check byte size restrictions.
|
||||
*/
|
||||
bytesize = byteSize(aOptions, current);
|
||||
if(bytesize < aOptions->mSizeMin)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(bytesize > aOptions->mSizeMax)
|
||||
if ((bytesize < aOptions->mSizeMin) ||
|
||||
(bytesize > aOptions->mSizeMax))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -982,11 +1006,8 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
LL_UI2L(bytesize64, bytesize);
|
||||
LL_UI2L(lifetime64, lifetime);
|
||||
LL_MUL(weight64, bytesize64, lifetime64);
|
||||
if(LL_UCMP(weight64, <, aOptions->mWeightMin64))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if(LL_UCMP(weight64, >, aOptions->mWeightMax64))
|
||||
if(LL_UCMP(weight64, <, aOptions->mWeightMin64) ||
|
||||
LL_UCMP(weight64, >, aOptions->mWeightMax64))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -1002,7 +1023,9 @@ int harvestRun(const STRun* aInRun, STRun* aOutRun, STOptions* aOptions, STConte
|
||||
{
|
||||
if('\0' != aOptions->mRestrictText[looper][0])
|
||||
{
|
||||
if(0 == hasCallsiteMatch(current->mEvents[0].mCallsite, aOptions->mRestrictText[looper], ST_FOLLOW_PARENTS))
|
||||
if(0 == hasCallsiteMatch(current->mEvents[0].mCallsite,
|
||||
aOptions->mRestrictText[looper],
|
||||
ST_FOLLOW_PARENTS))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@ -2312,16 +2335,16 @@ void htmlCallsiteAnchor(STRequest* inRequest, tmcallsite* aCallsite, const char*
|
||||
{
|
||||
char lxrHREFBuf[512];
|
||||
|
||||
PR_snprintf(lxrHREFBuf, sizeof(lxrHREFBuf), "<a href=\"http://lxr.mozilla.org/mozilla/source/%s#%u\" class=\"lxr\" target=\"_st_lxr\">(%s:%u)</a>", namesite->method->sourcefile + 8, namesite->method->linenumber, sourceFile, namesite->method->linenumber);
|
||||
PR_snprintf(lxrHREFBuf, sizeof(lxrHREFBuf), " [<a href=\"http://lxr.mozilla.org/mozilla/source/%s#%u\" class=\"lxr\" target=\"_st_lxr\">%s:%u</a>]", namesite->method->sourcefile + 8, namesite->method->linenumber, sourceFile, namesite->method->linenumber);
|
||||
PR_snprintf(textBuf, sizeof(textBuf), "<span class=\"source mozilla-source\">%s</span>%s", methodName, lxrHREFBuf);
|
||||
}
|
||||
else if(NULL != sourceFile)
|
||||
{
|
||||
PR_snprintf(textBuf, sizeof(textBuf), "<span class=\"source external-source\">%s<span class=\"source-extra\">(%s:%u)</span></span>", methodName, sourceFile, namesite->method->linenumber);
|
||||
PR_snprintf(textBuf, sizeof(textBuf), "<span class=\"source external-source\">%s [<span class=\"source-extra\">%s:%u</span>]</span>", methodName, sourceFile, namesite->method->linenumber);
|
||||
}
|
||||
else
|
||||
{
|
||||
PR_snprintf(textBuf, sizeof(textBuf), "<span class=\"source binary-source\">%s<span class=\"source-extra\">+%u(%u)</span></span>", methodName, namesite->offset, (PRUint32)namesite->entry.key);
|
||||
PR_snprintf(textBuf, sizeof(textBuf), "<span class=\"source binary-source\">%s [<span class=\"source-extra\">+%u(%u)</span>]</span>", methodName, namesite->offset, (PRUint32)namesite->entry.key);
|
||||
}
|
||||
|
||||
aText = textBuf;
|
||||
@ -2352,7 +2375,8 @@ void htmlHeader(STRequest* inRequest, const char* aTitle)
|
||||
"</head>\n"
|
||||
"<body>\n"
|
||||
"<div class=spacetrace-header>\n"
|
||||
"<div class=navigate>\n"
|
||||
"<span class=spacetrace-title>Spacetrace</span>"
|
||||
"<span class=navigate>\n"
|
||||
"<span class=\"category-title header-text\">Category:</span>\n"
|
||||
"<span class=\"current-category\">%s</span>\n",
|
||||
aTitle,
|
||||
@ -2364,9 +2388,9 @@ void htmlHeader(STRequest* inRequest, const char* aTitle)
|
||||
|
||||
PR_fprintf(inRequest->mFD,"<span class=\"header-item\">");
|
||||
htmlAnchor(inRequest, "options.html", "Options", NULL, "header-menuitem", &inRequest->mOptions);
|
||||
PR_fprintf(inRequest->mFD,"</span>\n");
|
||||
PR_fprintf(inRequest->mFD,"</span>\n");
|
||||
|
||||
PR_fprintf(inRequest->mFD,"</div>\n");
|
||||
PR_fprintf(inRequest->mFD,"</span>\n"); /* class=navigate */
|
||||
|
||||
PR_fprintf(inRequest->mFD, "</div>\n<div class=\"header-separator\"></div>\n");
|
||||
}
|
||||
@ -5660,7 +5684,7 @@ void handleClient(void* inArg)
|
||||
** mime type, otherwise, say it is text/html.
|
||||
*/
|
||||
PR_fprintf(aFD, "HTTP/1.1 200 OK%s", crlf);
|
||||
PR_fprintf(aFD, "Server: %s%s", "$Id: spacetrace.c,v 1.42 2003-05-22 20:59:55 alecf%flett.org Exp $", crlf);
|
||||
PR_fprintf(aFD, "Server: %s%s", "$Id: spacetrace.c,v 1.43 2003-06-04 20:15:07 alecf%flett.org Exp $", crlf);
|
||||
PR_fprintf(aFD, "Content-type: ");
|
||||
if(NULL != strstr(start, ".png"))
|
||||
{
|
||||
|
||||
@ -1,16 +1,25 @@
|
||||
body {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
font: Arial, sans-serif;
|
||||
}
|
||||
|
||||
/* header stuff */
|
||||
.spacetrace-header {
|
||||
color: white;
|
||||
background: green;
|
||||
min-height: 2em;
|
||||
/* min-height: 2em; */
|
||||
}
|
||||
|
||||
.spacetrace-title {
|
||||
font-size: x-large;
|
||||
font-weight: bold;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
.navigate {
|
||||
background: lightgrey;
|
||||
/* background: lightgrey; */
|
||||
color: black;
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
margin: 0px;
|
||||
@ -18,8 +27,11 @@ body {
|
||||
}
|
||||
|
||||
.header-item {
|
||||
border: 2px outset;
|
||||
border: 1px outset;
|
||||
color: ButtonText;
|
||||
background: ButtonFace;
|
||||
margin: 0px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.header-item > a {
|
||||
|
||||
@ -43,6 +43,10 @@
|
||||
#endif
|
||||
#include "prlog.h"
|
||||
#include "plhash.h"
|
||||
/* make sure this happens before tmreader.h */
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 2
|
||||
#include "plarena.h"
|
||||
|
||||
#include "prnetdb.h"
|
||||
#include "nsTraceMalloc.h"
|
||||
#include "tmreader.h"
|
||||
@ -274,31 +278,37 @@ static int get_tmevent(FILE *fp, tmevent *event)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void *arena_alloc(void* pool, PRSize size)
|
||||
{
|
||||
PLArenaPool* arena = (PLArenaPool*)pool;
|
||||
void* result;
|
||||
PL_ARENA_ALLOCATE(result, arena, size);
|
||||
memset(result, 0, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void *generic_alloctable(void *pool, PRSize size)
|
||||
{
|
||||
return malloc(size);
|
||||
return arena_alloc(pool, size);
|
||||
}
|
||||
|
||||
static void generic_freetable(void *pool, void *item)
|
||||
{
|
||||
free(item);
|
||||
/* do nothing - arena-allocated */
|
||||
}
|
||||
|
||||
static PLHashEntry *filename_allocentry(void *pool, const void *key)
|
||||
{
|
||||
return calloc(1, sizeof(PLHashEntry));
|
||||
return (PLHashEntry*)arena_alloc(pool, sizeof(PLHashEntry));
|
||||
}
|
||||
|
||||
static PLHashEntry *callsite_allocentry(void *pool, const void *key)
|
||||
{
|
||||
return calloc(1, sizeof(tmcallsite));
|
||||
return (PLHashEntry*)arena_alloc(pool, sizeof(tmcallsite));
|
||||
}
|
||||
|
||||
static PLHashEntry *graphnode_allocentry(void *pool, const void *key)
|
||||
static init_graphnode(tmgraphnode* node)
|
||||
{
|
||||
tmgraphnode *node = (tmgraphnode*) malloc(sizeof(tmgraphnode));
|
||||
if (!node)
|
||||
return NULL;
|
||||
node->in = node->out = NULL;
|
||||
node->up = node->down = node->next = NULL;
|
||||
node->low = 0;
|
||||
@ -308,14 +318,19 @@ static PLHashEntry *graphnode_allocentry(void *pool, const void *key)
|
||||
node->frees.calls.direct = node->frees.calls.total = 0;
|
||||
node->sqsum = 0;
|
||||
node->sort = -1;
|
||||
}
|
||||
|
||||
static PLHashEntry *graphnode_allocentry(void *pool, const void *key)
|
||||
{
|
||||
tmgraphnode* node = (tmgraphnode*)arena_alloc(pool, sizeof(tmgraphnode));
|
||||
if (!node)
|
||||
return NULL;
|
||||
init_graphnode(node);
|
||||
return &node->entry;
|
||||
}
|
||||
|
||||
static PLHashEntry *method_allocentry(void *pool, const void *key)
|
||||
static void init_method(tmmethodnode *node)
|
||||
{
|
||||
tmmethodnode *node = (tmmethodnode*) malloc(sizeof(tmmethodnode));
|
||||
if (!node)
|
||||
return NULL;
|
||||
node->graphnode.in = node->graphnode.out = NULL;
|
||||
node->graphnode.up = node->graphnode.down = node->graphnode.next = NULL;
|
||||
node->graphnode.low = 0;
|
||||
@ -327,6 +342,15 @@ static PLHashEntry *method_allocentry(void *pool, const void *key)
|
||||
node->graphnode.sort = -1;
|
||||
node->sourcefile = NULL;
|
||||
node->linenumber = 0;
|
||||
}
|
||||
|
||||
static PLHashEntry *method_allocentry(void *pool, const void *key)
|
||||
{
|
||||
tmmethodnode *node =
|
||||
(tmmethodnode*) arena_alloc(pool, sizeof(tmmethodnode));
|
||||
if (!node)
|
||||
return NULL;
|
||||
init_method(node);
|
||||
return &node->graphnode.entry;
|
||||
}
|
||||
|
||||
@ -334,10 +358,11 @@ static void graphnode_freeentry(void *pool, PLHashEntry *he, PRUintn flag)
|
||||
{
|
||||
/* Always free the value, which points to a strdup'd string. */
|
||||
free(he->value);
|
||||
|
||||
#if 0 /* using arenas now, no freeing! */
|
||||
/* Free the whole thing if we're told to. */
|
||||
if (flag == HT_FREE_ENTRY)
|
||||
free((void*) he);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void component_freeentry(void *pool, PLHashEntry *he, PRUintn flag)
|
||||
@ -347,7 +372,9 @@ static void component_freeentry(void *pool, PLHashEntry *he, PRUintn flag)
|
||||
|
||||
/* Free the key, which was strdup'd (N.B. value also points to it). */
|
||||
free((void*) tmcomponent_name(comp));
|
||||
#if 0 /* using arenas now, no freeing! */
|
||||
free((void*) comp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -390,22 +417,23 @@ tmreader *tmreader_new(const char *program, void *data)
|
||||
return NULL;
|
||||
tmr->program = program;
|
||||
tmr->data = data;
|
||||
PL_INIT_ARENA_POOL(&tmr->arena, "TMReader", 256*1024);
|
||||
|
||||
tmr->libraries = PL_NewHashTable(100, hash_serial, PL_CompareValues,
|
||||
PL_CompareStrings, &graphnode_hashallocops,
|
||||
NULL);
|
||||
&tmr->arena);
|
||||
tmr->filenames = PL_NewHashTable(100, hash_serial, PL_CompareValues,
|
||||
PL_CompareStrings, &filename_hashallocops,
|
||||
NULL);
|
||||
&tmr->arena);
|
||||
tmr->components = PL_NewHashTable(10000, PL_HashString, PL_CompareStrings,
|
||||
PL_CompareValues, &component_hashallocops,
|
||||
NULL);
|
||||
&tmr->arena);
|
||||
tmr->methods = PL_NewHashTable(10000, hash_serial, PL_CompareValues,
|
||||
PL_CompareStrings, &method_hashallocops,
|
||||
NULL);
|
||||
&tmr->arena);
|
||||
tmr->callsites = PL_NewHashTable(200000, hash_serial, PL_CompareValues,
|
||||
PL_CompareValues, &callsite_hashallocops,
|
||||
NULL);
|
||||
&tmr->arena);
|
||||
tmr->calltree_root.entry.value = (void*) strdup("root");
|
||||
|
||||
if (!tmr->libraries || !tmr->components || !tmr->methods ||
|
||||
@ -429,6 +457,7 @@ void tmreader_destroy(tmreader *tmr)
|
||||
PL_HashTableDestroy(tmr->methods);
|
||||
if (tmr->callsites)
|
||||
PL_HashTableDestroy(tmr->callsites);
|
||||
PL_FinishArenaPool(&tmr->arena);
|
||||
free(tmr);
|
||||
}
|
||||
|
||||
@ -669,12 +698,12 @@ int tmreader_eventloop(tmreader *tmr, const char *filename,
|
||||
size = event.u.alloc.size;
|
||||
oldsize = event.u.alloc.oldsize;
|
||||
delta = (double)size - (double)oldsize;
|
||||
site->allocs.bytes.direct += delta;
|
||||
site->allocs.bytes.direct += (unsigned long)delta;
|
||||
if (event.type != TM_EVENT_REALLOC)
|
||||
site->allocs.calls.direct++;
|
||||
meth = site->method;
|
||||
if (meth) {
|
||||
meth->graphnode.allocs.bytes.direct += delta;
|
||||
meth->graphnode.allocs.bytes.direct += (unsigned long)delta;
|
||||
sqdelta = delta * delta;
|
||||
if (event.type == TM_EVENT_REALLOC) {
|
||||
sqszdelta = ((double)size * size)
|
||||
@ -686,7 +715,7 @@ int tmreader_eventloop(tmreader *tmr, const char *filename,
|
||||
}
|
||||
comp = meth->graphnode.up;
|
||||
if (comp) {
|
||||
comp->allocs.bytes.direct += delta;
|
||||
comp->allocs.bytes.direct += (unsigned long)delta;
|
||||
if (event.type == TM_EVENT_REALLOC) {
|
||||
comp->sqsum += sqszdelta;
|
||||
} else {
|
||||
@ -695,7 +724,7 @@ int tmreader_eventloop(tmreader *tmr, const char *filename,
|
||||
}
|
||||
lib = comp->up;
|
||||
if (lib) {
|
||||
lib->allocs.bytes.direct += delta;
|
||||
lib->allocs.bytes.direct += (unsigned long)delta;
|
||||
if (event.type == TM_EVENT_REALLOC) {
|
||||
lib->sqsum += sqszdelta;
|
||||
} else {
|
||||
|
||||
@ -38,6 +38,7 @@
|
||||
#include "prtypes.h"
|
||||
#include "plhash.h"
|
||||
#include "nsTraceMalloc.h"
|
||||
#include "plarena.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
@ -168,6 +169,7 @@ struct tmreader {
|
||||
PLHashTable *components;
|
||||
PLHashTable *methods;
|
||||
PLHashTable *callsites;
|
||||
PLArenaPool arena;
|
||||
tmcallsite calltree_root;
|
||||
uint32 ticksPerSec;
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user