Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Functions | Variables
trace.cpp File Reference
#include <windows.h>
#include <imagehlp.h>
#include <stdio.h>
#include "pldhash.h"

Go to the source code of this file.

Classes

class  Reporter
struct  CallEntry
class  Node
struct  ModulesEntry

Defines

#define HIT_INTERVAL   1000

Functions

static void Log (void *addr)
 __declspec (naked dllexport) void _penter()
static PLDHashOperator PR_CALLBACK DumpFiles (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg)
static PLDHashOperator PR_CALLBACK ListCounts (PLDHashTable *table, PLDHashEntryHdr *hdr, PRUint32 number, void *arg)

Variables

static Reporter theReporter
static FILElogfile
static PLDHashTable Calls
static PLDHashTableOps Ops
static PLDHashTable Modules
static PLDHashTableOps ModOps

Class Documentation

struct CallEntry

Definition at line 89 of file trace.cpp.

Class Members
const void * addr
unsigned count
unsigned hits
DWORD tick
struct ModulesEntry

Definition at line 125 of file trace.cpp.

Collaboration diagram for ModulesEntry:
Class Members
Node * byCount
char * moduleName

Define Documentation

#define HIT_INTERVAL   1000

Definition at line 74 of file trace.cpp.


Function Documentation

__declspec ( naked  dllexport)

Definition at line 192 of file trace.cpp.

{
    __asm {
        push ecx               // save ecx for caller
        push dword ptr [esp+4] // the caller's address is the only param
        call Log               // ...to Log()
        add  esp,4
        pop  ecx               // restore ecx for caller
        ret
    }
}

Here is the call graph for this function:

static PLDHashOperator PR_CALLBACK DumpFiles ( PLDHashTable table,
PLDHashEntryHdr hdr,
PRUint32  number,
void arg 
) [static]

Definition at line 211 of file trace.cpp.

{
    ModulesEntry* entry = (ModulesEntry*) hdr;    
    Node*         cur = entry->byCount;
    char          dest[MAX_PATH];
    char          pdbName[MAX_PATH];
    FILE*         orderFile;

    strcpy(pdbName, entry->moduleName);
    strcat(pdbName, ".pdb");

    if (!::SearchTreeForFile(MOZ_SRC, pdbName, dest) ) {
        fprintf(logfile,"+++ERROR Could not find %s\n",pdbName);
        return PL_DHASH_NEXT;
    }
    dest[strlen(dest)-strlen(pdbName)-strlen("WIN32_D.OBJ\\")] = 0;
    strcat(dest,"win32.order");
    orderFile = fopen(dest,"w");
    fprintf(logfile,"Creating order file %s\n",dest);
    
    while (cur) {
        if (cur->function[0] == '_')  // demangle "C" style function names
            fprintf(orderFile,"%s ; %d %d\n", cur->function+1, cur->hits, cur->count );
        else
            fprintf(orderFile,"%s ; %d %d\n", cur->function, cur->hits, cur->count );
        cur = cur->next;
    }

    fflush(orderFile);
    fclose(orderFile);
    return PL_DHASH_NEXT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PLDHashOperator PR_CALLBACK ListCounts ( PLDHashTable table,
PLDHashEntryHdr hdr,
PRUint32  number,
void arg 
) [static]

Definition at line 251 of file trace.cpp.

{
    BOOL ok;
    CallEntry* entry = (CallEntry*) hdr;

    IMAGEHLP_MODULE module;
    module.SizeOfStruct = sizeof(module);

    ok = ::SymGetModuleInfo(::GetCurrentProcess(),
                            (unsigned) entry->addr,
                            &module);

    char buf[sizeof(IMAGEHLP_SYMBOL) + 512];
    PIMAGEHLP_SYMBOL symbol = (PIMAGEHLP_SYMBOL) buf;
    symbol->SizeOfStruct = sizeof(buf);
    symbol->MaxNameLength = 512;

    DWORD displacement;
    ok = ::SymGetSymFromAddr(::GetCurrentProcess(),
                             (unsigned) entry->addr,
                             &displacement,
                             symbol);

    if (ok)
    {
        if (displacement > 0) 
            return PL_DHASH_NEXT;
        static int modInitialized = 0;
        if (!modInitialized) {
            modInitialized = PL_DHashTableInit(&Modules, &ModOps, 0, sizeof(ModulesEntry), 16);
            if (!modInitialized)
                return PL_DHASH_NEXT;
        }

        ModulesEntry* mod
            = (ModulesEntry*) PL_DHashTableOperate(&Modules,
                                                   module.ModuleName,
                                                   PL_DHASH_ADD);
        if (!mod)
            return PL_DHASH_STOP;       // OOM

        if (!mod->moduleName) {
            mod->moduleName = strdup(module.ModuleName);
            mod->byCount = new Node();
            mod->byCount->function = strdup(symbol->Name);
            mod->byCount->count = entry->count;
            mod->byCount->hits = entry->hits;
        } else {
            // insertion sort.
            Node* cur = mod->byCount;
            Node* foo = new Node();
            foo->function = strdup(symbol->Name);
            foo->count = entry->count;
            foo->hits = entry->hits;

            if
#if defined(SORT_BY_CALL_COUNT)
                (cur->count < entry->count)
#else
                ((cur->hits < entry->hits) || (cur->hits == entry->hits && cur->count < entry->count))
#endif
            {
                if (!strcmp(cur->function,symbol->Name)) 
                    return PL_DHASH_NEXT;
                foo->next = mod->byCount;
                mod->byCount = foo;                
            } else {
                while (cur->next) {
                    if (!strcmp(cur->function,symbol->Name)) 
                        return PL_DHASH_NEXT;
                    if
#if defined(SORT_BY_CALL_COUNT)
                        (cur->next->count > entry->count)
#else
                        ((cur->next->hits > entry->hits) || (cur->next->hits == entry->hits && cur->next->count > entry->count))
#endif
                    { cur = cur->next; }
                    else { break; }
                }
                foo->next = cur->next;  
                cur->next = foo;
            }
        }
    } // if (ok)
    return PL_DHASH_NEXT;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void Log ( void addr) [static]

Definition at line 148 of file trace.cpp.

{
static int initialized = 0;

    addr = (void*) ((unsigned) addr - 5);

    if (!initialized) {
        initialized = PL_DHashTableInit(&Calls, &Ops, 0, sizeof(CallEntry), 16);
        if (!initialized) 
            return;
    }

    entry = (CallEntry*) PL_DHashTableOperate(&Calls, addr, PL_DHASH_ADD);
    if (!entry)
        return; // OOM

    if (!entry->addr)
        entry->addr = addr;

    //
    //  Another call recorded.
    //
    ++entry->count;

    //
    // Only record a hit if the appropriate amount of time has passed.
    //
    DWORD curtick = GetTickCount();
    if(curtick >= (entry->tick + HIT_INTERVAL))
    {
        //
        //  Record the interval hit.
        //  Update the tick.
        //
        entry->hits++;
        entry->tick = curtick;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

PLDHashTable Calls [static]

Definition at line 87 of file trace.cpp.

FILE* logfile [static]

Definition at line 82 of file trace.cpp.

Definition at line 123 of file trace.cpp.

PLDHashTableOps Ops [static]

Definition at line 81 of file trace.cpp.