Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Kotas <jkotas@microsoft.com>2018-05-11 18:35:24 +0300
committerGitHub <noreply@github.com>2018-05-11 18:35:24 +0300
commite19bace28a18a0d39a451bb0f0dbd325551508e1 (patch)
tree4a59bcf0cd83e8c412c71851a6659304bdd1e638 /src/System.Private.Reflection.Execution
parent8f12ec10abe7ec1eeee33955589a78fde94308d0 (diff)
Fix diagnostic stacktrace for shared generic methods (#5796)
Diagnostic stacktraces were missing symbols for shared generic methods. TryGetMethodForOriginalLdFtnResult is expecting fat pointer for these, and failed to find the method when used for method entrypoint. The fix is to create a clone of TryGetMethodForOriginalLdFtnResult that does not require instantiation argument and does not return exact instantiation.
Diffstat (limited to 'src/System.Private.Reflection.Execution')
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs155
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecution.cs7
-rw-r--r--src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs10
3 files changed, 115 insertions, 57 deletions
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs
index ad2675351..284e2c25b 100644
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs
+++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ExecutionEnvironmentImplementation.MappingTables.cs
@@ -907,25 +907,74 @@ namespace Internal.Reflection.Execution
{
GetFunctionPointerAndInstantiationArgumentForOriginalLdFtnResult(originalLdFtnResult, out IntPtr canonOriginalLdFtnResult, out IntPtr instantiationArgument);
- // Search TemplateMethodMap
- if ((instantiationArgument != IntPtr.Zero) && TryGetMethodForOriginalLdFtnResult_GenericMethodWithInstantiationArgument(instantiationArgument, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ if (instantiationArgument != IntPtr.Zero)
{
- return true;
+ // Search TemplateMethodMap
+ if (TryGetMethodForOriginalLdFtnResult_GenericMethodWithInstantiationArgument(instantiationArgument, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ return true;
+ }
+ else
+ {
+ // Search ExactInstantiationsMap
+ foreach (KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets> perModuleLookup in GetLdFtnReverseLookups_ExactInstantations())
+ {
+ int startIndex;
+ int endIndex;
+
+ if (perModuleLookup.Value.TryGetOffsetsRange(canonOriginalLdFtnResult, out startIndex, out endIndex))
+ {
+ for (int curIndex = startIndex; curIndex <= endIndex; curIndex++)
+ {
+ uint parserOffset = perModuleLookup.Value.Data[curIndex].Offset;
+ if (TryGetMethodForOriginalLdFtnResult_ExactInstantiation_Inner(perModuleLookup.Key, forStartAddress: false, canonOriginalLdFtnResult, parserOffset,
+ ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ return true;
+ }
+ }
+ }
}
+ // Search InvokeMap
+ foreach (KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets> perModuleLookup in GetLdFtnReverseLookups_InvokeMap())
+ {
+ int startIndex;
+ int endIndex;
+
+ if (perModuleLookup.Value.TryGetOffsetsRange(canonOriginalLdFtnResult, out startIndex, out endIndex))
+ {
+ for (int curIndex = startIndex; curIndex <= endIndex; curIndex++)
+ {
+ uint parserOffset = perModuleLookup.Value.Data[curIndex].Offset;
+ if (TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(perModuleLookup.Key, forStartAddress: false, canonOriginalLdFtnResult, instantiationArgument, parserOffset, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ return true;
+ }
+ }
+ }
+
+ methodHandle = default(QMethodDefinition);
+ genericMethodTypeArgumentHandles = null;
+ return false;
+ }
+
+ internal bool TryGetMethodForStartAddress(IntPtr methodStartAddress, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle)
+ {
// Search ExactInstantiationsMap
foreach (KeyValuePair<NativeFormatModuleInfo, FunctionPointersToOffsets> perModuleLookup in GetLdFtnReverseLookups_ExactInstantations())
{
int startIndex;
int endIndex;
- if (perModuleLookup.Value.TryGetOffsetsRange(canonOriginalLdFtnResult, out startIndex, out endIndex))
+ if (perModuleLookup.Value.TryGetOffsetsRange(methodStartAddress, out startIndex, out endIndex))
{
for (int curIndex = startIndex; curIndex <= endIndex; curIndex++)
{
uint parserOffset = perModuleLookup.Value.Data[curIndex].Offset;
- if (TryGetMethodForOriginalLdFtnResult_ExactInstantiation_Inner(perModuleLookup.Key, canonOriginalLdFtnResult, instantiationArgument, parserOffset, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ if (TryGetMethodForOriginalLdFtnResult_ExactInstantiation_Inner(perModuleLookup.Key, forStartAddress: true, methodStartAddress, parserOffset, ref declaringTypeHandle, out methodHandle, out _))
+ {
+ if (RuntimeAugments.IsGenericType(declaringTypeHandle))
+ declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle);
return true;
+ }
}
}
}
@@ -936,19 +985,22 @@ namespace Internal.Reflection.Execution
int startIndex;
int endIndex;
- if (perModuleLookup.Value.TryGetOffsetsRange(canonOriginalLdFtnResult, out startIndex, out endIndex))
+ if (perModuleLookup.Value.TryGetOffsetsRange(methodStartAddress, out startIndex, out endIndex))
{
for (int curIndex = startIndex; curIndex <= endIndex; curIndex++)
{
uint parserOffset = perModuleLookup.Value.Data[curIndex].Offset;
- if (TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(perModuleLookup.Key, canonOriginalLdFtnResult, instantiationArgument, parserOffset, ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ if (TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(perModuleLookup.Key, forStartAddress: true, methodStartAddress, IntPtr.Zero, parserOffset, ref declaringTypeHandle, out methodHandle, out _))
+ {
+ if (RuntimeAugments.IsGenericType(declaringTypeHandle))
+ declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle);
return true;
+ }
}
}
}
methodHandle = default(QMethodDefinition);
- genericMethodTypeArgumentHandles = null;
return false;
}
@@ -1013,7 +1065,7 @@ namespace Internal.Reflection.Execution
return functionPointerToOffsetInInvokeMap;
}
- private unsafe bool TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(NativeFormatModuleInfo mappingTableModule, IntPtr canonOriginalLdFtnResult, IntPtr instantiationArgument, uint parserOffset, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles)
+ private unsafe bool TryGetMethodForOriginalLdFtnResult_InvokeMap_Inner(NativeFormatModuleInfo mappingTableModule, bool forStartAddress, IntPtr canonOriginalLdFtnResult, IntPtr instantiationArgument, uint parserOffset, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles)
{
methodHandle = default(QMethodDefinition);
genericMethodTypeArgumentHandles = null;
@@ -1035,7 +1087,7 @@ namespace Internal.Reflection.Execution
// If the passed in method was a fat function pointer, but the entry in the mapping table doesn't need
// an instantiation argument (or the other way around), trivially reject it.
- if ((instantiationArgument == IntPtr.Zero) != ((entryFlags & InvokeTableFlags.RequiresInstArg) == 0))
+ if (!forStartAddress && ((instantiationArgument == IntPtr.Zero) != ((entryFlags & InvokeTableFlags.RequiresInstArg) == 0)))
return false;
Debug.Assert((entryFlags & InvokeTableFlags.HasEntrypoint) != 0);
@@ -1046,39 +1098,46 @@ namespace Internal.Reflection.Execution
IntPtr entryMethodEntrypoint = externalReferences.GetFunctionPointerFromIndex(entryParser.GetUnsigned());
if ((entryFlags & InvokeTableFlags.NeedsParameterInterpretation) == 0)
- entryParser.GetUnsigned(); // skip dynamic invoke cookie
+ entryParser.SkipInteger(); // skip dynamic invoke cookie
+ if (forStartAddress)
+ {
+ declaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryDeclaringTypeRaw);
+ }
+ else
+ {
#if DEBUG
- IntPtr targetAddress;
- Debug.Assert(entryMethodEntrypoint == canonOriginalLdFtnResult ||
- RuntimeAugments.GetCodeTarget(entryMethodEntrypoint) == canonOriginalLdFtnResult ||
- TypeLoaderEnvironment.TryGetTargetOfUnboxingAndInstantiatingStub(entryMethodEntrypoint, out targetAddress) &&
- targetAddress == canonOriginalLdFtnResult);
+ IntPtr targetAddress;
+ Debug.Assert(entryMethodEntrypoint == canonOriginalLdFtnResult ||
+ RuntimeAugments.GetCodeTarget(entryMethodEntrypoint) == canonOriginalLdFtnResult ||
+ TypeLoaderEnvironment.TryGetTargetOfUnboxingAndInstantiatingStub(entryMethodEntrypoint, out targetAddress) &&
+ targetAddress == canonOriginalLdFtnResult);
#endif
- if ((entryFlags & InvokeTableFlags.RequiresInstArg) == 0 && declaringTypeHandle.IsNull())
- declaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryDeclaringTypeRaw);
+ if ((entryFlags & InvokeTableFlags.RequiresInstArg) == 0 && declaringTypeHandle.IsNull())
+ declaringTypeHandle = externalReferences.GetRuntimeTypeHandleFromIndex(entryDeclaringTypeRaw);
- if ((entryFlags & InvokeTableFlags.IsGenericMethod) != 0)
- {
- if ((entryFlags & InvokeTableFlags.RequiresInstArg) != 0)
+ if ((entryFlags & InvokeTableFlags.IsGenericMethod) != 0)
{
- MethodNameAndSignature dummyNameAndSignature;
- bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out dummyNameAndSignature, out genericMethodTypeArgumentHandles);
- Debug.Assert(success);
+ if ((entryFlags & InvokeTableFlags.RequiresInstArg) != 0)
+ {
+ MethodNameAndSignature dummyNameAndSignature;
+ bool success = TypeLoaderEnvironment.Instance.TryGetGenericMethodComponents(instantiationArgument, out declaringTypeHandle, out dummyNameAndSignature, out genericMethodTypeArgumentHandles);
+ Debug.Assert(success);
+ }
+ else
+ genericMethodTypeArgumentHandles = GetTypeSequence(ref externalReferences, ref entryParser);
}
else
- genericMethodTypeArgumentHandles = GetTypeSequence(ref externalReferences, ref entryParser);
- }
- else
- {
- genericMethodTypeArgumentHandles = null;
- if ((entryFlags & InvokeTableFlags.RequiresInstArg) != 0)
- declaringTypeHandle = RuntimeAugments.CreateRuntimeTypeHandle(instantiationArgument);
- }
+ {
+ genericMethodTypeArgumentHandles = null;
+ if ((entryFlags & InvokeTableFlags.RequiresInstArg) != 0)
+ declaringTypeHandle = RuntimeAugments.CreateRuntimeTypeHandle(instantiationArgument);
+ }
- RuntimeTypeHandle entryType = externalReferences.GetRuntimeTypeHandleFromIndex(entryDeclaringTypeRaw);
- declaringTypeHandle = GetExactDeclaringType(entryType, declaringTypeHandle);
+ RuntimeTypeHandle entryType = externalReferences.GetRuntimeTypeHandleFromIndex(entryDeclaringTypeRaw);
+ declaringTypeHandle = GetExactDeclaringType(entryType, declaringTypeHandle);
+ }
if ((entryFlags & InvokeTableFlags.HasMetadataHandle) != 0)
{
@@ -1139,17 +1198,17 @@ namespace Internal.Reflection.Execution
uint parserOffset = entryParser.Offset;
// Declaring Handle
- entryParser.GetUnsigned();
+ entryParser.SkipInteger();
// NameAndSig
- entryParser.GetUnsigned();
+ entryParser.SkipInteger();
// generic method arity
int parsedArity = (int)entryParser.GetSequenceCount();
for (int i = 0; i < parsedArity; i++)
{
- entryParser.GetUnsigned();
+ entryParser.SkipInteger();
}
IntPtr functionPointer = externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned());
@@ -1162,14 +1221,11 @@ namespace Internal.Reflection.Execution
return functionPointerToOffsetInInvokeMap;
}
- private unsafe bool TryGetMethodForOriginalLdFtnResult_ExactInstantiation_Inner(NativeFormatModuleInfo mappingTableModule, IntPtr canonOriginalLdFtnResult, IntPtr instantiationArgument, uint parserOffset, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles)
+ private unsafe bool TryGetMethodForOriginalLdFtnResult_ExactInstantiation_Inner(NativeFormatModuleInfo mappingTableModule, bool forStartAddress, IntPtr canonOriginalLdFtnResult, uint parserOffset, ref RuntimeTypeHandle declaringTypeHandle, out QMethodDefinition methodHandle, out RuntimeTypeHandle[] genericMethodTypeArgumentHandles)
{
methodHandle = default(QMethodDefinition);
genericMethodTypeArgumentHandles = null;
- if (instantiationArgument != IntPtr.Zero)
- return false;
-
NativeReader invokeMapReader;
if (!TryGetNativeReaderForBlob(mappingTableModule, ReflectionMapBlob.ExactMethodInstantiationsHashtable, out invokeMapReader))
{
@@ -1191,11 +1247,22 @@ namespace Internal.Reflection.Execution
return false;
int parsedArity = (int)entryParser.GetSequenceCount();
- genericMethodTypeArgumentHandles = new RuntimeTypeHandle[parsedArity];
- for (int i = 0; i < parsedArity; i++)
+ if (forStartAddress)
{
- genericMethodTypeArgumentHandles[i] = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
+ for (int i = 0; i < parsedArity; i++)
+ {
+ entryParser.SkipInteger();
+ }
+ }
+ else
+ {
+ genericMethodTypeArgumentHandles = new RuntimeTypeHandle[parsedArity];
+
+ for (int i = 0; i < parsedArity; i++)
+ {
+ genericMethodTypeArgumentHandles[i] = externalReferences.GetRuntimeTypeHandleFromIndex(entryParser.GetUnsigned());
+ }
}
IntPtr functionPointer = externalReferences.GetIntPtrFromIndex(entryParser.GetUnsigned());
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecution.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecution.cs
index d2135fd08..f0261574f 100644
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecution.cs
+++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecution.cs
@@ -98,16 +98,13 @@ namespace Internal.Reflection.Execution
methodHandle = default(MethodHandle);
RuntimeTypeHandle declaringTypeHandle = default(RuntimeTypeHandle);
- if (!ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(methodStartAddress,
- ref declaringTypeHandle, out QMethodDefinition qMethodDefinition, out _))
+ if (!ExecutionEnvironment.TryGetMethodForStartAddress(methodStartAddress,
+ ref declaringTypeHandle, out QMethodDefinition qMethodDefinition))
return false;
if (!qMethodDefinition.IsNativeFormatMetadataBased)
return false;
- if (RuntimeAugments.IsGenericType(declaringTypeHandle))
- declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle);
-
if (!ExecutionEnvironment.TryGetMetadataForNamedType(declaringTypeHandle, out QTypeDefinition qTypeDefinition))
return false;
diff --git a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
index 1a004f50d..b6ba92e2b 100644
--- a/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
+++ b/src/System.Private.Reflection.Execution/src/Internal/Reflection/Execution/ReflectionExecutionDomainCallbacksImplementation.cs
@@ -104,18 +104,12 @@ namespace Internal.Reflection.Execution
{
RuntimeTypeHandle declaringTypeHandle = default(RuntimeTypeHandle);
QMethodDefinition methodHandle;
- RuntimeTypeHandle[] genericMethodTypeArgumentHandles;
- if (!ReflectionExecution.ExecutionEnvironment.TryGetMethodForOriginalLdFtnResult(methodStartAddress,
- ref declaringTypeHandle, out methodHandle, out genericMethodTypeArgumentHandles))
+ if (!ReflectionExecution.ExecutionEnvironment.TryGetMethodForStartAddress(methodStartAddress,
+ ref declaringTypeHandle, out methodHandle))
{
return null;
}
- if (RuntimeAugments.IsGenericType(declaringTypeHandle))
- {
- declaringTypeHandle = RuntimeAugments.GetGenericDefinition(declaringTypeHandle);
- }
-
// We don't use the type argument handles as we want the uninstantiated method info
return ReflectionCoreExecution.ExecutionDomain.GetMethod(declaringTypeHandle, methodHandle, genericMethodTypeArgumentHandles: null);
}