summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEugene Rozenfeld <erozen@microsoft.com>2018-10-11 13:03:26 -0700
committerGitHub <noreply@github.com>2018-10-11 13:03:26 -0700
commit5f9f37432568b9abd91de39949ae860e9151798e (patch)
treed526a60db61b6add23c2c3c90a3ca7f3c6eaa35d /src
parent5c039559b96bf71e4281331977160ff4c8c44af8 (diff)
downloadcoreclr-5f9f37432568b9abd91de39949ae860e9151798e.tar.gz
coreclr-5f9f37432568b9abd91de39949ae860e9151798e.tar.bz2
coreclr-5f9f37432568b9abd91de39949ae860e9151798e.zip
JitEE interface additions to support object stack allocation. (#20283)
Add two methods to JitEE interface: getHeapClassSize and canAllocateOnStack. Change JITEEVersionIdentifier.
Diffstat (limited to 'src')
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h5
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/lwmlist.h2
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp44
-rw-r--r--src/ToolBox/superpmi/superpmi-shared/methodcontext.h12
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp19
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp13
-rw-r--r--src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp11
-rw-r--r--src/ToolBox/superpmi/superpmi/icorjitinfo.cpp13
-rw-r--r--src/inc/corinfo.h19
-rw-r--r--src/jit/ICorJitInfo_API_names.h2
-rw-r--r--src/jit/ICorJitInfo_API_wrapper.hpp16
-rw-r--r--src/vm/jitinterface.cpp66
-rw-r--r--src/vm/jitinterface.h2
-rw-r--r--src/zap/zapinfo.cpp10
-rw-r--r--src/zap/zapinfo.h2
15 files changed, 230 insertions, 6 deletions
diff --git a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
index 29c1b44711..e21f72b668 100644
--- a/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
+++ b/src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
@@ -326,6 +326,11 @@ size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDL
// return the number of bytes needed by an instance of the class
unsigned getClassSize(CORINFO_CLASS_HANDLE cls);
+// return the number of bytes needed by an instance of the class allocated on the heap
+unsigned getHeapClassSize(CORINFO_CLASS_HANDLE cls);
+
+BOOL canAllocateOnStack(CORINFO_CLASS_HANDLE cls);
+
unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint = FALSE);
// This is only called for Value classes. It returns a boolean array
diff --git a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
index 779a9b65c8..42ffc01423 100644
--- a/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
+++ b/src/ToolBox/superpmi/superpmi-shared/lwmlist.h
@@ -72,6 +72,8 @@ LWM(GetClassNameFromMetadata, DLD, DD)
LWM(GetTypeInstantiationArgument, DWORDLONG, DWORDLONG)
LWM(GetClassNumInstanceFields, DWORDLONG, DWORD)
LWM(GetClassSize, DWORDLONG, DWORD)
+LWM(GetHeapClassSize, DWORDLONG, DWORD)
+LWM(CanAllocateOnStack, DWORDLONG, DWORD)
LWM(GetCookieForPInvokeCalliSig, GetCookieForPInvokeCalliSigValue, DLDL)
LWM(GetDefaultEqualityComparerClass, DWORDLONG, DWORDLONG)
LWM(GetDelegateCtor, Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
index 6ebe9881fb..ea6dbd4953 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
@@ -1722,6 +1722,50 @@ unsigned MethodContext::repGetClassSize(CORINFO_CLASS_HANDLE cls)
return result;
}
+void MethodContext::recGetHeapClassSize(CORINFO_CLASS_HANDLE cls, unsigned result)
+{
+ if (GetHeapClassSize == nullptr)
+ GetHeapClassSize = new LightWeightMap<DWORDLONG, DWORD>();
+
+ GetHeapClassSize->Add((DWORDLONG)cls, (DWORD)result);
+ DEBUG_REC(dmpGetHeapClassSize((DWORDLONG)cls, (DWORD)result));
+}
+void MethodContext::dmpGetHeapClassSize(DWORDLONG key, DWORD val)
+{
+ printf("GetHeapClassSize key %016llX, value %u", key, val);
+}
+unsigned MethodContext::repGetHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ AssertCodeMsg(GetHeapClassSize != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llX", (DWORDLONG)cls);
+ AssertCodeMsg(GetHeapClassSize->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX",
+ (DWORDLONG)cls);
+ unsigned result = (unsigned)GetHeapClassSize->Get((DWORDLONG)cls);
+ DEBUG_REP(dmpGetHeapClassSize((DWORDLONG)cls, (DWORD)result));
+ return result;
+}
+
+void MethodContext::recCanAllocateOnStack(CORINFO_CLASS_HANDLE cls, BOOL result)
+{
+ if (CanAllocateOnStack == nullptr)
+ CanAllocateOnStack = new LightWeightMap<DWORDLONG, DWORD>();
+
+ CanAllocateOnStack->Add((DWORDLONG)cls, (DWORD)result);
+ DEBUG_REC(dmpCanAllocateOnStack((DWORDLONG)cls, (DWORD)result));
+}
+void MethodContext::dmpCanAllocateOnStack(DWORDLONG key, DWORD val)
+{
+ printf("CanAllocateOnStack key %016llX, value %u", key, val);
+}
+BOOL MethodContext::repCanAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ AssertCodeMsg(CanAllocateOnStack != nullptr, EXCEPTIONCODE_MC, "Didn't find %016llX", (DWORDLONG)cls);
+ AssertCodeMsg(CanAllocateOnStack->GetIndex((DWORDLONG)cls) != -1, EXCEPTIONCODE_MC, "Didn't find %016llX",
+ (DWORDLONG)cls);
+ BOOL result = (BOOL)CanAllocateOnStack->Get((DWORDLONG)cls);
+ DEBUG_REP(dmpCanAllocateOnStack((DWORDLONG)cls, (DWORD)result));
+ return result;
+}
+
void MethodContext::recGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls, unsigned result)
{
if (GetClassNumInstanceFields == nullptr)
diff --git a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
index 0a71c8df68..fa7d699e62 100644
--- a/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
+++ b/src/ToolBox/superpmi/superpmi-shared/methodcontext.h
@@ -696,6 +696,14 @@ public:
void dmpGetClassSize(DWORDLONG key, DWORD val);
unsigned repGetClassSize(CORINFO_CLASS_HANDLE cls);
+ void recGetHeapClassSize(CORINFO_CLASS_HANDLE cls, unsigned result);
+ void dmpGetHeapClassSize(DWORDLONG key, DWORD val);
+ unsigned repGetHeapClassSize(CORINFO_CLASS_HANDLE cls);
+
+ void recCanAllocateOnStack(CORINFO_CLASS_HANDLE cls, BOOL result);
+ void dmpCanAllocateOnStack(DWORDLONG key, DWORD val);
+ BOOL repCanAllocateOnStack(CORINFO_CLASS_HANDLE cls);
+
void recGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls, unsigned result);
void dmpGetClassNumInstanceFields(DWORDLONG key, DWORD value);
unsigned repGetClassNumInstanceFields(CORINFO_CLASS_HANDLE cls);
@@ -1309,7 +1317,7 @@ private:
};
// ********************* Please keep this up-to-date to ease adding more ***************
-// Highest packet number: 168
+// Highest packet number: 171
// *************************************************************************************
enum mcPackets
{
@@ -1378,6 +1386,8 @@ enum mcPackets
Packet_GetTypeInstantiationArgument = 167, // Added 12/4/17
Packet_GetClassNumInstanceFields = 46,
Packet_GetClassSize = 47,
+ Packet_GetHeapClassSize = 170, // Added 10/5/2018
+ Packet_CanAllocateOnStack = 171, // Added 10/5/2018
Packet_GetIntConfigValue = 151, // Added 2/12/2015
Packet_GetStringConfigValue = 152, // Added 2/12/2015
Packet_GetCookieForPInvokeCalliSig = 48,
diff --git a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
index 32cc072d68..200152a046 100644
--- a/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
@@ -683,6 +683,25 @@ unsigned interceptor_ICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
return temp;
}
+// return the number of bytes needed by an instance of the class allocated on the heap
+unsigned interceptor_ICJI::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ mc->cr->AddCall("getHeapClassSize");
+ unsigned temp = original_ICorJitInfo->getHeapClassSize(cls);
+ mc->recGetHeapClassSize(cls, temp);
+ return temp;
+}
+
+BOOL interceptor_ICJI::canAllocateOnStack(
+ CORINFO_CLASS_HANDLE cls
+)
+{
+ mc->cr->AddCall("canAllocateOnStack");
+ BOOL temp = original_ICorJitInfo->canAllocateOnStack(cls);
+ mc->recCanAllocateOnStack(cls, temp);
+ return temp;
+}
+
unsigned interceptor_ICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
{
mc->cr->AddCall("getClassAlignmentRequirement");
diff --git a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
index 8a3e80ca4c..c2100e245f 100644
--- a/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
@@ -519,6 +519,19 @@ unsigned interceptor_ICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
return original_ICorJitInfo->getClassSize(cls);
}
+// return the number of bytes needed by an instance of the class allocated on the heap
+unsigned interceptor_ICJI::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ mcs->AddCall("getHeapClassSize");
+ return original_ICorJitInfo->getHeapClassSize(cls);
+}
+
+BOOL interceptor_ICJI::canAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ mcs->AddCall("canAllocateOnStack");
+ return original_ICorJitInfo->canAllocateOnStack(cls);
+}
+
unsigned interceptor_ICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
{
mcs->AddCall("getClassAlignmentRequirement");
diff --git a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
index 90b2fdb628..4ebd09a4f6 100644
--- a/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
@@ -464,6 +464,17 @@ unsigned interceptor_ICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
return original_ICorJitInfo->getClassSize(cls);
}
+// return the number of bytes needed by an instance of the class allocated on the heap
+unsigned interceptor_ICJI::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ return original_ICorJitInfo->getHeapClassSize(cls);
+}
+
+BOOL interceptor_ICJI::canAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ return original_ICorJitInfo->canAllocateOnStack(cls);
+}
+
unsigned interceptor_ICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
{
return original_ICorJitInfo->getClassAlignmentRequirement(cls, fDoubleAlignHint);
diff --git a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
index 3eb5a312a9..ac1abcc38d 100644
--- a/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
+++ b/src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
@@ -577,6 +577,19 @@ unsigned MyICJI::getClassSize(CORINFO_CLASS_HANDLE cls)
return jitInstance->mc->repGetClassSize(cls);
}
+// return the number of bytes needed by an instance of the class allocated on the heap
+unsigned MyICJI::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ jitInstance->mc->cr->AddCall("getHeapClassSize");
+ return jitInstance->mc->repGetHeapClassSize(cls);
+}
+
+BOOL MyICJI::canAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ jitInstance->mc->cr->AddCall("canAllocateOnStack");
+ return jitInstance->mc->repCanAllocateOnStack(cls);
+}
+
unsigned MyICJI::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
{
jitInstance->mc->cr->AddCall("getClassAlignmentRequirement");
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index 88f8c1b8c2..b7728bf271 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -213,11 +213,11 @@ TODO: Talk about initializing strutures before use
#define SELECTANY extern __declspec(selectany)
#endif
-SELECTANY const GUID JITEEVersionIdentifier = { /* 45aafd4d-1d23-4647-9ce1-cf09a2677ca0 */
- 0x45aafd4d,
- 0x1d23,
- 0x4647,
- {0x9c, 0xe1, 0xcf, 0x09, 0xa2, 0x67, 0x7c, 0xa0}
+SELECTANY const GUID JITEEVersionIdentifier = { /* 12768bf8-549c-455b-a3df-57a751a81813 */
+ 0x12768bf8,
+ 0x549c,
+ 0x455b,
+ {0xa3, 0xdf, 0x57, 0xa7, 0x51, 0xa8, 0x18, 0x13}
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -2383,6 +2383,15 @@ public:
CORINFO_CLASS_HANDLE cls
) = 0;
+ // return the number of bytes needed by an instance of the class allocated on the heap
+ virtual unsigned getHeapClassSize(
+ CORINFO_CLASS_HANDLE cls
+ ) = 0;
+
+ virtual BOOL canAllocateOnStack(
+ CORINFO_CLASS_HANDLE cls
+ ) = 0;
+
virtual unsigned getClassAlignmentRequirement (
CORINFO_CLASS_HANDLE cls,
BOOL fDoubleAlignHint = FALSE
diff --git a/src/jit/ICorJitInfo_API_names.h b/src/jit/ICorJitInfo_API_names.h
index c9edd544be..45a1a080ac 100644
--- a/src/jit/ICorJitInfo_API_names.h
+++ b/src/jit/ICorJitInfo_API_names.h
@@ -51,6 +51,8 @@ DEF_CLR_API(LongLifetimeMalloc)
DEF_CLR_API(LongLifetimeFree)
DEF_CLR_API(getClassModuleIdForStatics)
DEF_CLR_API(getClassSize)
+DEF_CLR_API(getHeapClassSize)
+DEF_CLR_API(canAllocateOnStack)
DEF_CLR_API(getClassAlignmentRequirement)
DEF_CLR_API(getClassGClayout)
DEF_CLR_API(getClassNumInstanceFields)
diff --git a/src/jit/ICorJitInfo_API_wrapper.hpp b/src/jit/ICorJitInfo_API_wrapper.hpp
index 9eaeb5d179..970a9b8a30 100644
--- a/src/jit/ICorJitInfo_API_wrapper.hpp
+++ b/src/jit/ICorJitInfo_API_wrapper.hpp
@@ -481,6 +481,22 @@ unsigned WrapICorJitInfo::getClassSize(CORINFO_CLASS_HANDLE cls)
return temp;
}
+unsigned WrapICorJitInfo::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(getHeapClassSize);
+ unsigned temp = wrapHnd->getHeapClassSize(cls);
+ API_LEAVE(getHeapClassSize);
+ return temp;
+}
+
+BOOL WrapICorJitInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ API_ENTER(canAllocateOnStack);
+ BOOL temp = wrapHnd->canAllocateOnStack(cls);
+ API_LEAVE(canAllocateOnStack);
+ return temp;
+}
+
unsigned WrapICorJitInfo::getClassAlignmentRequirement(
CORINFO_CLASS_HANDLE cls,
BOOL fDoubleAlignHint)
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 7532f5e9aa..f52009ac3f 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -1937,6 +1937,72 @@ CEEInfo::getClassSize(
return result;
}
+//---------------------------------------------------------------------------------------
+//
+// Get the size of a reference type as allocated on the heap. This includes the size of the fields
+// (and any padding between the fields) and the size of a method table pointer but doesn't include
+// object header size or any padding for minimum size.
+unsigned
+CEEInfo::getHeapClassSize(
+ CORINFO_CLASS_HANDLE clsHnd)
+{
+ CONTRACTL{
+ SO_TOLERANT;
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ unsigned result = 0;
+
+ JIT_TO_EE_TRANSITION_LEAF();
+
+ TypeHandle VMClsHnd(clsHnd);
+ MethodTable* pMT = VMClsHnd.GetMethodTable();
+ _ASSERTE(pMT);
+ _ASSERTE(!pMT->IsValueType());
+
+ // Add OBJECT_SIZE to account for method table pointer.
+ result = pMT->GetNumInstanceFieldBytes() + OBJECT_SIZE;
+
+ EE_TO_JIT_TRANSITION_LEAF();
+ return result;
+}
+
+//---------------------------------------------------------------------------------------
+//
+// Return TRUE if an object of this type can be allocated on the stack.
+BOOL CEEInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE clsHnd)
+{
+ CONTRACTL{
+ SO_TOLERANT;
+ NOTHROW;
+ GC_NOTRIGGER;
+ MODE_PREEMPTIVE;
+ } CONTRACTL_END;
+
+ BOOL result = FALSE;
+
+ JIT_TO_EE_TRANSITION_LEAF();
+
+ TypeHandle VMClsHnd(clsHnd);
+ MethodTable* pMT = VMClsHnd.GetMethodTable();
+ _ASSERTE(pMT);
+ _ASSERTE(!pMT->IsValueType());
+
+ result = !pMT->HasFinalizer();
+
+#ifdef FEATURE_READYTORUN_COMPILER
+ if (IsReadyToRunCompilation() && !pMT->IsInheritanceChainLayoutFixedInCurrentVersionBubble())
+ {
+ result = false;
+ }
+#endif
+
+ EE_TO_JIT_TRANSITION_LEAF();
+ return result;
+}
+
unsigned CEEInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE type, BOOL fDoubleAlignHint)
{
CONTRACTL {
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index a4f6576cdf..d99a0ff2ec 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -491,6 +491,8 @@ public:
BOOL isStructRequiringStackAllocRetBuf(CORINFO_CLASS_HANDLE cls);
unsigned getClassSize (CORINFO_CLASS_HANDLE cls);
+ unsigned getHeapClassSize(CORINFO_CLASS_HANDLE cls);
+ BOOL canAllocateOnStack(CORINFO_CLASS_HANDLE cls);
unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint);
static unsigned getClassAlignmentRequirementStatic(TypeHandle clsHnd);
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index 341e0d82af..486cc18406 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -3315,6 +3315,16 @@ unsigned ZapInfo::getClassSize(CORINFO_CLASS_HANDLE cls)
return size;
}
+unsigned ZapInfo::getHeapClassSize(CORINFO_CLASS_HANDLE cls)
+{
+ return m_pEEJitInfo->getHeapClassSize(cls);
+}
+
+BOOL ZapInfo::canAllocateOnStack(CORINFO_CLASS_HANDLE cls)
+{
+ return m_pEEJitInfo->canAllocateOnStack(cls);
+}
+
unsigned ZapInfo::getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint)
{
return m_pEEJitInfo->getClassAlignmentRequirement(cls, fDoubleAlignHint);
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index 8b5ad1d4e8..70d6332790 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -529,6 +529,8 @@ public:
size_t getClassModuleIdForStatics(CORINFO_CLASS_HANDLE cls, CORINFO_MODULE_HANDLE *pModule, void **ppIndirection);
unsigned getClassSize(CORINFO_CLASS_HANDLE cls);
+ unsigned getHeapClassSize(CORINFO_CLASS_HANDLE cls);
+ BOOL canAllocateOnStack(CORINFO_CLASS_HANDLE cls);
unsigned getClassAlignmentRequirement(CORINFO_CLASS_HANDLE cls, BOOL fDoubleAlignHint);
CORINFO_FIELD_HANDLE getFieldInClass(CORINFO_CLASS_HANDLE clsHnd, INT num);