home *** CD-ROM | disk | FTP | other *** search
/ Enter 1999 November / ENTER11_1.bin / WARSZTAT / SDKJava32.exe / data1.cab / fg_Samples / Samples / Profiler / jviewprf / callprof.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-17  |  5.2 KB  |  218 lines

  1. // callprof.cpp
  2. //
  3. // Created 01/06/98
  4. //
  5. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  6. //
  7.  
  8. #include "project.hpp"
  9. #pragma hdrstop
  10.  
  11. #include "callprof.hpp"
  12. #include "jviewprf.hpp"
  13. #include "utils.hpp"
  14.  
  15.  
  16. BOOL CallProfiler::CompareEntries (CallProfilerEntry *ent1, CallProfilerEntry *ent2)
  17. {
  18.     if (g_ProfOptions & OPT_PROF_CALLS)
  19.         return ent1->TotalExclusiveTime > ent2->TotalExclusiveTime;
  20.     else
  21.         return ent1->nSamples > ent2->nSamples;
  22. }
  23.  
  24.  
  25. VOID CallProfiler::LinkEntryInSortOrder (CallProfilerEntry *ent)
  26. {
  27.     CallProfilerEntry **prev = &m_list;
  28.     CallProfilerEntry *cur;
  29.  
  30.     while (1)
  31.     {
  32.         cur = *prev;
  33.         if (cur == NULL)
  34.             break;
  35.  
  36.         if (CompareEntries(ent, cur))
  37.             break;
  38.  
  39.         prev = &cur->listnext;
  40.     }
  41.  
  42.     *prev = ent;
  43.     ent->listnext = cur;
  44. }
  45.  
  46.  
  47. VOID CallProfiler::SortEntries ()
  48. {
  49.     for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
  50.     {
  51.         CallProfilerEntry *cur = m_hash[i];
  52.         while (cur != NULL)
  53.         {
  54.             LinkEntryInSortOrder(cur);
  55.  
  56.             cur = cur->next;
  57.         }
  58.     }
  59. }
  60.  
  61.  
  62. //static
  63. VOID CallProfiler::MarkIncompleteMethodsCB (ThreadRecord *pThread, PVOID token)
  64. {
  65.     ULONG *pfAnyIncomplete = (ULONG*)token;
  66.  
  67.     CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
  68.     if (pent)
  69.     {
  70.         pent->fIncomplete = TRUE;
  71.         *pfAnyIncomplete = 1;
  72.     }
  73. }
  74.  
  75.  
  76. HRESULT CallProfiler::Initialize (EventMonitor *pmon)
  77. {
  78.     (m_pmon = pmon)->AddRef();
  79.  
  80.     return S_OK;
  81. }
  82.  
  83.  
  84. VOID CallProfiler::Destruct ()
  85. {
  86.     for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
  87.     {
  88.         CallProfilerEntry *cur = m_hash[i];
  89.         while (cur != NULL)
  90.         {
  91.             CallProfilerEntry *trash = cur;
  92.             cur = cur->next;
  93.             delete(trash);
  94.         }
  95.     }
  96.  
  97.     DeleteCriticalSection(&m_cs);
  98.  
  99.     if (m_pmon)
  100.         m_pmon->Release();
  101. }
  102.  
  103.  
  104. VOID CallProfiler::ResumeMethod (ThreadRecord *pThread, MethodID id, BOOL fJustCalled)
  105. {
  106.     PROFTIME EventTime = GetProfilerTime();
  107.  
  108.     CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
  109.  
  110.     if (pent)
  111.     {
  112.         InterlockedAdd(&pent->TotalExclusiveTime, EventTime - pThread->calldata.StartTime);
  113.         pThread->calldata.pentCurMethod = NULL;
  114.     }
  115.  
  116.     if (id != NULL)
  117.     {
  118.         pent = LookupMethod(id, fJustCalled);
  119.         if (pent)
  120.         {
  121.             if (fJustCalled)
  122.             {
  123.                 InterlockedIncrement(&pent->nCalls);
  124.             }
  125.  
  126.             pThread->calldata.pentCurMethod = pent;
  127.             pThread->calldata.StartTime = GetProfilerTime();
  128.         }
  129.     }
  130. }
  131.  
  132.  
  133. VOID CallProfiler::ExitMethod (ThreadRecord *pThread)
  134. {
  135.     PROFTIME EventTime = GetProfilerTime();
  136.  
  137.     CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
  138.  
  139.     if (pent)
  140.     {
  141.         InterlockedAdd(&pent->TotalExclusiveTime, EventTime - pThread->calldata.StartTime);
  142.  
  143.         pThread->calldata.pentCurMethod = NULL;
  144.     }
  145. }
  146.  
  147.  
  148. VOID CallProfiler::ExceptionThrown (ThreadRecord *pThread)
  149. {
  150.     if (!(g_ProfOptions & OPT_PROF_CALLS))
  151.         return;
  152.  
  153.     CallProfilerEntry *pent = pThread->calldata.pentCurMethod;
  154.  
  155.     if (pent)
  156.     {
  157.         ExitMethod(pThread);
  158.  
  159.         InterlockedIncrement(&pent->nExceptionsThrown);
  160.     }
  161. }
  162.  
  163.  
  164. VOID CallProfiler::SpewResults ()
  165. {
  166.     // We collect the info anyways, but since it's lengthy, if the user
  167.     // doesn't want it we won't display it.
  168.     if (!(g_ProfOptions & OPT_CALL_TIMES))
  169.         return;
  170.  
  171.  
  172.     SortEntries();
  173.  
  174.     CallProfilerEntry *cur = m_list;
  175.     if (!cur)
  176.         return;
  177.  
  178.     ULONG fAnyIncomplete = 0;
  179.  
  180.     m_pmon->IterateThreads(&MarkIncompleteMethodsCB, &fAnyIncomplete);
  181.  
  182. #define WIDTH_EXEC_MODEL        4
  183. #define WIDTH_NUM_CALLS         5
  184. #define WIDTH_NUM_EXCEPTIONS    6
  185. #define WIDTH_TIME              10
  186.  
  187. #define TOTAL_WIDTH_FIXED_FIELDS (1+WIDTH_EXEC_MODEL+1+WIDTH_NUM_CALLS+1+WIDTH_NUM_EXCEPTIONS+1+WIDTH_TIME)
  188.  
  189.     WriteOutputEx(WRITE_FIT, "s", TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete, 1.0, "Method");
  190.     WriteOutput(" Type Calls Throws Time\n");
  191.  
  192.     IJavaEventMonitorIDInfo *pinfo = m_pmon->GetVMInfoIfc();
  193.  
  194.     do
  195.     {
  196.         PSTR pszMethodUtf8;
  197.         JAVA_EXECUTION_MODEL exec;
  198.         if (SUCCEEDED(pinfo->MethodInformation(cur->id, &pszMethodUtf8, NULL, &exec, NULL, NULL)))
  199.         {
  200.             WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8, "s ", TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete, 1.0, pszMethodUtf8);
  201.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "c ", WIDTH_EXEC_MODEL, CharForExecutionModel(exec));
  202.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_NUM_CALLS, cur->nCalls);
  203.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_NUM_EXCEPTIONS, cur->nExceptionsThrown);
  204.  
  205.             float time = (float)cur->TotalExclusiveTime;
  206.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, ".2f%s", WIDTH_TIME, ConvertProfilerTimeToUS(time), cur->fIncomplete ? "*\n" : "\n");
  207.  
  208.             CoTaskMemFree(pszMethodUtf8);
  209.         }
  210.         cur = cur->listnext;
  211.     }
  212.     while (cur);
  213.  
  214.     if (fAnyIncomplete)
  215.         WriteOutput("* = last call did not complete before process terminated\n");
  216. }
  217.  
  218.