|
Lines 17-22
Link Here
|
| 17 |
#include "HeapProxy.h" |
17 |
#include "HeapProxy.h" |
| 18 |
#include "ThreadProxy.h" |
18 |
#include "ThreadProxy.h" |
| 19 |
#include "ValidityChecks.h" |
19 |
#include "ValidityChecks.h" |
|
|
20 |
#include "MRTEInfrastructureDefinitions.h" |
| 20 |
|
21 |
|
| 21 |
#include <assert.h> |
22 |
#include <assert.h> |
| 22 |
#include <string.h> |
23 |
#include <string.h> |
|
Lines 67-76
Link Here
|
| 67 |
} |
68 |
} |
| 68 |
} |
69 |
} |
| 69 |
|
70 |
|
| 70 |
TResult CCGAdaptor::Init(ILogAssert *pLogger, MPI::IEventFilter* pFilter) |
71 |
TResult CCGAdaptor::Init(ILogAssert *pLogger, |
|
|
72 |
MPI::IEventFilter* pFilter, |
| 73 |
MPI::BitSet configFlags) |
| 71 |
{ |
74 |
{ |
| 72 |
// Call common initializer |
75 |
// Call common initializer |
| 73 |
TResult res = CInstrumentationAdaptorBase::Init(pLogger); |
76 |
TResult res = CInstrumentationAdaptorBase::Init(pLogger, configFlags); |
| 74 |
if (MRTE_FAILED(res)) |
77 |
if (MRTE_FAILED(res)) |
| 75 |
{ |
78 |
{ |
| 76 |
return MRTE_ERROR_FAIL; |
79 |
return MRTE_ERROR_FAIL; |
|
Lines 378-384
Link Here
|
| 378 |
// If no methods were instrumented, modify the return code to indicate this |
381 |
// If no methods were instrumented, modify the return code to indicate this |
| 379 |
if (MRTE_SUCCEEDED(res) && instrMethodCount == 0) |
382 |
if (MRTE_SUCCEEDED(res) && instrMethodCount == 0) |
| 380 |
{ |
383 |
{ |
| 381 |
LOG_INFORMATIVE1("CGAdaptor", 3, false, "Class %s was not instrumented because all its methods were excluded", |
384 |
LOG_INFORMATIVE1("CGAdaptor", 3, false, |
|
|
385 |
"Class %s was not instrumented because all its methods were excluded", |
| 382 |
classInfo.szClassName); |
386 |
classInfo.szClassName); |
| 383 |
res = MRTE_ERROR_INSTRUMENTATION_NOT_NEEDED; |
387 |
res = MRTE_ERROR_INSTRUMENTATION_NOT_NEEDED; |
| 384 |
} |
388 |
} |
|
Lines 681-687
Link Here
|
| 681 |
} |
685 |
} |
| 682 |
|
686 |
|
| 683 |
res = InjectEpilogCode(pMethod, pInstructionsIter, pOriginalFirstInstr, isJVMInitVar, |
687 |
res = InjectEpilogCode(pMethod, pInstructionsIter, pOriginalFirstInstr, isJVMInitVar, |
| 684 |
cpMethodId, cpLeaveCallback, bJVMInitDone); |
688 |
cpMethodId, cpLeaveCallback, bJVMInitDone, |
|
|
689 |
IsConstructor(pInfo->szName)); |
| 690 |
|
| 691 |
if (MRTE_RESULT_OK != res) |
| 692 |
{ |
| 693 |
return res; |
| 694 |
} |
| 685 |
|
695 |
|
| 686 |
pInstructionsIter->Free(); |
696 |
pInstructionsIter->Free(); |
| 687 |
res = pMethod->ApplyInstrumentation(); |
697 |
res = pMethod->ApplyInstrumentation(); |
|
Lines 837-843
Link Here
|
| 837 |
TVariableID isJVMInitVar, |
847 |
TVariableID isJVMInitVar, |
| 838 |
TConstantPoolIndex cpiMethodId, |
848 |
TConstantPoolIndex cpiMethodId, |
| 839 |
TConstantPoolIndex cpiLeaveCallback, |
849 |
TConstantPoolIndex cpiLeaveCallback, |
| 840 |
bool bJVMInitDone) |
850 |
bool bJVMInitDone, |
|
|
851 |
bool bIsConstructor) |
| 841 |
{ |
852 |
{ |
| 842 |
TResult res; |
853 |
TResult res; |
| 843 |
|
854 |
|
|
Lines 899-906
Link Here
|
| 899 |
// whether the method terminates normally or abnormally |
910 |
// whether the method terminates normally or abnormally |
| 900 |
|
911 |
|
| 901 |
IInstruction *pStartTry; |
912 |
IInstruction *pStartTry; |
| 902 |
pInstructionsIter->GetFirst(); |
913 |
if (bIsConstructor) |
| 903 |
pStartTry = pOriginalFirstMethodInst; |
914 |
{ |
|
|
915 |
// The instrumented method is a constructor. The protected block should start |
| 916 |
// only after the call to the constructor of the superclass (or another constructor |
| 917 |
// of the current class) to prevent verification issues |
| 918 |
// (see https://bugs.eclipse.org/170075) |
| 919 |
|
| 920 |
// Find where the original method code starts (need to skip the injected prolog) |
| 921 |
pStartTry = pInstructionsIter->GetFirst(); |
| 922 |
while (pStartTry != pOriginalFirstMethodInst && pStartTry != NULL) |
| 923 |
{ |
| 924 |
pStartTry = pInstructionsIter->GetNext(); |
| 925 |
} |
| 926 |
if (NULL == pStartTry) |
| 927 |
{ |
| 928 |
LOG_INFORMATIVE("CGAdaptor", 0, false, |
| 929 |
"Cannot find the first instruction of the method"); |
| 930 |
return MRTE_ERROR_FAIL; |
| 931 |
} |
| 932 |
|
| 933 |
// Search for the first "invokespecial" instruction. |
| 934 |
// Since this is a constructor, it is expected to have an "invokespecial" of another |
| 935 |
// constructor in this class or in its superclass |
| 936 |
// |
| 937 |
// If this is not the case (may happen for generated or instrumented code) the |
| 938 |
// constructor will not be instrumented |
| 939 |
while (pStartTry != NULL |
| 940 |
&& pStartTry->GetMnemonic() != MNM_INVOKESPECIAL) |
| 941 |
{ |
| 942 |
pStartTry = pInstructionsIter->GetNext(); |
| 943 |
} |
| 944 |
if (pStartTry != NULL |
| 945 |
&& pStartTry->GetMnemonic() == MNM_INVOKESPECIAL) |
| 946 |
{ |
| 947 |
// Assume this is the constructor invocation |
| 948 |
pStartTry = pInstructionsIter->GetNext(); |
| 949 |
} |
| 950 |
else |
| 951 |
{ |
| 952 |
LOG_INFORMATIVE("CGAdaptor", 0, false, |
| 953 |
"Constructor method does not start with invocation of super-constructor. " |
| 954 |
"Method will not be instrumented"); |
| 955 |
return MRTE_ERROR_UNABLE_TO_INSTRUMENT; |
| 956 |
} |
| 957 |
} |
| 958 |
else |
| 959 |
{ |
| 960 |
// Regular method. The protected block spans the entire (original) method code |
| 961 |
pStartTry = pOriginalFirstMethodInst; |
| 962 |
} |
| 904 |
res = pMethod->BindTryFinallyBlock(pStartTry, pLastMethodInstruction, |
963 |
res = pMethod->BindTryFinallyBlock(pStartTry, pLastMethodInstruction, |
| 905 |
pFirstInstInFinally, pLastInstInFinally); |
964 |
pFirstInstInFinally, pLastInstInFinally); |
| 906 |
|
965 |
|
|
Lines 953-964
Link Here
|
| 953 |
return MRTE_RESULT_OK; |
1012 |
return MRTE_RESULT_OK; |
| 954 |
} |
1013 |
} |
| 955 |
|
1014 |
|
| 956 |
/* |
1015 |
bool CCGAdaptor::IsConstructor(const char *szMethodName) |
| 957 |
bool CCGAdaptor::IsConstructor(const SJavaMethodInfo &methodInfo) |
|
|
| 958 |
{ |
1016 |
{ |
| 959 |
bool bIsCtor; |
1017 |
bool bIsCtor; |
| 960 |
char *szName = CWideStringUtils::WideStringToCString(methodInfo.methodName); |
1018 |
if (strcmp(szMethodName, JAVA_INSTANCE_CONSTRUCTOR_NAME) == 0) |
| 961 |
if (strcmp(szName, JAVA_INSTANCE_CONSTRUCTOR_NAME) == 0) |
|
|
| 962 |
{ |
1019 |
{ |
| 963 |
bIsCtor = true; |
1020 |
bIsCtor = true; |
| 964 |
} |
1021 |
} |
|
Lines 966-975
Link Here
|
| 966 |
{ |
1023 |
{ |
| 967 |
bIsCtor = false; |
1024 |
bIsCtor = false; |
| 968 |
} |
1025 |
} |
| 969 |
delete szName; |
|
|
| 970 |
return bIsCtor; |
1026 |
return bIsCtor; |
| 971 |
} |
1027 |
} |
| 972 |
*/ |
|
|
| 973 |
|
1028 |
|
| 974 |
bool CCGAdaptor::IsProblematicMethod(const char *szClassName, |
1029 |
bool CCGAdaptor::IsProblematicMethod(const char *szClassName, |
| 975 |
const char *szMethodName) |
1030 |
const char *szMethodName) |