Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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 @@ -22,7 +22,7 @@ public MethodInvoker(MethodBase method, Signature signature)
}
else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke)
{
// Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing.
// Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing.
_invoked = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ public static void VerifyInvokeIsUsingEmit_Constructor()

private static bool IsEmitInvokeSupported()
{
// Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeCompiled is true.
return RuntimeFeature.IsDynamicCodeCompiled;
// Emit is only used for Invoke when RuntimeFeature.IsDynamicCodeSupported is true.
return RuntimeFeature.IsDynamicCodeSupported;
}

private static string InterpretedMethodName => PlatformDetection.IsMonoRuntime ?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,14 @@ public static ObjectFactory CreateFactory(
Type[] argumentTypes)
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP
if (!RuntimeFeature.IsDynamicCodeSupported)
if (!RuntimeFeature.IsDynamicCodeCompiled)
{
// Create a reflection-based factory when dynamic code isn't supported, e.g. app is published with NativeAOT.
// Reflection-based factory is faster than interpreted expressions and doesn't pull in System.Linq.Expressions dependency.
// Create a reflection-based factory when dynamic code is not compiled\jitted as would be the case with
// NativeAOT, iOS or WASM.
// For NativeAOT and iOS, using the reflection-based factory is faster than reflection-fallback interpreted
// expressions and also doesn't pull in the large System.Linq.Expressions dependency.
// For WASM, although it has the ability to use expressions (with dynamic code) and interpet the dynamic code
// efficiently, the size savings of not using System.Linq.Expressions is more important than CPU perf.
return CreateFactoryReflection(instanceType, argumentTypes);
}
#endif
Expand Down Expand Up @@ -163,10 +167,9 @@ public static ObjectFactory<T>
Type[] argumentTypes)
{
#if NETSTANDARD2_1_OR_GREATER || NETCOREAPP
if (!RuntimeFeature.IsDynamicCodeSupported)
if (!RuntimeFeature.IsDynamicCodeCompiled)
{
// Create a reflection-based factory when dynamic code isn't supported, e.g. app is published with NativeAOT.
// Reflection-based factory is faster than interpreted expressions and doesn't pull in System.Linq.Expressions dependency.
// See the comment above in the non-generic CreateFactory() for why we use 'IsDynamicCodeCompiled' here.
var factory = CreateFactoryReflection(typeof(T), argumentTypes);
return (serviceProvider, arguments) => (T)factory(serviceProvider, arguments);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,12 +204,12 @@ public void CreateFactory_CreatesFactoryMethod()
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand Down Expand Up @@ -238,12 +238,12 @@ public void CreateFactory_RemoteExecutor_CreatesFactoryMethod(bool isDynamicCode
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand All @@ -261,12 +261,12 @@ public void CreateFactory_RemoteExecutor_NullArguments_Throws(bool isDynamicCode
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand All @@ -285,12 +285,12 @@ public void CreateFactory_RemoteExecutor_NoArguments_UseNullDefaultValue(bool is
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand All @@ -309,12 +309,12 @@ public void CreateFactory_RemoteExecutor_NoArguments_ThrowRequiredValue(bool isD
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand All @@ -333,12 +333,12 @@ public void CreateFactory_RemoteExecutor_NullArgument_UseDefaultValue(bool isDyn
#if NETCOREAPP
[InlineData(false)]
#endif
public void CreateFactory_RemoteExecutor_NoParameters_Success(bool isDynamicCodeSupported)
public void CreateFactory_RemoteExecutor_NoParameters_Success(bool useDynamicCode)
{
var options = new RemoteInvokeOptions();
if (!isDynamicCodeSupported)
if (!useDynamicCode)
{
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
DisableDynamicCode(options);
}

using var remoteHandle = RemoteExecutor.Invoke(static () =>
Expand All @@ -351,7 +351,16 @@ public void CreateFactory_RemoteExecutor_NoParameters_Success(bool isDynamicCode
Assert.NotNull(item);
}, options);
}

private static void DisableDynamicCode(RemoteInvokeOptions options)
{
// We probably only need to set 'IsDynamicCodeCompiled' since only that is checked,
// but also set 'IsDynamicCodeSupported' for correctness.
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled", "false");
}
}
}

internal class A { }
internal class B { }
Expand Down Expand Up @@ -532,4 +541,4 @@ public ClassWithStringDefaultValue(string text = "DEFAULT")
Text = text;
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -939,6 +939,7 @@ Func<Type, ServiceCallSite> CreateAotCompatibilityCallSiteFactory()

RemoteInvokeOptions options = new RemoteInvokeOptions();
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeSupported", "false");
options.RuntimeConfigurationOptions.Add("System.Runtime.CompilerServices.RuntimeFeature.IsDynamicCodeCompiled", "false");

using RemoteInvokeHandle remoteHandle = RemoteExecutor.Invoke(() =>
{
Expand Down Expand Up @@ -966,7 +967,7 @@ Func<Type, ServiceCallSite> CreateAotCompatibilityCallSiteFactory()
Assert.Equal(2, ((Struct1)callSite.Value).Value);
}, options);

// Verify the above scenarios work when IsDynamicCodeSupported is not set
// Verify the above scenarios work when IsDynamicCodeSupported + IsDynamicCodeCompiled are not set
Func<Type, ServiceCallSite> callSiteFactory = CreateAotCompatibilityCallSiteFactory();

// Open Generics
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo)
}
else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke)
{
// Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing.
// Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing.
_invoked = true;
}
}
Expand Down Expand Up @@ -53,7 +53,7 @@ public ConstructorInvoker(RuntimeConstructorInfo constructorInfo)
}
else
{
if (RuntimeFeature.IsDynamicCodeCompiled)
if (RuntimeFeature.IsDynamicCodeSupported)
{
_invokeFunc = InvokerEmitUtil.CreateInvokeDelegate(_method);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,13 @@ public static unsafe InvokeFunc CreateInvokeDelegate(MethodBase method)

// Invoke the method.
// For CallStack reasons, don't inline target method.
#if MONO
il.Emit(OpCodes.Call, Methods.DisableInline());
#if TARGET_WASM
// Mono interpreter does not support\need this intrinsic.
#elif MONO
il.Emit(OpCodes.Call, Methods.DisableInline());
#else
il.Emit(OpCodes.Call, Methods.NextCallReturnAddress());
il.Emit(OpCodes.Pop);
il.Emit(OpCodes.Call, Methods.NextCallReturnAddress());
il.Emit(OpCodes.Pop);
#endif

if (emitNew)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ internal sealed partial class MethodInvoker
}
else
{
if (RuntimeFeature.IsDynamicCodeCompiled)
if (RuntimeFeature.IsDynamicCodeSupported)
{
_invokeFunc = InvokerEmitUtil.CreateInvokeDelegate(_method);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public MethodInvoker(MethodBase method)
}
else if (LocalAppContextSwitches.ForceEmitInvoke && !LocalAppContextSwitches.ForceInterpretedInvoke)
{
// Always use emit invoke (if IsDynamicCodeCompiled == true); useful for testing.
// Always use emit invoke (if IsDynamicCodeSupported == true); useful for testing.
_invoked = true;
}
}
Expand Down