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

JitEE interface additions to support object stack allocation. #20283

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rev JIT/EE interface GUID?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Look for JITEEVersionIdentifier)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

) = 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 @@ -1945,6 +1945,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
erozenfeld marked this conversation as resolved.
Show resolved Hide resolved
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;
erozenfeld marked this conversation as resolved.
Show resolved Hide resolved

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;
}

erozenfeld marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -484,6 +484,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 @@ -3307,6 +3307,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