Move ownership of p/invoke fixup cells (#4353)
The RVA static fields that represent p/invoke lazy fixup cells are currently owned by the same type that owns the p/invoke. This means that if the owning type has a static constructor, accessing the lazy fixup cell with trigger it. The p/invoke should not trigger a beforefieldinit class constructor though. I'm moving the field to be owned by the global type in the compiler-generated pseudo assembly. It doesn't really matter who owns it.
This commit is contained in:
Родитель
5aca61df65
Коммит
61b3a728cf
|
@ -238,8 +238,8 @@ namespace Internal.IL.Stubs
|
||||||
_importMetadata.Module,
|
_importMetadata.Module,
|
||||||
_pInvokeILEmitterConfiguration))
|
_pInvokeILEmitterConfiguration))
|
||||||
{
|
{
|
||||||
MetadataType lazyHelperType = _targetMethod.Context.GetHelperType("InteropHelpers");
|
MetadataType lazyHelperType = context.GetHelperType("InteropHelpers");
|
||||||
FieldDesc lazyDispatchCell = new PInvokeLazyFixupField(_targetMethod);
|
FieldDesc lazyDispatchCell = _interopStateManager.GetPInvokeLazyFixupField(_targetMethod);
|
||||||
|
|
||||||
fnptrLoadStream.Emit(ILOpcode.ldsflda, emitter.NewToken(lazyDispatchCell));
|
fnptrLoadStream.Emit(ILOpcode.ldsflda, emitter.NewToken(lazyDispatchCell));
|
||||||
fnptrLoadStream.Emit(ILOpcode.call, emitter.NewToken(lazyHelperType
|
fnptrLoadStream.Emit(ILOpcode.call, emitter.NewToken(lazyHelperType
|
||||||
|
@ -251,7 +251,7 @@ namespace Internal.IL.Stubs
|
||||||
_targetMethod.Signature.Flags | unmanagedCallConv, 0, nativeReturnType,
|
_targetMethod.Signature.Flags | unmanagedCallConv, 0, nativeReturnType,
|
||||||
nativeParameterTypes);
|
nativeParameterTypes);
|
||||||
|
|
||||||
ILLocalVariable vNativeFunctionPointer = emitter.NewLocal(_targetMethod.Context
|
ILLocalVariable vNativeFunctionPointer = emitter.NewLocal(context
|
||||||
.GetWellKnownType(WellKnownType.IntPtr));
|
.GetWellKnownType(WellKnownType.IntPtr));
|
||||||
|
|
||||||
fnptrLoadStream.EmitStLoc(vNativeFunctionPointer);
|
fnptrLoadStream.EmitStLoc(vNativeFunctionPointer);
|
||||||
|
|
|
@ -15,14 +15,24 @@ namespace Internal.IL.Stubs
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class PInvokeLazyFixupField : FieldDesc
|
public sealed partial class PInvokeLazyFixupField : FieldDesc
|
||||||
{
|
{
|
||||||
private MethodDesc _targetMethod;
|
private readonly DefType _owningType;
|
||||||
|
private readonly MethodDesc _targetMethod;
|
||||||
|
|
||||||
public PInvokeLazyFixupField(MethodDesc targetMethod)
|
public PInvokeLazyFixupField(DefType owningType, MethodDesc targetMethod)
|
||||||
{
|
{
|
||||||
Debug.Assert(targetMethod.IsPInvoke);
|
Debug.Assert(targetMethod.IsPInvoke);
|
||||||
|
_owningType = owningType;
|
||||||
_targetMethod = targetMethod;
|
_targetMethod = targetMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MethodDesc TargetMethod
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _targetMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PInvokeMetadata PInvokeMetadata
|
public PInvokeMetadata PInvokeMetadata
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
@ -91,7 +101,7 @@ namespace Internal.IL.Stubs
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return (DefType)_targetMethod.OwningType;
|
return _owningType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ namespace Internal.TypeSystem
|
||||||
private readonly ForwardDelegateCreationStubHashtable _forwardDelegateCreationStubHashtable;
|
private readonly ForwardDelegateCreationStubHashtable _forwardDelegateCreationStubHashtable;
|
||||||
private readonly PInvokeDelegateWrapperHashtable _pInvokeDelegateWrapperHashtable;
|
private readonly PInvokeDelegateWrapperHashtable _pInvokeDelegateWrapperHashtable;
|
||||||
private readonly InlineArrayHashTable _inlineArrayHashtable;
|
private readonly InlineArrayHashTable _inlineArrayHashtable;
|
||||||
|
private readonly PInvokeLazyFixupFieldHashtable _pInvokeLazyFixupFieldHashtable;
|
||||||
|
|
||||||
public InteropStateManager(ModuleDesc generatedAssembly)
|
public InteropStateManager(ModuleDesc generatedAssembly)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +32,7 @@ namespace Internal.TypeSystem
|
||||||
_forwardDelegateCreationStubHashtable = new ForwardDelegateCreationStubHashtable(this, _generatedAssembly.GetGlobalModuleType());
|
_forwardDelegateCreationStubHashtable = new ForwardDelegateCreationStubHashtable(this, _generatedAssembly.GetGlobalModuleType());
|
||||||
_pInvokeDelegateWrapperHashtable = new PInvokeDelegateWrapperHashtable(this, _generatedAssembly);
|
_pInvokeDelegateWrapperHashtable = new PInvokeDelegateWrapperHashtable(this, _generatedAssembly);
|
||||||
_inlineArrayHashtable = new InlineArrayHashTable(this, _generatedAssembly);
|
_inlineArrayHashtable = new InlineArrayHashTable(this, _generatedAssembly);
|
||||||
|
_pInvokeLazyFixupFieldHashtable = new PInvokeLazyFixupFieldHashtable(_generatedAssembly.GetGlobalModuleType());
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Delegate Marshalling Stubs
|
// Delegate Marshalling Stubs
|
||||||
|
@ -180,6 +182,10 @@ namespace Internal.TypeSystem
|
||||||
return _inlineArrayHashtable.GetOrCreateValue(candidate);
|
return _inlineArrayHashtable.GetOrCreateValue(candidate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FieldDesc GetPInvokeLazyFixupField(MethodDesc method)
|
||||||
|
{
|
||||||
|
return _pInvokeLazyFixupFieldHashtable.GetOrCreateValue(method);
|
||||||
|
}
|
||||||
|
|
||||||
private class NativeStructTypeHashtable : LockFreeReaderHashtable<MetadataType, NativeStructType>
|
private class NativeStructTypeHashtable : LockFreeReaderHashtable<MetadataType, NativeStructType>
|
||||||
{
|
{
|
||||||
|
@ -433,6 +439,39 @@ namespace Internal.TypeSystem
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class PInvokeLazyFixupFieldHashtable : LockFreeReaderHashtable<MethodDesc, PInvokeLazyFixupField>
|
||||||
|
{
|
||||||
|
protected override int GetKeyHashCode(MethodDesc key)
|
||||||
|
{
|
||||||
|
return key.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override int GetValueHashCode(PInvokeLazyFixupField value)
|
||||||
|
{
|
||||||
|
return value.TargetMethod.GetHashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CompareKeyToValue(MethodDesc key, PInvokeLazyFixupField value)
|
||||||
|
{
|
||||||
|
return key == value.TargetMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CompareValueToValue(PInvokeLazyFixupField value1, PInvokeLazyFixupField value2)
|
||||||
|
{
|
||||||
|
return value1.TargetMethod == value2.TargetMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override PInvokeLazyFixupField CreateValueFromKey(MethodDesc key)
|
||||||
|
{
|
||||||
|
return new PInvokeLazyFixupField(_owningType, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly DefType _owningType;
|
||||||
|
|
||||||
|
public PInvokeLazyFixupFieldHashtable(DefType owningType)
|
||||||
|
{
|
||||||
|
_owningType = owningType;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче