summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2016-03-31 00:44:55 -0700
committerJan Kotas <jkotas@microsoft.com>2016-03-31 00:44:55 -0700
commitd3502c29c511292d0c6046b1aafe87295d2372d9 (patch)
tree92a8862dfa8f94137662dd16aae5d1a7b2859f72
parent0cce34c8976fd887bee0cf877c36b9abfa555635 (diff)
parentc4378e7f0773577e9924ff4ebad0cc3af43fb3a8 (diff)
downloadcoreclr-d3502c29c511292d0c6046b1aafe87295d2372d9.tar.gz
coreclr-d3502c29c511292d0c6046b1aafe87295d2372d9.tar.bz2
coreclr-d3502c29c511292d0c6046b1aafe87295d2372d9.zip
Merge pull request #4021 from dotnet-bot/from-tfs
Merge changes from TFS
-rw-r--r--src/ToolBox/SOS/Strike/platformspecific.h4
-rw-r--r--src/ToolBox/SOS/Strike/util.cpp2
-rw-r--r--src/debug/daccess/fntableaccess.cpp16
-rw-r--r--src/debug/daccess/fntableaccess.h8
-rw-r--r--src/debug/daccess/nidump.cpp2
-rw-r--r--src/gcdump/gcdumpnonx86.cpp23
-rw-r--r--src/gcinfo/gcinfodumper.cpp79
-rw-r--r--src/inc/clrnt.h13
-rw-r--r--src/inc/corinfo.h18
-rw-r--r--src/inc/regdisp.h1
-rw-r--r--src/jit/flowgraph.cpp7
-rw-r--r--[-rwxr-xr-x]src/jit/gentree.cpp2
-rw-r--r--src/jit/gentree.h2
-rw-r--r--src/jit/importer.cpp6
-rw-r--r--src/unwinder/amd64/unwinder_amd64.cpp4
-rw-r--r--src/unwinder/arm/unwinder_arm.cpp2
-rw-r--r--src/unwinder/arm64/unwinder_arm64.cpp8
-rw-r--r--src/unwinder/unwinder.cpp2
-rw-r--r--src/vm/amd64/cgenamd64.cpp2
-rw-r--r--src/vm/amd64/cgencpu.h2
-rw-r--r--src/vm/amd64/excepamd64.cpp6
-rw-r--r--src/vm/amd64/excepcpu.h4
-rw-r--r--src/vm/clsload.hpp8
-rw-r--r--src/vm/codeman.cpp28
-rw-r--r--src/vm/codeman.h10
-rw-r--r--src/vm/exceptionhandling.cpp4
-rw-r--r--src/vm/i386/stublinkerx86.cpp2
-rw-r--r--src/vm/jithelpers.cpp8
-rw-r--r--src/vm/jitinterface.cpp19
-rw-r--r--src/vm/jitinterface.h6
-rw-r--r--src/vm/nativeformatreader.h6
-rw-r--r--src/vm/readytoruninfo.cpp6
-rw-r--r--src/vm/rtlfunctions.h4
-rw-r--r--src/vm/stackwalk.cpp8
-rw-r--r--src/vm/stublink.cpp4
-rw-r--r--src/vm/stublink.h6
-rw-r--r--src/vm/threads.h2
-rw-r--r--src/vm/win32threadpool.cpp2
-rw-r--r--src/zap/zapcode.cpp2
-rw-r--r--src/zap/zapcode.h2
-rw-r--r--src/zap/zapimport.cpp9
-rw-r--r--src/zap/zapimport.h3
-rw-r--r--src/zap/zapinfo.cpp22
-rw-r--r--src/zap/zapinfo.h6
-rw-r--r--tests/src/readytorun/main.cs23
45 files changed, 289 insertions, 114 deletions
diff --git a/src/ToolBox/SOS/Strike/platformspecific.h b/src/ToolBox/SOS/Strike/platformspecific.h
index d79a46055e..fdbc5b52ca 100644
--- a/src/ToolBox/SOS/Strike/platformspecific.h
+++ b/src/ToolBox/SOS/Strike/platformspecific.h
@@ -47,6 +47,10 @@ struct DT_UNICODE_STRING
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4 // ARM Thumb-2 Little-Endian
#endif
+#ifndef IMAGE_FILE_MACHINE_ARM64
+#define IMAGE_FILE_MACHINE_ARM64 0xAA64 // ARM64 Little-Endian
+#endif
+
#ifdef _TARGET_WIN64_
typedef ULONG DT_GDI_HANDLE_BUFFER[DT_GDI_HANDLE_BUFFER_SIZE64];
#else
diff --git a/src/ToolBox/SOS/Strike/util.cpp b/src/ToolBox/SOS/Strike/util.cpp
index 8722845a72..c26bae49fa 100644
--- a/src/ToolBox/SOS/Strike/util.cpp
+++ b/src/ToolBox/SOS/Strike/util.cpp
@@ -4557,6 +4557,8 @@ public:
*pPlatform = CORDB_PLATFORM_WINDOWS_AMD64;
else if(platformKind == IMAGE_FILE_MACHINE_ARMNT)
*pPlatform = CORDB_PLATFORM_WINDOWS_ARM;
+ else if(platformKind == IMAGE_FILE_MACHINE_ARM64)
+ *pPlatform = CORDB_PLATFORM_WINDOWS_ARM64;
else
return E_FAIL;
#endif
diff --git a/src/debug/daccess/fntableaccess.cpp b/src/debug/daccess/fntableaccess.cpp
index 66298832d2..e7b96ec3e0 100644
--- a/src/debug/daccess/fntableaccess.cpp
+++ b/src/debug/daccess/fntableaccess.cpp
@@ -143,7 +143,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
- OUT PRUNTIME_FUNCTION* ppFunctions)
+ OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
@@ -179,7 +179,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
DWORD nEntries;
DWORD index;
DWORD_PTR pUnwindInfo;
- PRUNTIME_FUNCTION pFunctions;
+ PT_RUNTIME_FUNCTION pFunctions;
LONG64 lSmallestOffset;
//
@@ -217,7 +217,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_JIT(IN ReadMemoryFunction
OutOfProcessFindHeader(fpReadMemory, pUserContext, Hp.pHdrMap, hdrOffset, hdrOffset);
}
- pFunctions = (PRUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(RUNTIME_FUNCTION)));
+ pFunctions = (PT_RUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(T_RUNTIME_FUNCTION)));
*ppFunctions = pFunctions;
*pnEntries = nEntries;
@@ -274,7 +274,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
- OUT PRUNTIME_FUNCTION* ppFunctions)
+ OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
@@ -292,7 +292,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction
UINT nEntries = 0;
UINT nEntriesAllocated = 0;
- RUNTIME_FUNCTION *rgFunctions = NULL;
+ PT_RUNTIME_FUNCTION rgFunctions = NULL;
for (int pass = 1; pass <= 2; pass++)
{
@@ -371,7 +371,7 @@ static NTSTATUS OutOfProcessFunctionTableCallback_Stub(IN ReadMemoryFunction
_ASSERTE(!nEntriesAllocated);
nEntriesAllocated = nEntries;
- rgFunctions = (PRUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(RUNTIME_FUNCTION)));
+ rgFunctions = (PT_RUNTIME_FUNCTION)ClrHeapAlloc(ClrGetProcessHeap(), HEAP_ZERO_MEMORY, S_SIZE_T(nEntries) * S_SIZE_T(sizeof(T_RUNTIME_FUNCTION)));
nEntries = 0;
}
else
@@ -397,7 +397,7 @@ BOOL ReadMemory(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_
extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess,
IN PVOID TableAddress,
OUT PULONG pnEntries,
- OUT PRUNTIME_FUNCTION* ppFunctions)
+ OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
return OutOfProcessFunctionTableCallbackEx(&ReadMemory, hProcess, TableAddress, pnEntries, ppFunctions);
}
@@ -406,7 +406,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction
IN PVOID pUserContext,
IN PVOID TableAddress,
OUT PULONG pnEntries,
- OUT PRUNTIME_FUNCTION* ppFunctions)
+ OUT PT_RUNTIME_FUNCTION* ppFunctions)
{
if (NULL == pnEntries) { return STATUS_INVALID_PARAMETER_3; }
if (NULL == ppFunctions) { return STATUS_INVALID_PARAMETER_4; }
diff --git a/src/debug/daccess/fntableaccess.h b/src/debug/daccess/fntableaccess.h
index 9e98e7c51f..0dbabdf8c9 100644
--- a/src/debug/daccess/fntableaccess.h
+++ b/src/debug/daccess/fntableaccess.h
@@ -53,7 +53,7 @@ typedef struct _FakeHpRealCodeHdr
LPVOID phdrJitGCInfo; // changed from BYTE*
LPVOID hdrMDesc; // changed from MethodDesc*
DWORD nUnwindInfos;
- RUNTIME_FUNCTION unwindInfos[0];
+ T_RUNTIME_FUNCTION unwindInfos[0];
} FakeRealCodeHeader;
typedef struct _FakeHpCodeHdr
@@ -75,7 +75,7 @@ struct FakeStubUnwindInfoHeaderSuffix
struct FakeStubUnwindInfoHeader
{
FakeStubUnwindInfoHeader *pNext;
- RUNTIME_FUNCTION FunctionEntry;
+ T_RUNTIME_FUNCTION FunctionEntry;
UNWIND_INFO UnwindInfo; // variable length
};
@@ -200,7 +200,7 @@ static_assert_no_msg( FAKEDYNFNTABLE_STUB
BOOL WINAPI DllMain(HINSTANCE hDLL, DWORD dwReason, LPVOID pReserved);
//NTSTATUS OutOfProcessFindHeader(HANDLE hProcess, DWORD_PTR pMapIn, DWORD_PTR addr, DWORD_PTR &codeHead);
-extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PRUNTIME_FUNCTION* ppFunctions);
+extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);
// OutOfProcessFunctionTableCallbackEx is like the standard OS-defined OutOfProcessFunctionTableCallback, but rather
@@ -209,7 +209,7 @@ extern "C" NTSTATUS OutOfProcessFunctionTableCallback(IN HANDLE hProcess, IN
// pUserContext is passed directly to fpReadMemory, and the semantics of all other ReadMemoryFunction arguments (and return value) are
// the same as those for kernel32!ReadProcessMemory.
typedef BOOL (ReadMemoryFunction)(PVOID pUserContext, LPCVOID lpBaseAddress, PVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead);
-extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PRUNTIME_FUNCTION* ppFunctions);
+extern "C" NTSTATUS OutOfProcessFunctionTableCallbackEx(IN ReadMemoryFunction fpReadMemory, IN PVOID pUserContext, IN PVOID TableAddress, OUT PULONG pnEntries, OUT PT_RUNTIME_FUNCTION* ppFunctions);
#endif // CHECK_DUPLICATED_STRUCT_LAYOUTS
diff --git a/src/debug/daccess/nidump.cpp b/src/debug/daccess/nidump.cpp
index 8dcac82865..9b4fe1c176 100644
--- a/src/debug/daccess/nidump.cpp
+++ b/src/debug/daccess/nidump.cpp
@@ -9315,7 +9315,7 @@ void NativeImageDumper::DumpReadyToRun()
if (pRuntimeFunctionsDir != NULL)
{
m_pRuntimeFunctions = dac_cast<PTR_RUNTIME_FUNCTION>(m_decoder.GetDirectoryData(pRuntimeFunctionsDir));
- m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(RUNTIME_FUNCTION);
+ m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(T_RUNTIME_FUNCTION);
}
else
{
diff --git a/src/gcdump/gcdumpnonx86.cpp b/src/gcdump/gcdumpnonx86.cpp
index 361a4f8ec4..8167d3abd8 100644
--- a/src/gcdump/gcdumpnonx86.cpp
+++ b/src/gcdump/gcdumpnonx86.cpp
@@ -42,12 +42,27 @@ PCSTR GetRegName (UINT32 regnum)
return "???";
#elif defined(_TARGET_ARM64_)
- if (regnum > 28)
- return "???";
static CHAR szRegName[16];
- _snprintf_s(szRegName, _countof(szRegName), sizeof(szRegName), "X%u", regnum);
- return szRegName;
+ if (regnum < 29)
+ {
+ _snprintf_s(szRegName, _countof(szRegName), sizeof(szRegName), "X%u", regnum);
+ return szRegName;
+ }
+ else if(regnum == 29)
+ {
+ return "Fp";
+ }
+ else if(regnum == 30)
+ {
+ return "Lr";
+ }
+ else if(regnum == 31)
+ {
+ return "Sp";
+ }
+
+ return "???";
#elif defined(_TARGET_ARM_)
if (regnum > 128)
return "???";
diff --git a/src/gcinfo/gcinfodumper.cpp b/src/gcinfo/gcinfodumper.cpp
index 68465a301e..34666d63e8 100644
--- a/src/gcinfo/gcinfodumper.cpp
+++ b/src/gcinfo/gcinfodumper.cpp
@@ -75,6 +75,11 @@ void GcInfoDumper::FreePointerRecords (LivePointerRecord *pRecords)
}
}
+//This function tries to find the address of the managed object in the registers of the current function's context,
+//failing which it checks if it is present in the stack of the current function. IF it finds one it reports appropriately
+//
+//For Amd64, this additionally tries to probe in the stack for the caller.
+//This behavior largely seems to be present for legacy x64 jit and is not likely to be used anywhere else
BOOL GcInfoDumper::ReportPointerRecord (
UINT32 CodeOffset,
BOOL fLive,
@@ -146,7 +151,6 @@ BOOL GcInfoDumper::ReportPointerRecord (
{ FIELD_OFFSET(T_CONTEXT, Sp) },
{ FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, R7) },
#elif defined(_TARGET_ARM64_)
-//ARM64TODO: Verify the correctness of the following for ARM64
#undef REG
#define REG(reg, field) { FIELD_OFFSET(Arm64VolatileContextPointer, field) }
REG(x0, X0),
@@ -167,7 +171,6 @@ BOOL GcInfoDumper::ReportPointerRecord (
REG(x15, X15),
REG(x16, X16),
REG(x17, X17),
- { FIELD_OFFSET(T_CONTEXT, X18) },
#undef REG
#define REG(reg, field) { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, field) }
REG(x19, X19),
@@ -180,11 +183,14 @@ BOOL GcInfoDumper::ReportPointerRecord (
REG(x26, X26),
REG(x27, X27),
REG(x28, X28),
+ REG(Fp, Fp),
+ REG(Lr, Lr),
{ FIELD_OFFSET(T_CONTEXT, Sp) },
- { FIELD_OFFSET(T_KNONVOLATILE_CONTEXT_POINTERS, Lr) },
+#undef REG
+#else
+PORTABILITY_ASSERT("GcInfoDumper::ReportPointerRecord is not implemented on this platform.")
#endif
-#undef REG
};
const UINT nCONTEXTRegisters = sizeof(rgRegisters)/sizeof(rgRegisters[0]);
@@ -199,13 +205,12 @@ BOOL GcInfoDumper::ReportPointerRecord (
iSPRegister = (FIELD_OFFSET(CONTEXT, Rsp) - FIELD_OFFSET(CONTEXT, Rax)) / sizeof(ULONGLONG);
#elif defined(_TARGET_ARM64_)
iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, X0)) / sizeof(ULONGLONG);
- UINT iBFRegister = m_StackBaseRegister;
#elif defined(_TARGET_ARM_)
iSPRegister = (FIELD_OFFSET(T_CONTEXT, Sp) - FIELD_OFFSET(T_CONTEXT, R0)) / sizeof(ULONG);
UINT iBFRegister = m_StackBaseRegister;
#endif
-#ifdef _TARGET_ARM_
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
BYTE* pContext = (BYTE*)&(pRD->volatileCurrContextPointers);
#else
BYTE* pContext = (BYTE*)pRD->pCurrentContext;
@@ -254,6 +259,25 @@ BOOL GcInfoDumper::ReportPointerRecord (
{
break;
}
+#elif defined (_TARGET_ARM64_)
+
+ if (ctx == 1)
+ {
+ if (iReg < 18 ) // skip volatile registers for second context
+ {
+ continue;
+ }
+
+ if (iReg == 30)
+ {
+ iEncodedReg = iSPRegister;
+ }
+ }
+
+ if (ctx == 0 && iReg > 17)
+ {
+ break;
+ }
#endif
{
_ASSERTE(iReg < nCONTEXTRegisters);
@@ -271,6 +295,13 @@ BOOL GcInfoDumper::ReportPointerRecord (
{
pReg = *(SIZE_T**)((BYTE*)pRD->pCurrentContextPointers + rgRegisters[iEncodedReg].cbContextOffset);
}
+
+#elif defined(_TARGET_ARM64_)
+ pReg = *(SIZE_T**)(pContext + rgRegisters[iReg].cbContextOffset);
+ if (iEncodedReg == iSPRegister)
+ {
+ pReg = (SIZE_T*)((BYTE*)pRD->pCurrentContext + rgRegisters[iEncodedReg].cbContextOffset);
+ }
#else
pReg = (SIZE_T*)(pContext + rgRegisters[iReg].cbContextOffset);
#endif
@@ -286,7 +317,7 @@ BOOL GcInfoDumper::ReportPointerRecord (
if (ptr == (SIZE_T)pReg)
{
// Make sure the register is in the current frame.
-#ifndef _TARGET_ARM_
+#if defined(_TARGET_AMD64_)
if (0 != ctx)
{
m_Error = REPORTED_REGISTER_IN_CALLERS_FRAME;
@@ -338,10 +369,14 @@ BOOL GcInfoDumper::ReportPointerRecord (
GcStackSlotBase base;
if (iSPRegister == iEncodedReg)
{
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
+ base = GC_SP_REL;
+#else
if (0 == ctx)
base = GC_SP_REL;
else
base = GC_CALLER_SP_REL;
+#endif //defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
}
else
{
@@ -363,7 +398,7 @@ BOOL GcInfoDumper::ReportPointerRecord (
}
}
-#ifdef _TARGET_ARM_
+#if defined(_TARGET_ARM_) || defined(_TARGET_ARM64_)
pContext = (BYTE*)pRD->pCurrentContextPointers;
#else
pContext = (BYTE*)pRD->pCallerContext;
@@ -542,6 +577,34 @@ GcInfoDumper::EnumerateStateChangesResults GcInfoDumper::EnumerateStateChanges (
}
/// Set R12
*(ppVolatileReg+4) = &regdisp.pCurrentContext->R0+12;
+
+#elif defined(_TARGET_ARM64_)
+ FILL_REGS(pCurrentContext->X0, 33);
+ FILL_REGS(pCallerContext->X0, 33);
+
+ regdisp.pCurrentContextPointers = &regdisp.ctxPtrsOne;
+ regdisp.pCallerContextPointers = &regdisp.ctxPtrsTwo;
+
+ ULONG64 **ppCurrentReg = &regdisp.pCurrentContextPointers->X19;
+ ULONG64 **ppCallerReg = &regdisp.pCallerContextPointers->X19;
+
+ for (iReg = 0; iReg < 11; iReg++)
+ {
+ *(ppCurrentReg + iReg) = &regdisp.pCurrentContext->X19 + iReg;
+ *(ppCallerReg + iReg) = &regdisp.pCallerContext->X19 + iReg;
+ }
+
+ /// Set Lr
+ *(ppCurrentReg + 11) = &regdisp.pCurrentContext->Lr;
+ *(ppCallerReg + 11) = &regdisp.pCallerContext->Lr;
+
+ ULONG64 **ppVolatileReg = &regdisp.volatileCurrContextPointers.X0;
+ for (iReg = 0; iReg < 18; iReg++)
+ {
+ *(ppVolatileReg+iReg) = &regdisp.pCurrentContext->X0 + iReg;
+ }
+#else
+PORTABILITY_ASSERT("GcInfoDumper::EnumerateStateChanges is not implemented on this platform.")
#endif
#undef FILL_REGS
diff --git a/src/inc/clrnt.h b/src/inc/clrnt.h
index 5958906898..fd7e56b61b 100644
--- a/src/inc/clrnt.h
+++ b/src/inc/clrnt.h
@@ -762,7 +762,7 @@ typedef enum _FUNCTION_TABLE_TYPE {
typedef struct _DYNAMIC_FUNCTION_TABLE {
LIST_ENTRY Links;
- PRUNTIME_FUNCTION FunctionTable;
+ PT_RUNTIME_FUNCTION FunctionTable;
LARGE_INTEGER TimeStamp;
#ifdef _TARGET_ARM_
@@ -796,7 +796,7 @@ typedef struct _DYNAMIC_FUNCTION_TABLE {
#define RUNTIME_FUNCTION__GetUnwindInfoAddress(prf) (prf)->UnwindData
#define RUNTIME_FUNCTION__SetUnwindInfoAddress(prf,address) do { (prf)->UnwindData = (address); } while (0)
-#define OFFSETOF__RUNTIME_FUNCTION__UnwindInfoAddress offsetof(RUNTIME_FUNCTION, UnwindData)
+#define OFFSETOF__RUNTIME_FUNCTION__UnwindInfoAddress offsetof(T_RUNTIME_FUNCTION, UnwindData)
//
@@ -893,7 +893,7 @@ PEXCEPTION_ROUTINE
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
@@ -908,7 +908,7 @@ RtlVirtualUnwind_Unsafe(
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
@@ -951,7 +951,7 @@ typedef struct _DISPATCHER_CONTEXT {
FORCEINLINE
ULONG
RtlpGetFunctionEndAddress (
- __in PRUNTIME_FUNCTION FunctionEntry,
+ __in PT_RUNTIME_FUNCTION FunctionEntry,
__in ULONG ImageBase
)
{
@@ -1011,6 +1011,7 @@ RtlVirtualUnwind (
#endif // _TARGET_ARM_
#ifdef _TARGET_ARM64_
+#include "daccess.h"
#define UNW_FLAG_NHANDLER 0x0 /* any handler */
#define UNW_FLAG_EHANDLER 0x1 /* filter handler */
@@ -1031,7 +1032,7 @@ RtlpGetFunctionEndAddress (
if ((FunctionLength & 3) != 0) {
FunctionLength = (FunctionLength >> 2) & 0x7ff;
} else {
- FunctionLength = *(ULONG64*)(ImageBase + FunctionLength) & 0x3ffff;
+ FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
}
return FunctionEntry->BeginAddress + 4 * FunctionLength;
diff --git a/src/inc/corinfo.h b/src/inc/corinfo.h
index bb1a1c339c..fb839996c0 100644
--- a/src/inc/corinfo.h
+++ b/src/inc/corinfo.h
@@ -231,11 +231,11 @@ TODO: Talk about initializing strutures before use
#if COR_JIT_EE_VERSION > 460
// Update this one
-SELECTANY const GUID JITEEVersionIdentifier = { /* 35ef98ab-fd22-4ccc-8ddb-b1156a7d94f3 */
- 0x35ef98ab,
- 0xfd22,
- 0x4ccc,
- { 0x8d, 0xdb, 0xb1, 0x15, 0x6a, 0x7d, 0x94, 0xf3 }
+SELECTANY const GUID JITEEVersionIdentifier = { /* 27626524-7315-4ed0-b74e-a0e4579883bb */
+ 0x27626524,
+ 0x7315,
+ 0x4ed0,
+ { 0xb7, 0x4e, 0xa0, 0xe4, 0x57, 0x98, 0x83, 0xbb }
};
#else
@@ -2390,6 +2390,14 @@ public:
CORINFO_CONST_LOOKUP * pLookup
) = 0;
+#if COR_JIT_EE_VERSION > 460
+ virtual void getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ ) = 0;
+#endif
+
virtual const char* getHelperName(
CorInfoHelpFunc
) = 0;
diff --git a/src/inc/regdisp.h b/src/inc/regdisp.h
index 1dbfafae41..09a6a38f62 100644
--- a/src/inc/regdisp.h
+++ b/src/inc/regdisp.h
@@ -104,6 +104,7 @@ typedef struct _Arm64VolatileContextPointer
PDWORD64 X15;
PDWORD64 X16;
PDWORD64 X17;
+ //X18 is reserved by OS, in userspace it represents TEB
};
PDWORD64 X[18];
};
diff --git a/src/jit/flowgraph.cpp b/src/jit/flowgraph.cpp
index d075401ed4..4e3ba8648b 100644
--- a/src/jit/flowgraph.cpp
+++ b/src/jit/flowgraph.cpp
@@ -6924,7 +6924,12 @@ GenTreePtr Compiler::fgOptimizeDelegateConstructor(GenTreePtr call, CORINFO_C
helperArgs->gtOp.gtOp2 = gtNewArgList(call->gtCall.gtCallArgs->gtOp.gtOp1);
call = gtNewHelperCallNode(CORINFO_HELP_READYTORUN_DELEGATE_CTOR, TYP_VOID, GTF_EXCEPT, helperArgs);
- call->gtCall.gtEntryPoint = targetMethod->gtFptrVal.gtDelegateCtor;
+#if COR_JIT_EE_VERSION > 460
+ info.compCompHnd->getReadyToRunDelegateCtorHelper(targetMethod->gtFptrVal.gtLdftnResolvedToken, clsHnd, &call->gtCall.gtEntryPoint);
+#else
+ info.compCompHnd->getReadyToRunHelper(targetMethod->gtFptrVal.gtLdftnResolvedToken,
+ CORINFO_HELP_READYTORUN_DELEGATE_CTOR, &call->gtCall.gtEntryPoint);
+#endif
}
}
else
diff --git a/src/jit/gentree.cpp b/src/jit/gentree.cpp
index cad84177c4..a0ce79b11c 100755..100644
--- a/src/jit/gentree.cpp
+++ b/src/jit/gentree.cpp
@@ -5954,7 +5954,7 @@ GenTreePtr Compiler::gtCloneExpr(GenTree * tree,
#ifdef FEATURE_READYTORUN_COMPILER
copy->gtFptrVal.gtEntryPoint = tree->gtFptrVal.gtEntryPoint;
- copy->gtFptrVal.gtDelegateCtor = tree->gtFptrVal.gtDelegateCtor;
+ copy->gtFptrVal.gtLdftnResolvedToken = tree->gtFptrVal.gtLdftnResolvedToken;
#endif
goto DONE;
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 631f67b79f..d95c473e17 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -2547,7 +2547,7 @@ struct GenTreeFptrVal: public GenTree
#ifdef FEATURE_READYTORUN_COMPILER
CORINFO_CONST_LOOKUP gtEntryPoint;
- CORINFO_CONST_LOOKUP gtDelegateCtor;
+ CORINFO_RESOLVED_TOKEN* gtLdftnResolvedToken;
#endif
GenTreeFptrVal(var_types type, CORINFO_METHOD_HANDLE meth) :
diff --git a/src/jit/importer.cpp b/src/jit/importer.cpp
index 7993918df0..558fc1f39f 100644
--- a/src/jit/importer.cpp
+++ b/src/jit/importer.cpp
@@ -1663,10 +1663,8 @@ GenTreePtr Compiler::impMethodPointer(CORINFO_RESOLVED_TOKEN * pResolvedToken, C
if (opts.IsReadyToRun())
{
op1->gtFptrVal.gtEntryPoint = pCallInfo->codePointerLookup.constLookup;
-
- // In almost all cases, we are going to create the delegate out of the function pointer. While we are here,
- // get the pointer to the optimized delegate helper. Only one of the two is going to be embedded into the code.
- info.compCompHnd->getReadyToRunHelper(pResolvedToken, CORINFO_HELP_READYTORUN_DELEGATE_CTOR, &op1->gtFptrVal.gtDelegateCtor);
+ op1->gtFptrVal.gtLdftnResolvedToken = new(this, CMK_Unknown) CORINFO_RESOLVED_TOKEN;
+ *op1->gtFptrVal.gtLdftnResolvedToken = *pResolvedToken;
}
else
op1->gtFptrVal.gtEntryPoint.addr = nullptr;
diff --git a/src/unwinder/amd64/unwinder_amd64.cpp b/src/unwinder/amd64/unwinder_amd64.cpp
index 583a11f2dc..b3dd1ab1ac 100644
--- a/src/unwinder/amd64/unwinder_amd64.cpp
+++ b/src/unwinder/amd64/unwinder_amd64.cpp
@@ -170,7 +170,7 @@ UNWIND_INFO * DacGetUnwindInfo(TADDR taUnwindInfo)
{
cbUnwindInfo += sizeof(UNWIND_CODE);
}
- cbUnwindInfo += sizeof(RUNTIME_FUNCTION);
+ cbUnwindInfo += sizeof(T_RUNTIME_FUNCTION);
}
return reinterpret_cast<UNWIND_INFO *>(DacInstantiateTypeByAddress(taUnwindInfo, cbUnwindInfo, true));
}
@@ -325,7 +325,7 @@ PEXCEPTION_ROUTINE RtlVirtualUnwind_Unsafe(
__in ULONG HandlerType,
__in ULONG64 ImageBase,
__in ULONG64 ControlPc,
- __in PRUNTIME_FUNCTION FunctionEntry,
+ __in PT_RUNTIME_FUNCTION FunctionEntry,
__in OUT PCONTEXT ContextRecord,
__out PVOID *HandlerData,
__out PULONG64 EstablisherFrame,
diff --git a/src/unwinder/arm/unwinder_arm.cpp b/src/unwinder/arm/unwinder_arm.cpp
index af595b9bb9..6b1f6864cc 100644
--- a/src/unwinder/arm/unwinder_arm.cpp
+++ b/src/unwinder/arm/unwinder_arm.cpp
@@ -1501,7 +1501,7 @@ PEXCEPTION_ROUTINE RtlVirtualUnwind(
__in ULONG HandlerType,
__in ULONG ImageBase,
__in ULONG ControlPc,
- __in PRUNTIME_FUNCTION FunctionEntry,
+ __in PT_RUNTIME_FUNCTION FunctionEntry,
__in OUT PCONTEXT ContextRecord,
__out PVOID *HandlerData,
__out PULONG EstablisherFrame,
diff --git a/src/unwinder/arm64/unwinder_arm64.cpp b/src/unwinder/arm64/unwinder_arm64.cpp
index fb2f9340af..e13c7b917d 100644
--- a/src/unwinder/arm64/unwinder_arm64.cpp
+++ b/src/unwinder/arm64/unwinder_arm64.cpp
@@ -103,9 +103,9 @@ typedef struct _ARM64_VFP_STATE
// Macros for accessing memory. These can be overridden if other code
// (in particular the debugger) needs to use them.
-#define MEMORY_READ_BYTE(params, addr) (*(const BYTE *)(addr))
-#define MEMORY_READ_DWORD(params, addr) (*(const DWORD *)(addr))
-#define MEMORY_READ_QWORD(params, addr) (*(const UINT64 *)(addr))
+#define MEMORY_READ_BYTE(params, addr) (*dac_cast<PTR_BYTE>(addr))
+#define MEMORY_READ_DWORD(params, addr) (*dac_cast<PTR_DWORD>(addr))
+#define MEMORY_READ_QWORD(params, addr) (*dac_cast<PTR_UINT64>(addr))
typedef struct _ARM64_UNWIND_PARAMS
{
@@ -1597,7 +1597,7 @@ RtlVirtualUnwind(
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
diff --git a/src/unwinder/unwinder.cpp b/src/unwinder/unwinder.cpp
index 7b14b80798..5ab3048905 100644
--- a/src/unwinder/unwinder.cpp
+++ b/src/unwinder/unwinder.cpp
@@ -51,7 +51,7 @@ HRESULT OOPStackUnwinder::GetFunctionEntry( DWORD64 addres
__out_ecount(cbBuffer) PVOID pBuffer,
DWORD cbBuffer)
{
- if (cbBuffer < sizeof(RUNTIME_FUNCTION))
+ if (cbBuffer < sizeof(T_RUNTIME_FUNCTION))
{
return E_INVALIDARG;
}
diff --git a/src/vm/amd64/cgenamd64.cpp b/src/vm/amd64/cgenamd64.cpp
index 9ba89ae8cf..a83c166474 100644
--- a/src/vm/amd64/cgenamd64.cpp
+++ b/src/vm/amd64/cgenamd64.cpp
@@ -799,7 +799,7 @@ BOOL DoesSlotCallPrestub(PCODE pCode)
// we use this function to get at these offsets
//
DWORD GetOffsetAtEndOfFunction(ULONGLONG uImageBase,
- PRUNTIME_FUNCTION pFunctionEntry,
+ PT_RUNTIME_FUNCTION pFunctionEntry,
int offsetNum /* = 1*/)
{
CONTRACTL
diff --git a/src/vm/amd64/cgencpu.h b/src/vm/amd64/cgencpu.h
index c66692467a..3d99b6f7f0 100644
--- a/src/vm/amd64/cgencpu.h
+++ b/src/vm/amd64/cgencpu.h
@@ -507,7 +507,7 @@ struct HijackArgs
#ifndef DACCESS_COMPILE
DWORD GetOffsetAtEndOfFunction(ULONGLONG uImageBase,
- PRUNTIME_FUNCTION pFunctionEntry,
+ PT_RUNTIME_FUNCTION pFunctionEntry,
int offsetNum = 1);
#endif // DACCESS_COMPILE
diff --git a/src/vm/amd64/excepamd64.cpp b/src/vm/amd64/excepamd64.cpp
index cf8ed14a8b..2fc553a987 100644
--- a/src/vm/amd64/excepamd64.cpp
+++ b/src/vm/amd64/excepamd64.cpp
@@ -147,7 +147,7 @@ RtlVirtualUnwind (
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
@@ -183,7 +183,7 @@ RtlVirtualUnwind_Worker (
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
@@ -430,7 +430,7 @@ RtlVirtualUnwind_Worker (
// as well as a single byte representation of the Function code so that tests to make sure
// that we're out of the prologue will not fail.
- RUNTIME_FUNCTION FakeFunctionEntry;
+ T_RUNTIME_FUNCTION FakeFunctionEntry;
//
// The buffer contains 4 sections
diff --git a/src/vm/amd64/excepcpu.h b/src/vm/amd64/excepcpu.h
index 5e96dbd1c5..150416608b 100644
--- a/src/vm/amd64/excepcpu.h
+++ b/src/vm/amd64/excepcpu.h
@@ -65,7 +65,7 @@ RtlVirtualUnwind (
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
@@ -77,7 +77,7 @@ RtlVirtualUnwind_Worker (
IN ULONG HandlerType,
IN ULONG64 ImageBase,
IN ULONG64 ControlPc,
- IN PRUNTIME_FUNCTION FunctionEntry,
+ IN PT_RUNTIME_FUNCTION FunctionEntry,
IN OUT PCONTEXT ContextRecord,
OUT PVOID *HandlerData,
OUT PULONG64 EstablisherFrame,
diff --git a/src/vm/clsload.hpp b/src/vm/clsload.hpp
index ca561a8049..e2705ae2e4 100644
--- a/src/vm/clsload.hpp
+++ b/src/vm/clsload.hpp
@@ -87,18 +87,24 @@ public:
const HashedTypeEntry& SetClassHashBasedEntryValue(EEClassHashEntry_t * pClassHashEntry)
{
+ LIMITED_METHOD_CONTRACT;
+
m_EntryType = EntryType::IsHashedClassEntry;
m_pClassHashEntry = dac_cast<PTR_EEClassHashEntry>(pClassHashEntry);
return *this;
}
EEClassHashEntry_t * GetClassHashBasedEntryValue()
{
+ LIMITED_METHOD_CONTRACT;
+
_ASSERT(m_EntryType == EntryType::IsHashedClassEntry);
return m_pClassHashEntry;
}
const HashedTypeEntry& SetTokenBasedEntryValue(mdTypeDef typeToken, Module * pModule)
{
+ LIMITED_METHOD_CONTRACT;
+
m_EntryType = EntryType::IsHashedTokenEntry;
m_TokenAndModulePair.m_TypeToken = typeToken;
m_TokenAndModulePair.m_pModule = pModule;
@@ -106,6 +112,8 @@ public:
}
const TokenTypeEntry& GetTokenBasedEntryValue()
{
+ LIMITED_METHOD_CONTRACT;
+
_ASSERT(m_EntryType == EntryType::IsHashedTokenEntry);
return m_TokenAndModulePair;
}
diff --git a/src/vm/codeman.cpp b/src/vm/codeman.cpp
index fec74bb6ae..e625bca06c 100644
--- a/src/vm/codeman.cpp
+++ b/src/vm/codeman.cpp
@@ -73,7 +73,7 @@ CrstStatic ExecutionManager::m_RangeCrst;
// Support for new style unwind information (to allow OS to stack crawl JIT compiled code).
typedef NTSTATUS (WINAPI* RtlAddGrowableFunctionTableFnPtr) (
- PVOID *DynamicTable, RUNTIME_FUNCTION* FunctionTable, ULONG EntryCount,
+ PVOID *DynamicTable, PRUNTIME_FUNCTION FunctionTable, ULONG EntryCount,
ULONG MaximumEntryCount, ULONG_PTR rangeStart, ULONG_PTR rangeEnd);
typedef VOID (WINAPI* RtlGrowFunctionTableFnPtr) (PVOID DynamicTable, ULONG NewEntryCount);
typedef VOID (WINAPI* RtlDeleteGrowableFunctionTableFnPtr) (PVOID DynamicTable);
@@ -92,7 +92,7 @@ Volatile<bool> UnwindInfoTable::s_publishingActive = false;
#if _DEBUG
// Fake functions on Win7 checked build to excercize the code paths, they are no-ops
NTSTATUS WINAPI FakeRtlAddGrowableFunctionTable (
- PVOID *DynamicTable, RUNTIME_FUNCTION* FunctionTable, ULONG EntryCount,
+ PVOID *DynamicTable, PT_RUNTIME_FUNCTION FunctionTable, ULONG EntryCount,
ULONG MaximumEntryCount, ULONG_PTR rangeStart, ULONG_PTR rangeEnd) { *DynamicTable = (PVOID) 1; return 0; }
VOID WINAPI FakeRtlGrowFunctionTable (PVOID DynamicTable, ULONG NewEntryCount) { }
VOID WINAPI FakeRtlDeleteGrowableFunctionTable (PVOID DynamicTable) {}
@@ -158,7 +158,7 @@ UnwindInfoTable::UnwindInfoTable(ULONG_PTR rangeStart, ULONG_PTR rangeEnd, ULONG
iRangeStart = rangeStart;
iRangeEnd = rangeEnd;
hHandle = NULL;
- pTable = new RUNTIME_FUNCTION[cTableMaxCount];
+ pTable = new T_RUNTIME_FUNCTION[cTableMaxCount];
}
/****************************************************************************/
@@ -221,7 +221,7 @@ void UnwindInfoTable::UnRegister()
// Add 'data' to the linked list whose head is pointed at by 'unwindInfoPtr'
//
/* static */
-void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, RUNTIME_FUNCTION* data,
+void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, PT_RUNTIME_FUNCTION data,
TADDR rangeStart, TADDR rangeEnd)
{
CONTRACTL
@@ -377,7 +377,7 @@ void UnwindInfoTable::AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, RUNT
// Publish the stack unwind data 'data' which is relative 'baseAddress'
// to the operating system in a way ETW stack tracing can use.
-/* static */ void UnwindInfoTable::PublishUnwindInfoForMethod(TADDR baseAddress, RUNTIME_FUNCTION* unwindInfo, int unwindInfoCount)
+/* static */ void UnwindInfoTable::PublishUnwindInfoForMethod(TADDR baseAddress, PT_RUNTIME_FUNCTION unwindInfo, int unwindInfoCount)
{
STANDARD_VM_CONTRACT;
if (!s_publishingActive)
@@ -2139,16 +2139,16 @@ void CodeHeapRequestInfo::Init()
#ifdef WIN64EXCEPTIONS
#ifdef _WIN64
-extern "C" PRUNTIME_FUNCTION GetRuntimeFunctionCallback(IN ULONG64 ControlPc,
+extern "C" PT_RUNTIME_FUNCTION GetRuntimeFunctionCallback(IN ULONG64 ControlPc,
IN PVOID Context)
#else
-extern "C" PRUNTIME_FUNCTION GetRuntimeFunctionCallback(IN ULONG ControlPc,
+extern "C" PT_RUNTIME_FUNCTION GetRuntimeFunctionCallback(IN ULONG ControlPc,
IN PVOID Context)
#endif
{
WRAPPER_NO_CONTRACT;
- PRUNTIME_FUNCTION prf = NULL;
+ PT_RUNTIME_FUNCTION prf = NULL;
// We must preserve this so that GCStress=4 eh processing doesnt kill last error.
BEGIN_PRESERVE_LAST_ERROR;
@@ -2492,7 +2492,7 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, CorJitAll
SIZE_T totalSize = blockSize;
#if defined(USE_INDIRECT_CODEHEADER)
- SIZE_T realHeaderSize = offsetof(RealCodeHeader, unwindInfos[0]) + (sizeof(RUNTIME_FUNCTION) * nUnwindInfos);
+ SIZE_T realHeaderSize = offsetof(RealCodeHeader, unwindInfos[0]) + (sizeof(T_RUNTIME_FUNCTION) * nUnwindInfos);
// if this is a LCG method then we will be allocating the RealCodeHeader
// following the code so that the code block can be removed easily by
@@ -3913,13 +3913,13 @@ void GetUnmanagedStackWalkInfo(IN ULONG64 ControlPc,
T_RUNTIME_FUNCTION functionEntry;
DWORD dwLow = 0;
- DWORD dwHigh = cbSize / sizeof(RUNTIME_FUNCTION);
+ DWORD dwHigh = cbSize / sizeof(T_RUNTIME_FUNCTION);
DWORD dwMid = 0;
while (dwLow <= dwHigh)
{
dwMid = (dwLow + dwHigh) >> 1;
- taFuncEntry = pExceptionDir + dwMid * sizeof(RUNTIME_FUNCTION);
+ taFuncEntry = pExceptionDir + dwMid * sizeof(T_RUNTIME_FUNCTION);
hr = DacReadAll(taFuncEntry, &functionEntry, sizeof(functionEntry), false);
if (FAILED(hr))
{
@@ -5688,7 +5688,7 @@ static void EnumRuntimeFunctionEntriesToFindEntry(PTR_RUNTIME_FUNCTION pRtf, PTR
IMAGE_DATA_DIRECTORY * pProgramExceptionsDirectory = pNativeLayout->GetDirectoryEntry(IMAGE_DIRECTORY_ENTRY_EXCEPTION);
if (!pProgramExceptionsDirectory ||
(pProgramExceptionsDirectory->Size == 0) ||
- (pProgramExceptionsDirectory->Size % sizeof(RUNTIME_FUNCTION) != 0))
+ (pProgramExceptionsDirectory->Size % sizeof(T_RUNTIME_FUNCTION) != 0))
{
// Program exceptions directory malformatted
return;
@@ -5698,7 +5698,7 @@ static void EnumRuntimeFunctionEntriesToFindEntry(PTR_RUNTIME_FUNCTION pRtf, PTR
PTR_RUNTIME_FUNCTION firstFunctionEntry(moduleBase + pProgramExceptionsDirectory->VirtualAddress);
if (pRtf < firstFunctionEntry ||
- ((dac_cast<TADDR>(pRtf) - dac_cast<TADDR>(firstFunctionEntry)) % sizeof(RUNTIME_FUNCTION) != 0))
+ ((dac_cast<TADDR>(pRtf) - dac_cast<TADDR>(firstFunctionEntry)) % sizeof(T_RUNTIME_FUNCTION) != 0))
{
// Program exceptions directory malformatted
return;
@@ -5717,7 +5717,7 @@ static void EnumRuntimeFunctionEntriesToFindEntry(PTR_RUNTIME_FUNCTION pRtf, PTR
#endif // defined(_MSC_VER)
ULONG low = 0; // index in the function entry table of low end of search range
- ULONG high = (pProgramExceptionsDirectory->Size)/sizeof(RUNTIME_FUNCTION) - 1; // index of high end of search range
+ ULONG high = (pProgramExceptionsDirectory->Size)/sizeof(T_RUNTIME_FUNCTION) - 1; // index of high end of search range
ULONG mid = (low + high) /2; // index of entry to be compared
if (indexToLocate > high)
diff --git a/src/vm/codeman.h b/src/vm/codeman.h
index 3f10aba74c..dbe990e9ab 100644
--- a/src/vm/codeman.h
+++ b/src/vm/codeman.h
@@ -141,7 +141,7 @@ public:
#ifdef WIN64EXCEPTIONS
DWORD nUnwindInfos;
- RUNTIME_FUNCTION unwindInfos[0];
+ T_RUNTIME_FUNCTION unwindInfos[0];
#endif // WIN64EXCEPTIONS
public:
@@ -304,7 +304,7 @@ public:
SUPPORTS_DAC;
_ASSERTE(iUnwindInfo < GetNumberOfUnwindInfos());
return dac_cast<PTR_RUNTIME_FUNCTION>(
- PTR_TO_MEMBER_TADDR(RealCodeHeader, pRealCodeHeader, unwindInfos) + iUnwindInfo * sizeof(RUNTIME_FUNCTION));
+ PTR_TO_MEMBER_TADDR(RealCodeHeader, pRealCodeHeader, unwindInfos) + iUnwindInfo * sizeof(T_RUNTIME_FUNCTION));
}
#endif // WIN64EXCEPTIONS
@@ -531,12 +531,12 @@ public:
// All public functions are thread-safe.
// These are wrapper functions over the UnwindInfoTable functions that are specific to JIT compile code
- static void PublishUnwindInfoForMethod(TADDR baseAddress, RUNTIME_FUNCTION* unwindInfo, int unwindInfoCount);
+ static void PublishUnwindInfoForMethod(TADDR baseAddress, T_RUNTIME_FUNCTION* unwindInfo, int unwindInfoCount);
static void UnpublishUnwindInfoForMethod(TADDR entryPoint);
// These are lower level functions that assume you have found the list of UnwindInfoTable entries
// These are used by the stublinker and the high-level method functions above
- static void AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, RUNTIME_FUNCTION* data, TADDR rangeStart, TADDR rangeEnd);
+ static void AddToUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, T_RUNTIME_FUNCTION* data, TADDR rangeStart, TADDR rangeEnd);
static void RemoveFromUnwindInfoTable(UnwindInfoTable** unwindInfoPtr, TADDR baseAddress, TADDR entryPoint);
// By default this publishing is off, this routine turns it on (and optionally publishes existing methods)
@@ -556,7 +556,7 @@ private:
PVOID hHandle; // OS handle for a published RUNTIME_FUNCTION table
ULONG_PTR iRangeStart; // Start of memory described by this table
ULONG_PTR iRangeEnd; // End of memory described by this table
- RUNTIME_FUNCTION* pTable; // The actual list of method unwind info, sorted by address
+ T_RUNTIME_FUNCTION* pTable; // The actual list of method unwind info, sorted by address
ULONG cTableCurCount;
ULONG cTableMaxCount;
int cDeletedEntries; // Number of slots we removed.
diff --git a/src/vm/exceptionhandling.cpp b/src/vm/exceptionhandling.cpp
index 35d95120dd..14ba4e4b42 100644
--- a/src/vm/exceptionhandling.cpp
+++ b/src/vm/exceptionhandling.cpp
@@ -5350,7 +5350,7 @@ void FixupDispatcherContext(DISPATCHER_CONTEXT* pDispatcherContext, CONTEXT* pCo
#endif // _TARGET_ARM_ || _TARGET_ARM64_
- INDEBUG(pDispatcherContext->FunctionEntry = (PRUNTIME_FUNCTION)INVALID_POINTER_CD);
+ INDEBUG(pDispatcherContext->FunctionEntry = (PT_RUNTIME_FUNCTION)INVALID_POINTER_CD);
INDEBUG(pDispatcherContext->ImageBase = INVALID_POINTER_CD);
pDispatcherContext->FunctionEntry = RtlLookupFunctionEntry(pDispatcherContext->ControlPc,
@@ -5358,7 +5358,7 @@ void FixupDispatcherContext(DISPATCHER_CONTEXT* pDispatcherContext, CONTEXT* pCo
NULL
);
- _ASSERTE(((PRUNTIME_FUNCTION)INVALID_POINTER_CD) != pDispatcherContext->FunctionEntry);
+ _ASSERTE(((PT_RUNTIME_FUNCTION)INVALID_POINTER_CD) != pDispatcherContext->FunctionEntry);
_ASSERTE(INVALID_POINTER_CD != pDispatcherContext->ImageBase);
//
diff --git a/src/vm/i386/stublinkerx86.cpp b/src/vm/i386/stublinkerx86.cpp
index 362edb542c..2d9e01f69f 100644
--- a/src/vm/i386/stublinkerx86.cpp
+++ b/src/vm/i386/stublinkerx86.cpp
@@ -3638,7 +3638,7 @@ extern "C" VOID __cdecl DebugCheckStubUnwindInfoWorker (CONTEXT *pStubContext)
LOG((LF_STUBS, LL_INFO1000000, "pc %p, sp %p\n", ControlPc, GetSP(&ctx)));
ULONG64 ImageBase;
- RUNTIME_FUNCTION *pFunctionEntry = RtlLookupFunctionEntry(
+ T_RUNTIME_FUNCTION *pFunctionEntry = RtlLookupFunctionEntry(
ControlPc,
&ImageBase,
NULL);
diff --git a/src/vm/jithelpers.cpp b/src/vm/jithelpers.cpp
index 95ba2b4ae2..aa99f06ab9 100644
--- a/src/vm/jithelpers.cpp
+++ b/src/vm/jithelpers.cpp
@@ -6676,8 +6676,8 @@ void F_CALL_VA_CONV JIT_TailCall(PCODE copyArgs, PCODE target, ...)
CONTEXT ctx;
// Unwind back to our caller in managed code
- static PRUNTIME_FUNCTION my_pdata;
- static ULONG_PTR my_imagebase;
+ static PT_RUNTIME_FUNCTION my_pdata;
+ static ULONG_PTR my_imagebase;
ctx.ContextFlags = CONTEXT_ALL;
RtlCaptureContext(&ctx);
@@ -7035,7 +7035,7 @@ void InitJitHelperLogging()
hlpFuncCount->count = 0;
#ifdef _TARGET_AMD64_
ULONGLONG uImageBase;
- PRUNTIME_FUNCTION pFunctionEntry;
+ PT_RUNTIME_FUNCTION pFunctionEntry;
pFunctionEntry = RtlLookupFunctionEntry((ULONGLONG)hlpFunc->pfnHelper, &uImageBase, NULL);
if (pFunctionEntry != NULL)
@@ -7080,7 +7080,7 @@ void InitJitHelperLogging()
#ifdef _TARGET_AMD64_
ULONGLONG uImageBase;
- PRUNTIME_FUNCTION pFunctionEntry;
+ PT_RUNTIME_FUNCTION pFunctionEntry;
pFunctionEntry = RtlLookupFunctionEntry((ULONGLONG)hlpFunc->pfnHelper, &uImageBase, NULL);
if (pFunctionEntry != NULL)
diff --git a/src/vm/jitinterface.cpp b/src/vm/jitinterface.cpp
index 3247ccb100..46542482ba 100644
--- a/src/vm/jitinterface.cpp
+++ b/src/vm/jitinterface.cpp
@@ -6092,6 +6092,17 @@ void CEEInfo::getReadyToRunHelper(
}
/***********************************************************************/
+void CEEInfo::getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ )
+{
+ LIMITED_METHOD_CONTRACT;
+ UNREACHABLE(); // only called during NGen
+}
+
+/***********************************************************************/
// see code:Nullable#NullableVerification
CORINFO_CLASS_HANDLE CEEInfo::getTypeForBox(CORINFO_CLASS_HANDLE cls)
@@ -10467,7 +10478,7 @@ void CEEJitInfo::allocUnwindInfo (
_ASSERTE(m_usedUnwindInfos > 0);
}
- PRUNTIME_FUNCTION pRuntimeFunction = m_CodeHeader->GetUnwindInfo(m_usedUnwindInfos);
+ PT_RUNTIME_FUNCTION pRuntimeFunction = m_CodeHeader->GetUnwindInfo(m_usedUnwindInfos);
m_usedUnwindInfos++;
// Make sure that the RUNTIME_FUNCTION is aligned on a DWORD sized boundary
@@ -10552,7 +10563,7 @@ void CEEJitInfo::allocUnwindInfo (
for (ULONG iUnwindInfo = 0; iUnwindInfo < m_usedUnwindInfos - 1; iUnwindInfo++)
{
- PRUNTIME_FUNCTION pOtherFunction = m_CodeHeader->GetUnwindInfo(iUnwindInfo);
+ PT_RUNTIME_FUNCTION pOtherFunction = m_CodeHeader->GetUnwindInfo(iUnwindInfo);
_ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunction, baseAddress)
|| RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunction)));
}
@@ -13671,7 +13682,7 @@ LPVOID EECodeInfo::findNextFunclet (LPVOID pvFuncletStart, SIZE_T
while (cbCode > 0)
{
- PRUNTIME_FUNCTION pFunctionEntry;
+ PT_RUNTIME_FUNCTION pFunctionEntry;
ULONGLONG uImageBase;
#ifdef FEATURE_PAL
EECodeInfo codeInfo;
@@ -13683,7 +13694,7 @@ LPVOID EECodeInfo::findNextFunclet (LPVOID pvFuncletStart, SIZE_T
// This is GCStress debug only - use the slow OS APIs to enumerate funclets
//
- pFunctionEntry = (PRUNTIME_FUNCTION) RtlLookupFunctionEntry((ULONGLONG)pvFuncletStart,
+ pFunctionEntry = (PT_RUNTIME_FUNCTION) RtlLookupFunctionEntry((ULONGLONG)pvFuncletStart,
&uImageBase
AMD64_ARG(NULL)
);
diff --git a/src/vm/jitinterface.h b/src/vm/jitinterface.h
index 215ceda4b2..00edc6e212 100644
--- a/src/vm/jitinterface.h
+++ b/src/vm/jitinterface.h
@@ -538,6 +538,12 @@ public:
CORINFO_CONST_LOOKUP * pLookup
);
+ void getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ );
+
CorInfoInitClassResult initClass(
CORINFO_FIELD_HANDLE field,
CORINFO_METHOD_HANDLE method,
diff --git a/src/vm/nativeformatreader.h b/src/vm/nativeformatreader.h
index cfebb498ca..a410884626 100644
--- a/src/vm/nativeformatreader.h
+++ b/src/vm/nativeformatreader.h
@@ -44,7 +44,11 @@ namespace NativeFormat
void ThrowBadImageFormatException()
{
_ASSERTE(false);
- ThrowHR(COR_E_BADIMAGEFORMAT);
+
+#ifndef DACCESS_COMPILE
+ // Failfast instead of throwing, to avoid violating NOTHROW contracts of callers
+ EEPOLICY_HANDLE_FATAL_ERROR(COR_E_BADIMAGEFORMAT);
+#endif
}
uint EnsureOffsetInRange(uint offset, uint lookAhead)
diff --git a/src/vm/readytoruninfo.cpp b/src/vm/readytoruninfo.cpp
index d00db7150f..158a23370f 100644
--- a/src/vm/readytoruninfo.cpp
+++ b/src/vm/readytoruninfo.cpp
@@ -84,7 +84,7 @@ BOOL ReadyToRunInfo::TryLookupTypeTokenFromName(NameHandle *pName, mdToken * pFo
{
GC_NOTRIGGER;
NOTHROW;
- SO_TOLERANT;
+ SO_INTOLERANT;
SUPPORTS_DAC;
PRECONDITION(!m_availableTypesHashtable.IsNull());
}
@@ -429,8 +429,8 @@ ReadyToRunInfo::ReadyToRunInfo(Module * pModule, PEImageLayout * pLayout, READYT
IMAGE_DATA_DIRECTORY * pRuntimeFunctionsDir = FindSection(READYTORUN_SECTION_RUNTIME_FUNCTIONS);
if (pRuntimeFunctionsDir != NULL)
{
- m_pRuntimeFunctions = (RUNTIME_FUNCTION *)pLayout->GetDirectoryData(pRuntimeFunctionsDir);
- m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(RUNTIME_FUNCTION);
+ m_pRuntimeFunctions = (T_RUNTIME_FUNCTION *)pLayout->GetDirectoryData(pRuntimeFunctionsDir);
+ m_nRuntimeFunctions = pRuntimeFunctionsDir->Size / sizeof(T_RUNTIME_FUNCTION);
}
else
{
diff --git a/src/vm/rtlfunctions.h b/src/vm/rtlfunctions.h
index d08cd75699..9d1d46b6f8 100644
--- a/src/vm/rtlfunctions.h
+++ b/src/vm/rtlfunctions.h
@@ -20,7 +20,7 @@ enum EEDynamicFunctionTableType
};
// Used by OutOfProcessFunctionTableCallback in DLLS\mscordbg\DebugSupport.cpp
-// to figure out how to parse a dunamic function table that was registered
+// to figure out how to parse a dynamic function table that was registered
// with a callback.
inline
EEDynamicFunctionTableType IdentifyDynamicFunctionTableTypeFromContext (PVOID pvContext)
@@ -65,7 +65,7 @@ inline
VOID DeleteEEFunctionTable(
PVOID pvTableID)
{
- RtlDeleteFunctionTable((PRUNTIME_FUNCTION)((ULONG64)pvTableID | 3));
+ RtlDeleteFunctionTable((PT_RUNTIME_FUNCTION)((ULONG64)pvTableID | 3));
}
#else // WIN64EXCEPTIONS && !DACCESS_COMPILE && !CROSSGEN_COMPILE && !FEATURE_PAL
diff --git a/src/vm/stackwalk.cpp b/src/vm/stackwalk.cpp
index 2250fd517a..3c2dfd7f84 100644
--- a/src/vm/stackwalk.cpp
+++ b/src/vm/stackwalk.cpp
@@ -596,7 +596,7 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
#if !defined(DACCESS_COMPILE)
UINT_PTR uImageBase;
- PRUNTIME_FUNCTION pFunctionEntry;
+ PT_RUNTIME_FUNCTION pFunctionEntry;
if (pCodeInfo == NULL)
{
@@ -623,7 +623,7 @@ PCODE Thread::VirtualUnwindCallFrame(T_CONTEXT* pContext,
#if defined(_DEBUG) && !defined(FEATURE_PAL)
UINT_PTR uImageBaseFromOS;
- PRUNTIME_FUNCTION pFunctionEntryFromOS;
+ PT_RUNTIME_FUNCTION pFunctionEntryFromOS;
pFunctionEntryFromOS = RtlLookupFunctionEntry(uControlPc,
ARM_ONLY((DWORD*))(&uImageBaseFromOS),
@@ -679,7 +679,7 @@ PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
#if defined(_DEBUG) && !defined(FEATURE_PAL)
UINT_PTR uImageBase;
- PRUNTIME_FUNCTION pFunctionEntry = RtlLookupFunctionEntry((UINT_PTR)GetIP(pContext),
+ PT_RUNTIME_FUNCTION pFunctionEntry = RtlLookupFunctionEntry((UINT_PTR)GetIP(pContext),
ARM_ONLY((DWORD*))(&uImageBase),
NULL);
@@ -708,7 +708,7 @@ PCODE Thread::VirtualUnwindLeafCallFrame(T_CONTEXT* pContext)
// static
PCODE Thread::VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, KNONVOLATILE_CONTEXT_POINTERS* pContextPointers,
- PRUNTIME_FUNCTION pFunctionEntry, UINT_PTR uImageBase)
+ PT_RUNTIME_FUNCTION pFunctionEntry, UINT_PTR uImageBase)
{
CONTRACTL
{
diff --git a/src/vm/stublink.cpp b/src/vm/stublink.cpp
index 92b4a15209..d1833260c5 100644
--- a/src/vm/stublink.cpp
+++ b/src/vm/stublink.cpp
@@ -1476,7 +1476,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStub, int globalsize)
//
// Fill in the RUNTIME_FUNCTION struct for this prologue.
//
- RUNTIME_FUNCTION *pCurFunction = &pUnwindInfoHeader->FunctionEntry;
+ PT_RUNTIME_FUNCTION pCurFunction = &pUnwindInfoHeader->FunctionEntry;
_ASSERTE(IS_ALIGNED(pCurFunction, sizeof(ULONG)));
S_UINT32 sBeginAddress = S_BYTEPTR(pCode) - S_BYTEPTR(pbBaseAddress);
@@ -1499,7 +1499,7 @@ bool StubLinker::EmitUnwindInfo(Stub* pStub, int globalsize)
//
UNWIND_INFO *pUnwindInfo = &pUnwindInfoHeader->UnwindInfo;
- RUNTIME_FUNCTION *pCurFunction = &pUnwindInfoHeader->FunctionEntry;
+ PT_RUNTIME_FUNCTION pCurFunction = &pUnwindInfoHeader->FunctionEntry;
_ASSERTE(IS_ALIGNED(pCurFunction, sizeof(ULONG)));
S_UINT32 sBeginAddress = S_BYTEPTR(pCode) - S_BYTEPTR(pbBaseAddress);
diff --git a/src/vm/stublink.h b/src/vm/stublink.h
index 8df3499b68..d7f0034587 100644
--- a/src/vm/stublink.h
+++ b/src/vm/stublink.h
@@ -349,7 +349,7 @@ protected:
{
if (m_nUnwindSlots == 0) return 0;
- return sizeof(RUNTIME_FUNCTION) + offsetof(UNWIND_INFO, UnwindCode) + m_nUnwindSlots * sizeof(UNWIND_CODE);
+ return sizeof(T_RUNTIME_FUNCTION) + offsetof(UNWIND_INFO, UnwindCode) + m_nUnwindSlots * sizeof(UNWIND_CODE);
}
#endif // _TARGET_AMD64_
@@ -359,7 +359,7 @@ protected:
// epilog.
private:
// Reserve fixed size block that's big enough to fit any unwind info we can have
- static const int c_nUnwindInfoSize = sizeof(RUNTIME_FUNCTION) + sizeof(DWORD) + MAX_UNWIND_CODE_WORDS *4;
+ static const int c_nUnwindInfoSize = sizeof(T_RUNTIME_FUNCTION) + sizeof(DWORD) + MAX_UNWIND_CODE_WORDS *4;
//
// Returns total UnwindInfoSize, including RUNTIME_FUNCTION entry
@@ -377,7 +377,7 @@ private:
private:
// Reserve fixed size block that's big enough to fit any unwind info we can have
- static const int c_nUnwindInfoSize = sizeof(RUNTIME_FUNCTION) + sizeof(DWORD) + MAX_UNWIND_CODE_WORDS *4;
+ static const int c_nUnwindInfoSize = sizeof(T_RUNTIME_FUNCTION) + sizeof(DWORD) + MAX_UNWIND_CODE_WORDS *4;
UINT UnwindInfoSize(UINT codeSize)
{
if (!m_fProlog) return 0;
diff --git a/src/vm/threads.h b/src/vm/threads.h
index 9cf309d70a..26477af2fc 100644
--- a/src/vm/threads.h
+++ b/src/vm/threads.h
@@ -3625,7 +3625,7 @@ public:
static UINT_PTR VirtualUnwindCallFrame(PREGDISPLAY pRD, EECodeInfo * pCodeInfo = NULL);
static PCODE VirtualUnwindLeafCallFrame(T_CONTEXT* pContext);
static PCODE VirtualUnwindNonLeafCallFrame(T_CONTEXT* pContext, T_KNONVOLATILE_CONTEXT_POINTERS* pContextPointers = NULL,
- PRUNTIME_FUNCTION pFunctionEntry = NULL, UINT_PTR uImageBase = NULL);
+ PT_RUNTIME_FUNCTION pFunctionEntry = NULL, UINT_PTR uImageBase = NULL);
static UINT_PTR VirtualUnwindToFirstManagedCallFrame(T_CONTEXT* pContext);
#endif // WIN64EXCEPTIONS
diff --git a/src/vm/win32threadpool.cpp b/src/vm/win32threadpool.cpp
index af7b26c1e2..fc25f4e7b9 100644
--- a/src/vm/win32threadpool.cpp
+++ b/src/vm/win32threadpool.cpp
@@ -305,11 +305,13 @@ DWORD GetDefaultMaxLimitWorkerThreads(DWORD minLimit)
DWORD GetForceMinWorkerThreadsValue()
{
+ WRAPPER_NO_CONTRACT;
return Configuration::GetKnobDWORDValue(W("System.Threading.ThreadPool.MinThreads"), CLRConfig::INTERNAL_ThreadPool_ForceMinWorkerThreads);
}
DWORD GetForceMaxWorkerThreadsValue()
{
+ WRAPPER_NO_CONTRACT;
return Configuration::GetKnobDWORDValue(W("System.Threading.ThreadPool.MaxThreads"), CLRConfig::INTERNAL_ThreadPool_ForceMaxWorkerThreads);
}
diff --git a/src/zap/zapcode.cpp b/src/zap/zapcode.cpp
index 2e7f21590a..ca1c023f20 100644
--- a/src/zap/zapcode.cpp
+++ b/src/zap/zapcode.cpp
@@ -1291,7 +1291,7 @@ ZapGCInfo * ZapGCInfoTable::GetGCInfo(PVOID pBlob, SIZE_T cbBlob)
void ZapUnwindInfo::Save(ZapWriter * pZapWriter)
{
- RUNTIME_FUNCTION runtimeFunction;
+ T_RUNTIME_FUNCTION runtimeFunction;
#if defined(_TARGET_ARM_)
RUNTIME_FUNCTION__SetBeginAddress(&runtimeFunction, GetStartAddress());
diff --git a/src/zap/zapcode.h b/src/zap/zapcode.h
index d68f9028c1..ed8cc2d807 100644
--- a/src/zap/zapcode.h
+++ b/src/zap/zapcode.h
@@ -427,7 +427,7 @@ public:
virtual DWORD GetSize()
{
- return sizeof(RUNTIME_FUNCTION);
+ return sizeof(T_RUNTIME_FUNCTION);
}
virtual ZapNodeType GetType()
diff --git a/src/zap/zapimport.cpp b/src/zap/zapimport.cpp
index c1947a96f0..4e7b151d74 100644
--- a/src/zap/zapimport.cpp
+++ b/src/zap/zapimport.cpp
@@ -1791,13 +1791,20 @@ ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind
return pImport;
}
-ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken)
+ZapImport * ZapImportTable::GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_CLASS_HANDLE delegateType /*=NULL*/)
{
SigBuilder sigBuilder;
EncodeMethod((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE),
handle, &sigBuilder, pResolvedToken);
+ if (delegateType != NULL)
+ {
+ _ASSERTE((CORCOMPILE_FIXUP_BLOB_KIND)(kind & ~CORINFO_HELP_READYTORUN_ATYPICAL_CALLSITE) == ENCODE_DELEGATE_CTOR);
+ GetCompileInfo()->EncodeClass(m_pImage->GetModuleHandle(), delegateType, &sigBuilder, NULL, NULL);
+ }
+
return GetImportForSignature<ZapDynamicHelperCell, ZapNodeType_DynamicHelperCell>((void *)kind, &sigBuilder);
}
diff --git a/src/zap/zapimport.h b/src/zap/zapimport.h
index 9d55e03531..9aa5e95f27 100644
--- a/src/zap/zapimport.h
+++ b/src/zap/zapimport.h
@@ -432,7 +432,8 @@ public:
ZapImport * GetExternalMethodCell(CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken, CORINFO_RESOLVED_TOKEN * pConstrainedResolvedToken);
ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_CLASS_HANDLE handle);
- ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
+ ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_METHOD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken,
+ CORINFO_CLASS_HANDLE delegateType = NULL);
ZapImport * GetDynamicHelperCell(CORCOMPILE_FIXUP_BLOB_KIND kind, CORINFO_FIELD_HANDLE handle, CORINFO_RESOLVED_TOKEN * pResolvedToken);
#ifdef FEATURE_READYTORUN_COMPILER
diff --git a/src/zap/zapinfo.cpp b/src/zap/zapinfo.cpp
index c8a08a3cc6..cf8e9b7c7e 100644
--- a/src/zap/zapinfo.cpp
+++ b/src/zap/zapinfo.cpp
@@ -2667,7 +2667,7 @@ CORINFO_METHOD_HANDLE ZapInfo::GetDelegateCtor(CORINFO_METHOD_HANDLE methHnd,
CORINFO_METHOD_HANDLE targetMethodHnd,
DelegateCtorArgs * pCtorData)
{
- // For ReadyToRun, this optimization is done via ZapInfo::getReadyToRunHelper
+ // For ReadyToRun, this optimization is done via ZapInfo::getReadyToRunDelegateCtorHelper
if (IsReadyToRunCompilation())
return methHnd;
@@ -3410,11 +3410,6 @@ void ZapInfo::getReadyToRunHelper(
}
break;
- case CORINFO_HELP_READYTORUN_DELEGATE_CTOR:
- pImport = m_pImage->GetImportTable()->GetDynamicHelperCell(
- (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DELEGATE_CTOR | fAtypicalCallsite), pResolvedToken->hMethod, pResolvedToken);
- break;
-
default:
_ASSERTE(false);
ThrowHR(E_NOTIMPL);
@@ -3425,6 +3420,21 @@ void ZapInfo::getReadyToRunHelper(
#endif
}
+void ZapInfo::getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ )
+{
+#ifdef FEATURE_READYTORUN_COMPILER
+ _ASSERTE(IsReadyToRunCompilation());
+
+ pLookup->accessType = IAT_PVALUE;
+ pLookup->addr = m_pImage->GetImportTable()->GetDynamicHelperCell(
+ (CORCOMPILE_FIXUP_BLOB_KIND)(ENCODE_DELEGATE_CTOR), pTargetMethod->hMethod, pTargetMethod, delegateType);
+#endif
+}
+
//
// ICorModuleInfo
diff --git a/src/zap/zapinfo.h b/src/zap/zapinfo.h
index 83528e9e7b..5fe3dcb76e 100644
--- a/src/zap/zapinfo.h
+++ b/src/zap/zapinfo.h
@@ -550,6 +550,12 @@ public:
CORINFO_CONST_LOOKUP * pLookup
);
+ void getReadyToRunDelegateCtorHelper(
+ CORINFO_RESOLVED_TOKEN * pTargetMethod,
+ CORINFO_CLASS_HANDLE delegateType,
+ CORINFO_CONST_LOOKUP * pLookup
+ );
+
CorInfoInitClassResult initClass(
CORINFO_FIELD_HANDLE field,
CORINFO_METHOD_HANDLE method,
diff --git a/tests/src/readytorun/main.cs b/tests/src/readytorun/main.cs
index 427ca42340..70157bc278 100644
--- a/tests/src/readytorun/main.cs
+++ b/tests/src/readytorun/main.cs
@@ -40,6 +40,15 @@ class InheritingFromGrowingBase : GrowingBase
public int x;
}
+
+static class OpenClosedDelegateExtension
+{
+ public static string OpenClosedDelegateTarget(this string x, string foo)
+ {
+ return x + ", " + foo;
+ }
+}
+
class Program
{
static void TestVirtualMethodCalls()
@@ -335,6 +344,18 @@ class Program
Assert.AreEqual(o.ChildByte, (byte)67);
}
+ static void TestOpenClosedDelegate()
+ {
+ // This test is verifying the the fixups for open vs. closed delegate created against the same target
+ // method are encoded correctly.
+
+ Func<string, string, object> idOpen = OpenClosedDelegateExtension.OpenClosedDelegateTarget;
+ Assert.AreEqual(idOpen("World", "foo"), "World, foo");
+
+ Func<string, object> idClosed = "World".OpenClosedDelegateTarget;
+ Assert.AreEqual(idClosed("hey"), "World, hey");
+ }
+
static void RunAllTests()
{
TestVirtualMethodCalls();
@@ -380,6 +401,8 @@ class Program
TestCastClassCSE();
TestRangeCheckElimination();
+
+ TestOpenClosedDelegate();
}
static int Main()