unsafe private static void TestGCDescsForEquality(IntPtr dynamicGCDesc, IntPtr templateGCDesc, int cbGCDesc, bool isInstanceGCDesc) { if (templateGCDesc == IntPtr.Zero) return; Debug.Assert(dynamicGCDesc != IntPtr.Zero); Debug.Assert(cbGCDesc == MemoryHelpers.AlignUp(cbGCDesc, 4)); uint* pMem1 = (uint*)dynamicGCDesc.ToPointer(); uint* pMem2 = (uint*)templateGCDesc.ToPointer(); bool foundDifferences = false; for (int i = 0; i < cbGCDesc; i += 4) { if (*pMem1 != *pMem2) { // Log all the differences before the assert Debug.WriteLine("ERROR: GCDesc comparison failed at byte #" + i.LowLevelToString() + " while comparing " + dynamicGCDesc.LowLevelToString() + " with " + templateGCDesc.LowLevelToString() + ": [" + (*pMem1).LowLevelToString() + "]/[" + (*pMem2).LowLevelToString() + "]"); foundDifferences = true; } if (isInstanceGCDesc) { pMem1--; pMem2--; } else { pMem1++; pMem2++; } } Debug.Assert(!foundDifferences); }
/// <summary> /// Initialize the module enumerator state machine and locate the preferred module index. /// </summary> /// <param name="moduleMap">Module map to enumerate</param> /// <param name="preferredModuleHandle">Optional module handle to enumerate first</param> internal ModuleInfoEnumerator(ModuleMap moduleMap, IntPtr preferredModuleHandle) { _modules = moduleMap.Modules; _preferredIndex = -1; _iterationIndex = -1; _currentModule = null; if (preferredModuleHandle != default(IntPtr) && !moduleMap.HandleToModuleIndex.TryGetValue(preferredModuleHandle, out _preferredIndex)) { Environment.FailFast("Invalid module requested in enumeration: " + preferredModuleHandle.LowLevelToString()); } }
/// <summary> /// Register a new module. Call all module registration callbacks. /// </summary> /// <param name="moduleHandle">Module handle to register</param> public void RegisterModule(IntPtr newModuleHandle) { // prevent multiple threads from registering modules concurrently using (LockHolder.Hold(_moduleRegistrationLock)) { // Don't allow double module registration int oldModuleIndex; if (_loadedModuleMap.HandleToModuleIndex.TryGetValue(newModuleHandle, out oldModuleIndex)) { Environment.FailFast("Module " + newModuleHandle.LowLevelToString() + " is being registered for the second time"); } ModuleInfo newModuleInfo = new ModuleInfo(newModuleHandle); // Copy existing modules to new dictionary int oldModuleCount = _loadedModuleMap.Modules.Length; ModuleInfo[] updatedModules = new ModuleInfo[oldModuleCount + 1]; if (oldModuleCount > 0) { Array.Copy(_loadedModuleMap.Modules, 0, updatedModules, 0, oldModuleCount); } updatedModules[oldModuleCount] = newModuleInfo; // Atomically update the module map _loadedModuleMap = new ModuleMap(updatedModules); if (_moduleRegistrationCallbacks != null) { _moduleRegistrationCallbacks(newModuleInfo); } } }