Back to index

lightning-sunbird  0.9+nobinonly
Functions
jsd_step.c File Reference
#include "jsd.h"

Go to the source code of this file.

Functions

JSBool _callHook (JSDContext *jsdc, JSContext *cx, JSStackFrame *fp, JSBool before, uintN type, JSD_CallHookProc hook, void *hookData)
void *JS_DLL_CALLBACK jsd_FunctionCallHook (JSContext *cx, JSStackFrame *fp, JSBool before, JSBool *ok, void *closure)
void *JS_DLL_CALLBACK jsd_TopLevelCallHook (JSContext *cx, JSStackFrame *fp, JSBool before, JSBool *ok, void *closure)

Function Documentation

JSBool _callHook ( JSDContext jsdc,
JSContext cx,
JSStackFrame fp,
JSBool  before,
uintN  type,
JSD_CallHookProc  hook,
void hookData 
)

Definition at line 112 of file jsd_step.c.

{
    JSDScript*        jsdscript;
    JSScript*         jsscript;
    JSBool            hookresult = JS_TRUE;
    
    if (!jsdc || !jsdc->inited)
        return JS_FALSE;

    if (!hook && !(jsdc->flags & JSD_COLLECT_PROFILE_DATA) &&
        jsdc->flags & JSD_DISABLE_OBJECT_TRACE)
    {
        /* no hook to call, no profile data needs to be collected, and
         * the client has object tracing disabled, so there is nothing
         * to do here.
         */
        return hookresult;
    }
    
    if (before && JS_IsConstructorFrame(cx, fp))
        jsd_Constructing(jsdc, cx, JS_GetFrameThis(cx, fp), fp);

    jsscript = JS_GetFrameScript(cx, fp);
    if (jsscript)
    {
        JSD_LOCK_SCRIPTS(jsdc);
        jsdscript = jsd_FindJSDScript(jsdc, jsscript);
        JSD_UNLOCK_SCRIPTS(jsdc);
    
        if (jsdscript)
        {
            if (JSD_IS_PROFILE_ENABLED(jsdc, jsdscript))
            {
                JSDProfileData *pdata;
                pdata = jsd_GetScriptProfileData (jsdc, jsdscript);
                if (pdata)
                {
                    if (before)
                    {
                        if (JSLL_IS_ZERO(pdata->lastCallStart))
                        {
                            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);
                                }
                                JSLL_ADD(callerpdata->runningTime, callerpdata->runningTime, ll_delta);
                            }
                            /* We're the new current function, and no return
                             * has happened yet. */
                            jsdc->callingFunctionPData = pdata;
                            jsdc->lastReturnTime = JSLL_ZERO;
                            /* 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 &&
                               !JSLL_IS_ZERO(pdata->lastCallStart)) {
                        int64 now, ll_delta;
                        jsdouble delta;
                        now = JS_Now();
                        JSLL_SUB(ll_delta, now, pdata->lastCallStart);
                        JSLL_L2D(delta, ll_delta);
                        delta /= 1000.0;
                        pdata->totalExecutionTime += delta;
                        /* 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);
                            JSLL_ADD(pdata->runningTime, 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) {
                        --pdata->recurseDepth;
                        ++pdata->callCount;
                    }
                }
                if (hook)
                    jsd_CallCallHook (jsdc, cx, type, hook, hookData);
            } else {
                if (hook)
                    hookresult = 
                        jsd_CallCallHook (jsdc, cx, type, hook, hookData);
                else
                    hookresult = JS_TRUE;
            }
        }
    }

#ifdef JSD_TRACE
    _interpreterTrace(jsdc, cx, fp, before);
    return JS_TRUE;
#else
    return hookresult;
#endif

}

Here is the call graph for this function:

Here is the caller graph for this function:

void* JS_DLL_CALLBACK jsd_FunctionCallHook ( JSContext cx,
JSStackFrame fp,
JSBool  before,
JSBool ok,
void closure 
)

Definition at line 270 of file jsd_step.c.

{
    JSDContext*       jsdc;
    JSD_CallHookProc  hook;
    void*             hookData;

    jsdc = (JSDContext*) closure;
    
    /* local in case jsdc->functionHook gets cleared on another thread */
    JSD_LOCK();
    hook     = jsdc->functionHook;
    hookData = jsdc->functionHookData;
    JSD_UNLOCK();
    
    if (_callHook (jsdc, cx, fp, before,
                   (before) ? JSD_HOOK_FUNCTION_CALL : JSD_HOOK_FUNCTION_RETURN,
                   hook, hookData))
    {
        return closure;
    }
    
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void* JS_DLL_CALLBACK jsd_TopLevelCallHook ( JSContext cx,
JSStackFrame fp,
JSBool  before,
JSBool ok,
void closure 
)

Definition at line 296 of file jsd_step.c.

{
    JSDContext*       jsdc;
    JSD_CallHookProc  hook;
    void*             hookData;

    jsdc = (JSDContext*) closure;

    /* local in case jsdc->toplevelHook gets cleared on another thread */
    JSD_LOCK();
    hook     = jsdc->toplevelHook;
    hookData = jsdc->toplevelHookData;
    JSD_UNLOCK();
    
    if (_callHook (jsdc, cx, fp, before,
                   (before) ? JSD_HOOK_TOPLEVEL_START : JSD_HOOK_TOPLEVEL_END,
                   hook, hookData))
    {
        return closure;
    }
    
    return NULL;
    
}

Here is the call graph for this function:

Here is the caller graph for this function: