enable MOZ_TIMELINE tool, bug 78793, r=rogc, sr=waterson

This commit is contained in:
cathleen%netscape.com 2001-08-17 02:03:34 +00:00
parent 852e355fe9
commit be72d98064
22 changed files with 825 additions and 5 deletions

View File

@ -66,6 +66,7 @@ content_packs 1
xml_rpc 1
cview 1
help 1
timeline 0 MOZ_TIMELINE
string_debug 0 DEBUG_STRING
string_stats 0 DEBUG_STRING_STATS

View File

@ -87,6 +87,7 @@ MOZ_COMPONENT_NSPR_LIBS=@MOZ_COMPONENT_NSPR_LIBS@
MOZ_COMPONENT_XPCOM_LIBS=@MOZ_COMPONENT_XPCOM_LIBS@
XPCOM_LIBS=@XPCOM_LIBS@
MOZ_REORDER=@MOZ_REORDER@
MOZ_TIMELINE=@MOZ_TIMELINE@
ClientWallet=1
CookieManagement=1

View File

@ -246,6 +246,11 @@ CFLAGS=$(CFLAGS) -DXPCONNECT_STANDALONE
CFLAGS=$(CFLAGS) -DMOZ_PERF_METRICS
!endif
# Enable timeline service if MOZ_TIMELINE is set
!ifdef MOZ_TIMELINE
CFLAGS=$(CFLAGS) -DMOZ_TIMELINE
!endif
!ifndef MOZ_JAVA
MOZ_OJI = 1 # on by default now
!endif

View File

@ -3161,6 +3161,24 @@ MOZ_ARG_ENABLE_STRING(reorder,
MOZ_REORDER=1
fi ])
dnl ========================================================
dnl =
dnl = --enable-timeline
dnl =
dnl = Enable timeline service, which provides lightweight
dnl = instrumentation of mozilla for performance measurement.
dnl =
dnl = Timeline is off by default.
dnl =
dnl ========================================================
MOZ_TIMELINE=0
MOZ_ARG_ENABLE_STRING(timeline,
[ --enable-timeline Enable timeline ],
[ if test "$enableval" != "no"; then
AC_DEFINE(MOZ_TIMELINE)
MOZ_TIMELINE=1
fi ])
dnl ========================================================
dnl =
dnl = --disable-debug
@ -4068,6 +4086,7 @@ AC_SUBST(MOZ_OS2_EMX_OBJECTFORMAT)
AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
AC_SUBST(MOZ_REORDER)
AC_SUBST(MOZ_TIMELINE)
dnl system JPEG support
dnl ========================================================

View File

@ -51,6 +51,7 @@
#include "nsISupportsArray.h"
#include "nsCOMPtr.h"
#include "nsIScriptSecurityManager.h"
#include "nsITimelineService.h"
#ifdef INCLUDE_XUL
#include "nsIXULPrototypeCache.h"
@ -614,6 +615,8 @@ SheetLoadData::OnStreamComplete(nsIStreamLoader* aLoader,
PRUint32 stringLen,
const char* string)
{
NS_TIMELINE_OUTDENT();
NS_TIMELINE_MARK_LOADER("SheetLoadData::OnStreamComplete(%s)", aLoader);
nsresult result = NS_OK;
nsString *strUnicodeBuffer = nsnull;
@ -1230,6 +1233,10 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
nsCOMPtr<nsILoadGroup> loadGroup;
mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
#ifdef MOZ_TIMELINE
NS_TIMELINE_MARK_URI("Loading style sheet: %s", urlClone);
NS_TIMELINE_INDENT();
#endif
result = NS_NewStreamLoader(&loader, urlClone, aData, nsnull, loadGroup,
nsnull, nsIChannel::LOAD_NORMAL);
#ifdef NS_DEBUG

View File

@ -51,6 +51,7 @@
#include "nsISupportsArray.h"
#include "nsCOMPtr.h"
#include "nsIScriptSecurityManager.h"
#include "nsITimelineService.h"
#ifdef INCLUDE_XUL
#include "nsIXULPrototypeCache.h"
@ -614,6 +615,8 @@ SheetLoadData::OnStreamComplete(nsIStreamLoader* aLoader,
PRUint32 stringLen,
const char* string)
{
NS_TIMELINE_OUTDENT();
NS_TIMELINE_MARK_LOADER("SheetLoadData::OnStreamComplete(%s)", aLoader);
nsresult result = NS_OK;
nsString *strUnicodeBuffer = nsnull;
@ -1230,6 +1233,10 @@ CSSLoaderImpl::LoadSheet(URLKey& aKey, SheetLoadData* aData)
nsCOMPtr<nsILoadGroup> loadGroup;
mDocument->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
#ifdef MOZ_TIMELINE
NS_TIMELINE_MARK_URI("Loading style sheet: %s", urlClone);
NS_TIMELINE_INDENT();
#endif
result = NS_NewStreamLoader(&loader, urlClone, aData, nsnull, loadGroup,
nsnull, nsIChannel::LOAD_NORMAL);
#ifdef NS_DEBUG

View File

@ -40,6 +40,7 @@
#include "nsICategoryManager.h"
#include "nsIURLParser.h"
#include "nsISupportsPrimitives.h"
#include "nsITimelineService.h"
static NS_DEFINE_CID(kFileTransportService, NS_FILETRANSPORTSERVICE_CID);
static NS_DEFINE_CID(kEventQueueService, NS_EVENTQUEUESERVICE_CID);
@ -663,6 +664,7 @@ nsIOService::NewChannelFromURI(nsIURI *aURI, nsIChannel **result)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(aURI);
NS_TIMELINE_MARK_URI("nsIOService::NewChannelFromURI(%s)", aURI);
nsXPIDLCString scheme;
rv = aURI->GetScheme(getter_Copies(scheme));

View File

@ -74,6 +74,7 @@
#include "nsAtomService.h"
#include "nsTraceRefcnt.h"
#include "nsTimelineService.h"
#ifdef GC_LEAK_DETECTOR
#include "nsLeakDetector.h"
@ -115,6 +116,10 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsConsoleService);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsAtomService);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsExceptionService);
#ifdef MOZ_TIMELINE
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimelineService);
#endif
////////////////////////////////////////////////////////////////////////////////
// XPCOM initialization
//
@ -198,6 +203,9 @@ static nsModuleComponentInfo components[] = {
COMPONENT(CONSOLESERVICE, nsConsoleServiceConstructor),
COMPONENT(EXCEPTIONSERVICE, nsExceptionServiceConstructor),
COMPONENT(ATOMSERVICE, nsAtomServiceConstructor),
#ifdef MOZ_TIMELINE
COMPONENT(TIMELINESERVICE, nsTimelineServiceConstructor),
#endif
COMPONENT(OBSERVER, nsObserver::Create),
COMPONENT(OBSERVERSERVICE, nsObserverService::Create),
COMPONENT(GENERICFACTORY, nsGenericFactory::Create),

View File

@ -43,6 +43,7 @@
#include "nsCRT.h"
#include "nsIObserverService.h"
#include "nsITimelineService.h"
#ifdef XP_MAC // sdagley dougt fix
#include <Files.h>
@ -91,6 +92,11 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID,
const char *aType,
nsIFactory **_retval)
{
NS_TIMELINE_MARKV(("nsNativeComponentLoader::GetFactory(%s)...",
aLocation));
NS_TIMELINE_INDENT();
NS_TIMELINE_START_TIMER("nsNativeComponentLoader::GetFactory");
nsresult rv;
if (!_retval)
@ -158,6 +164,12 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID,
// this is ok to limp along.
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Factory creation failed");
NS_TIMELINE_STOP_TIMER("nsNativeComponentLoader::GetFactory");
NS_TIMELINE_OUTDENT();
NS_TIMELINE_MARKV(("...nsNativeComponentLoader::GetFactory(%s) done",
aLocation));
NS_TIMELINE_MARK_TIMER("nsNativeComponentLoader::GetFactory");
return rv;
}

View File

@ -36,6 +36,7 @@
#include "nsCOMPtr.h"
#include "nsCRT.h"
#include "nsString.h"
#include "nsITimelineService.h"
#if defined(VMS) && defined(DEBUG)
#include <lib$routines.h>
#include <ssdef.h>
@ -337,7 +338,10 @@ PRBool nsDll::Load(void)
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_FALSE);
#endif
NS_TIMELINE_START_TIMER("PR_LoadLibrary");
m_instance = PR_LoadLibrary(m_dllName);
NS_TIMELINE_STOP_TIMER("PR_LoadLibrary");
NS_TIMELINE_MARK_TIMER("PR_LoadLibrary");
#ifdef NS_BUILD_REFCNT_LOGGING
nsTraceRefcnt::SetActivityIsLegal(PR_TRUE);

View File

@ -27,3 +27,4 @@ nsVoidBTree.h
pldhash.h
plvector.h
nsTextFormatter.h
nsTimelineService.h

View File

@ -9,5 +9,6 @@ nsIProperties.idl
nsISerializable.idl
nsIStopwatch.idl
nsISupportsArray.idl
nsITimelineService.idl
nsISupportsIterators.idl
nsISupportsPrimitives.idl

View File

@ -66,6 +66,7 @@ CPPSRCS = \
nsVoidArray.cpp \
nsVoidBTree.cpp \
nsTextFormatter.cpp \
nsTimelineService.cpp \
$(NULL)
EXPORTS = \
@ -114,6 +115,7 @@ XPIDLSRCS = \
nsISupportsArray.idl \
nsISupportsIterators.idl \
nsISupportsPrimitives.idl \
nsITimelineService.idl \
$(NULL)
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))

View File

@ -50,6 +50,7 @@ EXPORTS = \
nsSupportsArray.h \
nsSupportsPrimitives.h \
nsTime.h \
nsTimelineService.h \
nsUnitConversion.h \
nsVector.h \
nsVoidArray.h \
@ -68,6 +69,7 @@ XPIDLSRCS = \
.\nsIObserver.idl \
.\nsIObserverService.idl \
.\nsIPersistentProperties2.idl \
.\nsITimelineService.idl \
.\nsIProperties.idl \
.\nsISerializable.idl \
.\nsIStopwatch.idl \
@ -116,6 +118,7 @@ CPP_OBJS = \
.\$(OBJDIR)\nsSupportsArrayEnumerator.obj \
.\$(OBJDIR)\nsSupportsPrimitives.obj \
.\$(OBJDIR)\nsTextFormatter.obj \
.\$(OBJDIR)\nsTimelineService.obj \
.\$(OBJDIR)\nsUnicharBuffer.obj \
.\$(OBJDIR)\nsVoidArray.obj \
.\$(OBJDIR)\nsVoidBTree.obj \

View File

@ -0,0 +1,187 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsISupports.idl"
%{C++
#ifdef MOZ_TIMELINE
%}
/**
* nsITimelineService is used to constuct a timeline of program
* execution. The timeline is output to a file, either stderr or the
* value of the environment variable NS_TIMELINE_LOG_FILE. On the
* Mac, the timeline is output to the file named "timeline.txt". The
* reason it's different on the Mac is that the Mac environment
* initialization code happens after timeline initialization code.
*
* If NS_TIMELINE_INIT_TIME is set in the environment, that will be
* used as the time of startup; otherwise the current time when mark()
* is first called will be used.
*
* mark() is used to put marks on the timeline.
*
* indent() and outdent() are used to format the timeline a bit to
* show nesting. This doesn't produce perfect results in the face of
* asychrony and multiple threads.
*
* enter() and leave() are convenience functions that add marks to the
* timeline and do indentation.
*
* startTimer() and stopTimer() control named stop watches. If
* startTimer() is called more than once, an equal number of
* stopTimer() calls are needed to actually stop the timer. This
* makes these timers slightly useful in a threaded environment.
*
* markTimer() puts a mark on the timeline containing the total for
* the named timer.
*
* Don't use nsITimelineService in C++ code; use the NS_TIMELINE
* macros instead. nsITimelineService exists so that JavaScript code
* can mark the timeline.
*/
[scriptable, uuid(93276790-3daf-11d5-b67d-000064657374)]
interface nsITimelineService : nsISupports
{
/**
* mark()
* Print "<elapsed time>: <text>\n" in the timeline log file.
*/
void mark(in string text);
/**
* causes subsequent marks to be indented for a more readable
* report.
*/
void indent();
/**
* Causes subsequent marks to be outdented.
*/
void outdent();
/**
* enter/leave bracket code with "<text>..." and "...<text>" as
* well as indentation.
*/
void enter(in string text);
void leave(in string text);
void startTimer(in string timerName);
void stopTimer(in string timerName);
void markTimer(in string timerName);
};
%{C++
#endif /* MOZ_TIMELINE */
%}
%{C++
#ifdef MOZ_TIMELINE
/*
* These are equivalent to the corresponding nsITimelineService
* methods, and can be called before XPCOM is initialized.
*/
PR_EXTERN(nsresult) NS_TimelineMark(const char *text, ...);
PR_EXTERN(nsresult) NS_TimelineStartTimer(const char *timerName);
PR_EXTERN(nsresult) NS_TimelineStopTimer(const char *timerName);
PR_EXTERN(nsresult) NS_TimelineMarkTimer(const char *timerName);
PR_EXTERN(nsresult) NS_TimelineIndent();
PR_EXTERN(nsresult) NS_TimelineOutdent();
PR_EXTERN(nsresult) NS_TimelineEnter(const char *text);
PR_EXTERN(nsresult) NS_TimelineLeave(const char *text);
/*
* Use these macros for the above calls so we can easily compile them
* out.
*/
#define NS_TIMELINE_MARK(text) NS_TimelineMark(text)
#define NS_TIMELINE_MARKV(args) NS_TimelineMark args
#define NS_TIMELINE_INDENT() NS_TimelineIndent()
#define NS_TIMELINE_OUTDENT() NS_TimelineOutdent()
#define NS_TIMELINE_ENTER(text) NS_TimelineEnter(text)
#define NS_TIMELINE_LEAVE(text) NS_TimelineLeave(text)
#define NS_TIMELINE_START_TIMER(timerName) NS_TimelineStartTimer(timerName)
#define NS_TIMELINE_STOP_TIMER(timerName) NS_TimelineStopTimer(timerName)
#define NS_TIMELINE_MARK_TIMER(timerName) NS_TimelineMarkTimer(timerName)
/*
* NS_TIMELINE_MARK_ macros for various data types. Each of these
* macros replaces "%s" in its "text" argument with a string
* representation of its last argument.
*
* Please feel free to add more NS_TIMELINE_MARK_ macros for
* various data types so that code using NS_TIMELINE is uncluttered.
* Don't forget the empty versions in the #else section below for
* non-timeline builds.
*/
#define NS_TIMELINE_MARK_URI(text, uri) \
{ \
char *spec = NULL; \
if (uri) { \
uri->GetSpec(&spec); \
} \
if (spec != NULL) { \
NS_TimelineMark(text, spec); \
nsCRT::free(spec); \
} else { \
NS_TimelineMark(text, "??"); \
} \
}
#define NS_TIMELINE_MARK_CHANNEL(text, channel) \
{ \
nsCOMPtr<nsIURI> uri; \
if (channel) { \
channel->GetURI(getter_AddRefs(uri)); \
} \
NS_TIMELINE_MARK_URI(text, uri); \
}
#define NS_TIMELINE_MARK_LOADER(text, loader) \
{ \
nsCOMPtr<nsIRequest> request; \
loader->GetRequest(getter_AddRefs(request)); \
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request)); \
NS_TIMELINE_MARK_CHANNEL(text, channel); \
}
#else /* !defined(MOZ_TIMELINE) */
#define NS_TIMELINE_MARK(text)
#define NS_TIMELINE_MARKV(args)
#define NS_TIMELINE_INDENT()
#define NS_TIMELINE_OUTDENT()
#define NS_TIMELINE_START_TIMER(timerName)
#define NS_TIMELINE_STOP_TIMER(timerName)
#define NS_TIMELINE_MARK_TIMER(timerName)
#define NS_TIMELINE_ENTER(text)
#define NS_TIMELINE_LEAVE(text)
#define NS_TIMELINE_MARK_URI(text, uri)
#define NS_TIMELINE_MARK_CHANNEL(text, channel)
#define NS_TIMELINE_MARK_LOADER(text, loader);
#endif /* defined(MOZ_TIMELINE) */
%}

View File

@ -0,0 +1,453 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsTimelineService.h"
#include "prlong.h"
#include "prprf.h"
#include "prenv.h"
#include "plhash.h"
#include "prlock.h"
#include "prinit.h"
#include "prinrval.h"
#ifdef MOZ_TIMELINE
#define MAXINDENT 20
#ifdef XP_MAC
static PRIntervalTime initInterval = 0;
#endif
static PRTime initTime = 0;
static PRFileDesc *timelineFD = PR_STDERR;
static PRHashTable *timers;
static PRLock *timerLock;
static int indent;
/* Implementation file */
NS_IMPL_ISUPPORTS1(nsTimelineService, nsITimelineService)
static PRTime Now(void);
/*
* Timer structure stored in a hash table to keep track of named
* timers.
*/
class nsTimelineServiceTimer {
public:
nsTimelineServiceTimer();
~nsTimelineServiceTimer();
void start();
/*
* Caller passes in "now" rather than having us calculate it so
* that we can avoid including timer overhead in the time being
* measured.
*/
void stop(PRTime now);
PRTime getAccum();
PRTime getAccum(PRTime now);
private:
PRTime mAccum;
PRTime mStart;
PRInt32 mRunning;
PRLock *mLock;
};
nsTimelineServiceTimer::nsTimelineServiceTimer()
: mAccum(LL_ZERO), mStart(LL_ZERO), mRunning(0), mLock(PR_NewLock())
{
}
nsTimelineServiceTimer::~nsTimelineServiceTimer()
{
PR_DestroyLock(mLock);
}
void nsTimelineServiceTimer::start()
{
PR_Lock(mLock);
if (!mRunning) {
mStart = Now();
}
mRunning++;
PR_Unlock(mLock);
}
void nsTimelineServiceTimer::stop(PRTime now)
{
PR_Lock(mLock);
mRunning--;
if (mRunning == 0) {
PRTime delta, accum;
LL_SUB(delta, now, mStart);
LL_ADD(accum, mAccum, delta);
mAccum = accum;
}
PR_Unlock(mLock);
}
PRTime nsTimelineServiceTimer::getAccum()
{
PRTime accum;
PR_Lock(mLock);
if (!mRunning) {
accum = mAccum;
} else {
PRTime delta;
LL_SUB(delta, Now(), mStart);
LL_ADD(accum, mAccum, delta);
}
PR_Unlock(mLock);
return accum;
}
PRTime nsTimelineServiceTimer::getAccum(PRTime now)
{
PRTime accum;
PR_Lock(mLock);
if (!mRunning) {
accum = mAccum;
} else {
PRTime delta;
LL_SUB(delta, now, mStart);
LL_ADD(accum, mAccum, delta);
}
PR_Unlock(mLock);
return accum;
}
#ifdef XP_MAC
/*
* PR_Now() on the Mac only gives us a resolution of seconds. Using
* PR_IntervalNow() gives us better resolution. with the drawback that
* the timeline is only good for about six hours.
*
* PR_IntervalNow() occasionally exhibits discontinuities on Windows,
* so we only use it on the Mac. Bleah!
*/
static PRTime Now(void)
{
PRIntervalTime numTicks = PR_IntervalNow() - initInterval;
PRTime now;
LL_ADD(now, initTime, PR_IntervalToMilliseconds(numTicks) * 1000);
return now;
}
#else
static PRTime Now(void)
{
return PR_Now();
}
#endif
static void TimelineInit(void)
{
char *timeStr;
char *fileName;
PRInt32 secs, msecs;
PRFileDesc *fd;
PRInt64 tmp1, tmp2;
timeStr = PR_GetEnv("NS_TIMELINE_INIT_TIME");
#ifdef XP_MAC
initInterval = PR_IntervalNow();
#endif
if (timeStr != NULL && 2 == PR_sscanf(timeStr, "%d.%d", &secs, &msecs)) {
LL_MUL(tmp1, (PRInt64)secs, 1000000);
LL_MUL(tmp2, (PRInt64)msecs, 1000);
LL_ADD(initTime, tmp1, tmp2);
#ifdef XP_MAC
initInterval -= PR_MicrosecondsToInterval(
(PRUint32)(PR_Now() - initTime));
#endif
} else {
initTime = PR_Now();
}
#ifdef XP_MAC
fileName = "timeline.txt";
#else
fileName = PR_GetEnv("NS_TIMELINE_LOG_FILE");
#endif
if (fileName != NULL
&& (fd = PR_Open(fileName, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE,
0666)) != NULL) {
timelineFD = fd;
PR_fprintf(fd,
"NOTE: due to threading and asynchrony, the indentation\n"
"that you see does not necessarily correspond to nesting\n"
"in the code.\n\n");
}
}
static void ParseTime(PRTime tm, PRInt32& secs, PRInt32& msecs)
{
PRTime llsecs, llmsecs, tmp;
LL_DIV(llsecs, tm, 1000000);
LL_MOD(tmp, tm, 1000000);
LL_DIV(llmsecs, tmp, 1000);
LL_L2I(secs, llsecs);
LL_L2I(msecs, llmsecs);
}
static char *Indent(char *buf)
{
int amount = indent;
if (amount > MAXINDENT) {
amount = MAXINDENT;
}
if (amount < 0) {
amount = 0;
indent = 0;
PR_Write(timelineFD, "indent underflow!\n", 18);
}
while (amount--) {
*buf++ = ' ';
}
return buf;
}
static void PrintTime(PRTime tm, const char *text, va_list args)
{
PRInt32 secs, msecs;
char pbuf[500], *pc, tbuf[500];
ParseTime(tm, secs, msecs);
// snprintf/write rather than fprintf because we don't want
// messages from multiple threads to garble one another.
pc = Indent(pbuf);
PR_vsnprintf(pc, sizeof pbuf - (pc - pbuf), text, args);
PR_snprintf(tbuf, sizeof tbuf, "%05d.%03d: %s\n",
secs, msecs, pbuf);
PR_Write(timelineFD, tbuf, strlen(tbuf));
}
/*
* Make this public if we need it.
*/
static nsresult NS_TimelineMarkV(const char *text, va_list args)
{
PRTime elapsed,tmp;
if (LL_IS_ZERO(initTime)) {
TimelineInit();
}
tmp = Now();
LL_SUB(elapsed, tmp, initTime);
PrintTime(elapsed, text, args);
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineMark(const char *text, ...)
{
va_list args;
va_start(args, text);
NS_TimelineMarkV(text, args);
return NS_OK;
}
/*
* PRCallOnceFN that initializes stuff for the timing service.
*/
static PRStatus InitTimers(void)
{
timerLock = PR_NewLock();
if (timerLock == NULL) {
return PR_FAILURE;
}
timers = PL_NewHashTable(100, PL_HashString, PL_CompareStrings,
PL_CompareValues, NULL, NULL);
return timers != NULL ? PR_SUCCESS : PR_FAILURE;
}
PR_IMPLEMENT(nsresult) NS_TimelineStartTimer(const char *timerName)
{
static PRCallOnceType once;
PR_CallOnce(&once, InitTimers);
if (timers == NULL) {
return NS_ERROR_FAILURE;
}
PR_Lock(timerLock);
nsTimelineServiceTimer *timer
= (nsTimelineServiceTimer *)PL_HashTableLookup(timers, timerName);
if (timer == NULL) {
timer = new nsTimelineServiceTimer;
PL_HashTableAdd(timers, timerName, timer);
}
PR_Unlock(timerLock);
timer->start();
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineStopTimer(const char *timerName)
{
if (timers == NULL) {
return NS_ERROR_FAILURE;
}
/*
* Strange-looking now/timer->stop() interaction is to avoid
* including time spent in PR_Lock and PL_HashTableLookup in the
* timer.
*/
PRTime now = Now();
PR_Lock(timerLock);
nsTimelineServiceTimer *timer
= (nsTimelineServiceTimer *)PL_HashTableLookup(timers, timerName);
PR_Unlock(timerLock);
if (timer == NULL) {
return NS_ERROR_FAILURE;
}
timer->stop(now);
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineMarkTimer(const char *timerName)
{
if (timers == NULL) {
return NS_ERROR_FAILURE;
}
PR_Lock(timerLock);
nsTimelineServiceTimer *timer
= (nsTimelineServiceTimer *)PL_HashTableLookup(timers, timerName);
PR_Unlock(timerLock);
if (timer == NULL) {
return NS_ERROR_FAILURE;
}
PRTime accum = timer->getAccum();
char buf[500];
PRInt32 sec, msec;
ParseTime(accum, sec, msec);
PR_snprintf(buf, sizeof buf, "%s total: %d.%03d",
timerName, sec, msec);
NS_TimelineMark(buf);
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineIndent()
{
indent++; // Could have threading issues here.
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineOutdent()
{
indent--; // Could have threading issues here.
return NS_OK;
}
PR_IMPLEMENT(nsresult) NS_TimelineEnter(const char *text)
{
nsresult rv = NS_TimelineMark("%s...", text);
if (!NS_SUCCEEDED(rv)) {
return rv;
}
return NS_TimelineIndent();
}
PR_IMPLEMENT(nsresult) NS_TimelineLeave(const char *text)
{
nsresult rv = NS_TimelineOutdent();
if (!NS_SUCCEEDED(rv)) {
return rv;
}
return NS_TimelineMark("...%s", text);
}
nsTimelineService::nsTimelineService()
{
NS_INIT_ISUPPORTS();
/* member initializers and constructor code */
}
nsTimelineService::~nsTimelineService()
{
/* destructor code */
}
/* void mark (in string text); */
NS_IMETHODIMP nsTimelineService::Mark(const char *text)
{
return NS_TimelineMark(text);
}
/* void startTimer (in string timerName); */
NS_IMETHODIMP nsTimelineService::StartTimer(const char *timerName)
{
return NS_TimelineStartTimer(timerName);
}
/* void stopTimer (in string timerName); */
NS_IMETHODIMP nsTimelineService::StopTimer(const char *timerName)
{
return NS_TimelineStopTimer(timerName);
}
/* void markTimer (in string timerName, in string text); */
NS_IMETHODIMP nsTimelineService::MarkTimer(const char *timerName)
{
return NS_TimelineMarkTimer(timerName);
}
/* void indent (); */
NS_IMETHODIMP nsTimelineService::Indent()
{
return NS_TimelineIndent();
}
/* void outdent (); */
NS_IMETHODIMP nsTimelineService::Outdent()
{
return NS_TimelineOutdent();
}
/* void enter (in string text); */
NS_IMETHODIMP nsTimelineService::Enter(const char *text)
{
return NS_TimelineEnter(text);
}
/* void leave (in string text); */
NS_IMETHODIMP nsTimelineService::Leave(const char *text)
{
return NS_TimelineLeave(text);
}
#endif /* MOZ_TIMELINE */

View File

@ -0,0 +1,48 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape 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/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "nsITimelineService.h"
#ifdef MOZ_TIMELINE
#define NS_TIMELINESERVICE_CID \
{ /* a335edf0-3daf-11d5-b67d-000064657374 */ \
0xa335edf0, \
0x3daf, \
0x11d5, \
{0xb6, 0x7d, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74}}
#define NS_TIMELINESERVICE_CONTRACTID "@mozilla.org;timeline-service;1"
#define NS_TIMELINESERVICE_CLASSNAME "Timeline Service"
class nsTimelineService : public nsITimelineService
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSITIMELINESERVICE
nsTimelineService();
virtual ~nsTimelineService();
/* additional members */
};
#endif

View File

@ -49,6 +49,7 @@
#include "nsXPIDLString.h"
#include "prproces.h"
#include "nsITimelineService.h"
// certainly not all the error that can be
// encountered, but many of them common ones
@ -1150,7 +1151,10 @@ nsLocalFile::Load(PRLibrary * *_retval)
if (! isFile)
return NS_ERROR_FILE_IS_DIRECTORY;
NS_TIMELINE_START_TIMER("PR_LoadLibrary");
*_retval = PR_LoadLibrary(mResolvedPath);
NS_TIMELINE_STOP_TIMER("PR_LoadLibrary");
NS_TIMELINE_MARK_TIMER("PR_LoadLibrary");
if (*_retval)
return NS_OK;

View File

@ -48,6 +48,7 @@
#include "nsIEnumerator.h"
#include "nsICmdLineService.h"
#include "nsCRT.h"
#include "nsITimelineService.h"
#ifdef NS_DEBUG
#include "prprf.h"
#endif
@ -144,10 +145,12 @@ nsAppShellService::Initialize( nsICmdLineService *aCmdLineService,
goto done;
}
NS_TIMELINE_ENTER("nsComponentManager::CreateInstance.");
// Create widget application shell
rv = nsComponentManager::CreateInstance(kAppShellCID, nsnull,
NS_GET_IID(nsIAppShell),
(void**)getter_AddRefs(mAppShell));
NS_TIMELINE_LEAVE("nsComponentManager::CreateInstance");
if (NS_FAILED(rv)) {
goto done;
}

View File

@ -59,6 +59,7 @@
#include "nsIDOMDocumentView.h"
#include "nsIDOMViewCSS.h"
#include "nsIDOMCSSStyleDeclaration.h"
#include "nsITimelineService.h"
#include "nsStyleConsts.h"
@ -546,14 +547,18 @@ NS_IMETHODIMP nsXULWindow::GetVisibility(PRBool* aVisibility)
NS_IMETHODIMP nsXULWindow::SetVisibility(PRBool aVisibility)
{
NS_TIMELINE_ENTER("nsXULWindow::SetVisibility.");
if(!mChromeLoaded)
{
mShowAfterLoad = aVisibility;
NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility");
return NS_OK;
}
if(mDebuting)
if(mDebuting) {
NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility");
return NS_OK;
}
mDebuting = PR_TRUE; // (Show / Focus is recursive)
//XXXTAB Do we really need to show docshell and the window? Isn't
@ -576,6 +581,7 @@ NS_IMETHODIMP nsXULWindow::SetVisibility(PRBool aVisibility)
splashScreenGone = PR_TRUE;
}
mDebuting = PR_FALSE;
NS_TIMELINE_LEAVE("nsXULWindow::SetVisibility");
return NS_OK;
}
@ -1261,6 +1267,7 @@ NS_IMETHODIMP nsXULWindow::GetNewWindow(PRInt32 aChromeFlags,
NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(PRInt32 aChromeFlags,
nsIDocShellTreeItem** aDocShellTreeItem)
{
NS_TIMELINE_ENTER("nsXULWindow::CreateNewChromeWindow");
nsCOMPtr<nsIAppShellService> appShell(do_GetService(kAppShellServiceCID));
NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
@ -1286,12 +1293,14 @@ NS_IMETHODIMP nsXULWindow::CreateNewChromeWindow(PRInt32 aChromeFlags,
newWindow->GetDocShell(getter_AddRefs(docShell));
CallQueryInterface(docShell, aDocShellTreeItem);
NS_TIMELINE_LEAVE("nsXULWindow::CreateNewChromeWindow done");
return NS_OK;
}
NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(PRInt32 aChromeFlags,
nsIDocShellTreeItem** aDocShellTreeItem)
{
NS_TIMELINE_ENTER("nsXULWindow::CreateNewContentWindow");
nsCOMPtr<nsIAppShellService> appShell(do_GetService(kAppShellServiceCID));
NS_ENSURE_TRUE(appShell, NS_ERROR_FAILURE);
@ -1387,6 +1396,7 @@ NS_IMETHODIMP nsXULWindow::CreateNewContentWindow(PRInt32 aChromeFlags,
// into the new window's content shell array. Locate the "content area" content
// shell.
newWindow->GetPrimaryContentShell(aDocShellTreeItem);
NS_TIMELINE_LEAVE("nsXULWindow::CreateNewContentWindow");
return NS_OK;
}

View File

@ -254,7 +254,7 @@ ifeq ($(MOZ_REORDER),1)
LDSCRIPT = ldscript
LDFLAGS += -Wl,-T,$(LDSCRIPT)
GARBAGE += $(LDSCRIPT)
ORDERFILE = mozilla-bin.order
ORDERFILE = $(srcdir)/mozilla-bin.order
$(PROGRAM) : $(LDSCRIPT) $(ORDERFILE)

View File

@ -84,6 +84,8 @@
#include "nsTraceMalloc.h"
#endif
#include "nsITimelineService.h"
#if defined(DEBUG_sspitzer) || defined(DEBUG_seth)
#define DEBUG_CMD_LINE
#endif
@ -1103,6 +1105,7 @@ static nsresult VerifyInstallation(int argc, char **argv)
static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
{
nsresult rv;
NS_TIMELINE_ENTER("main1");
//----------------------------------------------------------------
// First we need to check if a previous installation occured and
@ -1135,13 +1138,15 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
fpsetmask(0);
#endif
NS_TIMELINE_ENTER("init event service");
nsCOMPtr<nsIEventQueueService> eventQService(do_GetService(NS_EVENTQUEUESERVICE_CONTRACTID, &rv));
if (NS_SUCCEEDED(rv)) {
// XXX: What if this fails?
rv = eventQService->CreateThreadEventQueue();
}
NS_TIMELINE_LEAVE("init event service");
NS_TIMELINE_ENTER("init observer service");
// Setup an autoreg obserer, so that we can update a progress
// string in the splash screen
nsCOMPtr<nsIObserverService> obsService(do_GetService(NS_OBSERVERSERVICE_CONTRACTID));
@ -1153,6 +1158,7 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
obsService->AddObserver(splashScreenObserver, NS_ConvertASCIItoUCS2(NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID).get());
}
}
NS_TIMELINE_LEAVE("init observer service");
#if XP_MAC
stTSMCloser tsmCloser;
@ -1161,6 +1167,7 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
NS_ASSERTION(NS_SUCCEEDED(rv), "Initializing AppleEvents failed");
#endif
NS_TIMELINE_ENTER("setup registry");
// Ask XPInstall if we need to autoregister anything new.
PRBool needAutoReg = NS_SoftwareUpdateNeedsAutoReg();
@ -1175,6 +1182,7 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
if (needAutoReg) // XXX ...and autoreg was successful?
NS_SoftwareUpdateDidAutoReg();
NS_TIMELINE_LEAVE("setup registry");
// remove the nativeApp as an XPCOM autoreg observer
if (obsService)
@ -1186,6 +1194,8 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
}
}
NS_TIMELINE_ENTER("startupNotifier");
// Start up the core services:
// Please do not add new things to main1() - please hook into the
@ -1194,8 +1204,10 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
if(NS_FAILED(rv))
return rv;
startupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
NS_TIMELINE_LEAVE("startupNotifier");
NS_TIMELINE_ENTER("cmdLineArgs");
// Initialize the cmd line service
nsCOMPtr<nsICmdLineService> cmdLineArgs(do_GetService(kCmdLineServiceCID, &rv));
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get command line service");
@ -1212,9 +1224,15 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
return rv;
}
NS_TIMELINE_LEAVE("cmdLineArgs");
NS_TIMELINE_ENTER("InstallGlobalLocale");
rv = InstallGlobalLocale(cmdLineArgs);
if(NS_FAILED(rv))
return rv;
NS_TIMELINE_LEAVE("InstallGlobalLocale");
NS_TIMELINE_ENTER("appShell");
nsCOMPtr<nsIAppShellService> appShell(do_GetService(kAppShellServiceCID, &rv));
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to get the appshell service");
@ -1240,10 +1258,15 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
return rv;
}
NS_TIMELINE_LEAVE("appShell");
NS_TIMELINE_ENTER("appShell->Initialize");
// Create the Application Shell instance...
rv = appShell->Initialize(cmdLineArgs, nativeApp);
NS_TIMELINE_LEAVE("appShell->Initialize");
// We are done with the native app (or splash screen) object here;
// the app shell owns it now.
NS_IF_RELEASE(nativeApp);
@ -1259,15 +1282,21 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
appShell->SetQuitOnLastWindowClosing(PR_FALSE);
// Initialize Profile Service here.
NS_TIMELINE_ENTER("InitializeProfileService");
rv = InitializeProfileService(cmdLineArgs);
NS_TIMELINE_LEAVE("InitializeProfileService");
if (NS_FAILED(rv)) return rv;
// Enumerate AppShellComponenets
NS_TIMELINE_ENTER("appShell->EnumerateAndInitializeComponents");
appShell->EnumerateAndInitializeComponents();
NS_TIMELINE_LEAVE("appShell->EnumerateAndInitializeComponents");
// rjc: now must explicitly call appshell's CreateHiddenWindow() function AFTER profile manager.
// if the profile manager ever switches to using nsIDOMWindowInternal stuff, this might have to change
NS_TIMELINE_ENTER("appShell->CreateHiddenWindow");
appShell->CreateHiddenWindow();
NS_TIMELINE_LEAVE("appShell->CreateHiddenWindow");
nsCOMPtr<nsINativeAppSupport> nativeApps;
rv = GetNativeAppSupport(getter_AddRefs(nativeApps));
@ -1299,17 +1328,23 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
return rv;
// Make sure there exists at least 1 window.
NS_TIMELINE_ENTER("Ensure1Window");
rv = Ensure1Window( cmdLineArgs );
NS_TIMELINE_LEAVE("Ensure1Window");
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to Ensure1Window");
if (NS_FAILED(rv)) return rv;
// Startup wallet service so it registers for notifications
NS_TIMELINE_ENTER("walletService");
nsCOMPtr<nsIWalletService> walletService(do_GetService(NS_WALLETSERVICE_CONTRACTID, &rv));
NS_TIMELINE_LEAVE("walletService");
// From this point on, should be true
appShell->SetQuitOnLastWindowClosing(PR_TRUE);
// Start main event loop
NS_TIMELINE_ENTER("appShell->Run");
rv = appShell->Run();
NS_TIMELINE_LEAVE("appShell->Run");
NS_ASSERTION(NS_SUCCEEDED(rv), "failed to run appshell");
/*
@ -1318,6 +1353,8 @@ static nsresult main1(int argc, char* argv[], nsISupports *nativeApp )
*/
(void) appShell->Shutdown();
NS_TIMELINE_LEAVE("main1");
return rv;
}
@ -1533,9 +1570,10 @@ static PRBool GetWantSplashScreen(int argc, char* argv[])
return dosplash;
}
int main(int argc, char* argv[])
{
NS_TIMELINE_MARK("enter main");
#if defined(XP_UNIX) || defined(XP_BEOS)
InstallUnixSignalHandlers(argv[0]);
#endif
@ -1607,9 +1645,13 @@ int main(int argc, char* argv[])
NSGetStaticModuleInfo = apprunner_getModuleInfo;
#endif
NS_TIMELINE_MARK("InitXPCom...");
rv = NS_InitXPCOM(NULL, NULL);
NS_ASSERTION( NS_SUCCEEDED(rv), "NS_InitXPCOM failed" );
NS_TIMELINE_MARK("...InitXPCOM done");
#ifdef MOZ_ENABLE_XREMOTE
// handle -remote now that xpcom is fired up
int remoterv;