home *** CD-ROM | disk | FTP | other *** search
- // callprof.cpp
- //
- // Created 01/06/98
- //
- // (C) Copyright 1995 - 1999 Microsoft Corporation. All rights reserved.
- //
-
- #include "project.hpp"
- #pragma hdrstop
-
- #include "callprof.hpp"
- #include "jviewprf.hpp"
- #include "utils.hpp"
-
-
- BOOL CallProfiler::CompareEntries (CallProfilerEntry *ent1, CallProfilerEntry *ent2)
- {
- if (g_ProfOptions & OPT_PROF_CALLS)
- return ent1->TotalExclusiveTime > ent2->TotalExclusiveTime;
- else
- return ent1->nSamples > ent2->nSamples;
- }
-
-
- VOID CallProfiler::LinkEntryInSortOrder (CallProfilerEntry *ent)
- {
- CallProfilerEntry **prev = &m_list;
- CallProfilerEntry *cur;
-
- while (1)
- {
- cur = *prev;
- if (cur == NULL)
- break;
-
- if (CompareEntries(ent, cur))
- break;
-
- prev = &cur->listnext;
- }
-
- *prev = ent;
- ent->listnext = cur;
- }
-
-
- VOID CallProfiler::SortEntries ()
- {
- for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
- {
- CallProfilerEntry *cur = m_hash[i];
- while (cur != NULL)
- {
- LinkEntryInSortOrder(cur);
-
- cur = cur->next;
- }
- }
- }
-
-
- //static
- VOID CallProfiler::MarkIncompleteMethodsCB (ThreadRecord *pThread, PVOID token)
- {
- ULONG *pfAnyIncomplete = (ULONG*)token;
-
- CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
- if (pent)
- {
- pent->fIncomplete = TRUE;
- *pfAnyIncomplete = 1;
- }
- }
-
-
- HRESULT CallProfiler::Initialize (EventMonitor *pmon)
- {
- (m_pmon = pmon)->AddRef();
-
- return S_OK;
- }
-
-
- VOID CallProfiler::Destruct ()
- {
- for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
- {
- CallProfilerEntry *cur = m_hash[i];
- while (cur != NULL)
- {
- CallProfilerEntry *trash = cur;
- cur = cur->next;
- delete(trash);
- }
- }
-
- DeleteCriticalSection(&m_cs);
-
- if (m_pmon)
- m_pmon->Release();
- }
-
-
- VOID CallProfiler::ResumeMethod (ThreadRecord *pThread, MethodID id, BOOL fJustCalled)
- {
- PROFTIME EventTime = GetProfilerTime();
-
- CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
-
- if (pent)
- {
- InterlockedAdd(&pent->TotalExclusiveTime, EventTime - pThread->calldata.StartTime);
- pThread->calldata.pentCurMethod = NULL;
- }
-
- if (id != NULL)
- {
- pent = LookupMethod(id, fJustCalled);
- if (pent)
- {
- if (fJustCalled)
- {
- InterlockedIncrement(&pent->nCalls);
- }
-
- pThread->calldata.pentCurMethod = pent;
- pThread->calldata.StartTime = GetProfilerTime();
- }
- }
- }
-
-
- VOID CallProfiler::ExitMethod (ThreadRecord *pThread)
- {
- PROFTIME EventTime = GetProfilerTime();
-
- CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
-
- if (pent)
- {
- InterlockedAdd(&pent->TotalExclusiveTime, EventTime - pThread->calldata.StartTime);
-
- pThread->calldata.pentCurMethod = NULL;
- }
- }
-
-
- VOID CallProfiler::ExceptionThrown (ThreadRecord *pThread)
- {
- if (!(g_ProfOptions & OPT_PROF_CALLS))
- return;
-
- CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
-
- if (pent)
- {
- ExitMethod(pThread);
-
- InterlockedIncrement(&pent->nExceptionsThrown);
- }
- }
-
-
- VOID CallProfiler::SpewResults ()
- {
- // We collect the info anyways, but since it's lengthy, if the user
- // doesn't want it we won't display it.
- if (!(g_ProfOptions & OPT_CALL_TIMES))
- return;
-
-
- SortEntries();
-
- CallProfilerEntry *cur = m_list;
- if (!cur)
- return;
-
- ULONG fAnyIncomplete = 0;
-
- m_pmon->IterateThreads(&MarkIncompleteMethodsCB, &fAnyIncomplete);
-
- #define WIDTH_EXEC_MODEL 4
- #define WIDTH_NUM_CALLS 5
- #define WIDTH_NUM_EXCEPTIONS 6
- #define WIDTH_TIME 10
-
- #define TOTAL_WIDTH_FIXED_FIELDS (1+WIDTH_EXEC_MODEL+1+WIDTH_NUM_CALLS+1+WIDTH_NUM_EXCEPTIONS+1+WIDTH_TIME)
-
- WriteOutputExArgs args;
-
- args.Width = TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete;
- args.PctFreeSpaceToUse = 100;
-
- WriteOutputEx(WRITE_FIT, &args, "Method");
-
- WriteOutput(" Type Calls Throws Time\n");
-
- IJavaEventMonitorIDInfo *pinfo = m_pmon->GetVMInfoIfc();
-
- do
- {
- PSTR pszMethodUtf8;
- JAVA_EXECUTION_MODEL exec;
- if (SUCCEEDED(pinfo->MethodInformation(cur->id, &pszMethodUtf8, NULL, &exec, NULL, NULL)))
- {
- WriteOutputFitString(WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete, 100, pszMethodUtf8);
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_EXEC_MODEL, StringForExecutionModel(exec));
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_NUM_CALLS, cur->nCalls);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_NUM_EXCEPTIONS, cur->nExceptionsThrown);
- WriteOutputFixedFloat(0, ConvertProfilerTimeToUS(cur->TotalExclusiveTime), 2);
- WriteOutput(cur->fIncomplete ? "*\n" : "\n");
-
- CoTaskMemFree(pszMethodUtf8);
- }
- cur = cur->listnext;
- }
- while (cur);
-
- if (fAnyIncomplete)
- WriteOutput("* = last call did not complete before process terminated\n");
- }
-
-