diff --git a/src/coreclr/debug/runtimeinfo/contracts.jsonc b/src/coreclr/debug/runtimeinfo/contracts.jsonc index 499a284cbcd70..235ce32ea0b11 100644 --- a/src/coreclr/debug/runtimeinfo/contracts.jsonc +++ b/src/coreclr/debug/runtimeinfo/contracts.jsonc @@ -13,6 +13,7 @@ "EcmaMetadata" : 1, "Exception": 1, "Loader": 1, + "NativeCodePointers": 1, "Object": 1, "RuntimeTypeSystem": 1, "Thread": 1 diff --git a/src/coreclr/debug/runtimeinfo/datadescriptor.h b/src/coreclr/debug/runtimeinfo/datadescriptor.h index 967df850abcc9..6c8dfdbc85696 100644 --- a/src/coreclr/debug/runtimeinfo/datadescriptor.h +++ b/src/coreclr/debug/runtimeinfo/datadescriptor.h @@ -233,8 +233,16 @@ CDAC_TYPE_END(Module) CDAC_TYPE_BEGIN(ModuleLookupMap) CDAC_TYPE_FIELD(ModuleLookupMap, /*pointer*/, TableData, offsetof(LookupMapBase, pTable)) +CDAC_TYPE_FIELD(ModuleLookupMap, /*pointer*/, Next, offsetof(LookupMapBase, pNext)) +CDAC_TYPE_FIELD(ModuleLookupMap, /*uint32*/, Count, offsetof(LookupMapBase, dwCount)) +CDAC_TYPE_FIELD(ModuleLookupMap, /*nuint*/, SupportedFlagsMask, offsetof(LookupMapBase, supportedFlags)) CDAC_TYPE_END(ModuleLookupMap) +CDAC_TYPE_BEGIN(LoaderAllocator) +CDAC_TYPE_INDETERMINATE(LoaderAllocator) +CDAC_TYPE_FIELD(LoaderAllocator, /*uint8*/, IsCollectible, cdac_data::IsCollectible) +CDAC_TYPE_END(LoaderAllocator) + // RuntimeTypeSystem CDAC_TYPE_BEGIN(MethodTable) @@ -299,11 +307,13 @@ CDAC_TYPE_FIELD(DynamicMetadata, /*inline byte array*/, Data, cdac_data::ChunkIndex) CDAC_TYPE_FIELD(MethodDesc, /*uint16*/, Slot, cdac_data::Slot) CDAC_TYPE_FIELD(MethodDesc, /*uint16*/, Flags, cdac_data::Flags) CDAC_TYPE_FIELD(MethodDesc, /*uint16*/, Flags3AndTokenRemainder, cdac_data::Flags3AndTokenRemainder) +CDAC_TYPE_FIELD(MethodDesc, /*uint8*/, EntryPointFlags, cdac_data::EntryPointFlags) +CDAC_TYPE_FIELD(MethodDesc, /*pointer*/, CodeData, cdac_data::CodeData) CDAC_TYPE_END(MethodDesc) CDAC_TYPE_BEGIN(MethodDescChunk) @@ -334,6 +344,105 @@ CDAC_TYPE_INDETERMINATE(DynamicMethodDesc) CDAC_TYPE_FIELD(DynamicMethodDesc, /*pointer*/, MethodName, cdac_data::MethodName) CDAC_TYPE_END(DynamicMethodDesc) +CDAC_TYPE_BEGIN(CodePointer) +CDAC_TYPE_SIZE(sizeof(PCODE)) +CDAC_TYPE_END(CodePointer) + +CDAC_TYPE_BEGIN(MethodDescCodeData) +CDAC_TYPE_INDETERMINATE(MethodDescCodeData) +CDAC_TYPE_FIELD(MethodDescCodeData, /*CodePointer*/, TemporaryEntryPoint, offsetof(MethodDescCodeData,TemporaryEntryPoint)) +CDAC_TYPE_FIELD(MethodDescCodeData, /*pointer*/, VersioningState, offsetof(MethodDescCodeData,VersioningState)) +CDAC_TYPE_END(MethodDescCodeData) + +CDAC_TYPE_BEGIN(MethodDescVersioningState) +CDAC_TYPE_INDETERMINATE(MethodDescVersioningState) +CDAC_TYPE_FIELD(MethodDescVersioningState, /*pointer*/, NativeCodeVersionNode, cdac_data::NativeCodeVersionNode) +CDAC_TYPE_FIELD(MethodDescVersioningState, /*uint8*/, Flags, cdac_data::Flags) +CDAC_TYPE_END(MethodDescVersioningState) + +CDAC_TYPE_BEGIN(PrecodeMachineDescriptor) +CDAC_TYPE_INDETERMINATE(PrecodeMachineDescriptor) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uintptr*/, CodePointerToInstrPointerMask, offsetof(PrecodeMachineDescriptor, CodePointerToInstrPointerMask)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, ReadWidthOfPrecodeType, offsetof(PrecodeMachineDescriptor, ReadWidthOfPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, ShiftOfPrecodeType, offsetof(PrecodeMachineDescriptor, ShiftOfPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, OffsetOfPrecodeType, offsetof(PrecodeMachineDescriptor, OffsetOfPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, InvalidPrecodeType, offsetof(PrecodeMachineDescriptor, InvalidPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, StubPrecodeType, offsetof(PrecodeMachineDescriptor, StubPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, HasNDirectImportPrecode, offsetof(PrecodeMachineDescriptor, HasNDirectImportPrecode)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, NDirectImportPrecodeType, offsetof(PrecodeMachineDescriptor, NDirectImportPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, HasFixupPrecode, offsetof(PrecodeMachineDescriptor, HasFixupPrecode)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint8*/, FixupPrecodeType, offsetof(PrecodeMachineDescriptor, FixupPrecodeType)) +CDAC_TYPE_FIELD(PrecodeMachineDescriptor, /*uint32*/, StubCodePageSize, offsetof(PrecodeMachineDescriptor, StubCodePageSize)) +CDAC_TYPE_END(PrecodeMachineDescriptor) + +CDAC_TYPE_BEGIN(StubPrecodeData) +CDAC_TYPE_INDETERMINATE(StubPrecodeData) +CDAC_TYPE_FIELD(StubPrecodeData, /*pointer*/, MethodDesc, offsetof(StubPrecodeData, MethodDesc)) +CDAC_TYPE_FIELD(StubPrecodeData, /*uint8*/, Type, offsetof(StubPrecodeData, Type)) +CDAC_TYPE_END(StubPrecodeData) + +CDAC_TYPE_BEGIN(FixupPrecodeData) +CDAC_TYPE_INDETERMINATE(FixupPrecodeData) +CDAC_TYPE_FIELD(FixupPrecodeData, /*pointer*/, MethodDesc, offsetof(FixupPrecodeData, MethodDesc)) +CDAC_TYPE_END(FixupPrecodeData) + +CDAC_TYPE_BEGIN(RangeSectionMap) +CDAC_TYPE_INDETERMINATE(RangeSectionMap) +CDAC_TYPE_FIELD(RangeSectionMap, /*pointer*/, TopLevelData, cdac_data::TopLevelData) +CDAC_TYPE_END(RangeSectionMap) + +CDAC_TYPE_BEGIN(RangeSectionFragment) +CDAC_TYPE_INDETERMINATE(RangeSectionFragment) +CDAC_TYPE_FIELD(RangeSectionFragment, /*pointer*/, RangeBegin, cdac_data::RangeSectionFragment::RangeBegin) +CDAC_TYPE_FIELD(RangeSectionFragment, /*pointer*/, RangeEndOpen, cdac_data::RangeSectionFragment::RangeEndOpen) +CDAC_TYPE_FIELD(RangeSectionFragment, /*pointer*/, RangeSection, cdac_data::RangeSectionFragment::RangeSection) +CDAC_TYPE_FIELD(RangeSectionFragment, /*pointer*/, Next, cdac_data::RangeSectionFragment::Next) +CDAC_TYPE_END(RangeSectionFragment) + +CDAC_TYPE_BEGIN(RangeSection) +CDAC_TYPE_INDETERMINATE(RangeSection) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, RangeBegin, cdac_data::RangeBegin) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, RangeEndOpen, cdac_data::RangeEndOpen) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, NextForDelete, cdac_data::NextForDelete) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, JitManager, cdac_data::JitManager) +CDAC_TYPE_FIELD(RangeSection, /*int32_t*/, Flags, cdac_data::Flags) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, HeapList, cdac_data::HeapList) +CDAC_TYPE_FIELD(RangeSection, /*pointer*/, R2RModule, cdac_data::R2RModule) +CDAC_TYPE_END(RangeSection) + +CDAC_TYPE_BEGIN(RealCodeHeader) +CDAC_TYPE_INDETERMINATE(RealCodeHeader) +CDAC_TYPE_FIELD(RealCodeHeader, /*pointer*/, MethodDesc, offsetof(RealCodeHeader, phdrMDesc)) +CDAC_TYPE_END(RealCodeHeader) + +CDAC_TYPE_BEGIN(HeapList) +CDAC_TYPE_FIELD(HeapList, /*pointer*/, Next, offsetof(HeapList, hpNext)) +CDAC_TYPE_FIELD(HeapList, /*pointer*/, StartAddress, offsetof(HeapList, startAddress)) +CDAC_TYPE_FIELD(HeapList, /*pointer*/, EndAddress, offsetof(HeapList, endAddress)) +CDAC_TYPE_FIELD(HeapList, /*pointer*/, MapBase, offsetof(HeapList, mapBase)) +CDAC_TYPE_FIELD(HeapList, /*pointer*/, HeaderMap, offsetof(HeapList, pHdrMap)) +CDAC_TYPE_END(HeapList) + +CDAC_TYPE_BEGIN(ILCodeVersioningState) +CDAC_TYPE_INDETERMINATE(ILCodeVersioningState) +CDAC_TYPE_FIELD(ILCodeVersioningState, /*pointer*/, Node, cdac_data::Node) +CDAC_TYPE_FIELD(ILCodeVersioningState, /*uint32*/, ActiveVersionKind, cdac_data::ActiveVersionKind) +CDAC_TYPE_FIELD(ILCodeVersioningState, /*pointer*/, ActiveVersionNode, cdac_data::ActiveVersionNode) +CDAC_TYPE_FIELD(ILCodeVersioningState, /*pointer*/, ActiveVersionModule, cdac_data::ActiveVersionModule) +CDAC_TYPE_FIELD(ILCodeVersioningState, /*uint32*/, ActiveVersionMethodDef, cdac_data::ActiveVersionMethodDef) +CDAC_TYPE_END(ILCodeVersioningState) + +CDAC_TYPE_BEGIN(NativeCodeVersionNode) +CDAC_TYPE_INDETERMINATE(NativeCodeVersionNode) +CDAC_TYPE_FIELD(NativeCodeVersionNode, /*pointer*/, Next, cdac_data::Next) +CDAC_TYPE_FIELD(NativeCodeVersionNode, /*pointer*/, MethodDesc, cdac_data::MethodDesc) +CDAC_TYPE_FIELD(NativeCodeVersionNode, /*pointer*/, NativeCode, cdac_data::NativeCode) +CDAC_TYPE_END(NativeCodeVersionNode) + +CDAC_TYPE_BEGIN(ProfControlBlock) +CDAC_TYPE_FIELD(ProfControlBlock, /*uint64*/, GlobalEventMask, offsetof(ProfControlBlock, globalEventMask)) +CDAC_TYPE_END(ProfControlBlock) + CDAC_TYPES_END() CDAC_GLOBALS_BEGIN() @@ -363,6 +472,7 @@ CDAC_GLOBAL(DirectorySeparator, uint8, (uint8_t)DIRECTORY_SEPARATOR_CHAR_A) CDAC_GLOBAL(MethodDescAlignment, uint64, MethodDesc::ALIGNMENT) CDAC_GLOBAL(ObjectHeaderSize, uint64, OBJHEADER_SIZE) CDAC_GLOBAL(SyncBlockValueToObjectOffset, uint16, OBJHEADER_SIZE - cdac_data::SyncBlockValue) +CDAC_GLOBAL(StubCodeBlockLast, uint8, STUB_CODE_BLOCK_LAST) CDAC_GLOBAL_POINTER(ArrayBoundsZero, cdac_data::ArrayBoundsZero) CDAC_GLOBAL_POINTER(ExceptionMethodTable, &::g_pExceptionClass) CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &::g_pFreeObjectMethodTable) @@ -372,6 +482,9 @@ CDAC_GLOBAL_POINTER(StringMethodTable, &::g_pStringClass) CDAC_GLOBAL_POINTER(SyncTableEntries, &::g_pSyncTable) CDAC_GLOBAL_POINTER(MiniMetaDataBuffAddress, &::g_MiniMetaDataBuffAddress) CDAC_GLOBAL_POINTER(MiniMetaDataBuffMaxSize, &::g_MiniMetaDataBuffMaxSize) +CDAC_GLOBAL_POINTER(PrecodeMachineDescriptor, &::g_PrecodeMachineDescriptor) +CDAC_GLOBAL_POINTER(ExecutionManagerCodeRangeMapAddress, cdac_data::CodeRangeMapAddress) +CDAC_GLOBAL_POINTER(ProfilerControlBlock, &::g_profControlBlock) CDAC_GLOBALS_END() #undef CDAC_BASELINE diff --git a/src/coreclr/vm/appdomain.hpp b/src/coreclr/vm/appdomain.hpp index 7bf26952da867..c13a0ad219740 100644 --- a/src/coreclr/vm/appdomain.hpp +++ b/src/coreclr/vm/appdomain.hpp @@ -35,6 +35,8 @@ #include "codeversion.h" +#include "cdacdata.h" + class BaseDomain; class SystemDomain; class AppDomain; diff --git a/src/coreclr/vm/ceemain.cpp b/src/coreclr/vm/ceemain.cpp index 3a1ab790f4753..b07547feccfb0 100644 --- a/src/coreclr/vm/ceemain.cpp +++ b/src/coreclr/vm/ceemain.cpp @@ -625,6 +625,7 @@ void EEStartupHelper() // We cache the SystemInfo for anyone to use throughout the life of the EE. GetSystemInfo(&g_SystemInfo); + PrecodeMachineDescriptor::Init(); // Set callbacks so that LoadStringRC knows which language our // threads are in so that it can return the proper localized string. diff --git a/src/coreclr/vm/codeman.h b/src/coreclr/vm/codeman.h index 0ff86927b6a58..ad69a91c98096 100644 --- a/src/coreclr/vm/codeman.h +++ b/src/coreclr/vm/codeman.h @@ -555,6 +555,8 @@ class Range { return end; } + + template friend struct ::cdac_data; }; struct RangeSection @@ -626,6 +628,19 @@ struct RangeSection RangeSection* _pRangeSectionNextForDelete = NULL; // Used for adding to the cleanup list + + template friend struct ::cdac_data; +}; + +template<> struct cdac_data +{ + static constexpr size_t RangeBegin = offsetof(RangeSection, _range.begin); + static constexpr size_t RangeEndOpen = offsetof(RangeSection, _range.end); + static constexpr size_t NextForDelete = offsetof(RangeSection, _pRangeSectionNextForDelete); + static constexpr size_t JitManager = offsetof(RangeSection, _pjit); + static constexpr size_t Flags = offsetof(RangeSection, _flags); + static constexpr size_t HeapList = offsetof(RangeSection, _pHeapList); + static constexpr size_t R2RModule = offsetof(RangeSection, _pR2RModule); }; enum class RangeSectionLockState @@ -835,7 +850,7 @@ class RangeSectionMap { // Upgrade to non-collectible #ifdef _DEBUG - TADDR initialValue = + TADDR initialValue = #endif InterlockedCompareExchangeT(&_ptr, ptr - 1, ptr); assert(initialValue == ptr || initialValue == (ptr - 1)); @@ -951,7 +966,7 @@ class RangeSectionMap auto levelNew = static_castVolatileLoad(NULL))[0])>(AllocateLevel()); if (levelNew == NULL) return NULL; - + if (!outerLevel->Install(levelNew, collectible)) { // Handle race where another thread grew the table @@ -1017,7 +1032,7 @@ class RangeSectionMap auto rangeSectionL3 = rangeSectionL3Ptr->VolatileLoadWithoutBarrier(pLockState); if (rangeSectionL3 == NULL) return NULL; - + auto rangeSectionL2Ptr = &((*rangeSectionL3)[EffectiveBitsForLevel(address, 3)]); if (level == 2) return rangeSectionL2Ptr; @@ -1071,7 +1086,7 @@ class RangeSectionMap // Account for the range not starting at the beginning of a last level fragment rangeSize += pRangeSection->_range.RangeStart() & (bytesAtLastLevel - 1); - + uintptr_t fragmentCount = ((rangeSize - 1) / bytesAtLastLevel) + 1; return fragmentCount; } @@ -1314,7 +1329,7 @@ class RangeSectionMap else { // Since the fragment linked lists are sorted such that the collectible ones are always after the non-collectible ones, this should never happen. - assert(!seenCollectibleRangeList); + assert(!seenCollectibleRangeList); } #endif entryInMapToUpdate = &(entryInMapToUpdate->VolatileLoadWithoutBarrier(pLockState))->pRangeSectionFragmentNext; @@ -1355,7 +1370,7 @@ class RangeSectionMap if (foundMeaningfulValue) break; - + // This level is completely empty. Free it, and then null out the pointer to it. pointerToLevelData->Uninstall(); #if defined(__GNUC__) @@ -1432,6 +1447,21 @@ class RangeSectionMap } #endif// DACCESS_COMPILE + template friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + static constexpr size_t TopLevelData = offsetof(RangeSectionMap, _topLevelData); + + struct RangeSectionFragment + { + static constexpr size_t RangeBegin = offsetof(RangeSectionMap::RangeSectionFragment, _range.begin); + static constexpr size_t RangeEndOpen = offsetof(RangeSectionMap::RangeSectionFragment, _range.end); + static constexpr size_t RangeSection = offsetof(RangeSectionMap::RangeSectionFragment, pRangeSection); + static constexpr size_t Next = offsetof(RangeSectionMap::RangeSectionFragment, pRangeSectionFragmentNext); + }; }; struct RangeSectionMapData @@ -2246,8 +2276,18 @@ class ExecutionManager JumpStubBlockHeader * m_pBlocks; JumpStubTable m_Table; }; + + template friend struct ::cdac_data; }; +#ifndef DACCESS_COMPILE +template<> +struct cdac_data +{ + static constexpr void* const CodeRangeMapAddress = (void*)&ExecutionManager::g_codeRangeMap.Data[0]; +}; +#endif + inline CodeHeader * EEJitManager::GetCodeHeader(const METHODTOKEN& MethodToken) { LIMITED_METHOD_DAC_CONTRACT; @@ -2552,6 +2592,8 @@ class EECodeInfo // Simple helper to return a pointer to the UNWIND_INFO given the offset to the unwind info. UNWIND_INFO * GetUnwindInfoHelper(ULONG unwindInfoOffset); #endif // TARGET_AMD64 + + template friend struct ::cdac_data; }; #include "codeman.inl" diff --git a/src/coreclr/vm/codeversion.h b/src/coreclr/vm/codeversion.h index bd778bd47d7bf..4fd09826e82cd 100644 --- a/src/coreclr/vm/codeversion.h +++ b/src/coreclr/vm/codeversion.h @@ -248,6 +248,14 @@ class ILCodeVersion mdMethodDef m_methodDef; } m_synthetic; }; + + template friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + // All fields are accessed via ILCodeVersioningState.m_activeVersion }; @@ -316,6 +324,16 @@ class NativeCodeVersionNode IsActiveChildFlag = 1 }; DWORD m_flags; + + template friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + static constexpr size_t Next = offsetof(NativeCodeVersionNode, m_pNextMethodDescSibling); + static constexpr size_t MethodDesc = offsetof(NativeCodeVersionNode, m_pMethodDesc); + static constexpr size_t NativeCode = offsetof(NativeCodeVersionNode, m_pNativeCode); }; class NativeCodeVersionCollection @@ -473,6 +491,15 @@ class MethodDescVersioningState BYTE m_flags; NativeCodeVersionId m_nextId; PTR_NativeCodeVersionNode m_pFirstVersionNode; + + template friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + static constexpr size_t NativeCodeVersionNode = offsetof(MethodDescVersioningState, m_pFirstVersionNode); + static constexpr size_t Flags = offsetof(MethodDescVersioningState, m_flags); }; class ILCodeVersioningState @@ -505,6 +532,18 @@ class ILCodeVersioningState PTR_ILCodeVersionNode m_pFirstVersionNode; PTR_Module m_pModule; mdMethodDef m_methodDef; + + template friend struct ::cdac_data; +}; + +template<> +struct cdac_data +{ + static constexpr size_t Node = offsetof(ILCodeVersioningState, m_pFirstVersionNode); + static constexpr size_t ActiveVersionKind = offsetof(ILCodeVersioningState, m_activeVersion.m_storageKind); + static constexpr size_t ActiveVersionNode = offsetof(ILCodeVersioningState, m_activeVersion.m_pVersionNode); + static constexpr size_t ActiveVersionModule = offsetof(ILCodeVersioningState, m_activeVersion.m_synthetic.m_pModule); + static constexpr size_t ActiveVersionMethodDef = offsetof(ILCodeVersioningState, m_activeVersion.m_synthetic.m_methodDef); }; class CodeVersionManager diff --git a/src/coreclr/vm/loaderallocator.cpp b/src/coreclr/vm/loaderallocator.cpp index 6cc8b62480a00..c76746ca3e9de 100644 --- a/src/coreclr/vm/loaderallocator.cpp +++ b/src/coreclr/vm/loaderallocator.cpp @@ -17,7 +17,7 @@ UINT64 LoaderAllocator::cLoaderAllocatorsCreated = 1; -LoaderAllocator::LoaderAllocator(bool collectible) : +LoaderAllocator::LoaderAllocator(bool collectible) : m_stubPrecodeRangeList(STUB_CODE_BLOCK_STUBPRECODE, collectible), m_fixupPrecodeRangeList(STUB_CODE_BLOCK_FIXUPPRECODE, collectible) { @@ -68,7 +68,7 @@ LoaderAllocator::LoaderAllocator(bool collectible) : m_pLastUsedCodeHeap = NULL; m_pLastUsedDynamicCodeHeap = NULL; m_pJumpStubCache = NULL; - m_IsCollectible = collectible; + m_IsCollectible = collectible ? 1 : 0; m_pMarshalingData = NULL; diff --git a/src/coreclr/vm/loaderallocator.hpp b/src/coreclr/vm/loaderallocator.hpp index 0bf475e33d5fa..6271692294550 100644 --- a/src/coreclr/vm/loaderallocator.hpp +++ b/src/coreclr/vm/loaderallocator.hpp @@ -47,7 +47,7 @@ class CodeRangeMapRangeList : public RangeList VPTR_VTABLE_CLASS(CodeRangeMapRangeList, RangeList) #if defined(DACCESS_COMPILE) || !defined(TARGET_WINDOWS) - CodeRangeMapRangeList() : + CodeRangeMapRangeList() : _RangeListRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT), _rangeListType(STUB_CODE_BLOCK_UNKNOWN), _id(NULL), @@ -55,7 +55,7 @@ class CodeRangeMapRangeList : public RangeList {} #endif - CodeRangeMapRangeList(StubCodeBlockKind rangeListType, bool collectible) : + CodeRangeMapRangeList(StubCodeBlockKind rangeListType, bool collectible) : _RangeListRWLock(COOPERATIVE_OR_PREEMPTIVE, LOCK_TYPE_DEFAULT), _rangeListType(rangeListType), _id(NULL), @@ -84,7 +84,7 @@ class CodeRangeMapRangeList : public RangeList _ASSERTE(id == _id || _id == NULL); _id = id; - // Grow the array first, so that a failure cannot break the + // Grow the array first, so that a failure cannot break the RangeSection::RangeSectionFlags flags = RangeSection::RANGE_SECTION_RANGELIST; if (_collectible) @@ -92,7 +92,7 @@ class CodeRangeMapRangeList : public RangeList _starts.Preallocate(_starts.GetCount() + 1); flags = (RangeSection::RangeSectionFlags)(flags | RangeSection::RANGE_SECTION_COLLECTIBLE); } - + ExecutionManager::AddCodeRange(start, end, ExecutionManager::GetEEJitManager(), flags, this); if (_collectible) @@ -145,7 +145,7 @@ class CodeRangeMapRangeList : public RangeList // This implementation only works for the case where the RangeList is used in a single LoaderHeap _ASSERTE(start == NULL); _ASSERTE(end == NULL); - + SimpleWriteLockHolder lh(&_RangeListRWLock); _ASSERTE(id == _id || (_id == NULL && _starts.IsEmpty())); @@ -171,7 +171,7 @@ class CodeRangeMapRangeList : public RangeList return FALSE; if ((pRS->_flags & RangeSection::RANGE_SECTION_RANGELIST) == 0) return FALSE; - + return (pRS->_pRangeList == this); } @@ -332,7 +332,7 @@ class LoaderAllocator bool m_fTerminated; bool m_fMarked; int m_nGCCount; - bool m_IsCollectible; + BYTE m_IsCollectible; // Pre-allocated blocks of heap for collectible assemblies. Will be set to NULL as soon as it is // used. See code in GetVSDHeapInitialBlock and GetCodeHeapInitialBlock @@ -570,7 +570,7 @@ class LoaderAllocator DispatchToken GetDispatchToken(UINT32 typeId, UINT32 slotNumber); virtual LoaderAllocatorID* Id() =0; - BOOL IsCollectible() { WRAPPER_NO_CONTRACT; return m_IsCollectible; } + BOOL IsCollectible() { WRAPPER_NO_CONTRACT; return m_IsCollectible != 0; } // This function may only be called while the runtime is suspended // As it does not lock around access to a RangeList @@ -865,8 +865,16 @@ class LoaderAllocator virtual void UnregisterDependentHandleToNativeObjectFromCleanup(LADependentHandleToNativeObject *dependentHandle) {}; virtual void CleanupDependentHandlesToNativeObjects() {}; #endif + + template friend struct ::cdac_data; }; // class LoaderAllocator +template<> +struct cdac_data +{ + static constexpr size_t IsCollectible = offsetof(LoaderAllocator, m_IsCollectible); +}; + typedef VPTR(LoaderAllocator) PTR_LoaderAllocator; extern "C" BOOL QCALLTYPE LoaderAllocator_Destroy(QCall::LoaderAllocatorHandle pLoaderAllocator); diff --git a/src/coreclr/vm/method.hpp b/src/coreclr/vm/method.hpp index 35882fdde5ddf..2f1bdcacfe593 100644 --- a/src/coreclr/vm/method.hpp +++ b/src/coreclr/vm/method.hpp @@ -1916,6 +1916,8 @@ template<> struct cdac_data static constexpr size_t Slot = offsetof(MethodDesc, m_wSlotNumber); static constexpr size_t Flags = offsetof(MethodDesc, m_wFlags); static constexpr size_t Flags3AndTokenRemainder = offsetof(MethodDesc, m_wFlags3AndTokenRemainder); + static constexpr size_t EntryPointFlags = offsetof(MethodDesc, m_bFlags4); + static constexpr size_t CodeData = offsetof(MethodDesc, m_codeData); }; #ifndef DACCESS_COMPILE diff --git a/src/coreclr/vm/precode.cpp b/src/coreclr/vm/precode.cpp index 4dbc3e4394834..cb708b428ef79 100644 --- a/src/coreclr/vm/precode.cpp +++ b/src/coreclr/vm/precode.cpp @@ -662,4 +662,55 @@ BOOL DoesSlotCallPrestub(PCODE pCode) return FALSE; } +PrecodeMachineDescriptor g_PrecodeMachineDescriptor; + +void PrecodeMachineDescriptor::Init() +{ +#ifndef TARGET_ARM + g_PrecodeMachineDescriptor.CodePointerToInstrPointerMask = ~0; +#else + // mask off the thumb bit + g_PrecodeMachineDescriptor.CodePointerToInstrPointerMask = ~1; +#endif + g_PrecodeMachineDescriptor.OffsetOfPrecodeType = OFFSETOF_PRECODE_TYPE; // FIXME(cdac): sometimes OFFSETOF_PRECODE_TYPE is undefined? + // cDAC will do (where N = 8*ReadWidthOfPrecodeType): + // uintN_t PrecodeType = *(uintN_t*)(pPrecode + OffsetOfPrecodeType); + // PrecodeType >>= ShiftOfPrecodeType; + // return (byte)PrecodeType; +#ifdef TARGET_LOONGARCH64 + g_PrecodeMachineDescriptor.ReadWidthOfPrecodeType = 2; + g_PrecodeMachineDescriptor.ShiftOfPrecodeType = 5; +#else + g_PrecodeMachineDescriptor.ReadWidthOfPrecodeType = 1; + g_PrecodeMachineDescriptor.ShiftOfPrecodeType = 0; +#endif + // uint8_t SizeOfPrecodeBase = SIZEOF_PRECODE_BASE; + + g_PrecodeMachineDescriptor.InvalidPrecodeType = InvalidPrecode::Type; + g_PrecodeMachineDescriptor.StubPrecodeType = StubPrecode::Type; +#ifdef HAS_NDIRECT_IMPORT_PRECODE + g_PrecodeMachineDescriptor.HasNDirectImportPrecode = 1; + g_PrecodeMachineDescriptor.NDirectImportPrecodeType = NDirectImportPrecode::Type; +#else + g_PrecodeMachineDescriptor.HasNDirectImportPrecode = 0; + g_PrecodeMachineDescriptor.NDirectImportPrecodeType = 0; +#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_FIXUP_PRECODE + g_PrecodeMachineDescriptor.HasFixupPrecode = 1; + g_PrecodeMachineDescriptor.FixupPrecodeType = FixupPrecode::Type; +#else + g_PrecodeMachineDescriptor.HasFixupPrecode = 0; + g_PrecodeMachineDescriptor.FixupPrecodeType = 0; +#endif // HAS_FIXUP_PRECODE +#ifdef HAS_THISPTR_RETBUF_PRECODE + g_PrecodeMachineDescriptor.HasThisPtrRetBufPrecode = 1; + g_PrecodeMachineDescriptor.HasThisPointerRetBufPrecodeType = ThisPtrRetBufPrecode::Type; +#else + g_PrecodeMachineDescriptor.HasThisPtrRetBufPrecode = 0; + g_PrecodeMachineDescriptor.HasThisPointerRetBufPrecodeType = 0; +#endif // HAS_THISPTR_RETBUF_PRECODE + g_PrecodeMachineDescriptor.StubCodePageSize = GetStubCodePageSize(); +} + #endif // !DACCESS_COMPILE + diff --git a/src/coreclr/vm/precode.h b/src/coreclr/vm/precode.h index 22ae9b1adaf18..55d68886af4da 100644 --- a/src/coreclr/vm/precode.h +++ b/src/coreclr/vm/precode.h @@ -596,4 +596,63 @@ static_assert_no_msg(NDirectImportPrecode::Type != ThisPtrRetBufPrecode::Type); static_assert_no_msg(sizeof(Precode) <= sizeof(NDirectImportPrecode)); static_assert_no_msg(sizeof(Precode) <= sizeof(FixupPrecode)); static_assert_no_msg(sizeof(Precode) <= sizeof(ThisPtrRetBufPrecode)); + +#ifndef DACCESS_COMPILE +// A summary of the precode layout for diagnostic purposes +struct PrecodeMachineDescriptor +{ +#ifndef TARGET_ARM + uintptr_t CodePointerToInstrPointerMask = ~0; +#else + // mask off the thumb bit + uintptr_t CodePointerToInstrPointerMask = ~1; +#endif + uint8_t OffsetOfPrecodeType = OFFSETOF_PRECODE_TYPE; // FIXME(cdac): sometimes OFFSETOF_PRECODE_TYPE is undefined? + // cDAC will do (where N = 8*ReadWidthOfPrecodeType): + // uintN_t PrecodeType = *(uintN_t*)(pPrecode + OffsetOfPrecodeType); + // PrecodeType >>= ShiftOfPrecodeType; + // return (byte)PrecodeType; +#ifdef TARGET_LOONGARCH64 + uint8_t ReadWidthOfPrecodeType = 2; + uint8_t ShiftOfPrecodeType = 5; +#else + uint8_t ReadWidthOfPrecodeType = 1; + uint8_t ShiftOfPrecodeType = 0; +#endif + // uint8_t SizeOfPrecodeBase = SIZEOF_PRECODE_BASE; + + uint8_t InvalidPrecodeType = InvalidPrecode::Type; + uint8_t StubPrecodeType = StubPrecode::Type; +#ifdef HAS_NDIRECT_IMPORT_PRECODE + uint8_t HasNDirectImportPrecode = 1; + uint8_t NDirectImportPrecodeType = NDirectImportPrecode::Type; +#else + uint8_t HasNDirectImportPrecode = 0; + uint8_t NDirectImportPrecodeType = 0; +#endif // HAS_NDIRECT_IMPORT_PRECODE +#ifdef HAS_FIXUP_PRECODE + uint8_t HasFixupPrecode = 1; + uint8_t FixupPrecodeType = FixupPrecode::Type; +#else + uint8_t HasFixupPrecode = 0; + uint8_t FixupPrecodeType = 0; +#endif // HAS_FIXUP_PRECODE +#ifdef HAS_THISPTR_RETBUF_PRECODE + uint8_t HasThisPtrRetBufPrecode = 1; + uint8_t HasThisPointerRetBufPrecodeType = ThisPtrRetBufPrecode::Type; +#else + uint8_t HasThisPtrRetBufPrecode = 0; + uint8_t HasThisPointerRetBufPrecodeType = 0; +#endif // HAS_THISPTR_RETBUF_PRECODE + uint32_t StubCodePageSize = GetStubCodePageSize(); +public: + PrecodeMachineDescriptor() = default; + PrecodeMachineDescriptor(const PrecodeMachineDescriptor&) = delete; + PrecodeMachineDescriptor& operator=(const PrecodeMachineDescriptor&) = delete; + static void Init(); +}; + +extern PrecodeMachineDescriptor g_PrecodeMachineDescriptor; +#endif //DACCESS_COMPILE + #endif // __PRECODE_H__