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>2015-12-29 00:05:54 +0300
committerJan Kotas <jkotas@microsoft.com>2015-12-30 16:54:24 +0300
commit1bc1dfa2a8470ec9508e04b11d7504e7df907206 (patch)
tree7d8de2269e8647662494a4162096f5ddd14c7ce7 /src/Common
parent5a6227d2a5645cc429905654685f36b2c516e2ba (diff)
Implement most RyuJIT intrinsics
- Add lookup of all RyuJIT intrinsics - Update manage implementations of the intrinsics to fit with what RyuJIT is capable of - Make intrinsic expansions by the codegen to be optional by providing fallback paths - Fix USE_PORTABLE_HELPERS to be defined for portable runtime only These changes are under CORERT ifdefs as necessary to be reconciled with .NET Native for UWP later.
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/src/TypeSystem/CodeGen/InstantiatedMethod.CodeGen.cs36
-rw-r--r--src/Common/src/TypeSystem/CodeGen/MethodDesc.CodeGen.cs68
-rw-r--r--src/Common/src/TypeSystem/CodeGen/MethodForInstantiatedType.CodeGen.cs36
-rw-r--r--src/Common/src/TypeSystem/IL/HelperExtensions.cs31
-rw-r--r--src/Common/src/TypeSystem/IL/ILProvider.cs10
-rw-r--r--src/Common/src/TypeSystem/IL/Stubs/InterlockedIntrinsic.cs61
6 files changed, 168 insertions, 74 deletions
diff --git a/src/Common/src/TypeSystem/CodeGen/InstantiatedMethod.CodeGen.cs b/src/Common/src/TypeSystem/CodeGen/InstantiatedMethod.CodeGen.cs
deleted file mode 100644
index f62af3023..000000000
--- a/src/Common/src/TypeSystem/CodeGen/InstantiatedMethod.CodeGen.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Internal.TypeSystem
-{
- // Additional members of InstantiatedMethod related to code generation.
- public partial class InstantiatedMethod
- {
- public override bool IsIntrinsic
- {
- get
- {
- return _methodDef.IsIntrinsic;
- }
- }
-
- public override bool IsNoInlining
- {
- get
- {
- return _methodDef.IsNoInlining;
- }
- }
-
- public override bool IsAggressiveInlining
- {
- get
- {
- return _methodDef.IsAggressiveInlining;
- }
- }
- }
-}
diff --git a/src/Common/src/TypeSystem/CodeGen/MethodDesc.CodeGen.cs b/src/Common/src/TypeSystem/CodeGen/MethodDesc.CodeGen.cs
index e45484f30..9f6784726 100644
--- a/src/Common/src/TypeSystem/CodeGen/MethodDesc.CodeGen.cs
+++ b/src/Common/src/TypeSystem/CodeGen/MethodDesc.CodeGen.cs
@@ -47,4 +47,72 @@ namespace Internal.TypeSystem
}
}
}
+
+ // Additional members of InstantiatedMethod related to code generation.
+ public partial class InstantiatedMethod
+ {
+ public override bool IsIntrinsic
+ {
+ get
+ {
+ return _methodDef.IsIntrinsic;
+ }
+ }
+
+ public override bool IsNoInlining
+ {
+ get
+ {
+ return _methodDef.IsNoInlining;
+ }
+ }
+
+ public override bool IsAggressiveInlining
+ {
+ get
+ {
+ return _methodDef.IsAggressiveInlining;
+ }
+ }
+ }
+
+ // Additional members of MethodForInstantiatedType related to code generation.
+ public partial class MethodForInstantiatedType
+ {
+ public override bool IsIntrinsic
+ {
+ get
+ {
+ return _typicalMethodDef.IsIntrinsic;
+ }
+ }
+
+ public override bool IsNoInlining
+ {
+ get
+ {
+ return _typicalMethodDef.IsNoInlining;
+ }
+ }
+
+ public override bool IsAggressiveInlining
+ {
+ get
+ {
+ return _typicalMethodDef.IsAggressiveInlining;
+ }
+ }
+ }
+
+ // Additional members of ArrayMethod related to code generation.
+ public partial class ArrayMethod
+ {
+ public override bool IsIntrinsic
+ {
+ get
+ {
+ return true;
+ }
+ }
+ }
}
diff --git a/src/Common/src/TypeSystem/CodeGen/MethodForInstantiatedType.CodeGen.cs b/src/Common/src/TypeSystem/CodeGen/MethodForInstantiatedType.CodeGen.cs
deleted file mode 100644
index a701afe84..000000000
--- a/src/Common/src/TypeSystem/CodeGen/MethodForInstantiatedType.CodeGen.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) Microsoft. All rights reserved.
-// Licensed under the MIT license. See LICENSE file in the project root for full license information.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace Internal.TypeSystem
-{
- // Additional members of MethodForInstantiatedType related to code generation.
- public partial class MethodForInstantiatedType
- {
- public override bool IsIntrinsic
- {
- get
- {
- return _typicalMethodDef.IsIntrinsic;
- }
- }
-
- public override bool IsNoInlining
- {
- get
- {
- return _typicalMethodDef.IsNoInlining;
- }
- }
-
- public override bool IsAggressiveInlining
- {
- get
- {
- return _typicalMethodDef.IsAggressiveInlining;
- }
- }
- }
-}
diff --git a/src/Common/src/TypeSystem/IL/HelperExtensions.cs b/src/Common/src/TypeSystem/IL/HelperExtensions.cs
index 6c494e4fb..ee46558bc 100644
--- a/src/Common/src/TypeSystem/IL/HelperExtensions.cs
+++ b/src/Common/src/TypeSystem/IL/HelperExtensions.cs
@@ -3,7 +3,6 @@
using System;
-using ILCompiler;
using Internal.TypeSystem;
using Internal.IL.Stubs;
@@ -13,6 +12,36 @@ namespace Internal.IL
{
internal static class HelperExtensions
{
+ /// <summary>
+ /// NEWOBJ operation on String type is actually a call to a static method that returns a String
+ /// instance (i.e. there's an explicit call to the runtime allocator from the static method body).
+ /// This method returns the alloc+init helper corresponding to a given string constructor.
+ /// </summary>
+ public static MethodDesc GetStringInitializer(this MethodDesc constructorMethod)
+ {
+ Debug.Assert(constructorMethod.IsConstructor);
+ Debug.Assert(constructorMethod.OwningType.IsString);
+
+ var constructorSignature = constructorMethod.Signature;
+
+ // There's an extra (useless) Object as the first arg to match RyuJIT expectations.
+ var parameters = new TypeDesc[constructorSignature.Length + 1];
+ parameters[0] = constructorMethod.Context.GetWellKnownType(WellKnownType.Object);
+ for (int i = 0; i < constructorSignature.Length; i++)
+ parameters[i + 1] = constructorSignature[i];
+
+ MethodSignature sig = new MethodSignature(
+ MethodSignatureFlags.Static, 0, constructorMethod.OwningType, parameters);
+
+ MethodDesc result = constructorMethod.OwningType.GetMethod("Ctor", sig);
+
+ // TODO: Better exception type. Should be: "CoreLib doesn't have a required thing in it".
+ if (result == null)
+ throw new NotImplementedException();
+
+ return result;
+ }
+
public static MetadataType GetHelperType(this TypeSystemContext context, string name)
{
MetadataType helperType = context.SystemModule.GetType("Internal.Runtime.CompilerHelpers", name, false);
diff --git a/src/Common/src/TypeSystem/IL/ILProvider.cs b/src/Common/src/TypeSystem/IL/ILProvider.cs
index 4d8cf5246..9b24cdfe4 100644
--- a/src/Common/src/TypeSystem/IL/ILProvider.cs
+++ b/src/Common/src/TypeSystem/IL/ILProvider.cs
@@ -31,10 +31,18 @@ namespace Internal.IL
if (owningType == null)
return null;
- if (method.Name == "UncheckedCast" && owningType.Name == "RuntimeHelpers" && owningType.Namespace == "System.Runtime.CompilerServices")
+ string methodName = method.Name;
+
+ if (methodName == "UncheckedCast" && owningType.Name == "RuntimeHelpers" && owningType.Namespace == "System.Runtime.CompilerServices")
{
return new ILStubMethodIL(new byte[] { (byte)ILOpcode.ldarg_0, (byte)ILOpcode.ret }, Array.Empty<LocalVariableDefinition>(), null);
}
+ else
+ if ((methodName == "CompareExchange" || methodName == "Exchange") && method.HasInstantiation && owningType.Name == "Interlocked" && owningType.Namespace == "System.Threading")
+ {
+ // TODO: Replace with regular implementation once ref locals are available in C# (https://github.com/dotnet/roslyn/issues/118)
+ return InterlockedIntrinsic.EmitIL(method);
+ }
return null;
}
diff --git a/src/Common/src/TypeSystem/IL/Stubs/InterlockedIntrinsic.cs b/src/Common/src/TypeSystem/IL/Stubs/InterlockedIntrinsic.cs
new file mode 100644
index 000000000..d2d56018b
--- /dev/null
+++ b/src/Common/src/TypeSystem/IL/Stubs/InterlockedIntrinsic.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+using System;
+
+using Internal.TypeSystem;
+
+using Debug = System.Diagnostics.Debug;
+
+namespace Internal.IL.Stubs
+{
+ /// <summary>
+ /// Provides method bodies for generic Interlocked intrinsics. These intrinsics work around the lack of byref locals
+ /// return values in C#. The intrinsic method forwards the call to the non-generic version.
+ /// </summary>
+ public static class InterlockedIntrinsic
+ {
+ public static MethodIL EmitIL(MethodDesc target)
+ {
+ Debug.Assert(target.Name == "CompareExchange" || target.Name == "Exchange");
+
+ //
+ // Find non-generic method to forward the generic method to.
+ //
+
+ int parameterCount = target.Signature.Length;
+ Debug.Assert(parameterCount == 3 || parameterCount == 2);
+
+ var objectType = target.Context.GetWellKnownType(WellKnownType.Object);
+
+ var parameters = new TypeDesc[parameterCount];
+ parameters[0] = objectType.MakeByRefType();
+ for (int i = 1; i < parameters.Length; i++)
+ parameters[i] = objectType;
+
+ MethodSignature nonGenericSignature = new MethodSignature(MethodSignatureFlags.Static, 0, objectType, parameters);
+
+ MethodDesc nonGenericMethod = target.OwningType.GetMethod(target.Name, nonGenericSignature);
+
+ // TODO: Better exception type. Should be: "CoreLib doesn't have a required thing in it".
+ if (nonGenericMethod == null)
+ throw new NotImplementedException();
+
+ //
+ // Emit the forwarder
+ //
+
+ ILEmitter emitter = new ILEmitter();
+ var codeStream = emitter.NewCodeStream();
+
+ // Reload all arguments
+ for (int i = 0; i < parameterCount; i++)
+ codeStream.EmitLdArg(i);
+
+ codeStream.Emit(ILOpcode.call, emitter.NewToken(nonGenericMethod));
+ codeStream.Emit(ILOpcode.ret);
+
+ return emitter.Link();
+ }
+ }
+}