diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs index 35d9cde9222fa..7e3209b56e8f7 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs @@ -566,74 +566,24 @@ public bool TryGetOffsetsRange(IntPtr functionPointer, out int firstParserOffset // ldftn reverse lookup hash. Must be cleared and reset if the module list changes. (All sets to // this variable must happen under a lock) private volatile KeyValuePair[] _ldftnReverseLookup_InvokeMap; - private Func _computeLdFtnLookupInvokeMapInvokeMap = ComputeLdftnReverseLookup_InvokeMap; /// - /// Initialize a lookup array of module to function pointer/parser offset pair arrays. Do so in a manner that will allow - /// future work which will invalidate the cache (by setting it to null) + /// Initialize a lookup array of module to function pointer/parser offset pair arrays. /// - /// pointer to static which holds cache value. This is treated as a volatile variable - /// - /// - private KeyValuePair[] GetLdFtnReverseLookups_Helper(ref KeyValuePair[] ldftnReverseLookupStatic, Func lookupComputer) + private KeyValuePair[] GetLdFtnReverseLookups_InvokeMap() { - KeyValuePair[] ldFtnReverseLookup = Volatile.Read(ref ldftnReverseLookupStatic); - - if (ldFtnReverseLookup != null) - return ldFtnReverseLookup; - else + KeyValuePair[] ldFtnReverseLookup = _ldftnReverseLookup_InvokeMap; + if (ldFtnReverseLookup == null) { - lock (this) + var ldFtnReverseLookupBuilder = new ArrayBuilder>(); + foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules()) { - ldFtnReverseLookup = Volatile.Read(ref ldftnReverseLookupStatic); - - // double checked lock, safe due to use of volatile on s_ldftnReverseHashes - if (ldFtnReverseLookup != null) - return ldFtnReverseLookup; - - // FUTURE: add a module load callback to invalidate this cache if a new module is loaded. - while (true) - { - int size = 0; - foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules()) - { - size++; - } - - ldFtnReverseLookup = new KeyValuePair[size]; - int index = 0; - bool restart = false; - foreach (NativeFormatModuleInfo module in ModuleList.EnumerateModules()) - { - // If the module list changes during execution of this code, rebuild from scratch - if (index >= ldFtnReverseLookup.Length) - { - restart = true; - break; - } - - ldFtnReverseLookup[index] = new KeyValuePair(module, lookupComputer(module)); - index++; - } - - if (restart) - continue; - - // unless we need to repeat the module enumeration, only execute the body of this while loop once. - break; - } - - Volatile.Write(ref ldftnReverseLookupStatic, ldFtnReverseLookup); - return ldFtnReverseLookup; + ldFtnReverseLookupBuilder.Add(new KeyValuePair(module, ComputeLdftnReverseLookup_InvokeMap(module))); } + ldFtnReverseLookup = ldFtnReverseLookupBuilder.ToArray(); + _ldftnReverseLookup_InvokeMap = ldFtnReverseLookup; } - } - - private KeyValuePair[] GetLdFtnReverseLookups_InvokeMap() - { -#pragma warning disable 0420 // GetLdFtnReverseLookups_Helper treats its first parameter as volatile by using explicit Volatile operations - return GetLdFtnReverseLookups_Helper(ref _ldftnReverseLookup_InvokeMap, _computeLdFtnLookupInvokeMapInvokeMap); -#pragma warning restore 0420 + return ldFtnReverseLookup; } internal unsafe void GetFunctionPointerAndInstantiationArgumentForOriginalLdFtnResult(IntPtr originalLdFtnResult, out IntPtr canonOriginalLdFtnResult, out IntPtr instantiationArgument) diff --git a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj index 76d3934794fd2..5527d5920f601 100644 --- a/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj +++ b/src/coreclr/nativeaot/System.Private.Reflection.Execution/src/System.Private.Reflection.Execution.csproj @@ -65,6 +65,9 @@ System\Collections\Generic\LowLevelDictionary.cs + + System\Collections\Generic\ArrayBuilder.cs + Internal\LowLevelLinq\LowLevelEnumerable.cs