зеркало из https://github.com/mozilla/gecko-dev.git
Fix bug 108103, new tool SpaceTrace
SR,RS=brendan, SR=waterson, R=dbaron
This commit is contained in:
Родитель
30eac5d8ce
Коммит
c096dbbd8b
|
@ -31,6 +31,7 @@ REQUIRES = string xpcom
|
|||
CSRCS += \
|
||||
bloatblame.c \
|
||||
leakstats.c \
|
||||
spacetrace.c \
|
||||
$(NULL)
|
||||
|
||||
SIMPLE_PROGRAMS = $(CSRCS:.c=$(BIN_SUFFIX))
|
||||
|
@ -42,6 +43,16 @@ LIBS += \
|
|||
tmreader.o \
|
||||
$(NULL)
|
||||
|
||||
ifdef HAVE_BOUTELL_GD
|
||||
LIBS += \
|
||||
-lgd \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += \
|
||||
-DHAVE_BOUTELL_GD \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
EXTRA_DEPS = tmreader.o
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -445,6 +445,29 @@ static void log_event4(logfile *fp, char event, uint32 serial, uint32 ui2,
|
|||
log_uint32(fp, ui4);
|
||||
}
|
||||
|
||||
static void log_event5(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5)
|
||||
{
|
||||
log_event4(fp, event, serial, ui2, ui3, ui4);
|
||||
log_uint32(fp, ui5);
|
||||
}
|
||||
|
||||
static void log_event6(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6)
|
||||
{
|
||||
log_event5(fp, event, serial, ui2, ui3, ui4, ui5);
|
||||
log_uint32(fp, ui6);
|
||||
}
|
||||
|
||||
static void log_event7(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6,
|
||||
uint32 ui7)
|
||||
{
|
||||
log_event6(fp, event, serial, ui2, ui3, ui4, ui5, ui6);
|
||||
log_uint32(fp, ui7);
|
||||
}
|
||||
|
||||
|
||||
typedef struct callsite callsite;
|
||||
|
||||
struct callsite {
|
||||
|
@ -1256,7 +1279,8 @@ __ptr_t malloc(size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_MALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_MALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1287,7 +1311,8 @@ __ptr_t calloc(size_t count, size_t size)
|
|||
site = backtrace(1);
|
||||
size *= count;
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_CALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_CALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1343,8 +1368,9 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site) {
|
||||
log_event4(logfp, TM_EVENT_REALLOC, site->serial, size,
|
||||
oldsite ? oldsite->serial : 0, oldsize);
|
||||
log_event7(logfp, TM_EVENT_REALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size,
|
||||
oldsite ? oldsite->serial : 0, (uint32)oldptr, oldsize);
|
||||
}
|
||||
if (ptr && allocations) {
|
||||
suppress_tracing++;
|
||||
|
@ -1396,8 +1422,8 @@ void free(__ptr_t ptr)
|
|||
site = (callsite*) he->value;
|
||||
if (site) {
|
||||
alloc = (allocation*) he;
|
||||
log_event2(logfp, TM_EVENT_FREE, site->serial,
|
||||
alloc->size);
|
||||
log_event4(logfp, TM_EVENT_FREE,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, alloc->size);
|
||||
}
|
||||
PL_HashTableRawRemove(allocations, hep, he);
|
||||
}
|
||||
|
@ -1809,7 +1835,7 @@ NS_TraceMallocFlushLogfiles()
|
|||
#ifdef XP_WIN32
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
MallocCallback(void *aPtr, size_t size)
|
||||
MallocCallback(void *ptr, size_t size)
|
||||
{
|
||||
callsite *site;
|
||||
PLHashEntry *he;
|
||||
|
@ -1817,15 +1843,16 @@ MallocCallback(void *aPtr, size_t size)
|
|||
|
||||
TM_ENTER_MONITOR();
|
||||
tmstats.malloc_calls++;
|
||||
if (!aPtr) {
|
||||
if (!ptr) {
|
||||
tmstats.malloc_failures++;
|
||||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(4);
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_MALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_MALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, aPtr, site);
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
suppress_tracing--;
|
||||
if (he) {
|
||||
alloc = (allocation*) he;
|
||||
|
@ -1851,7 +1878,8 @@ CallocCallback(void *ptr, size_t count, size_t size)
|
|||
site = backtrace(1);
|
||||
size *= count;
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_CALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_CALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1901,8 +1929,9 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site) {
|
||||
log_event4(logfp, TM_EVENT_REALLOC, site->serial, size,
|
||||
oldsite ? oldsite->serial : 0, oldsize);
|
||||
log_event7(logfp, TM_EVENT_REALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size,
|
||||
oldsite ? oldsite->serial : 0, (uint32)oldptr, oldsize);
|
||||
}
|
||||
if (ptr && allocations) {
|
||||
suppress_tracing++;
|
||||
|
@ -1953,7 +1982,8 @@ FreeCallback(void * ptr)
|
|||
site = (callsite*) he->value;
|
||||
if (site) {
|
||||
alloc = (allocation*) he;
|
||||
log_event2(logfp, TM_EVENT_FREE, site->serial, alloc->size);
|
||||
log_event4(logfp, TM_EVENT_FREE,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, alloc->size);
|
||||
}
|
||||
PL_HashTableRawRemove(allocations, hep, he);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ PR_BEGIN_EXTERN_C
|
|||
* NS_TraceMallocStartup comment (below) for magic number differences in log
|
||||
* file structure.
|
||||
*/
|
||||
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog04\r\n\032"
|
||||
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog06\r\n\032"
|
||||
#define NS_TRACE_MALLOC_MAGIC_SIZE 16
|
||||
|
||||
/**
|
||||
|
@ -108,7 +108,21 @@ typedef struct nsTMStats {
|
|||
* Event Operands (magic TMLog04)
|
||||
* 'R' site serial, realloc size, old site serial, realloc oldsize
|
||||
*
|
||||
* See xpcom/base/bloatblame.c for an example log-file reader.
|
||||
* Event Operands (magic TMLog05)
|
||||
* 'M' site serial, address, malloc size
|
||||
* 'C' site serial, address, calloc size
|
||||
* 'R' site serial, address, realloc size, old site serial,
|
||||
* old address, old size
|
||||
* 'F' site serial, address, free size
|
||||
*
|
||||
* Event Operands (magic TMLog06)
|
||||
* 'M' site serial, interval, address, malloc size
|
||||
* 'C' site serial, interval, address, calloc size
|
||||
* 'R' site serial, interval, address, realloc size, old site serial,
|
||||
* old address, old size
|
||||
* 'F' site serial, interval, address, free size
|
||||
*
|
||||
* See tools/trace-malloc/bloatblame.c for an example log-file reader.
|
||||
*/
|
||||
#define TM_EVENT_LIBRARY 'L'
|
||||
#define TM_EVENT_METHOD 'N'
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,452 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is spacetrace.h/spacetrace.c code, released
|
||||
* Nov 6, 2001.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Garrett Arch Blythe, 31-October-2001
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the MPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the MPL or the GPL.
|
||||
*/
|
||||
|
||||
#ifndef spacetrace_h__
|
||||
#define spacetrace_h__
|
||||
|
||||
/*
|
||||
** spacetrace.h
|
||||
**
|
||||
** SpaceTrace is meant to take the output of trace-malloc and present
|
||||
** a picture of allocations over the run of the application.
|
||||
*/
|
||||
|
||||
/*
|
||||
** Required includes.
|
||||
*/
|
||||
#include "nspr.h"
|
||||
#include "nsTraceMalloc.h"
|
||||
#include "tmreader.h"
|
||||
|
||||
/*
|
||||
** REPORT_ERROR
|
||||
** REPORT_INFO
|
||||
**
|
||||
** Just report errors and stuff in a consistent manner.
|
||||
*/
|
||||
#define REPORT_ERROR(code, function) \
|
||||
PR_fprintf(PR_STDERR, "error(%d):\t%s\n", code, #function)
|
||||
#define REPORT_INFO(msg) \
|
||||
PR_fprintf(PR_STDOUT, "%s: %s\n", globals.mOptions.mProgramName, (msg))
|
||||
|
||||
/*
|
||||
** CALLSITE_RUN
|
||||
**
|
||||
** How to get a callsite run.
|
||||
** Allows for further indirection if needed later.
|
||||
*/
|
||||
#define CALLSITE_RUN(callsite) \
|
||||
((STRun*)((callsite)->data))
|
||||
|
||||
/*
|
||||
** ST_PERMS
|
||||
** ST_FLAGS
|
||||
**
|
||||
** File permissions we desire.
|
||||
** 0644
|
||||
*/
|
||||
#define ST_PERMS (PR_IRUSR | PR_IWUSR | PR_IRGRP | PR_IROTH)
|
||||
#define ST_FLAGS (PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE)
|
||||
|
||||
/*
|
||||
** Sorting order
|
||||
*/
|
||||
#define ST_WEIGHT 0 /* size * interval */
|
||||
#define ST_SIZE 1
|
||||
#define ST_INTERVAL 2
|
||||
|
||||
/*
|
||||
** Callsite loop direction flags.
|
||||
*/
|
||||
#define ST_FOLLOW_SIBLINGS 0
|
||||
#define ST_FOLLOW_PARENTS 1
|
||||
|
||||
/*
|
||||
** Graph data.
|
||||
*/
|
||||
#define STGD_WIDTH 640
|
||||
#define STGD_HEIGHT 480
|
||||
#define STGD_MARGIN 75
|
||||
#define STGD_SPACE_X (STGD_WIDTH - (2 * STGD_MARGIN))
|
||||
#define STGD_SPACE_Y (STGD_HEIGHT - (2 * STGD_MARGIN))
|
||||
|
||||
/*
|
||||
** Minimum lifetime default, in seconds.
|
||||
*/
|
||||
#define ST_DEFAULT_LIFETIME_MIN 10
|
||||
|
||||
|
||||
/*
|
||||
** STAllocEvent
|
||||
**
|
||||
** An event that happens to an allocation (malloc, free, et. al.)
|
||||
*/
|
||||
typedef struct __struct_STAllocEvent
|
||||
{
|
||||
/*
|
||||
** Each event, foremost, has a chronologically increasing ID in
|
||||
** relation to other allocation events. This is a time stamp
|
||||
** of sorts.
|
||||
*/
|
||||
PRUint32 mInterval;
|
||||
|
||||
/*
|
||||
** The type of allocation event.
|
||||
** This maps directly to the trace malloc events (i.e. TM_EVENT_MALLOC)
|
||||
*/
|
||||
char mEventType;
|
||||
|
||||
/*
|
||||
** Every event has a heap ID (pointer).
|
||||
** In the event of a realloc, this is the new heap ID.
|
||||
** In the event of a free, this is the previous heap ID value.
|
||||
*/
|
||||
PRUint32 mHeapID;
|
||||
|
||||
/*
|
||||
** Every event, along with the heap ID, tells of the size.
|
||||
** In the event of a realloc, this is the new size.
|
||||
** In th event of a free, this is the previous size.
|
||||
*/
|
||||
PRUint32 mHeapSize;
|
||||
|
||||
/*
|
||||
** Every event has a callsite/stack backtrace.
|
||||
** In the event of a realloc, this is the new callsite.
|
||||
** In the event of a free, this is the previous call site.
|
||||
*/
|
||||
tmcallsite* mCallsite;
|
||||
} STAllocEvent;
|
||||
|
||||
/*
|
||||
** STAllocation
|
||||
**
|
||||
** An allocation is a temporal entity in the heap.
|
||||
** It possibly lives under different heap IDs (pointers) and different
|
||||
** sizes during its given time.
|
||||
** An allocation is defined by the events during its lifetime.
|
||||
** An allocation's lifetime is defined by the range of event IDs it holds.
|
||||
*/
|
||||
typedef struct __struct_STAllocation
|
||||
{
|
||||
/*
|
||||
** The array of events.
|
||||
*/
|
||||
PRUint32 mEventCount;
|
||||
STAllocEvent* mEvents;
|
||||
|
||||
/*
|
||||
** The lifetime/lifespan of the allocation.
|
||||
*/
|
||||
PRUint32 mMinInterval;
|
||||
PRUint32 mMaxInterval;
|
||||
|
||||
/*
|
||||
** Index of this allocation in the global run.
|
||||
*/
|
||||
PRUint32 mRunIndex;
|
||||
} STAllocation;
|
||||
|
||||
/*
|
||||
** STCallsiteStats
|
||||
**
|
||||
** Stats regarding a run, kept mainly for callsite runs.
|
||||
*/
|
||||
typedef struct __struct_STCallsiteStats
|
||||
{
|
||||
/*
|
||||
** Sum size of the allocations.
|
||||
** Callsite runs total all allocations below the callsite.
|
||||
*/
|
||||
PRUint32 mSize;
|
||||
|
||||
/*
|
||||
** Sum interval of the allocations.
|
||||
** Callsite runs total all allocations below the callsite.
|
||||
*/
|
||||
PRUint64 mInterval64;
|
||||
|
||||
/*
|
||||
** Sum weight of the allocations.
|
||||
** Callsite runs total all allocations below the callsite.
|
||||
*/
|
||||
PRUint64 mWeight64;
|
||||
|
||||
/*
|
||||
** A stamp, indicated the relevance of the run.
|
||||
** If the stamp does not match the origin value, the
|
||||
** data contained here-in is considered invalid.
|
||||
*/
|
||||
PRUint32 mStamp;
|
||||
} STCallsiteStats;
|
||||
|
||||
/*
|
||||
** STRun
|
||||
**
|
||||
** A run is a closed set of allocations.
|
||||
** Given a run, we can deduce information about the contained allocations.
|
||||
** We can also determine if an allocation lives beyond a run (leak).
|
||||
**
|
||||
** A run might be used to represent allocations for an entire application.
|
||||
** A run might also be used to represent allocations from a single callstack.
|
||||
*/
|
||||
typedef struct __struct_STRun
|
||||
{
|
||||
/*
|
||||
** The array of allocations.
|
||||
*/
|
||||
PRUint32 mAllocationCount;
|
||||
STAllocation** mAllocations;
|
||||
|
||||
/*
|
||||
** Callsites like to keep some information.
|
||||
*/
|
||||
STCallsiteStats mStats;
|
||||
} STRun;
|
||||
|
||||
/*
|
||||
** STOptions
|
||||
**
|
||||
** Structure containing the various options for this code.
|
||||
*/
|
||||
typedef struct __struct_STOptions
|
||||
{
|
||||
/*
|
||||
** The string which identifies this program.
|
||||
*/
|
||||
const char* mProgramName;
|
||||
|
||||
/*
|
||||
** File from which we retrieve the input.
|
||||
** The input should have been generated from a trace malloc run.
|
||||
*/
|
||||
const char* mFileName;
|
||||
|
||||
/*
|
||||
** Which directory we will take over and write our output.
|
||||
*/
|
||||
const char* mOutputDir;
|
||||
|
||||
/*
|
||||
** The various batch mode requests we've received.
|
||||
*/
|
||||
const char** mBatchRequests;
|
||||
PRUint32 mBatchRequestCount;
|
||||
|
||||
/*
|
||||
** Httpd port, where we accept queries.
|
||||
*/
|
||||
PRUint32 mHttpdPort;
|
||||
|
||||
/*
|
||||
** Wether or not we should show help.
|
||||
*/
|
||||
int mShowHelp;
|
||||
|
||||
/*
|
||||
** Maximum number of items to put in a list.
|
||||
*/
|
||||
PRUint32 mListItemMax;
|
||||
|
||||
/*
|
||||
** Sort order control.
|
||||
*/
|
||||
PRUint32 mOrderBy;
|
||||
|
||||
/*
|
||||
** Interval control.
|
||||
*/
|
||||
PRUint32 mIntervalMin;
|
||||
PRUint32 mIntervalMax;
|
||||
|
||||
/*
|
||||
** Allocation Interval control.
|
||||
*/
|
||||
PRUint32 mAllocationIntervalMin;
|
||||
PRUint32 mAllocationIntervalMax;
|
||||
|
||||
/*
|
||||
** Size control.
|
||||
*/
|
||||
PRUint32 mSizeMin;
|
||||
PRUint32 mSizeMax;
|
||||
|
||||
/*
|
||||
** Lifetime interval control.
|
||||
*/
|
||||
PRUint32 mLifetimeMin;
|
||||
PRUint32 mLifetimeMax;
|
||||
|
||||
/*
|
||||
** Weight control.
|
||||
*/
|
||||
PRUint64 mWeightMin64;
|
||||
PRUint64 mWeightMax64;
|
||||
|
||||
/*
|
||||
** Graph interval control.
|
||||
*/
|
||||
PRUint32 mGraphIntervalMin;
|
||||
PRUint32 mGraphIntervalMax;
|
||||
|
||||
/*
|
||||
** Restrict callsite backtraces to those containing text.
|
||||
*/
|
||||
char* mRestrictText;
|
||||
} STOptions;
|
||||
|
||||
/*
|
||||
** STRequest
|
||||
**
|
||||
** Things specific to a request.
|
||||
*/
|
||||
typedef struct __struct_STRequest
|
||||
{
|
||||
/*
|
||||
** Sink/where to output.
|
||||
*/
|
||||
PRFileDesc* mFD;
|
||||
|
||||
/*
|
||||
** The tmreader, should we need some data from it.
|
||||
*/
|
||||
tmreader* mTMR;
|
||||
|
||||
/*
|
||||
** The filename requested.
|
||||
*/
|
||||
const char* mFileName;
|
||||
|
||||
/*
|
||||
** The GET form data, if any.
|
||||
*/
|
||||
const char* mGetData;
|
||||
} STRequest;
|
||||
|
||||
/*
|
||||
** STCache
|
||||
**
|
||||
** Things we cache when the options get set.
|
||||
** We can avoid some heavy duty processing should the options remain
|
||||
** constant by caching them here.
|
||||
*/
|
||||
typedef struct __struct_STCache
|
||||
{
|
||||
/*
|
||||
** Pre sorted run.
|
||||
*/
|
||||
STRun* mSortedRun;
|
||||
|
||||
/*
|
||||
** Footprint graph cache.
|
||||
*/
|
||||
int mFootprintCached;
|
||||
PRUint32 mFootprintYData[STGD_SPACE_X];
|
||||
|
||||
/*
|
||||
** Interval graph cache.
|
||||
*/
|
||||
int mIntervalCached;
|
||||
PRUint32 mIntervalYData[STGD_SPACE_X];
|
||||
|
||||
/*
|
||||
** Lifespan graph cache.
|
||||
*/
|
||||
int mLifespanCached;
|
||||
PRUint32 mLifespanYData[STGD_SPACE_X];
|
||||
|
||||
/*
|
||||
** Weight graph cache.
|
||||
*/
|
||||
int mWeightCached;
|
||||
PRUint64 mWeightYData64[STGD_SPACE_X];
|
||||
} STCache;
|
||||
|
||||
/*
|
||||
** STGlobals
|
||||
**
|
||||
** Various globals we keep around.
|
||||
*/
|
||||
typedef struct __struct_STGlobals
|
||||
{
|
||||
/*
|
||||
** Options derived from the command line.
|
||||
*/
|
||||
STOptions mOptions;
|
||||
|
||||
/*
|
||||
** Cached data, generally reset by the options.
|
||||
*/
|
||||
STCache mCache;
|
||||
|
||||
/*
|
||||
** What the current request is.
|
||||
*/
|
||||
STRequest mRequest;
|
||||
|
||||
/*
|
||||
** Various counters for different types of events.
|
||||
*/
|
||||
PRUint32 mMallocCount;
|
||||
PRUint32 mCallocCount;
|
||||
PRUint32 mReallocCount;
|
||||
PRUint32 mFreeCount;
|
||||
|
||||
/*
|
||||
** Total events, operation counter.
|
||||
*/
|
||||
PRUint32 mOperationCount;
|
||||
|
||||
/*
|
||||
** The "run" of the input.
|
||||
*/
|
||||
STRun mRun;
|
||||
|
||||
/*
|
||||
** Operation minimum/maximum intervals.
|
||||
** So that we can determine the overall interval of the run.
|
||||
** NOTE: These are NOT the options to control the data set.
|
||||
*/
|
||||
PRUint32 mMinInterval;
|
||||
PRUint32 mMaxInterval;
|
||||
|
||||
/*
|
||||
** Set to non-zero when the httpd server should stop accepting
|
||||
** connections.
|
||||
*/
|
||||
int mStopHttpd;
|
||||
} STGlobals;
|
||||
|
||||
#endif /* spacetrace_h__ */
|
|
@ -167,16 +167,28 @@ static int get_tmevent(FILE *fp, tmevent *event)
|
|||
case TM_EVENT_MALLOC:
|
||||
case TM_EVENT_CALLOC:
|
||||
case TM_EVENT_FREE:
|
||||
event->u.alloc.oldsize = 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.interval))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.ptr))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.size))
|
||||
return 0;
|
||||
event->u.alloc.oldserial = 0;
|
||||
event->u.alloc.oldptr = 0;
|
||||
event->u.alloc.oldsize = 0;
|
||||
break;
|
||||
|
||||
case TM_EVENT_REALLOC:
|
||||
if (!get_uint32(fp, &event->u.alloc.interval))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.ptr))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.size))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.oldserial))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.oldptr))
|
||||
return 0;
|
||||
if (!get_uint32(fp, &event->u.alloc.oldsize))
|
||||
return 0;
|
||||
break;
|
||||
|
@ -243,7 +255,7 @@ static void generic_freetable(void *pool, void *item)
|
|||
|
||||
static PLHashEntry *callsite_allocentry(void *pool, const void *key)
|
||||
{
|
||||
return malloc(sizeof(tmcallsite));
|
||||
return calloc(1, sizeof(tmcallsite));
|
||||
}
|
||||
|
||||
static PLHashEntry *graphnode_allocentry(void *pool, const void *key)
|
||||
|
|
|
@ -65,8 +65,11 @@ struct tmevent {
|
|||
uint32 offset;
|
||||
} site;
|
||||
struct {
|
||||
uint32 interval;
|
||||
uint32 ptr;
|
||||
uint32 size;
|
||||
uint32 oldserial;
|
||||
uint32 oldptr;
|
||||
uint32 oldsize;
|
||||
} alloc;
|
||||
struct {
|
||||
|
@ -139,6 +142,9 @@ struct tmcallsite {
|
|||
uint32 offset; /* pc offset from start of method */
|
||||
tmallcounts allocs;
|
||||
tmallcounts frees;
|
||||
void *data; /* tmreader clients can stick arbitrary
|
||||
* data onto a callsite.
|
||||
*/
|
||||
};
|
||||
|
||||
struct tmreader {
|
||||
|
|
|
@ -445,6 +445,29 @@ static void log_event4(logfile *fp, char event, uint32 serial, uint32 ui2,
|
|||
log_uint32(fp, ui4);
|
||||
}
|
||||
|
||||
static void log_event5(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5)
|
||||
{
|
||||
log_event4(fp, event, serial, ui2, ui3, ui4);
|
||||
log_uint32(fp, ui5);
|
||||
}
|
||||
|
||||
static void log_event6(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6)
|
||||
{
|
||||
log_event5(fp, event, serial, ui2, ui3, ui4, ui5);
|
||||
log_uint32(fp, ui6);
|
||||
}
|
||||
|
||||
static void log_event7(logfile *fp, char event, uint32 serial, uint32 ui2,
|
||||
uint32 ui3, uint32 ui4, uint32 ui5, uint32 ui6,
|
||||
uint32 ui7)
|
||||
{
|
||||
log_event6(fp, event, serial, ui2, ui3, ui4, ui5, ui6);
|
||||
log_uint32(fp, ui7);
|
||||
}
|
||||
|
||||
|
||||
typedef struct callsite callsite;
|
||||
|
||||
struct callsite {
|
||||
|
@ -1256,7 +1279,8 @@ __ptr_t malloc(size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_MALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_MALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1287,7 +1311,8 @@ __ptr_t calloc(size_t count, size_t size)
|
|||
site = backtrace(1);
|
||||
size *= count;
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_CALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_CALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1343,8 +1368,9 @@ __ptr_t realloc(__ptr_t ptr, size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site) {
|
||||
log_event4(logfp, TM_EVENT_REALLOC, site->serial, size,
|
||||
oldsite ? oldsite->serial : 0, oldsize);
|
||||
log_event7(logfp, TM_EVENT_REALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size,
|
||||
oldsite ? oldsite->serial : 0, (uint32)oldptr, oldsize);
|
||||
}
|
||||
if (ptr && allocations) {
|
||||
suppress_tracing++;
|
||||
|
@ -1396,8 +1422,8 @@ void free(__ptr_t ptr)
|
|||
site = (callsite*) he->value;
|
||||
if (site) {
|
||||
alloc = (allocation*) he;
|
||||
log_event2(logfp, TM_EVENT_FREE, site->serial,
|
||||
alloc->size);
|
||||
log_event4(logfp, TM_EVENT_FREE,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, alloc->size);
|
||||
}
|
||||
PL_HashTableRawRemove(allocations, hep, he);
|
||||
}
|
||||
|
@ -1809,7 +1835,7 @@ NS_TraceMallocFlushLogfiles()
|
|||
#ifdef XP_WIN32
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
MallocCallback(void *aPtr, size_t size)
|
||||
MallocCallback(void *ptr, size_t size)
|
||||
{
|
||||
callsite *site;
|
||||
PLHashEntry *he;
|
||||
|
@ -1817,15 +1843,16 @@ MallocCallback(void *aPtr, size_t size)
|
|||
|
||||
TM_ENTER_MONITOR();
|
||||
tmstats.malloc_calls++;
|
||||
if (!aPtr) {
|
||||
if (!ptr) {
|
||||
tmstats.malloc_failures++;
|
||||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(4);
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_MALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_MALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, aPtr, site);
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
suppress_tracing--;
|
||||
if (he) {
|
||||
alloc = (allocation*) he;
|
||||
|
@ -1851,7 +1878,8 @@ CallocCallback(void *ptr, size_t count, size_t size)
|
|||
site = backtrace(1);
|
||||
size *= count;
|
||||
if (site)
|
||||
log_event2(logfp, TM_EVENT_CALLOC, site->serial, size);
|
||||
log_event4(logfp, TM_EVENT_CALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size);
|
||||
if (get_allocations()) {
|
||||
suppress_tracing++;
|
||||
he = PL_HashTableAdd(allocations, ptr, site);
|
||||
|
@ -1901,8 +1929,9 @@ ReallocCallback(void * oldptr, void *ptr, size_t size)
|
|||
} else if (suppress_tracing == 0) {
|
||||
site = backtrace(1);
|
||||
if (site) {
|
||||
log_event4(logfp, TM_EVENT_REALLOC, site->serial, size,
|
||||
oldsite ? oldsite->serial : 0, oldsize);
|
||||
log_event7(logfp, TM_EVENT_REALLOC,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, size,
|
||||
oldsite ? oldsite->serial : 0, (uint32)oldptr, oldsize);
|
||||
}
|
||||
if (ptr && allocations) {
|
||||
suppress_tracing++;
|
||||
|
@ -1953,7 +1982,8 @@ FreeCallback(void * ptr)
|
|||
site = (callsite*) he->value;
|
||||
if (site) {
|
||||
alloc = (allocation*) he;
|
||||
log_event2(logfp, TM_EVENT_FREE, site->serial, alloc->size);
|
||||
log_event4(logfp, TM_EVENT_FREE,
|
||||
site->serial, PR_IntervalNow(), (uint32)ptr, alloc->size);
|
||||
}
|
||||
PL_HashTableRawRemove(allocations, hep, he);
|
||||
}
|
||||
|
|
|
@ -45,7 +45,7 @@ PR_BEGIN_EXTERN_C
|
|||
* NS_TraceMallocStartup comment (below) for magic number differences in log
|
||||
* file structure.
|
||||
*/
|
||||
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog04\r\n\032"
|
||||
#define NS_TRACE_MALLOC_MAGIC "XPCOM\nTMLog06\r\n\032"
|
||||
#define NS_TRACE_MALLOC_MAGIC_SIZE 16
|
||||
|
||||
/**
|
||||
|
@ -108,7 +108,21 @@ typedef struct nsTMStats {
|
|||
* Event Operands (magic TMLog04)
|
||||
* 'R' site serial, realloc size, old site serial, realloc oldsize
|
||||
*
|
||||
* See xpcom/base/bloatblame.c for an example log-file reader.
|
||||
* Event Operands (magic TMLog05)
|
||||
* 'M' site serial, address, malloc size
|
||||
* 'C' site serial, address, calloc size
|
||||
* 'R' site serial, address, realloc size, old site serial,
|
||||
* old address, old size
|
||||
* 'F' site serial, address, free size
|
||||
*
|
||||
* Event Operands (magic TMLog06)
|
||||
* 'M' site serial, interval, address, malloc size
|
||||
* 'C' site serial, interval, address, calloc size
|
||||
* 'R' site serial, interval, address, realloc size, old site serial,
|
||||
* old address, old size
|
||||
* 'F' site serial, interval, address, free size
|
||||
*
|
||||
* See tools/trace-malloc/bloatblame.c for an example log-file reader.
|
||||
*/
|
||||
#define TM_EVENT_LIBRARY 'L'
|
||||
#define TM_EVENT_METHOD 'N'
|
||||
|
|
Загрузка…
Ссылка в новой задаче