From 0aaa3e0ddf929a7814565034cf40b3c98bba92f9 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Sat, 22 May 2021 00:53:12 +0200 Subject: [PATCH 1/9] Generate JITted code into a scratch buffer Copy it to the final location after the JITing is done. --- src/coreclr/vm/codeman.cpp | 17 +++--- src/coreclr/vm/codeman.h | 4 +- src/coreclr/vm/jitinterface.cpp | 95 ++++++++++++++++++++++++--------- src/coreclr/vm/jitinterface.h | 12 +++++ 4 files changed, 94 insertions(+), 34 deletions(-) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index e47b3206761d4..36da24d9db4b5 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -2492,7 +2492,7 @@ HeapList* EEJitManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHeapLi void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, - HeapList ** ppCodeHeap) + HeapList ** ppCodeHeap, size_t* pAllocatedSize) { CONTRACT(void *) { THROWS; @@ -2501,7 +2501,12 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, POSTCONDITION((RETVAL != NULL) || !pInfo->getThrowOnOutOfMemoryWithinRange()); } CONTRACT_END; - pInfo->setRequestSize(header+blockSize+(align-1)+pInfo->getReserveForJumpStubs()); + size_t allocatedSize = header+blockSize+(align-1)+pInfo->getReserveForJumpStubs(); + if (pAllocatedSize != NULL) + { + *pAllocatedSize = allocatedSize; + } + pInfo->setRequestSize(allocatedSize); void * mem = NULL; HeapList * pCodeHeap = NULL; @@ -2592,7 +2597,7 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, RETURN(mem); } -CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag +CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, size_t* pAllocatedSize #ifdef FEATURE_EH_FUNCLETS , UINT nUnwindInfos , TADDR * pModuleBase @@ -2665,7 +2670,7 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re HeapList *pCodeHeap = NULL; - TADDR pCode = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), totalSize, alignment, &pCodeHeap); + TADDR pCode = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), totalSize, alignment, &pCodeHeap, pAllocatedSize); _ASSERTE(pCodeHeap); @@ -2984,7 +2989,7 @@ JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD n { CrstHolder ch(&m_CodeHeapCritSec); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, CODE_SIZE_ALIGN, &pCodeHeap); + mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, CODE_SIZE_ALIGN, &pCodeHeap, NULL); if (mem == NULL) { _ASSERTE(!throwOnOutOfMemoryWithinRange); @@ -3040,7 +3045,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment { CrstHolder ch(&m_CodeHeapCritSec); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap); + mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap, NULL); // CodeHeader comes immediately before the block CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 85a857b09d726..06a0e54de6c1a 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -974,7 +974,7 @@ class EEJitManager : public IJitManager BOOL LoadJIT(); - CodeHeader* allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag + CodeHeader* allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, size_t* pAllocatedSize #ifdef FEATURE_EH_FUNCLETS , UINT nUnwindInfos , TADDR * pModuleBase @@ -1054,7 +1054,7 @@ private : bool CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCodeHeap); void* allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, - HeapList ** ppCodeHeap); + HeapList ** ppCodeHeap, size_t* pAllocatedSize); DomainCodeHeapList *GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE); DomainCodeHeapList *CreateCodeHeapList(CodeHeapRequestInfo *pInfo); diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index a8b5981d5adf1..135c0e19a8f67 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11190,8 +11190,32 @@ void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr) CodeHeader* pCodeHeader = m_CodeHeader; if (pCodeHeader) jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len); + + delete [] m_codeWriteBuffer; + m_codeWriteBuffer = NULL; } +/*********************************************************************/ +void CEEJitInfo::WriteCode() +{ + CONTRACTL { + THROWS; + GC_TRIGGERS; + } CONTRACTL_END; + + memcpy((void*)m_CodeHeader->GetCodeStartAddress(), m_codeWriteBuffer, m_codeWriteBufferSize); + delete [] m_codeWriteBuffer; + m_codeWriteBuffer = NULL; + +#if defined(TARGET_AMD64) + // Publish the new unwind information in a way that the ETW stack crawler can find + _ASSERTE(m_usedUnwindInfos == m_totalUnwindInfos); + UnwindInfoTable::PublishUnwindInfoForMethod(m_moduleBase, m_CodeHeader->GetUnwindInfo(0), m_totalUnwindInfos); +#endif // defined(TARGET_AMD64) + +} + + /*********************************************************************/ // Route jit information to the Jit Debug store. void CEEJitInfo::setBoundaries(CORINFO_METHOD_HANDLE ftn, uint32_t cMap, @@ -11455,12 +11479,30 @@ void CEEJitInfo::allocUnwindInfo ( } PT_RUNTIME_FUNCTION pRuntimeFunction = m_CodeHeader->GetUnwindInfo(m_usedUnwindInfos); + PT_RUNTIME_FUNCTION pRuntimeFunctionRW = (PT_RUNTIME_FUNCTION)((BYTE *)pRuntimeFunction + m_writeableOffset); + if ((BYTE*)pRuntimeFunctionRW < m_codeWriteBuffer || (BYTE*)pRuntimeFunctionRW >= (m_codeWriteBuffer + m_codeWriteBufferSize)) + { + pRuntimeFunctionRW = pRuntimeFunction; + } + else + { + __debugbreak(); + } + m_usedUnwindInfos++; // Make sure that the RUNTIME_FUNCTION is aligned on a DWORD sized boundary _ASSERTE(IS_ALIGNED(pRuntimeFunction, sizeof(DWORD))); UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *) &(m_theUnwindBlock[m_usedUnwindSize]); + UNWIND_INFO * pUnwindInfoRW = (UNWIND_INFO *)((BYTE*)pUnwindInfo + m_writeableOffset); + if ((BYTE*)pUnwindInfoRW < m_codeWriteBuffer || ((BYTE*)pUnwindInfoRW + unwindSize) > (m_codeWriteBuffer + m_codeWriteBufferSize)) + { + __debugbreak(); + } + + uint32_t prevUsedUnwindSize = m_usedUnwindSize; + m_usedUnwindSize += unwindSize; reservePersonalityRoutineSpace(m_usedUnwindSize); @@ -11504,13 +11546,13 @@ void CEEJitInfo::allocUnwindInfo ( unsigned unwindInfoDelta = (unsigned) unwindInfoDeltaT; - RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunction, currentCodeOffset + startOffset); + RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunctionRW, currentCodeOffset + startOffset); #ifdef TARGET_AMD64 - pRuntimeFunction->EndAddress = currentCodeOffset + endOffset; + pRuntimeFunctionRW->EndAddress = currentCodeOffset + endOffset; #endif - RUNTIME_FUNCTION__SetUnwindInfoAddress(pRuntimeFunction, unwindInfoDelta); + RUNTIME_FUNCTION__SetUnwindInfoAddress(pRuntimeFunctionRW, unwindInfoDelta); #ifdef _DEBUG if (funcKind != CORJIT_FUNC_ROOT) @@ -11520,14 +11562,13 @@ void CEEJitInfo::allocUnwindInfo ( for (ULONG iUnwindInfo = 0; iUnwindInfo < m_usedUnwindInfos - 1; 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))); + _ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunctionRW, baseAddress) + || RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunctionRW))); } } #endif // _DEBUG - /* Copy the UnwindBlock */ - memcpy(pUnwindInfo, pUnwindBlock, unwindSize); + memcpy(pUnwindInfoRW, pUnwindBlock, unwindSize); #if defined(TARGET_X86) @@ -11535,33 +11576,27 @@ void CEEJitInfo::allocUnwindInfo ( #elif defined(TARGET_AMD64) - pUnwindInfo->Flags = UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER; + pUnwindInfoRW->Flags = UNW_FLAG_EHANDLER | UNW_FLAG_UHANDLER; - ULONG * pPersonalityRoutine = (ULONG*)ALIGN_UP(&(pUnwindInfo->UnwindCode[pUnwindInfo->CountOfUnwindCodes]), sizeof(ULONG)); - *pPersonalityRoutine = ExecutionManager::GetCLRPersonalityRoutineValue(); + ULONG * pPersonalityRoutineRW = (ULONG*)ALIGN_UP(&(pUnwindInfoRW->UnwindCode[pUnwindInfoRW->CountOfUnwindCodes]), sizeof(ULONG)); + *pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue(); #elif defined(TARGET_ARM64) - *(LONG *)pUnwindInfo |= (1 << 20); // X bit + *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit - ULONG * pPersonalityRoutine = (ULONG*)((BYTE *)pUnwindInfo + ALIGN_UP(unwindSize, sizeof(ULONG))); - *pPersonalityRoutine = ExecutionManager::GetCLRPersonalityRoutineValue(); + ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); + *pPersonalityRoutineRW = ExecutionManager::GetCLRPersonalityRoutineValue(); #elif defined(TARGET_ARM) - *(LONG *)pUnwindInfo |= (1 << 20); // X bit + *(LONG *)pUnwindInfoRW |= (1 << 20); // X bit - ULONG * pPersonalityRoutine = (ULONG*)((BYTE *)pUnwindInfo + ALIGN_UP(unwindSize, sizeof(ULONG))); - *pPersonalityRoutine = (TADDR)ProcessCLRException - baseAddress; + ULONG * pPersonalityRoutineRW = (ULONG*)((BYTE *)pUnwindInfoRW + ALIGN_UP(unwindSize, sizeof(ULONG))); + *pPersonalityRoutineRW = (TADDR)ProcessCLRException - baseAddress; #endif -#if defined(TARGET_AMD64) - // Publish the new unwind information in a way that the ETW stack crawler can find - if (m_usedUnwindInfos == m_totalUnwindInfos) - UnwindInfoTable::PublishUnwindInfoForMethod(baseAddress, m_CodeHeader->GetUnwindInfo(0), m_totalUnwindInfos); -#endif // defined(TARGET_AMD64) - EE_TO_JIT_TRANSITION(); #else // FEATURE_EH_FUNCLETS LIMITED_METHOD_CONTRACT; @@ -12268,24 +12303,28 @@ void CEEJitInfo::allocMem (AllocMemArgs *pArgs) pArgs->hotCodeSize + pArgs->coldCodeSize, pArgs->roDataSize, totalSize.Value(), pArgs->flag, GetClrInstanceId()); } - m_CodeHeader = m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag + // TODO: move the write buffer allocation inside of the allocCode and use it to write the code header too. + m_CodeHeader = m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_codeWriteBufferSize #ifdef FEATURE_EH_FUNCLETS , m_totalUnwindInfos , &m_moduleBase #endif ); + m_codeWriteBufferSize = totalSize.Value(); BYTE* current = (BYTE *)m_CodeHeader->GetCodeStartAddress(); + m_codeWriteBuffer = new BYTE[m_codeWriteBufferSize]; + m_writeableOffset = m_codeWriteBuffer - current; *codeBlock = current; - *codeBlockRW = current; + *codeBlockRW = current + m_writeableOffset; current += codeSize; if (pArgs->roDataSize > 0) { current = (BYTE *)ALIGN_UP(current, roDataAlignment); pArgs->roDataBlock = current; - pArgs->roDataBlockRW = current; + pArgs->roDataBlockRW = current + m_writeableOffset; current += pArgs->roDataSize; } else @@ -13279,7 +13318,11 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, LOG((LF_JIT, LL_INFO10000, "Done Jitting method %s::%s %s }\n",cls,name, ftn->m_pszDebugMethodSignature)); - if (!SUCCEEDED(res)) + if (SUCCEEDED(res)) + { + jitInfo.WriteCode(); + } + else { jitInfo.BackoutJitData(jitMgr); ThrowExceptionForJit(res); diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 56cb5befac401..f4010d20d1041 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -705,6 +705,10 @@ class CEEJitInfo : public CEEInfo } CONTRACTL_END; m_CodeHeader = NULL; + m_writeableOffset = 0; + + delete [] m_codeWriteBuffer; + m_codeWriteBuffer = NULL; if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping); @@ -804,6 +808,9 @@ class CEEJitInfo : public CEEInfo : CEEInfo(fd, fVerifyOnly, allowInlining), m_jitManager(jm), m_CodeHeader(NULL), + m_codeWriteBuffer(NULL), + m_codeWriteBufferSize(0), + m_writeableOffset(0), m_ILHeader(header), #ifdef FEATURE_EH_FUNCLETS m_moduleBase(NULL), @@ -909,6 +916,8 @@ class CEEJitInfo : public CEEInfo void BackoutJitData(EEJitManager * jitMgr); + void WriteCode(); + void setPatchpointInfo(PatchpointInfo* patchpointInfo) override final; PatchpointInfo* getOSRInfo(unsigned* ilOffset) override final; @@ -934,6 +943,9 @@ protected : EEJitManager* m_jitManager; // responsible for allocating memory CodeHeader* m_CodeHeader; // descriptor for JITTED code + BYTE* m_codeWriteBuffer; + size_t m_codeWriteBufferSize; + size_t m_writeableOffset; COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file #ifdef FEATURE_EH_FUNCLETS TADDR m_moduleBase; // Base for unwind Infos From 951b9f1c316172e94adada7a0e25a8343d07bd12 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Sat, 22 May 2021 23:31:11 +0200 Subject: [PATCH 2/9] Put also the code header and real code header into the buffer --- src/coreclr/vm/codeman.cpp | 51 ++++++++++++----- src/coreclr/vm/codeman.h | 2 +- src/coreclr/vm/i386/stublinkerx86.cpp | 3 +- src/coreclr/vm/jitinterface.cpp | 82 +++++++++++++-------------- src/coreclr/vm/jitinterface.h | 14 +++-- 5 files changed, 90 insertions(+), 62 deletions(-) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 36da24d9db4b5..55730c6e13bdc 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -2504,7 +2504,7 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t allocatedSize = header+blockSize+(align-1)+pInfo->getReserveForJumpStubs(); if (pAllocatedSize != NULL) { - *pAllocatedSize = allocatedSize; + *pAllocatedSize = allocatedSize - (align - 1); } pInfo->setRequestSize(allocatedSize); @@ -2597,18 +2597,18 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, RETURN(mem); } -CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, size_t* pAllocatedSize +void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, size_t* pAllocatedSize, BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS , UINT nUnwindInfos , TADDR * pModuleBase #endif ) { - CONTRACT(CodeHeader *) { + CONTRACTL { THROWS; GC_NOTRIGGER; - POSTCONDITION(CheckPointer(RETVAL)); - } CONTRACT_END; +// POSTCONDITION(CheckPointer(RETVAL)); + } CONTRACTL_END; // // Alignment @@ -2641,6 +2641,7 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re SIZE_T totalSize = blockSize; CodeHeader * pCodeHdr = NULL; + CodeHeader * pCodeHdrRW = NULL; CodeHeapRequestInfo requestInfo(pMD); #if defined(FEATURE_JIT_PITCHING) @@ -2649,6 +2650,10 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re requestInfo.SetDynamicDomain(); } #endif + if (reserveForJumpStubs != 0) + { + __debugbreak(); + } requestInfo.setReserveForJumpStubs(reserveForJumpStubs); #if defined(USE_INDIRECT_CODEHEADER) @@ -2680,17 +2685,19 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re } _ASSERTE(IS_ALIGNED(pCode, alignment)); - +//Maybe this is the problem! // Initialize the CodeHeader *BEFORE* we publish this code range via the nibble // map so that we don't have to harden readers against uninitialized data. // However because we hold the lock, this initialization should be fast and cheap! pCodeHdr = ((CodeHeader *)pCode) - 1; + pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize](); #ifdef USE_INDIRECT_CODEHEADER if (requestInfo.IsDynamicDomain()) { - pCodeHdr->SetRealCodeHeader((BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*))); + // Set the real code header to the writeable mapping so that we can set its members via the CodeHeader methods below + pCodeHdrRW->SetRealCodeHeader((BYTE *)(pCodeHdrRW + 1) + ALIGN_UP(blockSize, sizeof(void*))); } else { @@ -2698,23 +2705,39 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t re // // allocate the real header in the low frequency heap BYTE* pRealHeader = (BYTE*)(void*)pMD->GetLoaderAllocator()->GetLowFrequencyHeap()->AllocMem(S_SIZE_T(realHeaderSize)); - pCodeHdr->SetRealCodeHeader(pRealHeader); + pCodeHdrRW->SetRealCodeHeader(pRealHeader); } #endif - pCodeHdr->SetDebugInfo(NULL); - pCodeHdr->SetEHInfo(NULL); - pCodeHdr->SetGCInfo(NULL); - pCodeHdr->SetMethodDesc(pMD); + pCodeHdrRW->SetDebugInfo(NULL); + pCodeHdrRW->SetEHInfo(NULL); + pCodeHdrRW->SetGCInfo(NULL); + pCodeHdrRW->SetMethodDesc(pMD); #ifdef FEATURE_EH_FUNCLETS - pCodeHdr->SetNumberOfUnwindInfos(nUnwindInfos); + pCodeHdrRW->SetNumberOfUnwindInfos(nUnwindInfos); *pModuleBase = pCodeHeap->GetModuleBase(); #endif + // This needs to happen elsewhere, + // if (requestInfo.IsDynamicDomain()) + // { + // // We are done setting the real code header members, so set it to the final executable mapping + // pCodeHdrRW->SetRealCodeHeader((BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*))); + // } NibbleMapSet(pCodeHeap, pCode, TRUE); + + if (requestInfo.IsDynamicDomain()) + { + *ppRealHeader = (BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*)); + } + else + { + *ppRealHeader = NULL; + } } - RETURN(pCodeHdr); + *ppCodeHeader = pCodeHdr; + *ppCodeHeaderRW = pCodeHdrRW; } EEJitManager::DomainCodeHeapList *EEJitManager::GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly) diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 06a0e54de6c1a..f01b7feb8035e 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -974,7 +974,7 @@ class EEJitManager : public IJitManager BOOL LoadJIT(); - CodeHeader* allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, size_t* pAllocatedSize + void allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, size_t* pAllocatedSize, BYTE** ppRealHeader #ifdef FEATURE_EH_FUNCLETS , UINT nUnwindInfos , TADDR * pModuleBase diff --git a/src/coreclr/vm/i386/stublinkerx86.cpp b/src/coreclr/vm/i386/stublinkerx86.cpp index 8817bf1cc4fe4..eba92f95b3084 100644 --- a/src/coreclr/vm/i386/stublinkerx86.cpp +++ b/src/coreclr/vm/i386/stublinkerx86.cpp @@ -5286,7 +5286,8 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int *(void**)GetBase() = (BYTE*)pMD - (iMethodDescChunkIndex * MethodDesc::ALIGNMENT); } - _ASSERTE(GetMethodDesc() == (TADDR)pMD); + MethodDesc* pPrecodeMD = (MethodDesc*)GetMethodDesc(); + _ASSERTE((TADDR)pPrecodeMD == (TADDR)pMD); PCODE target = (PCODE)GetEEFuncEntryPoint(PrecodeFixupThunk); #ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 135c0e19a8f67..4bc1eb29e4627 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11191,8 +11191,8 @@ void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr) if (pCodeHeader) jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len); - delete [] m_codeWriteBuffer; - m_codeWriteBuffer = NULL; + delete [] (BYTE*)m_CodeHeaderRW; + m_CodeHeaderRW = NULL; } /*********************************************************************/ @@ -11203,9 +11203,22 @@ void CEEJitInfo::WriteCode() GC_TRIGGERS; } CONTRACTL_END; - memcpy((void*)m_CodeHeader->GetCodeStartAddress(), m_codeWriteBuffer, m_codeWriteBufferSize); - delete [] m_codeWriteBuffer; - m_codeWriteBuffer = NULL; + if (m_pRealCodeHeader != NULL) + { + // Restore the read only version of the real code header + m_CodeHeaderRW->SetRealCodeHeader(m_pRealCodeHeader); + m_pRealCodeHeader = NULL; + } + +// memcpy((void*)m_CodeHeader->GetCodeStartAddress(), m_codeWriteBuffer, m_codeWriteBufferSize); + memcpy(m_CodeHeader, m_CodeHeaderRW, m_codeWriteBufferSize); + delete [] (BYTE*)m_CodeHeaderRW; + m_CodeHeaderRW = NULL; + // delete [] m_codeWriteBuffer; + // m_codeWriteBuffer = NULL; + + m_codeWriteBufferSize = 0; + #if defined(TARGET_AMD64) // Publish the new unwind information in a way that the ETW stack crawler can find @@ -11334,7 +11347,7 @@ void CEEJitInfo::CompressDebugInfo() NULL, m_pMethodBeingCompiled->GetLoaderAllocator()->GetLowFrequencyHeap()); - m_CodeHeader->SetDebugInfo(pDebugInfo); + m_CodeHeaderRW->SetDebugInfo(pDebugInfo); } EX_CATCH { @@ -11478,17 +11491,8 @@ void CEEJitInfo::allocUnwindInfo ( _ASSERTE(m_usedUnwindInfos > 0); } - PT_RUNTIME_FUNCTION pRuntimeFunction = m_CodeHeader->GetUnwindInfo(m_usedUnwindInfos); - PT_RUNTIME_FUNCTION pRuntimeFunctionRW = (PT_RUNTIME_FUNCTION)((BYTE *)pRuntimeFunction + m_writeableOffset); - if ((BYTE*)pRuntimeFunctionRW < m_codeWriteBuffer || (BYTE*)pRuntimeFunctionRW >= (m_codeWriteBuffer + m_codeWriteBufferSize)) - { - pRuntimeFunctionRW = pRuntimeFunction; - } - else - { - __debugbreak(); - } - + PT_RUNTIME_FUNCTION pRuntimeFunction = m_CodeHeaderRW->GetUnwindInfo(m_usedUnwindInfos); + m_usedUnwindInfos++; // Make sure that the RUNTIME_FUNCTION is aligned on a DWORD sized boundary @@ -11496,10 +11500,6 @@ void CEEJitInfo::allocUnwindInfo ( UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *) &(m_theUnwindBlock[m_usedUnwindSize]); UNWIND_INFO * pUnwindInfoRW = (UNWIND_INFO *)((BYTE*)pUnwindInfo + m_writeableOffset); - if ((BYTE*)pUnwindInfoRW < m_codeWriteBuffer || ((BYTE*)pUnwindInfoRW + unwindSize) > (m_codeWriteBuffer + m_codeWriteBufferSize)) - { - __debugbreak(); - } uint32_t prevUsedUnwindSize = m_usedUnwindSize; @@ -11546,13 +11546,13 @@ void CEEJitInfo::allocUnwindInfo ( unsigned unwindInfoDelta = (unsigned) unwindInfoDeltaT; - RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunctionRW, currentCodeOffset + startOffset); + RUNTIME_FUNCTION__SetBeginAddress(pRuntimeFunction, currentCodeOffset + startOffset); #ifdef TARGET_AMD64 - pRuntimeFunctionRW->EndAddress = currentCodeOffset + endOffset; + pRuntimeFunction->EndAddress = currentCodeOffset + endOffset; #endif - RUNTIME_FUNCTION__SetUnwindInfoAddress(pRuntimeFunctionRW, unwindInfoDelta); + RUNTIME_FUNCTION__SetUnwindInfoAddress(pRuntimeFunction, unwindInfoDelta); #ifdef _DEBUG if (funcKind != CORJIT_FUNC_ROOT) @@ -11561,9 +11561,9 @@ void CEEJitInfo::allocUnwindInfo ( for (ULONG iUnwindInfo = 0; iUnwindInfo < m_usedUnwindInfos - 1; iUnwindInfo++) { - PT_RUNTIME_FUNCTION pOtherFunction = m_CodeHeader->GetUnwindInfo(iUnwindInfo); - _ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunctionRW, baseAddress) - || RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunctionRW))); + PT_RUNTIME_FUNCTION pOtherFunction = m_CodeHeaderRW->GetUnwindInfo(iUnwindInfo); + _ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunction, baseAddress) + || RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunction))); } } #endif // _DEBUG @@ -12303,18 +12303,16 @@ void CEEJitInfo::allocMem (AllocMemArgs *pArgs) pArgs->hotCodeSize + pArgs->coldCodeSize, pArgs->roDataSize, totalSize.Value(), pArgs->flag, GetClrInstanceId()); } - // TODO: move the write buffer allocation inside of the allocCode and use it to write the code header too. - m_CodeHeader = m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_codeWriteBufferSize + m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pRealCodeHeader #ifdef FEATURE_EH_FUNCLETS , m_totalUnwindInfos , &m_moduleBase #endif ); - m_codeWriteBufferSize = totalSize.Value(); +// m_codeWriteBufferSize = totalSize.Value(); BYTE* current = (BYTE *)m_CodeHeader->GetCodeStartAddress(); - m_codeWriteBuffer = new BYTE[m_codeWriteBufferSize]; - m_writeableOffset = m_codeWriteBuffer - current; + m_writeableOffset = (BYTE *)m_CodeHeaderRW - (BYTE *)m_CodeHeader; *codeBlock = current; *codeBlockRW = current + m_writeableOffset; @@ -12362,8 +12360,8 @@ void * CEEJitInfo::allocGCInfo (size_t size) JIT_TO_EE_TRANSITION(); - _ASSERTE(m_CodeHeader != 0); - _ASSERTE(m_CodeHeader->GetGCInfo() == 0); + _ASSERTE(m_CodeHeaderRW != 0); + _ASSERTE(m_CodeHeaderRW->GetGCInfo() == 0); #ifdef HOST_64BIT if (size & 0xFFFFFFFF80000000LL) @@ -12372,13 +12370,13 @@ void * CEEJitInfo::allocGCInfo (size_t size) } #endif // HOST_64BIT - block = m_jitManager->allocGCInfo(m_CodeHeader,(DWORD)size, &m_GCinfo_len); + block = m_jitManager->allocGCInfo(m_CodeHeaderRW,(DWORD)size, &m_GCinfo_len); if (!block) { COMPlusThrowHR(CORJIT_OUTOFMEM); } - _ASSERTE(m_CodeHeader->GetGCInfo() != 0 && block == m_CodeHeader->GetGCInfo()); + _ASSERTE(m_CodeHeaderRW->GetGCInfo() != 0 && block == m_CodeHeaderRW->GetGCInfo()); EE_TO_JIT_TRANSITION(); @@ -12398,14 +12396,14 @@ void CEEJitInfo::setEHcount ( JIT_TO_EE_TRANSITION(); _ASSERTE(cEH != 0); - _ASSERTE(m_CodeHeader != 0); - _ASSERTE(m_CodeHeader->GetEHInfo() == 0); + _ASSERTE(m_CodeHeaderRW != 0); + _ASSERTE(m_CodeHeaderRW->GetEHInfo() == 0); EE_ILEXCEPTION* ret; - ret = m_jitManager->allocEHInfo(m_CodeHeader,cEH, &m_EHinfo_len); + ret = m_jitManager->allocEHInfo(m_CodeHeaderRW,cEH, &m_EHinfo_len); _ASSERTE(ret); // allocEHInfo throws if there's not enough memory - _ASSERTE(m_CodeHeader->GetEHInfo() != 0 && m_CodeHeader->GetEHInfo()->EHCount() == cEH); + _ASSERTE(m_CodeHeaderRW->GetEHInfo() != 0 && m_CodeHeaderRW->GetEHInfo()->EHCount() == cEH); EE_TO_JIT_TRANSITION(); } @@ -12424,9 +12422,9 @@ void CEEJitInfo::setEHinfo ( JIT_TO_EE_TRANSITION(); // Fix make the Code Manager EH clauses EH_INFO+ - _ASSERTE(m_CodeHeader->GetEHInfo() != 0 && EHnumber < m_CodeHeader->GetEHInfo()->EHCount()); + _ASSERTE(m_CodeHeaderRW->GetEHInfo() != 0 && EHnumber < m_CodeHeaderRW->GetEHInfo()->EHCount()); - EE_ILEXCEPTION_CLAUSE* pEHClause = m_CodeHeader->GetEHInfo()->EHClause(EHnumber); + EE_ILEXCEPTION_CLAUSE* pEHClause = m_CodeHeaderRW->GetEHInfo()->EHClause(EHnumber); pEHClause->TryStartPC = clause->TryOffset; pEHClause->TryEndPC = clause->TryLength; diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index f4010d20d1041..da3e907b8b490 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -707,8 +707,12 @@ class CEEJitInfo : public CEEInfo m_CodeHeader = NULL; m_writeableOffset = 0; - delete [] m_codeWriteBuffer; - m_codeWriteBuffer = NULL; + delete [] (BYTE*)m_CodeHeaderRW; + m_CodeHeaderRW = NULL; + + m_codeWriteBufferSize = 0; + + m_pRealCodeHeader = NULL; if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping); @@ -808,8 +812,9 @@ class CEEJitInfo : public CEEInfo : CEEInfo(fd, fVerifyOnly, allowInlining), m_jitManager(jm), m_CodeHeader(NULL), - m_codeWriteBuffer(NULL), + m_CodeHeaderRW(NULL), m_codeWriteBufferSize(0), + m_pRealCodeHeader(NULL), m_writeableOffset(0), m_ILHeader(header), #ifdef FEATURE_EH_FUNCLETS @@ -943,8 +948,9 @@ protected : EEJitManager* m_jitManager; // responsible for allocating memory CodeHeader* m_CodeHeader; // descriptor for JITTED code - BYTE* m_codeWriteBuffer; + CodeHeader* m_CodeHeaderRW; size_t m_codeWriteBufferSize; + BYTE* m_pRealCodeHeader; size_t m_writeableOffset; COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file #ifdef FEATURE_EH_FUNCLETS From afa6c2f135cf3a1605ad22cb9f311e80765e6635 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 24 May 2021 15:36:15 +0200 Subject: [PATCH 3/9] Publish code via nibble map after it is copied to its final location --- src/coreclr/vm/codeman.cpp | 68 ++++++++++++--------------- src/coreclr/vm/codeman.h | 20 ++++---- src/coreclr/vm/i386/stublinkerx86.cpp | 3 +- src/coreclr/vm/jitinterface.cpp | 30 +++++++----- src/coreclr/vm/jitinterface.h | 13 ++++- 5 files changed, 72 insertions(+), 62 deletions(-) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 55730c6e13bdc..88264215fa015 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -2492,7 +2492,7 @@ HeapList* EEJitManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHeapLi void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, - HeapList ** ppCodeHeap, size_t* pAllocatedSize) + HeapList ** ppCodeHeap) { CONTRACT(void *) { THROWS; @@ -2501,12 +2501,7 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, POSTCONDITION((RETVAL != NULL) || !pInfo->getThrowOnOutOfMemoryWithinRange()); } CONTRACT_END; - size_t allocatedSize = header+blockSize+(align-1)+pInfo->getReserveForJumpStubs(); - if (pAllocatedSize != NULL) - { - *pAllocatedSize = allocatedSize - (align - 1); - } - pInfo->setRequestSize(allocatedSize); + pInfo->setRequestSize(header+blockSize+(align-1)+pInfo->getReserveForJumpStubs()); void * mem = NULL; HeapList * pCodeHeap = NULL; @@ -2597,17 +2592,19 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo, RETURN(mem); } -void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, size_t* pAllocatedSize, BYTE** ppRealHeader +void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, + size_t* pAllocatedSize, HeapList** ppCodeHeap +#ifdef USE_INDIRECT_CODEHEADER + , BYTE** ppRealHeader +#endif #ifdef FEATURE_EH_FUNCLETS - , UINT nUnwindInfos - , TADDR * pModuleBase + , UINT nUnwindInfos #endif - ) + ) { CONTRACTL { THROWS; GC_NOTRIGGER; -// POSTCONDITION(CheckPointer(RETVAL)); } CONTRACTL_END; // @@ -2650,10 +2647,6 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo requestInfo.SetDynamicDomain(); } #endif - if (reserveForJumpStubs != 0) - { - __debugbreak(); - } requestInfo.setReserveForJumpStubs(reserveForJumpStubs); #if defined(USE_INDIRECT_CODEHEADER) @@ -2673,11 +2666,9 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo { CrstHolder ch(&m_CodeHeapCritSec); - HeapList *pCodeHeap = NULL; - - TADDR pCode = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), totalSize, alignment, &pCodeHeap, pAllocatedSize); - - _ASSERTE(pCodeHeap); + *ppCodeHeap = NULL; + TADDR pCode = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), totalSize, alignment, ppCodeHeap); + _ASSERTE(*ppCodeHeap); if (pMD->IsLCGMethod()) { @@ -2685,13 +2676,11 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo } _ASSERTE(IS_ALIGNED(pCode, alignment)); -//Maybe this is the problem! - // Initialize the CodeHeader *BEFORE* we publish this code range via the nibble - // map so that we don't have to harden readers against uninitialized data. - // However because we hold the lock, this initialization should be fast and cheap! pCodeHdr = ((CodeHeader *)pCode) - 1; - pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize](); + + *pAllocatedSize = sizeof(CodeHeader) + totalSize + reserveForJumpStubs; + pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize]; #ifdef USE_INDIRECT_CODEHEADER if (requestInfo.IsDynamicDomain()) @@ -2715,17 +2704,9 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo pCodeHdrRW->SetMethodDesc(pMD); #ifdef FEATURE_EH_FUNCLETS pCodeHdrRW->SetNumberOfUnwindInfos(nUnwindInfos); - *pModuleBase = pCodeHeap->GetModuleBase(); #endif - // This needs to happen elsewhere, - // if (requestInfo.IsDynamicDomain()) - // { - // // We are done setting the real code header members, so set it to the final executable mapping - // pCodeHdrRW->SetRealCodeHeader((BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*))); - // } - - NibbleMapSet(pCodeHeap, pCode, TRUE); +#ifdef USE_INDIRECT_CODEHEADER if (requestInfo.IsDynamicDomain()) { *ppRealHeader = (BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*)); @@ -2734,6 +2715,7 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo { *ppRealHeader = NULL; } +#endif // USE_INDIRECT_CODEHEADER } *ppCodeHeader = pCodeHdr; @@ -3012,7 +2994,7 @@ JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD n { CrstHolder ch(&m_CodeHeapCritSec); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, CODE_SIZE_ALIGN, &pCodeHeap, NULL); + mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(TADDR), blockSize, CODE_SIZE_ALIGN, &pCodeHeap); if (mem == NULL) { _ASSERTE(!throwOnOutOfMemoryWithinRange); @@ -3068,7 +3050,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment { CrstHolder ch(&m_CodeHeapCritSec); - mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap, NULL); + mem = (TADDR) allocCodeRaw(&requestInfo, sizeof(CodeHeader), blockSize, alignment, &pCodeHeap); // CodeHeader comes immediately before the block CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); @@ -3878,6 +3860,18 @@ TADDR EEJitManager::FindMethodCode(RangeSection * pRangeSection, PCODE currentPC } #if !defined(DACCESS_COMPILE) + +void EEJitManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, BOOL bSet) +{ + CONTRACTL { + NOTHROW; + GC_NOTRIGGER; + } CONTRACTL_END; + + CrstHolder ch(&m_CodeHeapCritSec); + NibbleMapSet(pHp, pCode, bSet); +} + void EEJitManager::NibbleMapSet(HeapList * pHp, TADDR pCode, BOOL bSet) { CONTRACTL { diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index f01b7feb8035e..e5b9e6fb2205b 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -461,9 +461,9 @@ class CodeHeap // The number of code heaps at which we increase the size of new code heaps. #define CODE_HEAP_SIZE_INCREASE_THRESHOLD 5 -typedef DPTR(struct _HeapList) PTR_HeapList; +typedef DPTR(struct HeapList) PTR_HeapList; -typedef struct _HeapList +struct HeapList { PTR_HeapList hpNext; @@ -497,7 +497,7 @@ typedef struct _HeapList void SetNext(PTR_HeapList next) { hpNext = next; } -} HeapList; +}; //----------------------------------------------------------------------------- // Implementation of the standard CodeHeap. @@ -974,12 +974,15 @@ class EEJitManager : public IJitManager BOOL LoadJIT(); - void allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, size_t* pAllocatedSize, BYTE** ppRealHeader + void allocCode(MethodDesc* pFD, size_t blockSize, size_t reserveForJumpStubs, CorJitAllocMemFlag flag, CodeHeader** ppCodeHeader, CodeHeader** ppCodeHeaderRW, + size_t* pAllocatedSize, HeapList** ppCodeHeap +#ifdef USE_INDIRECT_CODEHEADER + , BYTE** ppRealHeader +#endif #ifdef FEATURE_EH_FUNCLETS - , UINT nUnwindInfos - , TADDR * pModuleBase + , UINT nUnwindInfos #endif - ); + ); BYTE * allocGCInfo(CodeHeader* pCodeHeader, DWORD blockSize, size_t * pAllocationSize); EE_ILEXCEPTION* allocEHInfo(CodeHeader* pCodeHeader, unsigned numClauses, size_t * pAllocationSize); JumpStubBlockHeader* allocJumpStubBlock(MethodDesc* pMD, DWORD numJumps, @@ -1024,6 +1027,7 @@ class EEJitManager : public IJitManager #ifndef DACCESS_COMPILE // Heap Management functions void NibbleMapSet(HeapList * pHp, TADDR pCode, BOOL bSet); + void NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, BOOL bSet); #endif // !DACCESS_COMPILE static TADDR FindMethodCode(RangeSection * pRangeSection, PCODE currentPC); @@ -1054,7 +1058,7 @@ private : bool CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCodeHeap); void* allocCodeRaw(CodeHeapRequestInfo *pInfo, size_t header, size_t blockSize, unsigned align, - HeapList ** ppCodeHeap, size_t* pAllocatedSize); + HeapList ** ppCodeHeap); DomainCodeHeapList *GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE); DomainCodeHeapList *CreateCodeHeapList(CodeHeapRequestInfo *pInfo); diff --git a/src/coreclr/vm/i386/stublinkerx86.cpp b/src/coreclr/vm/i386/stublinkerx86.cpp index eba92f95b3084..8817bf1cc4fe4 100644 --- a/src/coreclr/vm/i386/stublinkerx86.cpp +++ b/src/coreclr/vm/i386/stublinkerx86.cpp @@ -5286,8 +5286,7 @@ void FixupPrecode::Init(MethodDesc* pMD, LoaderAllocator *pLoaderAllocator, int *(void**)GetBase() = (BYTE*)pMD - (iMethodDescChunkIndex * MethodDesc::ALIGNMENT); } - MethodDesc* pPrecodeMD = (MethodDesc*)GetMethodDesc(); - _ASSERTE((TADDR)pPrecodeMD == (TADDR)pMD); + _ASSERTE(GetMethodDesc() == (TADDR)pMD); PCODE target = (PCODE)GetEEFuncEntryPoint(PrecodeFixupThunk); #ifdef FIXUP_PRECODE_PREALLOCATE_DYNAMIC_METHOD_JUMP_STUBS diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 4bc1eb29e4627..c400618994efb 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11196,29 +11196,30 @@ void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr) } /*********************************************************************/ -void CEEJitInfo::WriteCode() +void CEEJitInfo::WriteCode(EEJitManager * jitMgr) { CONTRACTL { THROWS; GC_TRIGGERS; } CONTRACTL_END; +#ifdef USE_INDIRECT_CODEHEADER if (m_pRealCodeHeader != NULL) { // Restore the read only version of the real code header m_CodeHeaderRW->SetRealCodeHeader(m_pRealCodeHeader); m_pRealCodeHeader = NULL; } +#endif // USE_INDIRECT_CODEHEADER -// memcpy((void*)m_CodeHeader->GetCodeStartAddress(), m_codeWriteBuffer, m_codeWriteBufferSize); memcpy(m_CodeHeader, m_CodeHeaderRW, m_codeWriteBufferSize); delete [] (BYTE*)m_CodeHeaderRW; m_CodeHeaderRW = NULL; - // delete [] m_codeWriteBuffer; - // m_codeWriteBuffer = NULL; - m_codeWriteBufferSize = 0; + // Now that the code header was written to the final location, publish the code via the nibble map + jitMgr->NibbleMapSetUnlocked(m_pCodeHeap, m_CodeHeader->GetCodeStartAddress(), TRUE); + m_pCodeHeap = NULL; #if defined(TARGET_AMD64) // Publish the new unwind information in a way that the ETW stack crawler can find @@ -11501,8 +11502,6 @@ void CEEJitInfo::allocUnwindInfo ( UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *) &(m_theUnwindBlock[m_usedUnwindSize]); UNWIND_INFO * pUnwindInfoRW = (UNWIND_INFO *)((BYTE*)pUnwindInfo + m_writeableOffset); - uint32_t prevUsedUnwindSize = m_usedUnwindSize; - m_usedUnwindSize += unwindSize; reservePersonalityRoutineSpace(m_usedUnwindSize); @@ -12303,14 +12302,19 @@ void CEEJitInfo::allocMem (AllocMemArgs *pArgs) pArgs->hotCodeSize + pArgs->coldCodeSize, pArgs->roDataSize, totalSize.Value(), pArgs->flag, GetClrInstanceId()); } - m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pRealCodeHeader + m_jitManager->allocCode(m_pMethodBeingCompiled, totalSize.Value(), GetReserveForJumpStubs(), pArgs->flag, &m_CodeHeader, &m_CodeHeaderRW, &m_codeWriteBufferSize, &m_pCodeHeap +#ifdef USE_INDIRECT_CODEHEADER + , &m_pRealCodeHeader +#endif +#ifdef FEATURE_EH_FUNCLETS + , m_totalUnwindInfos +#endif + ); + #ifdef FEATURE_EH_FUNCLETS - , m_totalUnwindInfos - , &m_moduleBase + m_moduleBase = m_pCodeHeap->GetModuleBase(); #endif - ); -// m_codeWriteBufferSize = totalSize.Value(); BYTE* current = (BYTE *)m_CodeHeader->GetCodeStartAddress(); m_writeableOffset = (BYTE *)m_CodeHeaderRW - (BYTE *)m_CodeHeader; @@ -13318,7 +13322,7 @@ PCODE UnsafeJitFunction(PrepareCodeConfig* config, if (SUCCEEDED(res)) { - jitInfo.WriteCode(); + jitInfo.WriteCode(jitMgr); } else { diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index da3e907b8b490..ac9f790e49b5f 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -626,6 +626,7 @@ class CEEInfo : public ICorJitInfo /*********************************************************************/ class EEJitManager; +struct HeapList; struct _hpCodeHdr; typedef struct _hpCodeHdr CodeHeader; @@ -711,8 +712,10 @@ class CEEJitInfo : public CEEInfo m_CodeHeaderRW = NULL; m_codeWriteBufferSize = 0; - +#ifdef USE_INDIRECT_CODEHEADER m_pRealCodeHeader = NULL; +#endif + m_pCodeHeap = NULL; if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping); @@ -814,8 +817,11 @@ class CEEJitInfo : public CEEInfo m_CodeHeader(NULL), m_CodeHeaderRW(NULL), m_codeWriteBufferSize(0), +#ifdef USE_INDIRECT_CODEHEADER m_pRealCodeHeader(NULL), +#endif m_writeableOffset(0), + m_pCodeHeap(NULL), m_ILHeader(header), #ifdef FEATURE_EH_FUNCLETS m_moduleBase(NULL), @@ -921,7 +927,7 @@ class CEEJitInfo : public CEEInfo void BackoutJitData(EEJitManager * jitMgr); - void WriteCode(); + void WriteCode(EEJitManager * jitMgr); void setPatchpointInfo(PatchpointInfo* patchpointInfo) override final; PatchpointInfo* getOSRInfo(unsigned* ilOffset) override final; @@ -950,8 +956,11 @@ protected : CodeHeader* m_CodeHeader; // descriptor for JITTED code CodeHeader* m_CodeHeaderRW; size_t m_codeWriteBufferSize; +#ifdef USE_INDIRECT_CODEHEADER BYTE* m_pRealCodeHeader; +#endif size_t m_writeableOffset; + HeapList* m_pCodeHeap; COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file #ifdef FEATURE_EH_FUNCLETS TADDR m_moduleBase; // Base for unwind Infos From 43698c32bb007b737a4b060315680bf614b534a8 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Mon, 24 May 2021 17:45:24 +0200 Subject: [PATCH 4/9] Remove m_writeableOffset --- src/coreclr/vm/jitinterface.cpp | 10 ++++++---- src/coreclr/vm/jitinterface.h | 3 --- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index c400618994efb..ccd80fedb9f8b 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11499,8 +11499,10 @@ void CEEJitInfo::allocUnwindInfo ( // Make sure that the RUNTIME_FUNCTION is aligned on a DWORD sized boundary _ASSERTE(IS_ALIGNED(pRuntimeFunction, sizeof(DWORD))); + + size_t writeableOffset = (BYTE *)m_CodeHeaderRW - (BYTE *)m_CodeHeader; UNWIND_INFO * pUnwindInfo = (UNWIND_INFO *) &(m_theUnwindBlock[m_usedUnwindSize]); - UNWIND_INFO * pUnwindInfoRW = (UNWIND_INFO *)((BYTE*)pUnwindInfo + m_writeableOffset); + UNWIND_INFO * pUnwindInfoRW = (UNWIND_INFO *)((BYTE*)pUnwindInfo + writeableOffset); m_usedUnwindSize += unwindSize; @@ -12316,17 +12318,17 @@ void CEEJitInfo::allocMem (AllocMemArgs *pArgs) #endif BYTE* current = (BYTE *)m_CodeHeader->GetCodeStartAddress(); - m_writeableOffset = (BYTE *)m_CodeHeaderRW - (BYTE *)m_CodeHeader; + size_t writeableOffset = (BYTE *)m_CodeHeaderRW - (BYTE *)m_CodeHeader; *codeBlock = current; - *codeBlockRW = current + m_writeableOffset; + *codeBlockRW = current + writeableOffset; current += codeSize; if (pArgs->roDataSize > 0) { current = (BYTE *)ALIGN_UP(current, roDataAlignment); pArgs->roDataBlock = current; - pArgs->roDataBlockRW = current + m_writeableOffset; + pArgs->roDataBlockRW = current + writeableOffset; current += pArgs->roDataSize; } else diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index ac9f790e49b5f..59e00f0feadf4 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -706,7 +706,6 @@ class CEEJitInfo : public CEEInfo } CONTRACTL_END; m_CodeHeader = NULL; - m_writeableOffset = 0; delete [] (BYTE*)m_CodeHeaderRW; m_CodeHeaderRW = NULL; @@ -820,7 +819,6 @@ class CEEJitInfo : public CEEInfo #ifdef USE_INDIRECT_CODEHEADER m_pRealCodeHeader(NULL), #endif - m_writeableOffset(0), m_pCodeHeap(NULL), m_ILHeader(header), #ifdef FEATURE_EH_FUNCLETS @@ -959,7 +957,6 @@ protected : #ifdef USE_INDIRECT_CODEHEADER BYTE* m_pRealCodeHeader; #endif - size_t m_writeableOffset; HeapList* m_pCodeHeap; COR_ILMETHOD_DECODER * m_ILHeader; // the code header as exist in the file #ifdef FEATURE_EH_FUNCLETS From 263e072062c79795554db3e467a63496530495af Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 25 May 2021 00:24:22 +0200 Subject: [PATCH 5/9] Fix ARM64 relocation writing --- src/coreclr/vm/jitinterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index ccd80fedb9f8b..e2d9445671dde 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11718,7 +11718,7 @@ void CEEJitInfo::recordRelocation(void * location, delta = (INT64)(branchTarget - fixupLocation); _ASSERTE((delta & 0x3) == 0); // the low two bits must be zero - UINT32 branchInstr = *((UINT32*) fixupLocation); + UINT32 branchInstr = *((UINT32*) fixupLocationRW); branchInstr &= 0xFC000000; // keep bits 31-26 _ASSERTE((branchInstr & 0x7FFFFFFF) == 0x14000000); // Must be B or BL From c7b564c4a36213ef3d8fb5a505c7c385beb48078 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 25 May 2021 10:55:28 +0200 Subject: [PATCH 6/9] Reflect PR feedback --- src/coreclr/vm/codeman.cpp | 16 ++++++++-------- src/coreclr/vm/jitinterface.cpp | 9 +-------- src/coreclr/vm/jitinterface.h | 2 ++ 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 88264215fa015..966cec726be01 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -2679,7 +2679,7 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo pCodeHdr = ((CodeHeader *)pCode) - 1; - *pAllocatedSize = sizeof(CodeHeader) + totalSize + reserveForJumpStubs; + *pAllocatedSize = sizeof(CodeHeader) + totalSize; pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize]; #ifdef USE_INDIRECT_CODEHEADER @@ -3005,7 +3005,7 @@ JumpStubBlockHeader * EEJitManager::allocJumpStubBlock(MethodDesc* pMD, DWORD n CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); pCodeHdr->SetStubCodeBlockKind(STUB_CODE_BLOCK_JUMPSTUB); - NibbleMapSet(pCodeHeap, mem, TRUE); + NibbleMapSetUnlocked(pCodeHeap, mem, TRUE); pBlock = (JumpStubBlockHeader *)mem; @@ -3056,7 +3056,7 @@ void * EEJitManager::allocCodeFragmentBlock(size_t blockSize, unsigned alignment CodeHeader * pCodeHdr = (CodeHeader *) (mem - sizeof(CodeHeader)); pCodeHdr->SetStubCodeBlockKind(kind); - NibbleMapSet(pCodeHeap, mem, TRUE); + NibbleMapSetUnlocked(pCodeHeap, mem, TRUE); // Record the jump stub reservation pCodeHeap->reserveForJumpStubs += requestInfo.getReserveForJumpStubs(); @@ -3234,7 +3234,7 @@ void EEJitManager::RemoveJitData (CodeHeader * pCHdr, size_t GCinfo_len, size_t if (pHp == NULL) return; - NibbleMapSet(pHp, (TADDR)(pCHdr + 1), FALSE); + NibbleMapSetUnlocked(pHp, (TADDR)(pCHdr + 1), FALSE); } // Backout the GCInfo @@ -3396,7 +3396,7 @@ void EEJitManager::FreeCodeMemory(HostCodeHeap *pCodeHeap, void * codeStart) // so pCodeHeap can only be a HostCodeHeap. // clean up the NibbleMap - NibbleMapSet(pCodeHeap->m_pHeapList, (TADDR)codeStart, FALSE); + NibbleMapSetUnlocked(pCodeHeap->m_pHeapList, (TADDR)codeStart, FALSE); // The caller of this method doesn't call HostCodeHeap->FreeMemForCode // directly because the operation should be protected by m_CodeHeapCritSec. @@ -3861,7 +3861,7 @@ TADDR EEJitManager::FindMethodCode(RangeSection * pRangeSection, PCODE currentPC #if !defined(DACCESS_COMPILE) -void EEJitManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, BOOL bSet) +void EEJitManager::NibbleMapSet(HeapList * pHp, TADDR pCode, BOOL bSet) { CONTRACTL { NOTHROW; @@ -3869,10 +3869,10 @@ void EEJitManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, BOOL bSet) } CONTRACTL_END; CrstHolder ch(&m_CodeHeapCritSec); - NibbleMapSet(pHp, pCode, bSet); + NibbleMapSetUnlocked(pHp, pCode, bSet); } -void EEJitManager::NibbleMapSet(HeapList * pHp, TADDR pCode, BOOL bSet) +void EEJitManager::NibbleMapSetUnlocked(HeapList * pHp, TADDR pCode, BOOL bSet) { CONTRACTL { NOTHROW; diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index e2d9445671dde..5b657eb7d67df 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11190,9 +11190,6 @@ void CEEJitInfo::BackoutJitData(EEJitManager * jitMgr) CodeHeader* pCodeHeader = m_CodeHeader; if (pCodeHeader) jitMgr->RemoveJitData(pCodeHeader, m_GCinfo_len, m_EHinfo_len); - - delete [] (BYTE*)m_CodeHeaderRW; - m_CodeHeaderRW = NULL; } /*********************************************************************/ @@ -11213,13 +11210,9 @@ void CEEJitInfo::WriteCode(EEJitManager * jitMgr) #endif // USE_INDIRECT_CODEHEADER memcpy(m_CodeHeader, m_CodeHeaderRW, m_codeWriteBufferSize); - delete [] (BYTE*)m_CodeHeaderRW; - m_CodeHeaderRW = NULL; - m_codeWriteBufferSize = 0; // Now that the code header was written to the final location, publish the code via the nibble map - jitMgr->NibbleMapSetUnlocked(m_pCodeHeap, m_CodeHeader->GetCodeStartAddress(), TRUE); - m_pCodeHeap = NULL; + jitMgr->NibbleMapSet(m_pCodeHeap, m_CodeHeader->GetCodeStartAddress(), TRUE); #if defined(TARGET_AMD64) // Publish the new unwind information in a way that the ETW stack crawler can find diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 59e00f0feadf4..5dc40c907ad35 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -868,6 +868,8 @@ class CEEJitInfo : public CEEInfo MODE_ANY; } CONTRACTL_END; + delete [] (BYTE*)m_CodeHeaderRW; + if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping); From 4c67f8630b59200f4602cc41cd612ae2cabb6378 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 25 May 2021 19:14:33 +0200 Subject: [PATCH 7/9] Fix arm/arm64 assert --- src/coreclr/vm/jitinterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 5b657eb7d67df..3a741959fee2a 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11556,8 +11556,8 @@ void CEEJitInfo::allocUnwindInfo ( for (ULONG iUnwindInfo = 0; iUnwindInfo < m_usedUnwindInfos - 1; iUnwindInfo++) { PT_RUNTIME_FUNCTION pOtherFunction = m_CodeHeaderRW->GetUnwindInfo(iUnwindInfo); - _ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunction, baseAddress) - || RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunction))); + _ASSERTE(( RUNTIME_FUNCTION__BeginAddress(pOtherFunction) >= RUNTIME_FUNCTION__EndAddress(pRuntimeFunction, baseAddress + writeableOffset) + || RUNTIME_FUNCTION__EndAddress(pOtherFunction, baseAddress + writeableOffset) <= RUNTIME_FUNCTION__BeginAddress(pRuntimeFunction))); } } #endif // _DEBUG From 7922239468891d2a7a701621253c8e9fcc86cc04 Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Tue, 25 May 2021 22:54:43 +0200 Subject: [PATCH 8/9] Disable the scratch buffer usage until we enable W^X --- src/coreclr/vm/codeman.cpp | 4 ++++ src/coreclr/vm/jitinterface.h | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/coreclr/vm/codeman.cpp b/src/coreclr/vm/codeman.cpp index 966cec726be01..1898a791903f6 100644 --- a/src/coreclr/vm/codeman.cpp +++ b/src/coreclr/vm/codeman.cpp @@ -2680,7 +2680,11 @@ void EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, size_t reserveFo pCodeHdr = ((CodeHeader *)pCode) - 1; *pAllocatedSize = sizeof(CodeHeader) + totalSize; +#ifdef FEATURE_WXORX pCodeHdrRW = (CodeHeader *)new BYTE[*pAllocatedSize]; +#else + pCodeHdrRW = pCodeHdr; +#endif #ifdef USE_INDIRECT_CODEHEADER if (requestInfo.IsDynamicDomain()) diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 5dc40c907ad35..0a315c63a1f8b 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -707,7 +707,9 @@ class CEEJitInfo : public CEEInfo m_CodeHeader = NULL; +#ifdef FEATURE_WXORX delete [] (BYTE*)m_CodeHeaderRW; +#endif m_CodeHeaderRW = NULL; m_codeWriteBufferSize = 0; @@ -868,8 +870,9 @@ class CEEJitInfo : public CEEInfo MODE_ANY; } CONTRACTL_END; +#ifdef FEATURE_WXORX delete [] (BYTE*)m_CodeHeaderRW; - +#endif if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping); From 06482f040530ee69b7b69b8e31aa92cc530d4e9c Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Wed, 26 May 2021 10:14:55 +0200 Subject: [PATCH 9/9] Reflect PR feedback --- src/coreclr/vm/jitinterface.cpp | 5 ++++- src/coreclr/vm/jitinterface.h | 17 ++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 3a741959fee2a..dffcae19b0053 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -11209,7 +11209,10 @@ void CEEJitInfo::WriteCode(EEJitManager * jitMgr) } #endif // USE_INDIRECT_CODEHEADER - memcpy(m_CodeHeader, m_CodeHeaderRW, m_codeWriteBufferSize); + if (m_CodeHeaderRW != m_CodeHeader) + { + memcpy(m_CodeHeader, m_CodeHeaderRW, m_codeWriteBufferSize); + } // Now that the code header was written to the final location, publish the code via the nibble map jitMgr->NibbleMapSet(m_pCodeHeap, m_CodeHeader->GetCodeStartAddress(), TRUE); diff --git a/src/coreclr/vm/jitinterface.h b/src/coreclr/vm/jitinterface.h index 0a315c63a1f8b..8b6c5053c821b 100644 --- a/src/coreclr/vm/jitinterface.h +++ b/src/coreclr/vm/jitinterface.h @@ -705,11 +705,12 @@ class CEEJitInfo : public CEEInfo GC_NOTRIGGER; } CONTRACTL_END; + if (m_CodeHeaderRW != m_CodeHeader) + { + delete [] (BYTE*)m_CodeHeaderRW; + } + m_CodeHeader = NULL; - -#ifdef FEATURE_WXORX - delete [] (BYTE*)m_CodeHeaderRW; -#endif m_CodeHeaderRW = NULL; m_codeWriteBufferSize = 0; @@ -870,9 +871,11 @@ class CEEJitInfo : public CEEInfo MODE_ANY; } CONTRACTL_END; -#ifdef FEATURE_WXORX - delete [] (BYTE*)m_CodeHeaderRW; -#endif + if (m_CodeHeaderRW != m_CodeHeader) + { + delete [] (BYTE*)m_CodeHeaderRW; + } + if (m_pOffsetMapping != NULL) delete [] ((BYTE*) m_pOffsetMapping);