home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Profiler / jviewprf / calltrac.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  9.2 KB  |  355 lines

  1. // calltrac.cpp
  2. //
  3. // Created 01/18/99
  4. //
  5. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  6. //
  7.  
  8. #include "project.hpp"
  9. #pragma hdrstop
  10.  
  11. #include "calltrac.hpp"
  12. #include "jviewprf.hpp"
  13.  
  14.  
  15. void CallTracer::PrintStackLeader (ThreadRecord *pThread)
  16. {
  17.     WriteOutputFmt("%8x ", pThread->tid);
  18.  
  19.     ULONG indent = pThread->tracedata.nStackFrames;
  20.  
  21.     // Don't let the indentation get out of hand, bloating output files.
  22.     if (indent < g_OutputWidth)
  23.     {
  24.         while (indent--)
  25.             WriteOutput(" ", 1);
  26.     }
  27. }
  28.  
  29.  
  30. VOID CallTracer::SpewValue (CHAR chsig, PVOID pvalue)
  31. {
  32.     INT i;
  33.     
  34.     switch (chsig)
  35.     {
  36.     case '[':
  37.     case 'L':
  38.         {
  39.             ObjectID objid = *(ObjectID*)pvalue;
  40.             if (objid == NULL)
  41.             {
  42.                 WriteOutput("null");
  43.             }
  44.             else
  45.             {
  46.                 ClassID clsid;
  47.                 HRESULT hr = m_pmon->GetVMInfoIfc()->ObjectInformation(objid, &clsid);
  48.                 if (hr == S_OK)
  49.                 {
  50.                     IJavaEventMonitorIDInfo2 *pinfo2 = m_pmon->GetVMInfoIfc2();
  51.                     if (pinfo2 != NULL)
  52.                     {
  53.                         PWSTR descr;
  54.                         hr = pinfo2->DescribeObject(objid, &descr);
  55.                         if (hr == S_OK)
  56.                         {
  57.                             WriteOutputW(descr);
  58.                         
  59.                             CoTaskMemFree(descr);
  60.                         }
  61.                         else
  62.                         {
  63.                             goto USE_CLSNAME_FOR_DESCR;
  64.                         }
  65.                     }
  66.                     else
  67.                     {
  68.                 USE_CLSNAME_FOR_DESCR:
  69.                 
  70.                         PSTR pszClassUtf8;
  71.                         hr = m_pmon->GetVMInfoIfc()->ClassInformation(clsid, &pszClassUtf8, NULL, NULL, NULL, NULL);
  72.                         if (hr == S_OK)
  73.                         {
  74.                             WriteOutputUtf8(pszClassUtf8);
  75.  
  76.                             if ((g_ProfOptions & OPT_VERBOSE) && pszClassUtf8[0] == '[')
  77.                             {
  78.                                 // TODO: spew array elements
  79.                             }
  80.  
  81.                             CoTaskMemFree(pszClassUtf8);
  82.                         }
  83.                     }
  84.                 }
  85.             }
  86.         }
  87.         break;
  88.         
  89.     case 'Z':
  90.         WriteOutput(*(BOOL*)pvalue ? "true" : "false");
  91.         break;
  92.  
  93.     case 'C': {
  94.         WCHAR rgwch[2];
  95.         rgwch[0] = *(WCHAR*)pvalue;
  96.         rgwch[1] = L'\0';
  97.         WriteOutputW(rgwch);
  98.         break; }
  99.  
  100.     case 'J': {
  101.         __int64 val = *(__int64*)pvalue;
  102.         if (val < INT_MAX)
  103.             WriteOutputFmt("%d", (int)val);
  104.         else
  105.             WriteOutputFmt("0x%x%08x", (int)(val >> 32), (int)val);
  106.         break; }
  107.  
  108.     case 'D':
  109.         WriteOutputFloat(0, *(double*)pvalue);
  110.         break;
  111.  
  112.     case 'F':
  113.         WriteOutputFloat(0, *(float*)pvalue);
  114.         break;
  115.  
  116.     case 'B':
  117.         i = *(BYTE*)pvalue;
  118.         goto PRINT_INT;
  119.         
  120.     case 'S':
  121.         i = *(SHORT*)pvalue;
  122.         goto PRINT_INT;
  123.         
  124.     case 'I':
  125.         i = *(INT*)pvalue;
  126.     PRINT_INT:
  127.         WriteOutputFmt("%d", i);
  128.         break;
  129.  
  130.     case 'V':
  131.         break;
  132.     }
  133. }
  134.  
  135. int NextSigElement (PCSTR *ppszsig)
  136. {
  137.     int nslots = 1;
  138.     PCSTR psznext = *ppszsig;
  139.     CHAR chsig = *psznext;
  140.     if (chsig == 'L')
  141.     {
  142.     findsigend:
  143.         while (*++psznext != ';');
  144.     }
  145.     else if (chsig == '[')
  146.     {
  147.         while (1)
  148.         {
  149.             chsig = *psznext;
  150.             if (chsig != '[')
  151.                 break;
  152.             psznext++;
  153.         }
  154.         if (chsig == 'L')
  155.             goto findsigend;
  156.     }
  157.     else if (chsig == 'J' || chsig == 'D')
  158.     {
  159.         nslots = 2;
  160.     }
  161.     *ppszsig = psznext+1;
  162.     return nslots;
  163. }
  164.  
  165.  
  166. VOID CallTracer::SpewParams (ThreadRecord *pThread, MethodID method_id, StackID stack_id, ClassID idMethodClass, PCSTR pcszMethodName)
  167. {
  168.     IJavaEventMonitorIDInfo3 *pinfo3 = m_pmon->GetVMInfoIfc3();
  169.     if (pinfo3 != NULL)
  170.     {
  171.         DWORD *pparams;
  172.         JVM_CALLING_CONVENTION callconv;
  173.         DWORD flags;
  174.         if (SUCCEEDED(pinfo3->GetMethodEntryParameters(&pparams, NULL, &callconv, &flags)))
  175.         {
  176.             if (callconv == JVM_CALL_PASCAL)
  177.             {
  178.                 PCSTR pszsig = pcszMethodName;
  179.                 while (*pszsig++ != '(');
  180.  
  181.                 PCSTR pszsigtmp = pszsig;
  182.                 int totalparamslots = 0;
  183.                 while (*pszsigtmp != ')')
  184.                     totalparamslots += NextSigElement(&pszsigtmp);
  185.  
  186.                 if (totalparamslots)
  187.                 {
  188.                     PrintStackLeader(pThread);
  189.  
  190.                     WriteOutput("parameters: ");
  191.  
  192.                     pparams += totalparamslots;
  193.  
  194.                     pszsigtmp = pszsig;
  195.                     do
  196.                     {
  197.                         if (pszsigtmp != pszsig)
  198.                             WriteOutput(", ");
  199.  
  200.                         CHAR chvalsig = *pszsigtmp;
  201.  
  202.                         pparams -= NextSigElement(&pszsigtmp);
  203.  
  204.                         SpewValue(chvalsig, pparams);
  205.                     }
  206.                     while (*pszsigtmp != ')');
  207.  
  208.                     WriteOutput("\n");
  209.                 }
  210.  
  211.                 if (flags & JVM_CALL_THIS)
  212.                 {
  213.                     DWORD *pThis = pparams+totalparamslots;
  214.                     
  215.                     ObjectID idThis = *(ObjectID*)pThis;
  216.  
  217.                     ClassID idThisClass = NULL;
  218.  
  219.                     if (   FAILED(pinfo3->ObjectInformation(idThis, &idThisClass))
  220.                         || idThisClass != idMethodClass)
  221.                     {
  222.                         PrintStackLeader(pThread);
  223.                         
  224.                         WriteOutput("this: ");
  225.                         SpewValue('L', pThis);
  226.                         WriteOutput("\n");
  227.                     }
  228.                 }
  229.             }
  230.         }
  231.     }
  232. }
  233.  
  234.  
  235. VOID CallTracer::SpewReturnValue ()
  236. {
  237.     MethodID exiting_method_id;
  238.     __int64 *pretval;
  239.  
  240.     IJavaEventMonitorIDInfo3 *pinfo3 = m_pmon->GetVMInfoIfc3();
  241.  
  242.     HRESULT hr = pinfo3->GetMethodExitReturnValue(&exiting_method_id, &pretval);
  243.     if (SUCCEEDED(hr))
  244.     {
  245.         WriteOutput("return value: ");
  246.         if (hr == S_FALSE)
  247.         {
  248.             WriteOutput("void\n");
  249.         }
  250.         else
  251.         {
  252.             PSTR pszMethodUtf8;
  253.             hr = pinfo3->MethodInformation(exiting_method_id, &pszMethodUtf8, NULL, NULL, NULL, NULL);
  254.             if (hr == S_OK)
  255.             {
  256.                 PSTR retsig = pszMethodUtf8;
  257.                 while (*retsig++ != ')');
  258.                 SpewValue(*retsig, pretval);
  259.  
  260.                 CoTaskMemFree(pszMethodUtf8);
  261.             }
  262.  
  263.             WriteOutput("\n");
  264.         }
  265.     }
  266. }
  267.  
  268.  
  269. HRESULT CallTracer::Initialize (EventMonitor *pmon)
  270. {
  271.     (m_pmon = pmon)->AddRef();
  272.     return S_OK;
  273. }
  274.  
  275. VOID CallTracer::Destruct ()
  276. {
  277.     if (m_pmon)
  278.         m_pmon->Release();
  279. }
  280.  
  281.  
  282. VOID CallTracer::OnEnterMethod (ThreadRecord *pThread, MethodID method_id, StackID stack_id)
  283. {
  284.     if (g_ProfOptions & OPT_CALL_TRACE)
  285.     {
  286.         PSTR pszMethodUtf8 = NULL;
  287.         ClassID class_id;
  288.         JAVA_EXECUTION_MODEL jem;
  289.         if (SUCCEEDED(m_pmon->GetVMInfoIfc()->MethodInformation(method_id, &pszMethodUtf8, &class_id, &jem, NULL, NULL)))
  290.         {
  291.             PCSTR pcszExecModel;
  292.  
  293.             switch (jem)
  294.             {
  295.                 case JVM_EXECUTION_JIT_COMPILED:
  296.                     pcszExecModel = "JIT-compiled";
  297.                     break;
  298.  
  299.                 case JVM_EXECUTION_NATIVE:
  300.                     pcszExecModel = "native";
  301.                     break;
  302.  
  303.                 case JVM_EXECUTION_INTERPRETED:
  304.                     pcszExecModel = "interpreted";
  305.                     break;
  306.  
  307.                 case JVM_EXECUTION_FAST_INTERPRETED:
  308.                     pcszExecModel = "fast interpreted";
  309.                     break;
  310.  
  311.                 case JVM_EXECUTION_COM:
  312.                     pcszExecModel = "COM";
  313.                     break;
  314.  
  315.                 default:
  316.                     pcszExecModel = "UNKNOWN";
  317.                     break;
  318.             }
  319.  
  320.             PrintStackLeader(pThread);
  321.  
  322.             WriteOutputUtf8(pszMethodUtf8);
  323.             WriteOutputFmt(" [%s]\n", pcszExecModel);
  324.         }
  325.  
  326.         pThread->tracedata.nStackFrames++;
  327.  
  328.         if (pszMethodUtf8)
  329.         {
  330.             if (g_ProfOptions & OPT_CALL_TRACE_PARAMS)
  331.             {
  332.                 SpewParams(pThread, method_id, stack_id, class_id, pszMethodUtf8);
  333.             }
  334.  
  335.             CoTaskMemFree(pszMethodUtf8);
  336.         }
  337.     }
  338. }
  339.  
  340. VOID CallTracer::OnMethodExit (ThreadRecord *pThread, MethodID method_id, StackID stack_id)
  341. {
  342.     if (g_ProfOptions & OPT_CALL_TRACE)
  343.     {
  344.         PrintStackLeader(pThread);
  345.  
  346.         if (g_ProfOptions & OPT_CALL_TRACE_PARAMS)
  347.             SpewReturnValue();
  348.         else
  349.             WriteOutput("returned\n");
  350.  
  351.         pThread->tracedata.nStackFrames--;
  352.     }
  353. }
  354.  
  355.