Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
JitEE interface additions to support object stack allocation. (#20283)
Browse files Browse the repository at this point in the history
Add two methods to JitEE interface: getHeapClassSize and canAllocateOnStack.

Change JITEEVersionIdentifier.
  • Loading branch information
erozenfeld authored Oct 11, 2018
1 parent 5c03955 commit 5f9f374
Show file tree
Hide file tree
Showing 15 changed files with 230 additions and 6 deletions.
5 changes: 5 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
44 changes: 44 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
12 changes: 11 additions & 1 deletion src/ToolBox/superpmi/superpmi-shared/methodcontext.h
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,14 @@ class MethodContext
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);
Expand Down Expand Up @@ -1309,7 +1317,7 @@ class MethodContext
};

// ********************* Please keep this up-to-date to ease adding more ***************
// Highest packet number: 168
// Highest packet number: 171
// *************************************************************************************
enum mcPackets
{
Expand Down Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
13 changes: 13 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
11 changes: 11 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
13 changes: 13 additions & 0 deletions src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
19 changes: 14 additions & 5 deletions src/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2383,6 +2383,15 @@ class ICorStaticInfo
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
Expand Down
2 changes: 2 additions & 0 deletions src/jit/ICorJitInfo_API_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 16 additions & 0 deletions src/jit/ICorJitInfo_API_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
66 changes: 66 additions & 0 deletions src/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 2 additions & 0 deletions src/vm/jitinterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,8 @@ class CEEInfo : public ICorJitInfo
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);

Expand Down
10 changes: 10 additions & 0 deletions src/zap/zapinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions src/zap/zapinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ class ZapInfo
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);
Expand Down

0 comments on commit 5f9f374

Please sign in to comment.