home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Profiler / jviewprf / callprof.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  5.3 KB  |  223 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.     WriteOutputExArgs args;
  190.  
  191.     args.Width = TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete;
  192.     args.PctFreeSpaceToUse = 100;
  193.  
  194.     WriteOutputEx(WRITE_FIT, &args, "Method");
  195.  
  196.     WriteOutput(" Type Calls Throws Time\n");
  197.  
  198.     IJavaEventMonitorIDInfo *pinfo = m_pmon->GetVMInfoIfc();
  199.  
  200.     do
  201.     {
  202.         PSTR pszMethodUtf8;
  203.         JAVA_EXECUTION_MODEL exec;
  204.         if (SUCCEEDED(pinfo->MethodInformation(cur->id, &pszMethodUtf8, NULL, &exec, NULL, NULL)))
  205.         {
  206.             WriteOutputFitString(WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, TOTAL_WIDTH_FIXED_FIELDS+fAnyIncomplete, 100, pszMethodUtf8);
  207.             WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_EXEC_MODEL, StringForExecutionModel(exec));
  208.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_NUM_CALLS, cur->nCalls);
  209.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_NUM_EXCEPTIONS, cur->nExceptionsThrown);
  210.             WriteOutputFixedFloat(0, ConvertProfilerTimeToUS(cur->TotalExclusiveTime), 2);
  211.             WriteOutput(cur->fIncomplete ? "*\n" : "\n");
  212.  
  213.             CoTaskMemFree(pszMethodUtf8);
  214.         }
  215.         cur = cur->listnext;
  216.     }
  217.     while (cur);
  218.  
  219.     if (fAnyIncomplete)
  220.         WriteOutput("* = last call did not complete before process terminated\n");
  221. }
  222.  
  223.