Bug 281137 Add profiling column for functions excluding other functions running

jsd part
patch by silver@warwickcompsoc.co.uk r=shaver sr=dmose a=bsmedberg
This commit is contained in:
timeless%mozdev.org 2005-08-02 15:53:59 +00:00
parent 543835b5eb
commit d2b31f1255
7 changed files with 190 additions and 4 deletions

View File

@ -78,7 +78,7 @@ interface jsdIProperty;
* Debugger service. It's not a good idea to have more than one active client of
* the debugger service.
*/
[scriptable, uuid(01be7f9a-1dd2-11b2-9d55-aaf919b27c73)]
[scriptable, uuid(9dd9006a-4e5e-4a80-ac3d-007fb7335ca4)]
interface jsdIDebuggerService : nsISupports
{
/** Internal use only. */
@ -954,6 +954,21 @@ interface jsdIScript : jsdIEphemeral
* Total time spent in this function, in milliseconds.
*/
readonly attribute double totalExecutionTime;
/**
* Shortest execution time recorded, in milliseconds, excluding time spent
* in other called code.
*/
readonly attribute double minOwnExecutionTime;
/**
* Longest execution time recorded, in milliseconds, excluding time spent
* in other called code.
*/
readonly attribute double maxOwnExecutionTime;
/**
* Total time spent in this function, in milliseconds, excluding time spent
* in other called code.
*/
readonly attribute double totalOwnExecutionTime;
/**
* Clear profile data for this script.

View File

@ -170,6 +170,8 @@ struct JSDContext
JSHashTable* atoms;
JSCList objectsList;
JSHashTable* objectsTable;
JSDProfileData* callingFunctionPData;
int64 lastReturnTime;
#ifdef JSD_THREADSAFE
void* scriptsLock;
void* sourceTextLock;
@ -206,13 +208,18 @@ struct JSDScript
struct JSDProfileData
{
JSDProfileData* caller;
int64 lastCallStart;
int64 runningTime;
uintN callCount;
uintN recurseDepth;
uintN maxRecurseDepth;
jsdouble minExecutionTime;
jsdouble maxExecutionTime;
jsdouble totalExecutionTime;
jsdouble minOwnExecutionTime;
jsdouble maxOwnExecutionTime;
jsdouble totalOwnExecutionTime;
};
struct JSDSourceText
@ -409,6 +416,15 @@ jsd_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern jsdouble
jsd_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
extern void
jsd_ClearScriptProfileData(JSDContext* jsdc, JSDScript *script);

View File

@ -353,6 +353,33 @@ jsd_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
return 0.0;
}
jsdouble
jsd_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
return script->profileData->minOwnExecutionTime;
return 0.0;
}
jsdouble
jsd_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
return script->profileData->maxOwnExecutionTime;
return 0.0;
}
jsdouble
jsd_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
if (script->profileData)
return script->profileData->totalOwnExecutionTime;
return 0.0;
}
void
jsd_ClearScriptProfileData(JSDContext* jsdc, JSDScript *script)
{

View File

@ -151,11 +151,38 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
{
if (JSLL_IS_ZERO(pdata->lastCallStart))
{
pdata->lastCallStart = JS_Now();
int64 now;
JSDProfileData *callerpdata;
/* Get the time just the once, for consistency. */
now = JS_Now();
/* This contains a pointer to the profile data for
* the caller of this function. */
callerpdata = jsdc->callingFunctionPData;
if (callerpdata)
{
int64 ll_delta;
pdata->caller = callerpdata;
/* We need to 'stop' the timer for the caller.
* Use time since last return if appropriate. */
if (JSLL_IS_ZERO(jsdc->lastReturnTime))
JSLL_SUB(ll_delta, now, callerpdata->lastCallStart);
else
JSLL_SUB(ll_delta, now, jsdc->lastReturnTime);
callerpdata->runningTime += ll_delta;
}
/* We're the new current function, and no return
* has happened yet. */
jsdc->callingFunctionPData = pdata;
jsdc->lastReturnTime = 0;
/* This function has no running time (just been
* called!), and we'll need the call start time. */
pdata->runningTime = JSLL_ZERO;
pdata->lastCallStart = now;
} else {
if (++pdata->recurseDepth > pdata->maxRecurseDepth)
pdata->maxRecurseDepth = pdata->recurseDepth;
}
}
/* make sure we're called for the return too. */
hookresult = JS_TRUE;
} else if (!pdata->recurseDepth &&
@ -167,13 +194,48 @@ _callHook(JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before,
JSLL_L2D(delta, ll_delta);
delta /= 1000.0;
pdata->totalExecutionTime += delta;
if (!pdata->minExecutionTime ||
/* minExecutionTime starts as 0, so we need to overwrite
* it on the first call always. */
if ((0 == pdata->callCount) ||
delta < pdata->minExecutionTime)
{
pdata->minExecutionTime = delta;
}
if (delta > pdata->maxExecutionTime)
pdata->maxExecutionTime = delta;
/* If we last returned from a function (as opposed to
* having last entered this function), we need to inc.
* the running total by the time delta since the last
* return, and use the running total instead of the
* delta calculated above. */
if (!JSLL_IS_ZERO(jsdc->lastReturnTime))
{
// Add last chunk to running time, and use total
// running time as 'delta'.
JSLL_SUB(ll_delta, now, jsdc->lastReturnTime);
pdata->runningTime += ll_delta;
JSLL_L2D(delta, pdata->runningTime);
delta /= 1000.0;
}
pdata->totalOwnExecutionTime += delta;
/* See minExecutionTime comment above. */
if ((0 == pdata->callCount) ||
delta < pdata->minOwnExecutionTime)
{
pdata->minOwnExecutionTime = delta;
}
if (delta > pdata->maxOwnExecutionTime)
pdata->maxOwnExecutionTime = delta;
/* Current function is now our caller. */
jsdc->callingFunctionPData = pdata->caller;
/* No hanging pointers, please. */
pdata->caller = NULL;
/* Mark the time we returned, and indicate this
* function is no longer running. */
jsdc->lastReturnTime = now;
pdata->lastCallStart = JSLL_ZERO;
++pdata->callCount;
} else if (pdata->recurseDepth) {

View File

@ -1332,6 +1332,30 @@ jsdScript::GetTotalExecutionTime(double *_rval)
return NS_OK;
}
NS_IMETHODIMP
jsdScript::GetMinOwnExecutionTime(double *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_GetScriptMinOwnExecutionTime (mCx, mScript);
return NS_OK;
}
NS_IMETHODIMP
jsdScript::GetMaxOwnExecutionTime(double *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_GetScriptMaxOwnExecutionTime (mCx, mScript);
return NS_OK;
}
NS_IMETHODIMP
jsdScript::GetTotalOwnExecutionTime(double *_rval)
{
ASSERT_VALID_EPHEMERAL;
*_rval = JSD_GetScriptTotalOwnExecutionTime (mCx, mScript);
return NS_OK;
}
NS_IMETHODIMP
jsdScript::ClearProfileData()
{

View File

@ -213,6 +213,27 @@ JSD_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script)
return jsd_GetScriptTotalExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMinOwnExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptMaxOwnExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(jsdouble)
JSD_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script)
{
JSD_ASSERT_VALID_CONTEXT(jsdc);
return jsd_GetScriptTotalOwnExecutionTime(jsdc, script);
}
JSD_PUBLIC_API(void)
JSD_ClearScriptProfileData(JSDContext* jsdc, JSDScript *script)
{

View File

@ -327,6 +327,27 @@ JSD_GetScriptMaxExecutionTime(JSDContext* jsdc, JSDScript *script);
extern JSD_PUBLIC_API(jsdouble)
JSD_GetScriptTotalExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the shortest execution time recorded, excluding time spent in called
* functions.
*/
extern JSD_PUBLIC_API(jsdouble)
JSD_GetScriptMinOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the longest execution time recorded, excluding time spent in called
* functions.
*/
extern JSD_PUBLIC_API(jsdouble)
JSD_GetScriptMaxOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Get the total amount of time spent in this script, excluding time spent
* in called functions.
*/
extern JSD_PUBLIC_API(jsdouble)
JSD_GetScriptTotalOwnExecutionTime(JSDContext* jsdc, JSDScript *script);
/*
* Clear profile data for this script.
*/