Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify ldftn reverse lookups #88719

Merged
merged 5 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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<NativeFormatModuleInfo, FunctionPointersToOffsets>[] _ldftnReverseLookup_InvokeMap;
private Func<NativeFormatModuleInfo, FunctionPointersToOffsets> _computeLdFtnLookupInvokeMapInvokeMap = ComputeLdftnReverseLookup_InvokeMap;

/// <summary>
/// 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.
/// </summary>
/// <param name="ldftnReverseLookupStatic">pointer to static which holds cache value. This is treated as a volatile variable</param>
/// <param name="lookupComputer"></param>
/// <returns></returns>
private KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] GetLdFtnReverseLookups_Helper(ref KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] ldftnReverseLookupStatic, Func<NativeFormatModuleInfo, FunctionPointersToOffsets> lookupComputer)
private KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] GetLdFtnReverseLookups_InvokeMap()
{
KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] ldFtnReverseLookup = Volatile.Read(ref ldftnReverseLookupStatic);

if (ldFtnReverseLookup != null)
return ldFtnReverseLookup;
else
KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] ldFtnReverseLookup = _ldftnReverseLookup_InvokeMap;
if (ldFtnReverseLookup == null)
{
lock (this)
var ldFtnReverseLookupBuilder = new ArrayBuilder<KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>>();
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<NativeFormatModuleInfo, FunctionPointersToOffsets>[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<NativeFormatModuleInfo, FunctionPointersToOffsets>(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<NativeFormatModuleInfo, FunctionPointersToOffsets>(module, ComputeLdftnReverseLookup_InvokeMap(module)));
}
ldFtnReverseLookup = ldFtnReverseLookupBuilder.ToArray();
_ldftnReverseLookup_InvokeMap = ldFtnReverseLookup;
}
}

private KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets>[] 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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
<Compile Include="$(AotCommonPath)\System\Collections\Generic\LowLevelDictionary.cs">
<Link>System\Collections\Generic\LowLevelDictionary.cs</Link>
</Compile>
<Compile Include="$(CompilerCommonPath)\System\Collections\Generic\ArrayBuilder.cs">
<Link>System\Collections\Generic\ArrayBuilder.cs</Link>
</Compile>
<Compile Include="$(CompilerCommonPath)\Internal\LowLevelLinq\LowLevelEnumerable.cs">
<Link>Internal\LowLevelLinq\LowLevelEnumerable.cs</Link>
</Compile>
Expand Down