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