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

Allow jit to examine type of initonly static ref typed fields #20886

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
3 changes: 3 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/icorjitinfoimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,9 @@ unsigned getClassDomainID(CORINFO_CLASS_HANDLE cls, void** ppIndirection = NULL)
// return the data's address (for static fields only)
void* getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection = NULL);

// return the class handle for the current value of a static field
CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative);

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
CORINFO_VARARGS_HANDLE getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection = NULL);

Expand Down
1 change: 1 addition & 0 deletions src/ToolBox/superpmi/superpmi-shared/lwmlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ LWM(GetDelegateCtor, Agnostic_GetDelegateCtorIn, Agnostic_GetDelegateCtorOut)
LWM(GetEEInfo, DWORD, Agnostic_CORINFO_EE_INFO)
LWM(GetEHinfo, DLD, Agnostic_CORINFO_EH_CLAUSE)
LWM(GetFieldAddress, DWORDLONG, Agnostic_GetFieldAddress)
LWM(GetStaticFieldCurrentClass, DWORDLONG, Agnostic_GetStaticFieldCurrentClass)
LWM(GetFieldClass, DWORDLONG, DWORDLONG)
LWM(GetFieldInClass, DLD, DWORDLONG)
LWM(GetFieldInfo, Agnostic_GetFieldInfo, Agnostic_CORINFO_FIELD_INFO)
Expand Down
31 changes: 31 additions & 0 deletions src/ToolBox/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3466,6 +3466,37 @@ void* MethodContext::repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd
return temp;
}

void MethodContext::recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool isSpeculative, CORINFO_CLASS_HANDLE result)
{
if (GetStaticFieldCurrentClass == nullptr)
GetStaticFieldCurrentClass = new LightWeightMap<DWORDLONG, Agnostic_GetStaticFieldCurrentClass>();

Agnostic_GetStaticFieldCurrentClass value;

value.classHandle = (DWORDLONG)result;
value.isSpeculative = isSpeculative;

GetStaticFieldCurrentClass->Add((DWORDLONG)field, value);
DEBUG_REC(dmpGetFieldAddress((DWORDLONG)field, value));
}
void MethodContext::dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value)
{
printf("GetStaticFieldCurrentClass key fld-%016llX, value clsHnd-%016llX isSpeculative-%u", key, value.classHandle, value.isSpeculative);
}
CORINFO_CLASS_HANDLE MethodContext::repGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative)
{
Agnostic_GetStaticFieldCurrentClass value = GetStaticFieldCurrentClass->Get((DWORDLONG) field);

if (pIsSpeculative != nullptr)
{
*pIsSpeculative = value.isSpeculative;
}

CORINFO_CLASS_HANDLE result = (CORINFO_CLASS_HANDLE) value.classHandle;
DEBUG_REP(dmpGetStaticFieldCurrentValue((DWORDLONG)field, value));
return result;
}

void MethodContext::recGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs, unsigned len, unsigned result)
{
if (GetClassGClayout == 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 @@ -174,6 +174,11 @@ class MethodContext
DWORDLONG fieldAddress;
DWORD fieldValue;
};
struct Agnostic_GetStaticFieldCurrentClass
{
DWORDLONG classHandle;
bool isSpeculative;
};
struct Agnostic_CORINFO_RESOLVED_TOKEN
{
Agnostic_CORINFO_RESOLVED_TOKENin inValue;
Expand Down Expand Up @@ -923,6 +928,10 @@ class MethodContext
void dmpGetFieldAddress(DWORDLONG key, const Agnostic_GetFieldAddress& value);
void* repGetFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection);

void recGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool isSpeculative, CORINFO_CLASS_HANDLE result);
void dmpGetStaticFieldCurrentClass(DWORDLONG key, const Agnostic_GetStaticFieldCurrentClass& value);
CORINFO_CLASS_HANDLE repGetStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool* pIsSpeculative);

void recGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs, unsigned len, unsigned result);
void dmpGetClassGClayout(DWORDLONG key, const Agnostic_GetClassGClayout& value);
unsigned repGetClassGClayout(CORINFO_CLASS_HANDLE cls, BYTE* gcPtrs);
Expand Down Expand Up @@ -1317,7 +1326,7 @@ class MethodContext
};

// ********************* Please keep this up-to-date to ease adding more ***************
// Highest packet number: 171
// Highest packet number: 172
// *************************************************************************************
enum mcPackets
{
Expand Down Expand Up @@ -1396,6 +1405,7 @@ enum mcPackets
Packet_GetEEInfo = 50,
Packet_GetEHinfo = 51,
Packet_GetFieldAddress = 52,
Packet_GetStaticFieldCurrentClass = 172, // Added 11/7/2018
Packet_GetFieldClass = 53,
Packet_GetFieldInClass = 54,
Packet_GetFieldInfo = 55,
Expand Down
14 changes: 14 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-collector/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1816,6 +1816,20 @@ void* interceptor_ICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd
return temp;
}

// return the class handle for the current value of a static field
CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative)
{
mc->cr->AddCall("getStaticFieldCurrentClass");
bool localIsSpeculative = false;
CORINFO_CLASS_HANDLE result = original_ICorJitInfo->getStaticFieldCurrentClass(field, &localIsSpeculative);
mc->recGetStaticFieldCurrentClass(field, localIsSpeculative, result);
if (pIsSpeculative != nullptr)
{
*pIsSpeculative = localIsSpeculative;
}
return result;
}

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection)
{
Expand Down
7 changes: 7 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-counter/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1403,6 +1403,13 @@ void* interceptor_ICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd
return original_ICorJitInfo->getFieldAddress(field, ppIndirection);
}

// return the class handle for the current value of a static field
CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative)
{
mcs->AddCall("getStaticFieldCurrentClass");
return original_ICorJitInfo->getStaticFieldCurrentClass(field, pIsSpeculative);
}

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection)
{
Expand Down
6 changes: 6 additions & 0 deletions src/ToolBox/superpmi/superpmi-shim-simple/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,12 @@ void* interceptor_ICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppInd
return original_ICorJitInfo->getFieldAddress(field, ppIndirection);
}

// return the class handle for the current value of a static field
CORINFO_CLASS_HANDLE interceptor_ICJI::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative)
{
return original_ICorJitInfo->getStaticFieldCurrentClass(field, pIsSpeculative);
}

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
CORINFO_VARARGS_HANDLE interceptor_ICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection)
{
Expand Down
7 changes: 7 additions & 0 deletions src/ToolBox/superpmi/superpmi/icorjitinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1516,6 +1516,13 @@ void* MyICJI::getFieldAddress(CORINFO_FIELD_HANDLE field, void** ppIndirection)
return jitInstance->mc->repGetFieldAddress(field, ppIndirection);
}

// return the class handle for the current value of a static field
CORINFO_CLASS_HANDLE MyICJI::getStaticFieldCurrentClass(CORINFO_FIELD_HANDLE field, bool *pIsSpeculative)
{
jitInstance->mc->cr->AddCall("getStaticFieldCurrentClass");
return jitInstance->mc->repGetStaticFieldCurrentClass(field, pIsSpeculative);
}

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
CORINFO_VARARGS_HANDLE MyICJI::getVarArgsHandle(CORINFO_SIG_INFO* pSig, void** ppIndirection)
{
Expand Down
2 changes: 2 additions & 0 deletions src/dlls/mscorrc/mscorrc.rc
Original file line number Diff line number Diff line change
Expand Up @@ -961,6 +961,8 @@ BEGIN
IDS_E_TYPEACCESS "Attempt by method '%1' to access type '%2' failed.%3"

IDS_INVOKE_NULLREF_RETURNED "The target method returned a null reference."

IDS_EE_CANNOT_SET_INITONLY_STATIC_FIELD "Cannot set initonly static field '%1%' after type '%2' is initialized."
END

// These strings are used for Event Log Entry
Expand Down
2 changes: 2 additions & 0 deletions src/dlls/mscorrc/resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -716,3 +716,5 @@
#define IDS_EE_ERROR_COM 0x2641

#define IDS_INVOKE_NULLREF_RETURNED 0x2642

#define IDS_EE_CANNOT_SET_INITONLY_STATIC_FIELD 0x2643
26 changes: 21 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 = { /* 3be99428-36f8-4a6c-acde-b42778b0f8bf */
0x3be99428,
0x36f8,
0x4a6c,
{0xac, 0xde, 0xb4, 0x27, 0x78, 0xb0, 0xf8, 0xbf}
SELECTANY const GUID JITEEVersionIdentifier = { /* b2da2a6e-72fa-4730-b47c-4c9275e1c5ce */
0xb2da2a6e,
0x72fa,
0x4730,
{0xb4, 0x7c, 0x4c, 0x92, 0x75, 0xe1, 0xc5, 0xce}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -3119,6 +3119,22 @@ class ICorDynamicInfo : public ICorStaticInfo
void **ppIndirection = NULL
) = 0;

// If pIsSpeculative is NULL, return the class handle for the value of ref-class typed
// static readonly fields, if there is a unique location for the static and the class
// is already initialized.
//
// If pIsSpeculative is not NULL, fetch the class handle for the value of all ref-class
// typed static fields, if there is a unique location for the static and the field is
// not null.
//
// Set *pIsSpeculative true if this type may change over time (field is not readonly or
// is readonly but class has not yet finished initialization). Set *pIsSpeculative false
// if this type will not change.
virtual CORINFO_CLASS_HANDLE getStaticFieldCurrentClass(
CORINFO_FIELD_HANDLE field,
bool *pIsSpeculative = NULL
) = 0;

// registers a vararg sig & returns a VM cookie for it (which can contain other stuff)
virtual CORINFO_VARARGS_HANDLE getVarArgsHandle(
CORINFO_SIG_INFO *pSig,
Expand Down
6 changes: 4 additions & 2 deletions src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2603,15 +2603,17 @@ class Compiler
// Get the handle, and assert if not found.
CORINFO_CLASS_HANDLE gtGetStructHandle(GenTree* tree);
// Get the handle for a ref type.
CORINFO_CLASS_HANDLE gtGetClassHandle(GenTree* tree, bool* isExact, bool* isNonNull);
CORINFO_CLASS_HANDLE gtGetClassHandle(GenTree* tree, bool* pIsExact, bool* pIsNonNull);
// Get the class handle for an helper call
CORINFO_CLASS_HANDLE gtGetHelperCallClassHandle(GenTreeCall* call, bool* isExact, bool* isNonNull);
CORINFO_CLASS_HANDLE gtGetHelperCallClassHandle(GenTreeCall* call, bool* pIsExact, bool* pIsNonNull);
// Get the element handle for an array of ref type.
CORINFO_CLASS_HANDLE gtGetArrayElementClassHandle(GenTree* array);
// Get a class handle from a helper call argument
CORINFO_CLASS_HANDLE gtGetHelperArgClassHandle(GenTree* array,
unsigned* runtimeLookupCount = nullptr,
GenTree** handleTree = nullptr);
// Get the class handle for a field
CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull);
// Check if this tree is a gc static base helper call
bool gtIsStaticGCBaseHelperCall(GenTree* tree);

Expand Down
Loading