Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 194081 | Differences between
and this patch

Collapse All | Expand All

(-)src-native/src/BaseProf/ProfEnv.cpp (+477 lines)
Lines 11-16 Link Here
11
 *
11
 *
12
 * $Id: ProfEnv.cpp,v 1.31 2008/12/08 13:37:37 jkubasta Exp $ 
12
 * $Id: ProfEnv.cpp,v 1.31 2008/12/08 13:37:37 jkubasta Exp $ 
13
 ************************************************************************/
13
 ************************************************************************/
14
#ifndef LIN
15
#pragma warning(disable:4786) // Add for bug 194081 to disable VC compiler warning when use STL
16
#endif
14
17
15
#include "ProfEnv.h"
18
#include "ProfEnv.h"
16
#include "log.h"
19
#include "log.h"
Lines 19-24 Link Here
19
using namespace Martini::MPI;
22
using namespace Martini::MPI;
20
using namespace Martini::OSA;
23
using namespace Martini::OSA;
21
using namespace Martini::JPIAgent;
24
using namespace Martini::JPIAgent;
25
using namespace std;  // Add for bug 194081
22
26
23
CProfEnv::CProfEnv(){
27
CProfEnv::CProfEnv(){
24
    m_pClassSData = 0;
28
    m_pClassSData = 0;
Lines 61-66 Link Here
61
    m_pAggStorage->Destroy(); 
65
    m_pAggStorage->Destroy(); 
62
    m_pSSMethodLeaveData_LockObject->Destroy(); 
66
    m_pSSMethodLeaveData_LockObject->Destroy(); 
63
    lockGetThreadInfoObject->Destroy(); 
67
    lockGetThreadInfoObject->Destroy(); 
68
    
69
    // Add for bug 194081
70
    m_pShadowStackTracker = NULL;
71
    // Add for bug 194081
64
}
72
}
65
73
66
void 
74
void 
Lines 101-106 Link Here
101
        delete m_pMethodSData;
109
        delete m_pMethodSData;
102
    }
110
    }
103
    m_pMethodSDataLockObject->Leave();
111
    m_pMethodSDataLockObject->Leave();
112
    
113
    // Add for bug 194081
114
    if (m_pShadowStackTracker)
115
    {
116
        delete m_pShadowStackTracker;
117
        m_pShadowStackTracker = NULL;
118
    }
119
    // Add for bug 194081
104
}
120
}
105
121
106
/*
122
/*
Lines 124-129 Link Here
124
    }
140
    }
125
    libraryLoader->Destroy();
141
    libraryLoader->Destroy();
126
    (*ecpEnv)(profName, &ec_env);
142
    (*ecpEnv)(profName, &ec_env);
143
    
144
    // Add for bug 194081
145
	m_pShadowStackTracker = new CCGShadowStackTracker(*this);
146
	if ( (NULL == m_pShadowStackTracker) ||
147
	    !(m_pShadowStackTracker->ValidateCGShadowStackTracker()) )
148
	{
149
	    return MRTE_ERROR_FAIL;
150
	}
151
	// Add for bug 194081
152
	
127
    return MRTE_RESULT_OSA_PLACE_HOLDER;
153
    return MRTE_RESULT_OSA_PLACE_HOLDER;
128
}
154
}
129
155
Lines 209-214 Link Here
209
    return ret;
235
    return ret;
210
}
236
}
211
237
238
// Add for bug 194081
239
void 
240
CProfEnv::DeleteMethodsData()
241
{
242
    if (m_pMethodSData) 
243
    {
244
        delete m_pMethodSData;
245
        m_pMethodSData = NULL;
246
    }
247
}
248
// Add for bug 194081
249
212
void 
250
void 
213
CProfEnv::AddNewMethodData(SMethodInfo* pSMethodInfo, TId methodId, bool isPrinted)
251
CProfEnv::AddNewMethodData(SMethodInfo* pSMethodInfo, TId methodId, bool isPrinted)
214
{
252
{
Lines 791-793 Link Here
791
    return MRTE_RESULT_OK;
829
    return MRTE_RESULT_OK;
792
}
830
}
793
831
832
//==================================================================
833
// Add for bug 194081
834
CCGShadowStackTracker::CCGShadowStackTracker(CProfEnv& profEnv)
835
    : m_refProfEnv(profEnv)
836
{
837
    m_lockVMStackDataMap = CreateThreadSync();
838
}
839
840
CCGShadowStackTracker::~CCGShadowStackTracker()
841
{
842
    if (m_lockVMStackDataMap)
843
    {
844
        m_lockVMStackDataMap->Destroy();
845
    }
846
}
847
848
bool CCGShadowStackTracker::isNeedTrack()
849
{
850
    return ( 
851
            ((m_refProfEnv.ec_env)->isCGExecDetails()) &&
852
            !((m_refProfEnv.ec_env)->isStandAlone()) 
853
           );
854
}
855
856
bool CCGShadowStackTracker::ValidateCGShadowStackTracker()
857
{
858
    if (!isNeedTrack())
859
    {
860
        return true;
861
    }
862
    
863
    // You can add additional validate condition in this function
864
    return (NULL != m_lockVMStackDataMap);
865
}
866
867
void CCGShadowStackTracker::TrackVMShutdown()
868
{
869
    if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH)))
870
    {// For profilers' common events, just handle for call graph
871
        return;
872
    }
873
    
874
    if (!isNeedTrack())
875
    {
876
        return;
877
    }
878
    
879
    ReportLeftStackTrackDataMethodsLeave();
880
}
881
882
TResult CCGShadowStackTracker::InitNewThreadInfoArray(
883
    SThreadInfoArray& threadInfoArray, 
884
    int MAX_THREADS, int MAX_FRAMES)
885
{
886
    DestroyThreadInfoArray(threadInfoArray);
887
            
888
    threadInfoArray.pEntries = 
889
   	(SThreadInfoArrayEntry*)malloc(sizeof(SThreadInfoArrayEntry) * MAX_THREADS);
890
    if (NULL == threadInfoArray.pEntries)
891
    { 
892
        return MRTE_ERROR_OUT_OF_MEMORY;
893
    }
894
895
    threadInfoArray.uiSize = MAX_THREADS;
896
    memset(threadInfoArray.pEntries, 0, sizeof(SThreadInfoArrayEntry) * MAX_THREADS);
897
    
898
    unsigned int i = 0;
899
    for (i = 0; i < MAX_THREADS; i++)
900
    {
901
        threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.uiSize = MAX_FRAMES;
902
        threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries = new SStackEntry[MAX_FRAMES];
903
904
        if (NULL == threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries)
905
        {
906
            DestroyThreadInfoArray(threadInfoArray);
907
            return MRTE_ERROR_OUT_OF_MEMORY;
908
        }
909
910
        memset(threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries, 0, 
911
              	sizeof(SStackEntry) * MAX_FRAMES);
912
    }
913
914
    return MRTE_RESULT_OK;
915
}
916
917
void CCGShadowStackTracker::DestroyThreadInfoArray(
918
    SThreadInfoArray& threadInfoArray)
919
{
920
    if (NULL != threadInfoArray.pEntries)
921
    {
922
        for (unsigned int i = 0; i < threadInfoArray.uiSize; i++)
923
        {
924
            if (NULL != threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries)
925
            {
926
                delete [](threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries);
927
            }
928
        }
929
930
        free(threadInfoArray.pEntries);
931
    }
932
            
933
    threadInfoArray.uiSize = 0;
934
    threadInfoArray.uiActualSize = 0;
935
}
936
937
TResult CCGShadowStackTracker::GetInitialShadowStackTraces(
938
    SThreadInfoArray& threadInfoArray)
939
{
940
    // Suspend all VM threads and Get all threads stack traces
941
    TResult res = (m_refProfEnv.m_pMpiApi)->SuspendVM();
942
    if (MRTE_FAILED(res))
943
    {
944
        LOG_ERROR("Can not suspend VM when try to get shadow stack sanpshot")
945
        return res;
946
    } 
947
    
948
    // TODO: This fixed thread num and frame num is a limit, referring to original AttachEvent.cpp
949
    int MAX_THREADS = 100;
950
    int MAX_FRAMES = 100;
951
        
952
    res = InitNewThreadInfoArray(threadInfoArray, MAX_THREADS, MAX_FRAMES);
953
    if (MRTE_FAILED(res))
954
    {
955
        (m_refProfEnv.m_pMpiApi)->ResumeVM();
956
        return res;
957
    }
958
959
    res = (m_refProfEnv.m_pMpiApi)->GetAllThreadsInfo(m_refProfEnv.m_clientId, MAX_FRAMES, 
960
        DR_VM_RELATIVE_STACK_TRACE, &threadInfoArray);
961
    if (MRTE_FAILED(res))
962
    {
963
        (m_refProfEnv.m_pMpiApi)->ResumeVM();
964
        DestroyThreadInfoArray(threadInfoArray);
965
    }
966
    
967
    return res;
968
}
969
970
void CCGShadowStackTracker::ReportThreadsStart(SThreadInfoArray& threadInfoArray)
971
{    
972
    for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++)
973
    {
974
        SThreadInfoArrayEntry* pThread = &(threadInfoArray.pEntries[threadIdx]);
975
        
976
        // Clear outdated data
977
        m_refProfEnv.m_Tickets.ReleaseTicket(pThread->threadId);
978
        m_refProfEnv.m_Tickets.DeleteThread(pThread->threadId);
979
        
980
        // Add new data info
981
        m_refProfEnv.m_Tickets.AddNewThread(pThread->threadId);
982
                
983
        m_refProfEnv.GetThreadInfo(m_refProfEnv.m_clientId, pThread->threadId, 
984
            DR_THREAD_INFO | DR_THREAD_ELAPSED_TIME | DR_THREAD_CPU_TIME, &(pThread->threadInfo));
985
        
986
        if (m_refProfEnv.m_profilerIsActive)
987
        {
988
            (m_refProfEnv.ec_env)->PrintThreadStartElement(pThread->threadId, 0, 
989
                &(pThread->threadInfo));
990
        }
991
        else
992
        {
993
            m_refProfEnv.StoreThreadEvent(pThread->threadId, THREAD_START_EVENT, 
994
                &(pThread->threadInfo), 0);            
995
        }
996
    }
997
}
998
999
void CCGShadowStackTracker::ReportMethodEnter(TId threadId, SThreadInfo* pThreadInfo, TId methodId)
1000
{
1001
    // Get classId according to methodId
1002
    SMethodInfo methodInfo = {0};
1003
    TResult iRes = (m_refProfEnv.m_pMpiApi)->GetMethodInfo(m_refProfEnv.m_clientId, 
1004
        methodId, DR_CLASS_ID, &methodInfo);
1005
    LOG_ASSERT(iRes == MRTE_RESULT_OK);
1006
    LOG_ASSERT((methodInfo.validData & DR_CLASS_ID) != 0);
1007
            
1008
    // Just for Exec Details
1009
    m_refProfEnv.CheckMethodId(methodId);
1010
            
1011
    if (m_refProfEnv.m_profilerIsActive)
1012
    {// Profiler is in run mode
1013
        unsigned long ticket = m_refProfEnv.m_Tickets.GetNewTicket(threadId, 
1014
            pThreadInfo->uiCpuNanos, true);
1015
        unsigned long stackDepth = m_refProfEnv.m_Tickets.GetStackDepth(threadId);
1016
        (m_refProfEnv.ec_env)->PrintMethodEntryElement(threadId, methodId, 
1017
                methodInfo.classId, ticket, stackDepth);
1018
    }
1019
    else
1020
    {// Profiler is in pause mode
1021
        m_refProfEnv.m_Tickets.AddMethodEnterData(threadId, methodId, 
1022
            methodInfo.classId, pThreadInfo->uiCpuNanos);
1023
    }
1024
}
1025
1026
void CCGShadowStackTracker::ReportMethodsEnter(SThreadInfoArray& threadInfoArray)
1027
{    
1028
    for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++)
1029
    {
1030
        TId threadId = threadInfoArray.pEntries[threadIdx].threadId;
1031
        SThreadInfo* pThreadInfo = &(threadInfoArray.pEntries[threadIdx].threadInfo);
1032
        
1033
        for (int stackTraceIdx = (pThreadInfo->vmOffsetStack).uiActualSize - 1; stackTraceIdx >= 0 ; 
1034
            stackTraceIdx--)
1035
        {
1036
            // Get methodId from stack trace info
1037
            SStackEntry* pStackEntry = &(pThreadInfo->vmOffsetStack.pStackEntries[stackTraceIdx]);
1038
            
1039
            ReportMethodEnter(threadId, pThreadInfo, pStackEntry->methodId);
1040
        }
1041
    }
1042
}
1043
1044
void CCGShadowStackTracker::SaveAllShadowStacksMethods(SThreadInfoArray& threadInfoArray)
1045
{
1046
    for (unsigned int threadIdx = 0; threadIdx < threadInfoArray.uiActualSize; threadIdx++)
1047
    {
1048
        SThreadInfoArrayEntry* pThread = &(threadInfoArray.pEntries[threadIdx]);
1049
        CVMStackTrackData vmStacks;
1050
        vmStacks.threadId = pThread->threadId;
1051
        unsigned int stackTraceSize = 
1052
            (pThread->threadInfo).vmOffsetStack.uiActualSize;
1053
1054
        for (int stackTraceIdx = stackTraceSize - 1; stackTraceIdx >= 0; stackTraceIdx--)
1055
        {
1056
            vmStacks.shadowStack.push(
1057
                (pThread->threadInfo).vmOffsetStack.pStackEntries[stackTraceIdx].methodId);
1058
        }
1059
        
1060
        m_lockVMStackDataMap->Enter();
1061
        m_VMStacktraceDataMap.insert(
1062
          std::pair<MPI::TId, CVMStackTrackData>(vmStacks.threadId, vmStacks));
1063
        m_lockVMStackDataMap->Leave();
1064
    }
1065
}
1066
1067
void CCGShadowStackTracker::TrackECAttach()
1068
{
1069
    if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH)))
1070
    {// For profilers' common events, just handle for call graph
1071
        return;
1072
    }
1073
    
1074
    if (!isNeedTrack())
1075
    {
1076
        return;
1077
    }
1078
    
1079
    SThreadInfoArray threadInfoArray = {0};
1080
    TResult res = GetInitialShadowStackTraces(threadInfoArray);
1081
    if (MRTE_FAILED(res))
1082
    {
1083
        LOG_ERROR("Can not get VM thread stack traces info.")
1084
        return;
1085
    }
1086
    
1087
    // Report related events and get initial shadow stacks
1088
    ReportThreadsStart(threadInfoArray);
1089
    
1090
    ReportMethodsEnter(threadInfoArray);
1091
    
1092
    SaveAllShadowStacksMethods(threadInfoArray);
1093
    
1094
    DestroyThreadInfoArray(threadInfoArray);
1095
    (m_refProfEnv.m_pMpiApi)->ResumeVM();
1096
}
1097
1098
void CCGShadowStackTracker::TrackECDetach()
1099
{
1100
    if (!(m_refProfEnv.IsSupportedEG(EG_CALL_GRAPH)))
1101
    {// For profilers' common events, just handle for call graph
1102
        return;
1103
    }
1104
    
1105
    if (!isNeedTrack())
1106
    {
1107
        return;
1108
    }
1109
    
1110
    ReportLeftStackTrackDataMethodsLeave();
1111
}
1112
1113
void CCGShadowStackTracker::ReportMethodLeave(TId threadId, TId methodId, 
1114
    TTimeStamp uiCpuNanos)
1115
{
1116
    SMethodInfo methodInfo;
1117
    TResult iRes = (m_refProfEnv.m_pMpiApi)->GetMethodInfo(m_refProfEnv.m_clientId, 
1118
        methodId, DR_CLASS_ID, &methodInfo);
1119
    LOG_ASSERT(iRes == MRTE_RESULT_OK);
1120
    LOG_ASSERT((methodInfo.validData & DR_CLASS_ID) != 0);
1121
    
1122
    // Just for Exec Details
1123
    U64 cpuTime = uiCpuNanos - m_refProfEnv.m_Tickets.GetCpuTime(threadId);
1124
    unsigned long ticket = m_refProfEnv.m_Tickets.ReleaseTicket(threadId);
1125
            
1126
    if (m_refProfEnv.m_profilerIsActive) 
1127
    {
1128
        (m_refProfEnv.ec_env)->PrintMethodExitElement(threadId, methodId, 
1129
            methodInfo.classId, ticket, cpuTime); 
1130
    }
1131
    else if (ticket != -1)
1132
    {
1133
        m_refProfEnv.AddMethodLeaveData(threadId, methodId, methodInfo.classId, 
1134
            ticket, cpuTime);    
1135
    }
1136
}
1137
1138
void CCGShadowStackTracker::UpdateShadowStack(stack< TId >& tmpShadowStack,
1139
    stack< TId >& shadowStack, const SMethodEnterEventData& data)
1140
{ 
1141
    // Because normal stack is empty now, the tmpShadowStack must less or equal shadowStack
1142
    while (tmpShadowStack.size() < shadowStack.size())
1143
    {// Geneate method leave events for shadow stack method
1144
        TId methodId = shadowStack.top();
1145
        shadowStack.pop();
1146
        ReportMethodLeave(data.threadId, methodId, data.uiCpuNanos);
1147
    }
1148
}
1149
1150
void CCGShadowStackTracker::TrackMethodEnter(SMethodEnterEventData &data)
1151
{
1152
    if (!isNeedTrack())
1153
    {
1154
        return;
1155
    }
1156
    
1157
    m_lockVMStackDataMap->Enter();
1158
    map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId);
1159
    m_lockVMStackDataMap->Leave();
1160
    
1161
    if (pos == m_VMStacktraceDataMap.end())
1162
    {// Enter a new thread after attach, it has no shadow stack record and can be handled normally
1163
        return;
1164
    }
1165
    
1166
    CVMStackTrackData& refVmStacks = pos->second;
1167
1168
    if (refVmStacks.normalStack.empty())
1169
    {
1170
        SStackTrace_ stackTrace = {0};
1171
        m_refProfEnv.GetStackTrace(data.threadId, &stackTrace);
1172
        
1173
        std::stack< MPI::TId > tmpShadowStack;
1174
        // Ignore the new entered method, CGProxy.EarlyMethodEnter and CGProxy.MethodEnter on the stack top
1175
        const int ignoredMethodNum = 3;
1176
        for (int stackTraceIdx = stackTrace.uiSize - 1; stackTraceIdx > ignoredMethodNum - 1; stackTraceIdx--)
1177
        {
1178
            tmpShadowStack.push(stackTrace.pStackEntries[stackTraceIdx].methodId);
1179
        }
1180
        
1181
        UpdateShadowStack(tmpShadowStack, refVmStacks.shadowStack, data);
1182
        m_refProfEnv.FreeStackTrace(&stackTrace);
1183
    }
1184
        
1185
    refVmStacks.normalStack.push(data.methodId);
1186
}
1187
1188
// return value: If continue to handle the MethodLeave events
1189
bool CCGShadowStackTracker::TrackMethodLeave(SMethodLeaveEventData &data)
1190
{
1191
    if (!isNeedTrack())
1192
    {
1193
        return true;
1194
    }   
1195
    
1196
    m_lockVMStackDataMap->Enter();
1197
    map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId);
1198
    m_lockVMStackDataMap->Leave();
1199
    
1200
    if (pos == m_VMStacktraceDataMap.end())
1201
    {// Enter a new thread after attach, it has no shadow stack record and can be handled normally
1202
        return true;
1203
    }
1204
    
1205
    CVMStackTrackData& refVmStacks = pos->second;
1206
    
1207
    if (refVmStacks.normalStack.empty())
1208
    {// Method leave notification is generated by instrumet before reattach, ignore it
1209
        return false;
1210
    }
1211
    else
1212
    {
1213
        refVmStacks.normalStack.pop(); 
1214
        return true;
1215
    }
1216
}
1217
1218
void CCGShadowStackTracker::TrackThreadEnd(SThreadEventData &data)
1219
{
1220
    if (!isNeedTrack())
1221
    {
1222
        return;
1223
    }
1224
1225
    m_lockVMStackDataMap->Enter();
1226
    map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.find(data.threadId);
1227
    m_lockVMStackDataMap->Leave();
1228
    
1229
    if (pos == m_VMStacktraceDataMap.end())
1230
    {// Enter a new thread after attach, it has no shadow stack record and can be handled normally
1231
        return;
1232
    }
1233
    
1234
    CVMStackTrackData& refVmStacks = pos->second;
1235
    
1236
    // refVmStacks.shadowStack report method leave events
1237
    while (!refVmStacks.shadowStack.empty())
1238
    {
1239
        TId methodId = refVmStacks.shadowStack.top();
1240
        refVmStacks.shadowStack.pop();
1241
        ReportMethodLeave(data.threadId, methodId, m_refProfEnv.m_Tickets.GetCpuTime(data.threadId));
1242
    }   
1243
}
1244
1245
void CCGShadowStackTracker::ReportLeftStackTrackDataMethodsLeave()
1246
{
1247
    m_lockVMStackDataMap->Enter();
1248
    
1249
    map< MPI::TId, CVMStackTrackData >::iterator pos = m_VMStacktraceDataMap.begin();
1250
    for(; pos != m_VMStacktraceDataMap.end(); pos++)
1251
    {
1252
        CVMStackTrackData& refVmStacks = pos->second;
1253
        
1254
        while (!refVmStacks.normalStack.empty())
1255
        {
1256
            TId methodId = refVmStacks.normalStack.top();
1257
            refVmStacks.normalStack.pop();
1258
            ReportMethodLeave(pos->first, methodId, m_refProfEnv.m_Tickets.GetCpuTime(pos->first));
1259
        }
1260
        
1261
        while (!refVmStacks.shadowStack.empty())
1262
        {
1263
            TId methodId = refVmStacks.shadowStack.top();
1264
            refVmStacks.shadowStack.pop();
1265
            ReportMethodLeave(pos->first, methodId, m_refProfEnv.m_Tickets.GetCpuTime(pos->first));
1266
        }
1267
    }
1268
    m_lockVMStackDataMap->Leave();
1269
}
1270
// Add for bug 194081
(-)src-native/src/BaseProf/DetachEvent.cpp (-1 / +4 lines)
Lines 40-46 Link Here
40
    if (!m_pProfEnv->m_bVMInitDone) {
40
    if (!m_pProfEnv->m_bVMInitDone) {
41
        return;
41
        return;
42
    }
42
    }
43
    m_pProfEnv->ec_env->SetProfileOption("EXECDETAILS", "false");
43
    // Modify for bug 194081
44
    // m_pProfEnv->ec_env->SetProfileOption("EXECDETAILS", "false");
45
    m_pProfEnv->m_pShadowStackTracker->TrackECDetach();
46
    // Modify for bug 194081
44
    if (!m_pProfEnv->IsSupportedEG(EG_CALL_GRAPH) && !m_pProfEnv->IsSupportedEG(EG_HEAP)) {
47
    if (!m_pProfEnv->IsSupportedEG(EG_CALL_GRAPH) && !m_pProfEnv->IsSupportedEG(EG_HEAP)) {
45
        return;
48
        return;
46
    }
49
    }
(-)src-native/src/BaseProf/ProfEnv.h (+84 lines)
Lines 15-20 Link Here
15
#ifndef _PROF_ENV_H_
15
#ifndef _PROF_ENV_H_
16
#define _PROF_ENV_H_
16
#define _PROF_ENV_H_
17
17
18
// Add for bug 194081
19
#include <stack>
20
#include <map>
21
// Add for bug 194081
22
18
#include "MpiAPI.h"
23
#include "MpiAPI.h"
19
#include "OSA.h"
24
#include "OSA.h"
20
25
Lines 50-55 Link Here
50
        MPI::SThreadInfo threadInfo; //For THREAD_START_EVENT only
55
        MPI::SThreadInfo threadInfo; //For THREAD_START_EVENT only
51
        MPI::TId objectId; //For THREAD_START_EVENT only
56
        MPI::TId objectId; //For THREAD_START_EVENT only
52
    };
57
    };
58
    
59
    // Add for bug 194081
60
    class CCGShadowStackTracker
61
    {
62
        class CVMStackTrackData
63
        {
64
        public:
65
            MPI::TId threadId;
66
            std::stack< MPI::TId > shadowStack;
67
            std::stack< MPI::TId > normalStack;
68
        };
69
70
    public:
71
    	CCGShadowStackTracker(CProfEnv& profEnv);
72
    	~CCGShadowStackTracker();
73
74
        // Assure init process is successful, called by CProfEnv init
75
    	bool ValidateCGShadowStackTracker();
76
    	
77
    	//---------------------------------------------------------------------
78
        // Common profiler events need to be tracked, except for VMInit, ECStart and ECStop event
79
    	void TrackVMShutdown();
80
81
    	void TrackECAttach();
82
    	void TrackECDetach();
83
    	
84
    	//---------------------------------------------------------------------
85
    	// Call Graph profiler specialized events, except for NewMethod and ThreadStart
86
        void TrackMethodEnter(MPI::SMethodEnterEventData& data);
87
        
88
        // TrackMethodLeave return bool to avoid handle MethodLeave events before reattach
89
        bool TrackMethodLeave(MPI::SMethodLeaveEventData& data);
90
        
91
        void TrackThreadEnd(MPI::SThreadEventData &data);
92
93
    private:
94
        // Functions for deciding whether to track corresponding events 
95
        bool isNeedTrack();
96
        
97
        // Used by ECAttach tracker
98
        TResult InitNewThreadInfoArray(MPI::SThreadInfoArray& threadInfoArray, 
99
            int MAX_THREADS, int MAX_FRAMES);
100
        void DestroyThreadInfoArray(MPI::SThreadInfoArray& threadInfoArray);
101
        
102
        TResult GetInitialShadowStackTraces(MPI::SThreadInfoArray& threadInfoArray);
103
        void ReportThreadsStart(MPI::SThreadInfoArray& threadInfoArray);  // Refer to CGProf ThreadStartHandler
104
        
105
        void ReportMethodEnter(MPI::TId threadId, MPI::SThreadInfo* pThreadInfo, MPI::TId methodId);
106
        void ReportMethodsEnter(MPI::SThreadInfoArray& threadInfoArray);
107
        
108
        void ReportAllStacksThreadsMethods(MPI::SThreadInfoArray& threadInfoArray);
109
        void SaveAllShadowStacksMethods(MPI::SThreadInfoArray& threadInfoArray);
110
        
111
        // Used by MethodEnter and ThreadEnd trackers, ReportLeftStackTrackDataMethodsLeave
112
        void ReportMethodLeave(MPI::TId threadId, MPI::TId methodId, MPI::TTimeStamp uiCpuNanos);
113
        
114
        // Used by MethodEnter tracker 
115
        void UpdateShadowStack(std::stack< MPI::TId >&, std::stack< MPI::TId >&, 
116
            const MPI::SMethodEnterEventData&);
117
            
118
        // Used by VMShutdown and Detach trackers
119
        // Generate method leave events for each left methods in track stack
120
        void ReportLeftStackTrackDataMethodsLeave();
121
122
    private:
123
    	CProfEnv& m_refProfEnv;
124
125
        OSA::IThreadSync* m_lockVMStackDataMap;
126
        std::map< MPI::TId, CVMStackTrackData > m_VMStacktraceDataMap;
127
    };
128
    // Add for bug 194081
53
129
54
    class CProfEnv
130
    class CProfEnv
55
    {
131
    {
Lines 82-87 Link Here
82
        bool IsObjectStored(MPI::TId objectId);
158
        bool IsObjectStored(MPI::TId objectId);
83
        //
159
        //
84
//        void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId);
160
//        void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId);
161
        // Add for bug 194081
162
        void DeleteMethodsData();
163
        // Add for bug 194081
85
        void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId, bool isPrinted);
164
        void AddNewMethodData(MPI::SMethodInfo* pSMethodInfo, MPI::TId methodId, bool isPrinted);
86
        //
165
        //
87
        MPI::SMethodInfo* GetMethodData(MPI::TId methodId);
166
        MPI::SMethodInfo* GetMethodData(MPI::TId methodId);
Lines 151-156 Link Here
151
        MPI::TId m_clientId;
230
        MPI::TId m_clientId;
152
        // Profiler library name
231
        // Profiler library name
153
        char* profName;
232
        char* profName;
233
        
234
        // Add for bug 194081
235
        CCGShadowStackTracker* m_pShadowStackTracker;
236
        // Add for bug 194081
237
        
154
    private:
238
    private:
155
        CClassDefDataSet* m_pClassSData;
239
        CClassDefDataSet* m_pClassSData;
156
        OSA::IThreadSync* m_pClassSDataLockObject;
240
        OSA::IThreadSync* m_pClassSDataLockObject;
(-)src-native/src/BaseProf/AttachEvent.cpp (-2 / +25 lines)
Lines 41-50 Link Here
41
    if (!m_pProfEnv->m_bVMInitDone) {
41
    if (!m_pProfEnv->m_bVMInitDone) {
42
        return;
42
        return;
43
    }
43
    }
44
44
    
45
    m_pProfEnv->DeleteAggCallGraphData();
45
    m_pProfEnv->DeleteAggCallGraphData();
46
    m_pProfEnv->DeleteStoredThreadEvents();
46
    m_pProfEnv->DeleteStoredThreadEvents();
47
47
48
    // Add for bug 194081
49
    if (m_pProfEnv->ec_env->isCGExecDetails())
50
    {
51
        m_pProfEnv->DeleteMethodsData();
52
        m_pProfEnv->m_pShadowStackTracker->TrackECAttach();
53
    
54
        TResult res = m_pProfEnv->EnableSupportedEG();
55
        if (MRTE_FAILED(res))
56
        {
57
            if (MRTE_ERROR_PHASE_FAILURE == res) 
58
            {
59
                LOG_DIE("Attach failed (too early)");
60
            } 
61
            else
62
            {
63
                LOG_DIE("Attach failed");
64
            }
65
        }
66
        
67
        return;
68
    }
69
    // Add for bug 194081
70
48
    const int MAX_THREADS = 100;
71
    const int MAX_THREADS = 100;
49
    const int MAX_FRAMES = 100;
72
    const int MAX_FRAMES = 100;
50
    TResult res; 
73
    TResult res; 
Lines 161-167 Link Here
161
            }
184
            }
162
        }
185
        }
163
        for (i = 0; i < MAX_THREADS; i++) {
186
        for (i = 0; i < MAX_THREADS; i++) {
164
            delete threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries;
187
            delete [](threadInfoArray.pEntries[i].threadInfo.vmOffsetStack.pStackEntries);
165
        }
188
        }
166
    } else {
189
    } else {
167
        res = m_pProfEnv->m_pMpiApi->GetAllThreadsInfo(m_pProfEnv->m_clientId, 0, DR_THREAD_INFO, &threadInfoArray);
190
        res = m_pProfEnv->m_pMpiApi->GetAllThreadsInfo(m_pProfEnv->m_clientId, 0, DR_THREAD_INFO, &threadInfoArray);
(-)src-native/src/BaseProf/BaseProfiler.h (-1 / +1 lines)
Lines 35-41 Link Here
35
        // Constructor
35
        // Constructor
36
        CBaseProfiler();
36
        CBaseProfiler();
37
        // Destructor
37
        // Destructor
38
        ~CBaseProfiler();
38
        virtual ~CBaseProfiler();
39
        // Initialization
39
        // Initialization
40
		TResult Init(MPI::IMpi *pMpiApi, MPI::TId clientId, const char *szOptions);
40
		TResult Init(MPI::IMpi *pMpiApi, MPI::TId clientId, const char *szOptions);
41
41
(-)src-native/src/BaseProf/VMShutdownEvent.cpp (-1 / +11 lines)
Lines 41-46 Link Here
41
    if (!m_pProfEnv->m_profilerIsActive) {
41
    if (!m_pProfEnv->m_profilerIsActive) {
42
        return;
42
        return;
43
    }
43
    }
44
    m_pProfEnv->PrintAggCallGraph();
44
    // Modified for bug 194081
45
    if (m_pProfEnv->ec_env->isCGExecDetails())
46
    {
47
        m_pProfEnv->m_pShadowStackTracker->TrackVMShutdown();
48
    }
49
    else
50
    {
51
        m_pProfEnv->PrintAggCallGraph();
52
    }
53
    // Modified for bug 194081
54
    
45
    m_pProfEnv->ec_env->PrintRuntimeShutdownElement();
55
    m_pProfEnv->ec_env->PrintRuntimeShutdownElement();
46
}
56
}
(-)src-native/src/CGProf/ThreadEndEvent.cpp (+4 lines)
Lines 40-45 Link Here
40
{
40
{
41
    if ((data.validData & DR_THREAD_ID) != 0)
41
    if ((data.validData & DR_THREAD_ID) != 0)
42
    {
42
    {
43
        // Add for bug 194081
44
        m_pProfEnv->m_pShadowStackTracker->TrackThreadEnd(data);
45
        // Add for bug 194081
46
        
43
        m_pProfEnv->m_Tickets.DeleteThread(data.threadId);
47
        m_pProfEnv->m_Tickets.DeleteThread(data.threadId);
44
        if (!m_pProfEnv->m_profilerIsActive) {
48
        if (!m_pProfEnv->m_profilerIsActive) {
45
            m_pProfEnv->StoreThreadEvent(data.threadId, THREAD_END_EVENT, &data, 0);
49
            m_pProfEnv->StoreThreadEvent(data.threadId, THREAD_END_EVENT, &data, 0);
(-)src-native/src/CGProf/MethodEnterEvent.cpp (+4 lines)
Lines 44-49 Link Here
44
    LOG_ASSERT((data.validData & DR_METHOD_ID) != 0);
44
    LOG_ASSERT((data.validData & DR_METHOD_ID) != 0);
45
    LOG_ASSERT((data.validData & DR_THREAD_ID) != 0);
45
    LOG_ASSERT((data.validData & DR_THREAD_ID) != 0);
46
    LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0);
46
    LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0);
47
    
48
    // Add for bug 194081
49
    m_pProfEnv->m_pShadowStackTracker->TrackMethodEnter(data);
50
    // Add for bug 194081
47
51
48
    SMethodInfo classInfo;
52
    SMethodInfo classInfo;
49
    TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, 
53
    TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, 
(-)src-native/src/CGProf/MethodLeaveEvent.cpp (+8 lines)
Lines 42-47 Link Here
42
    LOG_ASSERT((data.validData & DR_METHOD_ID) != 0);
42
    LOG_ASSERT((data.validData & DR_METHOD_ID) != 0);
43
    LOG_ASSERT((data.validData & DR_THREAD_ID) != 0);
43
    LOG_ASSERT((data.validData & DR_THREAD_ID) != 0);
44
    LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0);
44
    LOG_ASSERT((data.validData & DR_THREAD_CPU_TIME) != 0);
45
    
46
    // Add for bug 194081
47
    bool isContinueHandleMethodLeave = m_pProfEnv->m_pShadowStackTracker->TrackMethodLeave(data);
48
    if (!isContinueHandleMethodLeave)
49
    {
50
        return;
51
    }
52
    // Add for bug 194081
45
53
46
    SMethodInfo classInfo;
54
    SMethodInfo classInfo;
47
    TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, 
55
    TResult iRes = m_pProfEnv->m_pMpiApi->GetMethodInfo(m_pProfEnv->m_clientId, data.methodId, 
(-)src-native/src/JPIAgent/Options.h (-1 / +4 lines)
Lines 144-150 Link Here
144
144
145
        // is CG pfofiler aggregated
145
        // is CG pfofiler aggregated
146
        bool isCGExecDetails() {
146
        bool isCGExecDetails() {
147
            return (!isEnabled()) && (m_jvmtiAgent_Options.cgExecDetails == 1); //in enabled mode we support aggregated cg profiler only
147
            // Modified for bug 194081
148
            //return (!isEnabled()) && (m_jvmtiAgent_Options.cgExecDetails == 1); //in enabled mode we support aggregated cg profiler only
149
            return (m_jvmtiAgent_Options.cgExecDetails == 1);
150
            // Modified for bug 194081
148
        }
151
        }
149
152
150
        // if cg memory should be freed after snapshot then returns true
153
        // if cg memory should be freed after snapshot then returns true

Return to bug 194081