home *** CD-ROM | disk | FTP | other *** search
- // calltrac.cpp
- //
- // Created 01/18/99
- //
- // (C) Copyright 1995 - 1999 Microsoft Corporation. All rights reserved.
- //
-
- #include "project.hpp"
- #pragma hdrstop
-
- #include "calltrac.hpp"
- #include "jviewprf.hpp"
-
-
- void CallTracer::PrintStackLeader (ThreadRecord *pThread)
- {
- WriteOutputFmt("%8x ", pThread->tid);
-
- ULONG indent = pThread->tracedata.nStackFrames;
- while (indent)
- {
- ULONG spcs = indent;
- if (spcs > WRITE_MAX_SIZE_NORM_FMT-1)
- spcs = WRITE_MAX_SIZE_NORM_FMT-1;
- WriteOutputFmt("%*c", spcs, ' ');
- indent -= spcs;
- }
- }
-
-
- VOID CallTracer::SpewValue (CHAR chsig, PVOID pvalue)
- {
- INT i;
-
- switch (chsig)
- {
- case '[':
- case 'L':
- {
- ObjectID objid = *(ObjectID*)pvalue;
- if (objid == NULL)
- {
- WriteOutput("null");
- }
- else
- {
- ClassID clsid;
- HRESULT hr = m_pmon->GetVMInfoIfc()->ObjectInformation(objid, &clsid);
- if (hr == S_OK)
- {
- IJavaEventMonitorIDInfo2 *pinfo2 = m_pmon->GetVMInfoIfc2();
- if (pinfo2 != NULL)
- {
- PWSTR descr;
- hr = pinfo2->DescribeObject(objid, &descr);
- if (hr == S_OK)
- {
- WriteOutputW(descr);
-
- CoTaskMemFree(descr);
- }
- else
- {
- goto USE_CLSNAME_FOR_DESCR;
- }
- }
- else
- {
- USE_CLSNAME_FOR_DESCR:
-
- PSTR pszClassUtf8;
- hr = m_pmon->GetVMInfoIfc()->ClassInformation(clsid, &pszClassUtf8, NULL, NULL, NULL, NULL);
- if (hr == S_OK)
- {
- WriteOutputUtf8(pszClassUtf8);
-
- if ((g_ProfOptions & OPT_VERBOSE) && pszClassUtf8[0] == '[')
- {
- // TODO: spew array elements
- }
-
- CoTaskMemFree(pszClassUtf8);
- }
- }
- }
- }
- }
- break;
-
- case 'Z':
- WriteOutput(*(BOOL*)pvalue ? "true" : "false");
- break;
-
- case 'C':
- WriteOutputFmt("%lc", *(WCHAR*)pvalue);
- break;
-
- case 'J':
- WriteOutputFmt("%I64d", *(__int64*)pvalue);
- break;
-
- case 'D':
- WriteOutputFmt("%lg", *(double*)pvalue);
- break;
-
- case 'F':
- WriteOutputFmt("%g", *(float*)pvalue);
- break;
-
- case 'B':
- i = *(BYTE*)pvalue;
- goto PRINT_INT;
-
- case 'S':
- i = *(SHORT*)pvalue;
- goto PRINT_INT;
-
- case 'I':
- i = *(INT*)pvalue;
- PRINT_INT:
- WriteOutputFmt("%d", i);
- break;
-
- case 'V':
- break;
- }
- }
-
- int NextSigElement (PSTR *ppszsig)
- {
- int nslots = 1;
- PSTR psznext = *ppszsig;
- CHAR chsig = *psznext;
- if (chsig == 'L')
- {
- findsigend:
- psznext = strchr(psznext, ';');
- }
- else if (chsig == '[')
- {
- while (1)
- {
- chsig = *psznext;
- if (chsig != '[')
- break;
- psznext++;
- }
- if (chsig == 'L')
- goto findsigend;
- }
- else if (chsig == 'J' || chsig == 'D')
- {
- nslots = 2;
- }
- *ppszsig = psznext+1;
- return nslots;
- }
-
-
- VOID CallTracer::SpewParams (ThreadRecord *pThread, MethodID method_id, StackID stack_id, ClassID idMethodClass, PCSTR pcszMethodName)
- {
- IJavaEventMonitorIDInfo3 *pinfo3 = m_pmon->GetVMInfoIfc3();
- if (pinfo3 != NULL)
- {
- DWORD *pparams;
- JVM_CALLING_CONVENTION callconv;
- DWORD flags;
- if (SUCCEEDED(pinfo3->GetMethodEntryParameters(&pparams, NULL, &callconv, &flags)))
- {
- if (callconv == JVM_CALL_PASCAL)
- {
- PSTR pszsig = strchr(pcszMethodName, '(')+1;
-
- PSTR pszsigtmp = pszsig;
- int totalparamslots = 0;
- while (*pszsigtmp != ')')
- totalparamslots += NextSigElement(&pszsigtmp);
-
- if (totalparamslots)
- {
- PrintStackLeader(pThread);
-
- WriteOutput("parameters: ");
-
- pparams += totalparamslots;
-
- pszsigtmp = pszsig;
- do
- {
- if (pszsigtmp != pszsig)
- WriteOutput(", ");
-
- CHAR chvalsig = *pszsigtmp;
-
- pparams -= NextSigElement(&pszsigtmp);
-
- SpewValue(chvalsig, pparams);
- }
- while (*pszsigtmp != ')');
-
- WriteOutput("\n");
- }
-
- if (flags & JVM_CALL_THIS)
- {
- DWORD *pThis = pparams+totalparamslots;
-
- ObjectID idThis = *(ObjectID*)pThis;
-
- ClassID idThisClass = NULL;
-
- if ( FAILED(pinfo3->ObjectInformation(idThis, &idThisClass))
- || idThisClass != idMethodClass)
- {
- PrintStackLeader(pThread);
-
- WriteOutput("this: ");
- SpewValue('L', pThis);
- WriteOutput("\n");
- }
- }
- }
- }
- }
- }
-
-
- VOID CallTracer::SpewReturnValue ()
- {
- MethodID exiting_method_id;
- __int64 *pretval;
-
- IJavaEventMonitorIDInfo3 *pinfo3 = m_pmon->GetVMInfoIfc3();
-
- HRESULT hr = pinfo3->GetMethodExitReturnValue(&exiting_method_id, &pretval);
- if (SUCCEEDED(hr))
- {
- WriteOutput("return value: ");
- if (hr == S_FALSE)
- {
- WriteOutput("void\n");
- }
- else
- {
- PSTR pszMethodUtf8;
- hr = pinfo3->MethodInformation(exiting_method_id, &pszMethodUtf8, NULL, NULL, NULL, NULL);
- if (hr == S_OK)
- {
- PSTR retsig = strchr(pszMethodUtf8, ')')+1;
- SpewValue(*retsig, pretval);
-
- CoTaskMemFree(pszMethodUtf8);
- }
-
- WriteOutput("\n");
- }
- }
- }
-
-
- HRESULT CallTracer::Initialize (EventMonitor *pmon)
- {
- (m_pmon = pmon)->AddRef();
- return S_OK;
- }
-
- VOID CallTracer::Destruct ()
- {
- if (m_pmon)
- m_pmon->Release();
- }
-
-
- VOID CallTracer::OnEnterMethod (ThreadRecord *pThread, MethodID method_id, StackID stack_id)
- {
- if (g_ProfOptions & OPT_CALL_TRACE)
- {
- PSTR pszMethodUtf8 = NULL;
- ClassID class_id;
- JAVA_EXECUTION_MODEL jem;
- if (SUCCEEDED(m_pmon->GetVMInfoIfc()->MethodInformation(method_id, &pszMethodUtf8, &class_id, &jem, NULL, NULL)))
- {
- PCSTR pcszExecModel;
-
- switch (jem)
- {
- case JVM_EXECUTION_JIT_COMPILED:
- pcszExecModel = "JIT-compiled";
- break;
-
- case JVM_EXECUTION_NATIVE:
- pcszExecModel = "native";
- break;
-
- case JVM_EXECUTION_INTERPRETED:
- pcszExecModel = "interpreted";
- break;
-
- case JVM_EXECUTION_FAST_INTERPRETED:
- pcszExecModel = "fast interpreted";
- break;
-
- case JVM_EXECUTION_COM:
- pcszExecModel = "COM";
- break;
-
- default:
- pcszExecModel = "UNKNOWN";
- break;
- }
-
- PrintStackLeader(pThread);
-
- WriteOutputUtf8(pszMethodUtf8);
- WriteOutputFmt(" [%s]\n", pcszExecModel);
- }
-
- pThread->tracedata.nStackFrames++;
-
- if (pszMethodUtf8)
- {
- if (g_ProfOptions & OPT_CALL_TRACE_PARAMS)
- {
- SpewParams(pThread, method_id, stack_id, class_id, pszMethodUtf8);
- }
-
- CoTaskMemFree(pszMethodUtf8);
- }
- }
- }
-
- VOID CallTracer::OnMethodExit (ThreadRecord *pThread, MethodID method_id, StackID stack_id)
- {
- if (g_ProfOptions & OPT_CALL_TRACE)
- {
- PrintStackLeader(pThread);
-
- if (g_ProfOptions & OPT_CALL_TRACE_PARAMS)
- SpewReturnValue();
- else
- WriteOutput("returned\n");
-
- pThread->tracedata.nStackFrames--;
- }
- }
-
-