Merge pull request #3478 from vargaz/fix-pedump
authorRodrigo Kumpera <kumpera@users.noreply.github.com>
Mon, 29 Aug 2016 21:51:30 +0000 (17:51 -0400)
committerGitHub <noreply@github.com>
Mon, 29 Aug 2016 21:51:30 +0000 (17:51 -0400)
[runtime] Fix pedump by using the normal embedding APIs instead of in…

50 files changed:
docs/sources/mono-api-gc.html
mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources [deleted file]
mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs [deleted file]
mcs/class/Facades/subdirs.make
mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
mcs/mcs/anonymous.cs
mcs/mcs/statement.cs
mcs/tests/test-async-89.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml
mcs/tools/al/Al.cs
mono/metadata/sgen-bridge-internals.h
mono/metadata/sgen-bridge.c
mono/metadata/sgen-bridge.h
mono/metadata/sgen-mono.c
mono/metadata/sgen-new-bridge.c
mono/metadata/sgen-old-bridge.c
mono/metadata/sgen-tarjan-bridge.c
mono/mini/mini-amd64.c
mono/mini/mini-arm.c
mono/mini/mini-ia64.c
mono/mini/mini-mips.c
mono/mini/mini-ppc.c
mono/mini/mini-s390x.c
mono/mini/mini-sparc.c
mono/mini/mini-x86.c
mono/tests/sgen-bridge-pathologies.cs
mono/utils/Makefile.am
mono/utils/mono-hwcap-arm.c
mono/utils/mono-hwcap-arm.h [deleted file]
mono/utils/mono-hwcap-arm64.c
mono/utils/mono-hwcap-arm64.h [deleted file]
mono/utils/mono-hwcap-cross.c [new file with mode: 0644]
mono/utils/mono-hwcap-ia64.c
mono/utils/mono-hwcap-ia64.h [deleted file]
mono/utils/mono-hwcap-mips.c
mono/utils/mono-hwcap-mips.h [deleted file]
mono/utils/mono-hwcap-ppc.c
mono/utils/mono-hwcap-ppc.h [deleted file]
mono/utils/mono-hwcap-s390x.c
mono/utils/mono-hwcap-s390x.h [deleted file]
mono/utils/mono-hwcap-sparc.c
mono/utils/mono-hwcap-vars.h [new file with mode: 0644]
mono/utils/mono-hwcap-x86.c
mono/utils/mono-hwcap-x86.h [deleted file]
mono/utils/mono-hwcap.c
mono/utils/mono-hwcap.h

index 20d6cb9dc9b3566f7408862163ea6c0c98b30666..cddef0364cbfe34fa2f3fff6e0191d55853c9267 100644 (file)
@@ -40,9 +40,8 @@
        <p>The output of the SCC analysis is passed to the
        `cross_references()` callback.  It is expected to set the
        `is_alive` flag on those strongly connected components that it
-       wishes to be kept alive.  Only bridged objects will be
-       reported to the callback, i.e., non-bridged objects are
-       removed from the callback graph.
+       wishes to be kept alive.  The value of `is_alive` will be
+       ignored on any SCCs which lack bridges.
        
        <p>In monodroid each bridged object has a corresponding Java
        mirror object.  In the bridge callback it reifies the Mono
@@ -63,7 +62,7 @@
 
 <div class="mapi-header">
 enum {
-        SGEN_BRIDGE_VERSION = 4
+        SGEN_BRIDGE_VERSION = 5
 };
         
 typedef enum {
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs b/mcs/class/Facades/System.Private.CoreLib.InteropServices/AssemblyInfo.cs
deleted file mode 100644 (file)
index 833904b..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-// 
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-// 
-
-using System;
-using System.Reflection;
-using System.Runtime.CompilerServices;
-
-[assembly: AssemblyTitle ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyDescription ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyDefaultAlias ("System.Private.CoreLib.InteropServices.dll")]
-[assembly: AssemblyCompany ("Xamarin, Inc.")]
-[assembly: AssemblyProduct ("Mono Common Language Infrastructure")]
-[assembly: AssemblyCopyright ("Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)")]
-[assembly: AssemblyVersion ("4.0.0.0")]
-[assembly: AssemblyInformationalVersion ("4.0.0.0")]
-[assembly: AssemblyFileVersion ("4.0.0.0")]
-[assembly: AssemblyDelaySign (true)]
-[assembly: AssemblyKeyFile ("../../msfinal.pub")]
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj b/mcs/class/Facades/System.Private.CoreLib.InteropServices/Facades_System.Private.CoreLib.InteropServices-net_4_x.csproj
deleted file mode 100644 (file)
index c81a035..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <PropertyGroup>\r
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
-    <ProductVersion>9.0.30729</ProductVersion>\r
-    <SchemaVersion>2.0</SchemaVersion>\r
-    <ProjectGuid>{5D05F5E2-7378-4A35-B1A3-76ABEB4A71C3}</ProjectGuid>\r
-    <OutputType>Library</OutputType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
-    <IntermediateOutputPath>obj-Facades</IntermediateOutputPath>\r
-    <GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>\r
-    <NoStdLib>True</NoStdLib>\r
-    \r
-    <NoConfig>True</NoConfig>\r
-    \r
-    <AppDesignerFolder>Properties</AppDesignerFolder>\r
-    <RootNamespace>\r
-    </RootNamespace>\r
-    <AssemblyName>System.Private.CoreLib.InteropServices</AssemblyName>\r
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
-    <FileAlignment>512</FileAlignment>\r
-  </PropertyGroup>\r
-    <PropertyGroup>\r
-    <SignAssembly>true</SignAssembly>\r
-    <DelaySign>true</DelaySign>\r
-  </PropertyGroup>\r
-  <PropertyGroup>\r
-    <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
-    <DebugSymbols>true</DebugSymbols>\r
-    <DebugType>full</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>false</Optimize>\r
-    <DefineConstants>TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
-    <DebugType>pdbonly</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>true</Optimize>\r
-    <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
-  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
-  is a problem to compile the Mono mscorlib.dll -->\r
-  <PropertyGroup>\r
-    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
-  </PropertyGroup>\r
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
-  <ItemGroup>\r
-    <Compile Include="AssemblyInfo.cs" />\r
-    <Compile Include="TypeForwarders.cs" />\r  </ItemGroup>\r
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
-       Other similar extension points exist, see Microsoft.Common.targets.\r
-  <Target Name="BeforeBuild">\r
-  </Target>\r
-  <Target Name="AfterBuild">\r
-  </Target>\r
-  -->\r
-  <PropertyGroup>\r
-    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
-    </PreBuildEvent>\r
-    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
-    </PostBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-  </PropertyGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../System/System-net_4_x.csproj">\r
-      <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
-      <Name>System-net_4_x</Name>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <Folder Include="Properties\" />\r
-  </ItemGroup>\r
-</Project>\r
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile b/mcs/class/Facades/System.Private.CoreLib.InteropServices/Makefile
deleted file mode 100644 (file)
index 7b03ca8..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-MCS_BUILD_DIR = ../../../build
-
-thisdir = class/Facades/System.Private.CoreLib.InteropServices
-SUBDIRS = 
-include $(MCS_BUILD_DIR)/rules.make
-
-LIBRARY_SUBDIR = Facades
-LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
-
-LIBRARY = System.Private.CoreLib.InteropServices.dll
-
-KEY_FILE = ../../msfinal.pub
-SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
-LIB_REFS = System
-LIB_MCS_FLAGS = $(SIGN_FLAGS) 
-
-PLATFORM_DEBUG_FLAGS =
-
-NO_TEST = yes
-
-include $(MCS_BUILD_DIR)/library.make
-
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj b/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices-net_4_x.csproj
deleted file mode 100644 (file)
index 4813330..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
-  <PropertyGroup>\r
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
-    <ProductVersion>9.0.30729</ProductVersion>\r
-    <SchemaVersion>2.0</SchemaVersion>\r
-    <ProjectGuid>{BE4A05DF-5630-4E80-9521-7B4216229A60}</ProjectGuid>\r
-    <OutputType>Library</OutputType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <OutputPath>./../../../class/lib/net_4_x/Facades</OutputPath>\r
-    <NoStdLib>True</NoStdLib>\r
-    <NoConfig>True</NoConfig>\r
-    \r
-    <AppDesignerFolder>Properties</AppDesignerFolder>\r
-    <RootNamespace>\r
-    </RootNamespace>\r
-    <AssemblyName>System.Private.CoreLib.InteropServices</AssemblyName>\r
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>\r
-    <FileAlignment>512</FileAlignment>\r
-  </PropertyGroup>\r
-    <PropertyGroup>\r
-    <SignAssembly>true</SignAssembly>\r
-    <DelaySign>true</DelaySign>\r
-  </PropertyGroup>\r
-  <PropertyGroup>\r
-    <AssemblyOriginatorKeyFile>../../msfinal.pub</AssemblyOriginatorKeyFile>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
-    <DebugSymbols>true</DebugSymbols>\r
-    <DebugType>full</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>false</Optimize>\r
-    <DefineConstants>DEBUG;TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
-    <DebugType>pdbonly</DebugType>\r
-    <NoWarn>1699,1616,1699</NoWarn>\r
-    <Optimize>true</Optimize>\r
-    <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE</DefineConstants>\r
-    <ErrorReport>prompt</ErrorReport>\r
-    <WarningLevel>4</WarningLevel>\r
-  </PropertyGroup>\r
-  <!-- Set AddAdditionalExplicitAssemblyReferences to false, otherwise if targetting .NET4.0, \r
-  Microsoft.NETFramework.props will force a dependency on the assembly System.Core. This\r
-  is a problem to compile the Mono mscorlib.dll -->\r
-  <PropertyGroup>\r
-    <AddAdditionalExplicitAssemblyReferences>false</AddAdditionalExplicitAssemblyReferences>\r
-  </PropertyGroup>\r
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
-  <ItemGroup>\r
-    <Compile Include="AssemblyInfo.cs" />\r
-    <Compile Include="TypeForwarders.cs" />\r  </ItemGroup>\r
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
-       Other similar extension points exist, see Microsoft.Common.targets.\r
-  <Target Name="BeforeBuild">\r
-  </Target>\r
-  <Target Name="AfterBuild">\r
-  </Target>\r
-  -->\r
-  <PropertyGroup>\r
-    <PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-    <PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PreBuildEvent>\r
-\r
-    <PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-    <PostBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
-    </PostBuildEvent>\r
-  </PropertyGroup>\r
-  <ItemGroup>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../corlib/corlib-net_4_x.csproj">\r
-      <Project>{2CA6026B-2DC8-4C4C-A12C-1E8234049DB7}</Project>\r
-      <Name>corlib-net_4_x</Name>\r
-    </ProjectReference>\r
-    <ProjectReference Include="../../System/System-net_4_x.csproj">\r
-      <Project>{2762E921-91A8-4C87-91E9-BA628013F753}</Project>\r
-      <Name>System-net_4_x</Name>\r
-    </ProjectReference>\r
-  </ItemGroup>\r
-  <ItemGroup>\r
-    <Folder Include="Properties\" />\r
-  </ItemGroup>\r
-</Project>\r
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources b/mcs/class/Facades/System.Private.CoreLib.InteropServices/System.Private.CoreLib.InteropServices.dll.sources
deleted file mode 100644 (file)
index 8e33d4d..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-TypeForwarders.cs
-AssemblyInfo.cs
-
diff --git a/mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs b/mcs/class/Facades/System.Private.CoreLib.InteropServices/TypeForwarders.cs
deleted file mode 100644 (file)
index 7a1269d..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-// 
-// Copyright (c) 2015 Xamarin Inc. (http://www.xamarin.com)
-// 
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-// 
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-// 
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-// THE SOFTWARE.
-// 
-
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.CallingConvention))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.DllImportAttribute))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.GCHandle))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.GCHandleType))]
-[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.SafeHandle))]
-
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(Internal.Reflection.Execution.PayForPlayExperience.MissingMetadataExceptionCreator))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.DependencyReductionTypeRemoved))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.PreInitializedAttribute))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.InteropExtensions))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.NativeCallableAttributes))]
-//Missing: [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.RuntimeImportAttribute))]
index df1dd020404535839b69b35be715b25cdb7a9275..c980d70840d4d7c2def8ece1b62f4ce110d13c8c 100644 (file)
@@ -24,7 +24,7 @@ System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encrypt
 System.Security.Cryptography.Hashing.Algorithms System.Security.Cryptography.RSA System.Security.Cryptography.RandomNumberGenerator \
 System.Security.Principal.Windows System.Threading.Thread System.Threading.ThreadPool \
 System.Xml.XPath System.Xml.XmlDocument System.Xml.Xsl.Primitives Microsoft.Win32.Registry.AccessControl System.Diagnostics.StackTrace System.Globalization.Extensions \
-System.IO.FileSystem.AccessControl System.Private.CoreLib.InteropServices System.Reflection.TypeExtensions \
+System.IO.FileSystem.AccessControl System.Reflection.TypeExtensions \
 System.Security.SecureString System.Threading.AccessControl System.Threading.Overlapped System.Xml.XPath.XDocument \
 System.Security.Cryptography.Primitives System.Text.Encoding.CodePages System.IO.FileSystem.Watcher \
 System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.IO.Pipes
index e406357204f2a99d07bae57065d386b59cede021..f4e8a9705f78e0beeacafc11313de8475cea8a30 100644 (file)
@@ -1055,24 +1055,21 @@ namespace MonoTests.System.Threading.Tasks
                        var token = source.Token;
                        var evt = new ManualResetEventSlim ();
                        bool result = false;
-                       bool thrown = false;
 
-                       var task = Task.Factory.StartNew (() => evt.Wait (100));
+                       var task = Task.Factory.StartNew (() => { Assert.IsTrue (evt.Wait (2000), "#1"); });
                        var cont = task.ContinueWith (t => result = true, token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Default);
 
                        source.Cancel();
                        evt.Set ();
-                       task.Wait (100);
+                       Assert.IsTrue (task.Wait (2000), "#2");
                        try {
-                               cont.Wait (100);
-                       } catch (Exception ex) {
-                               thrown = true;
+                               Assert.IsFalse (cont.Wait (4000), "#3");
+                       } catch (AggregateException ex) {
                        }
 
-                       Assert.IsTrue (task.IsCompleted);
-                       Assert.IsTrue (cont.IsCanceled);
-                       Assert.IsFalse (result);
-                       Assert.IsTrue (thrown);
+                       Assert.IsTrue (task.IsCompleted, "#4");
+                       Assert.IsTrue (cont.IsCanceled, "#5");
+                       Assert.IsFalse (result, "#6");
                }
 
                [Test]
index 80481ed2091f6ba2cf1deb7c25e4c5514ce9e529..d27fe806048797af33538b202c262e0e040dff4e 100644 (file)
@@ -1595,6 +1595,15 @@ namespace Mono.CSharp {
                        if (res && errors != ec.Report.Errors)
                                return null;
 
+                       if (block.IsAsync && block.Original.ParametersBlock.HasCapturedThis && ec.CurrentAnonymousMethod != null && ec.CurrentAnonymousMethod.block.IsAsync) {
+                               //
+                               // We'll do ldftn to load the fabricated m_X method but
+                               // because we are inside struct the method can be hoisted
+                               // anywhere in the parent scope
+                               //
+                               ec.CurrentBlock.ParametersBlock.HasReferenceToStoreyForInstanceLambdas = true;
+                       }
+
                        return res ? this : null;
                }
 
@@ -1798,6 +1807,8 @@ namespace Mono.CSharp {
                                                        parent = storey = sm;
                                                }
                                        }
+                               } else if (src_block.ParametersBlock.HasReferenceToStoreyForInstanceLambdas) {
+                                       src_block.ParametersBlock.StateMachine.AddParentStoreyReference (ec, storey);
                                }
 
                                modifiers = storey != null ? Modifiers.INTERNAL : Modifiers.PRIVATE;
index d7105592ebb29cdcff8b38039e88696def303f62..7f54b33eeb599c16146c7adfcc0c2e12b3d5beaf 100644 (file)
@@ -2657,6 +2657,7 @@ namespace Mono.CSharp {
                        AwaitBlock = 1 << 13,
                        FinallyBlock = 1 << 14,
                        CatchBlock = 1 << 15,
+                       HasReferenceToStoreyForInstanceLambdas = 1 << 16,
                        Iterator = 1 << 20,
                        NoFlowAnalysis = 1 << 21,
                        InitializationEmitted = 1 << 22
@@ -3281,7 +3282,7 @@ namespace Mono.CSharp {
                                                        break;
                                        }
                                }
-                               
+
                                //
                                // We are the first storey on path and 'this' has to be hoisted
                                //
@@ -3349,7 +3350,7 @@ namespace Mono.CSharp {
 
                                                                //
                                                                // If we are state machine with no parent. We can hook into parent without additional
-                                                               // reference and capture this directly
+                                                               // reference and capture this directly
                                                                //
                                                                ExplicitBlock parent_storey_block = pb;
                                                                while (parent_storey_block.Parent != null) {
@@ -3666,6 +3667,15 @@ namespace Mono.CSharp {
 
                #region Properties
 
+               public bool HasReferenceToStoreyForInstanceLambdas {
+                       get {
+                               return (flags & Flags.HasReferenceToStoreyForInstanceLambdas) != 0;
+                       }
+                       set {
+                               flags = value ? flags | Flags.HasReferenceToStoreyForInstanceLambdas : flags & ~Flags.HasReferenceToStoreyForInstanceLambdas;
+                       }
+               }
+
                public bool IsAsync {
                        get {
                                return (flags & Flags.HasAsyncModifier) != 0;
diff --git a/mcs/tests/test-async-89.cs b/mcs/tests/test-async-89.cs
new file mode 100644 (file)
index 0000000..5a69685
--- /dev/null
@@ -0,0 +1,51 @@
+using System;
+using System.Threading.Tasks;
+
+class X
+{
+       public static void Main ()
+       {
+               new X ().Test ();
+       }
+
+       void Test ()
+       {
+               object v1 = null;
+
+               Action a = () =>
+               {
+                       if (v1 == null)
+                       {
+                               object v2 = null;
+
+                               Action a2 = () =>
+                               {
+                                       Console.WriteLine (v2);
+                               };
+                               
+                               Action a3 = async () =>
+                               {
+                                       // This scope needs to access to Scope which can do ldftn on instance method
+                                       {
+                                       Func<Task> a4 = async () =>
+                                       {
+                                               await Foo ();
+                                       };
+                                       }
+
+                                       await Task.Yield ();
+                               };
+
+                               a3 ();
+                       }
+               };
+
+               a ();
+       }
+
+       async Task Foo ()
+       {
+               await Task.FromResult (1);
+       }
+
+}
\ No newline at end of file
index 270fe53c92fdf6c81740a9b9d4f6d632b8673bd4..cde4e9e70d68ea66bba24d1169045aa8b6be1057 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-async-89.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>12</size>
+      </method>
+      <method name="Void Test()" attrs="129">
+        <size>41</size>
+      </method>
+      <method name="System.Threading.Tasks.Task Foo()" attrs="129">
+        <size>33</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1">
+      <method name="Void &lt;&gt;m__0()" attrs="131">
+        <size>67</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Foo&gt;c__async0">
+      <method name="Void MoveNext()" attrs="486">
+        <size>158</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2">
+      <method name="Void &lt;&gt;m__0()" attrs="131">
+        <size>13</size>
+      </method>
+      <method name="Void &lt;&gt;m__1()" attrs="131">
+        <size>48</size>
+      </method>
+      <method name="System.Threading.Tasks.Task &lt;&gt;m__2()" attrs="131">
+        <size>46</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2+&lt;Test&gt;c__async3">
+      <method name="Void MoveNext()" attrs="486">
+        <size>179</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+    <type name="X+&lt;Test&gt;c__AnonStorey1+&lt;Test&gt;c__AnonStorey2+&lt;Test&gt;c__async4">
+      <method name="Void MoveNext()" attrs="486">
+        <size>167</size>
+      </method>
+      <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+        <size>13</size>
+      </method>
+    </type>
+  </test>
   <test name="test-cls-00.cs">
     <type name="CLSCLass_6">
       <method name="Void add_Disposed(Delegate)" attrs="2182">
index bdc741144ea595cb7d7bcbeb8b509e5a3e225148..3670d2f2eb94c6562db2a34b84eb5653165e4c07 100644 (file)
@@ -13,14 +13,13 @@ using System.Globalization;
 using System.IO;
 using System.Collections;
 using System.Collections.Generic;
-using System.Reflection;
-using System.Reflection.Emit;
 using System.Security.Cryptography;
 using System.Text;
 using System.Configuration.Assemblies;
 
+using IKVM.Reflection;
+using IKVM.Reflection.Emit;
 using Mono.Security.Cryptography;
-using IKR = IKVM.Reflection;
 
 namespace Mono.AssemblyLinker
 {
@@ -49,6 +48,15 @@ namespace Mono.AssemblyLinker
                No
        }
 
+       public enum Platform {
+               AnyCPU,
+               AnyCPU32Preferred,
+               Arm,
+               X86,
+               X64,
+               IA64
+       }
+
        public class AssemblyLinker {
 
                ArrayList inputFiles = new ArrayList ();
@@ -59,24 +67,35 @@ namespace Mono.AssemblyLinker
                string entryPoint;
                string win32IconFile;
                string win32ResFile;
+               string title;
+               string description;
+               string company;
+               string product;
+               string copyright;
+               string trademark;
                string templateFile;
                bool isTemplateFile = false;
                Target target = Target.Dll;
+               Platform platform = Platform.AnyCPU;
                DelaySign delaysign = DelaySign.NotSet;
                string keyfile;
                string keyname;
                string culture;
+               Universe universe;
 
                public static int Main (String[] args) {
                        return new AssemblyLinker ().DynMain (args);
                }
 
                private int DynMain (String[] args) {
-                       ParseArgs (args);
+                       using (universe = new Universe (UniverseOptions.MetadataOnly)) {
+                               universe.LoadFile (typeof (object).Assembly.Location);
+                               ParseArgs (args);
 
-                       DoIt ();
+                               DoIt ();
 
-                       return 0;
+                               return 0;
+                       }
                }
 
                private void ParseArgs (string[] args) 
@@ -211,7 +230,7 @@ namespace Mono.AssemblyLinker
                                        if (realArg.StartsWith ("0x"))
                                                realArg = realArg.Substring (2);
                                        uint val = Convert.ToUInt32 (realArg, 16);
-                                       AddCattr (typeof (AssemblyAlgorithmIdAttribute), typeof (uint), val);
+                                       AddCattr (typeof (System.Reflection.AssemblyAlgorithmIdAttribute), typeof (uint), val);
                                } catch (Exception) {
                                        ReportInvalidArgument (opt, arg);
                                }
@@ -233,21 +252,21 @@ namespace Mono.AssemblyLinker
                        case "company":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyCompanyAttribute), arg);
+                               company = arg;
                                return true;
 
                        case "config":
                        case "configuration":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyConfigurationAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyConfigurationAttribute), arg);
                                return true;
 
                        case "copy":
                        case "copyright":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyCopyrightAttribute), arg);
+                               copyright = arg;
                                return true;
 
                        case "c":
@@ -273,7 +292,7 @@ namespace Mono.AssemblyLinker
                        case "description":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyDescriptionAttribute), arg);
+                               description = arg;
                                return true;
 
                        case "e":
@@ -292,7 +311,7 @@ namespace Mono.AssemblyLinker
                                if (arg == null)
                                        ReportMissingText (opt);
 
-                               AddCattr (typeof (AssemblyFileVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyFileVersionAttribute), arg);
                                return true;
 
                        case "flags":
@@ -303,7 +322,7 @@ namespace Mono.AssemblyLinker
                                        if (realArg.StartsWith ("0x"))
                                                realArg = realArg.Substring (2);
                                        uint val = Convert.ToUInt32 (realArg, 16);
-                                       AddCattr (typeof (AssemblyFlagsAttribute), typeof (uint), val);
+                                       AddCattr (typeof (System.Reflection.AssemblyFlagsAttribute), typeof (uint), val);
                                } catch (Exception) {
                                        ReportInvalidArgument (opt, arg);
                                }
@@ -342,18 +361,46 @@ namespace Mono.AssemblyLinker
                                outFile = arg;
                                return true;
 
+               case "platform":
+                       if (arg == null)
+                               ReportMissingText (opt);
+                       switch (arg.ToLowerInvariant ()) {
+                               case "arm":
+                                       platform = Platform.Arm;
+                                       break;
+                               case "anycpu":
+                                       platform = Platform.AnyCPU;
+                                       break;
+                               case "x86":
+                                       platform = Platform.X86;
+                                       break;
+                               case "x64":
+                                       platform = Platform.X64;
+                                       break;
+                               case "itanium":
+                                       platform = Platform.IA64;
+                                       break;
+                               case "anycpu32bitpreferred":
+                                       platform = Platform.AnyCPU32Preferred;
+                                       break;
+                               default:
+                                       ReportInvalidArgument (opt, arg);
+                                       break;
+                               }
+                               return true;
+
                        case "prod":
                        case "product":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyProductAttribute), arg);
+                               product = arg;
                                return true;
 
                        case "productv":
                        case "productversion":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyInformationalVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyInformationalVersionAttribute), arg);
                                return true;
 
                        case "t":
@@ -388,14 +435,14 @@ namespace Mono.AssemblyLinker
                        case "title":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyTitleAttribute), arg);
+                               title = arg;
                                return true;
 
                        case "trade":
                        case "trademark":
                                if (arg == null)
                                        ReportMissingText (opt);
-                               AddCattr (typeof (AssemblyTrademarkAttribute), arg);
+                               trademark = arg;
                                return true;
 
                        case "v":
@@ -405,7 +452,7 @@ namespace Mono.AssemblyLinker
                                        Version ();
                                        break;
                                }
-                               AddCattr (typeof (AssemblyVersionAttribute), arg);
+                               AddCattr (typeof (System.Reflection.AssemblyVersionAttribute), arg);
                                return true;
 
                        case "win32icon":
@@ -461,11 +508,14 @@ namespace Mono.AssemblyLinker
                        return command.ToLower ();
                }
 
-               private void AddCattr (Type attrType, Type arg, object value) {
-                       cattrs.Add (new CustomAttributeBuilder (attrType.GetConstructor (new Type [] { arg }), new object [] { value }));
+               private void AddCattr (System.Type attrType, System.Type arg, object value) {
+                       var importedAttrType = universe.Import(attrType);
+                       var importedArg = universe.Import(arg);
+
+                       cattrs.Add (new CustomAttributeBuilder (importedAttrType.GetConstructor (new [] { importedArg }), new [] { value }));
                }
 
-               private void AddCattr (Type attrType, object value) {
+               private void AddCattr (System.Type attrType, object value) {
                        AddCattr (attrType, typeof (string), value);
                }
 
@@ -596,12 +646,25 @@ namespace Mono.AssemblyLinker
                        if (isTemplateFile)
                                aname = ReadCustomAttributesFromTemplateFile (templateFile, aname);
 
+                       if (!String.IsNullOrEmpty (title))
+                               AddCattr (typeof (System.Reflection.AssemblyTitleAttribute), title);
+                       if (!String.IsNullOrEmpty (description))
+                               AddCattr (typeof (System.Reflection.AssemblyDescriptionAttribute), description);
+                       if (!String.IsNullOrEmpty (company))
+                               AddCattr (typeof (System.Reflection.AssemblyCompanyAttribute), company);
+                       if (!String.IsNullOrEmpty (product))
+                               AddCattr (typeof (System.Reflection.AssemblyProductAttribute), product);
+                       if (!String.IsNullOrEmpty (copyright))
+                               AddCattr (typeof (System.Reflection.AssemblyCopyrightAttribute), copyright);
+                       if (!String.IsNullOrEmpty (trademark))
+                               AddCattr (typeof (System.Reflection.AssemblyTrademarkAttribute), trademark);
+
                        SetKeyPair (aname);
 
                        if (fileName != outFile)
-                               ab = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName (outFile));
+                               ab = universe.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save, Path.GetDirectoryName (outFile));
                        else
-                               ab = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save);
+                               ab = universe.DefineDynamicAssembly (aname, AssemblyBuilderAccess.Save);
 
                        foreach (CustomAttributeBuilder cb in cattrs)
                                ab.SetCustomAttribute (cb);
@@ -611,10 +674,6 @@ namespace Mono.AssemblyLinker
                         */
 
                        foreach (ModuleInfo mod in inputFiles) {
-                               MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                               if (mi == null)
-                                       Report (0, "Cannot add modules on this runtime: try the Mono runtime instead.");
-
                                if (mod.target != null) {
                                        File.Copy (mod.fileName, mod.target, true);
                                        mod.fileName = mod.target;
@@ -631,7 +690,7 @@ namespace Mono.AssemblyLinker
                                if (isAssembly)
                                        ReportWarning (1020, "Ignoring included assembly '" + mod.fileName + "'");
                                else
-                                       mi.Invoke (ab, new object [] { mod.fileName });
+                               ab.__AddModule (universe.OpenRawModule(mod.fileName));
                        }
 
                        /*
@@ -645,7 +704,7 @@ namespace Mono.AssemblyLinker
                                MethodInfo mainMethodInfo = null;
 
                                try {
-                                       Type mainType = ab.GetType (mainClass);
+                                       IKVM.Reflection.Type mainType = ab.GetType (mainClass);
                                        if (mainType != null)
                                                mainMethodInfo = mainType.GetMethod (mainMethod);
                                }
@@ -666,10 +725,7 @@ namespace Mono.AssemblyLinker
 
                        if (win32IconFile != null) {
                                try {
-                                       MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
-                                       if (mi == null)
-                                               Report (0, "Cannot embed win32 icons on this runtime: try the Mono runtime instead.");
-                                       mi.Invoke (ab, new object [] {  win32IconFile });
+                                       ab.__DefineIconResource (File.ReadAllBytes (win32IconFile));
                                }
                                catch (Exception ex) {
                                        Report (1031, "Error reading icon '" + win32IconFile + "' --" + ex);
@@ -685,6 +741,8 @@ namespace Mono.AssemblyLinker
                                }
                        }
 
+                       ModuleBuilder mainModule = null;
+
                        foreach (ResourceInfo res in resources) {
                                if (res.name == null)
                                        res.name = Path.GetFileName (res.fileName);
@@ -694,11 +752,13 @@ namespace Mono.AssemblyLinker
                                                Report (1046, String.Format ("Resource identifier '{0}' has already been used in this assembly", res.name));
 
                                if (res.isEmbedded) {
-                                       MethodInfo mi = typeof (AssemblyBuilder).GetMethod ("EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
-                                               null, CallingConventions.Any, new Type [] { typeof (string), typeof (string) }, null);
-                                       if (mi == null)
-                                               Report (0, "Cannot embed resources on this runtime: try the Mono runtime instead.");
-                                       mi.Invoke (ab, new object [] { res.name, res.fileName });
+                                       if (mainModule == null) {
+                                               mainModule = ab.DefineDynamicModule (fileName, fileName, false);
+                                       }
+
+                                       Stream stream = new MemoryStream (File.ReadAllBytes (res.fileName));
+
+                                       mainModule.DefineManifestResource (res.name, stream, res.isPrivate ? ResourceAttributes.Private : ResourceAttributes.Public);
                                }
                                else {
                                        if (res.target != null) {
@@ -721,8 +781,36 @@ namespace Mono.AssemblyLinker
                                }
                        }
 
+                       PortableExecutableKinds pekind = PortableExecutableKinds.ILOnly;
+                       ImageFileMachine machine;
+
+                       switch (platform) {
+                       case Platform.X86:
+                               pekind |= PortableExecutableKinds.Required32Bit;
+                               machine = ImageFileMachine.I386;
+                               break;
+                       case Platform.X64:
+                               pekind |= PortableExecutableKinds.PE32Plus;
+                               machine = ImageFileMachine.AMD64;
+                               break;
+                       case Platform.IA64:
+                               machine = ImageFileMachine.IA64;
+                               break;
+                       case Platform.AnyCPU32Preferred:
+                               pekind |= PortableExecutableKinds.Preferred32Bit;
+                               machine = ImageFileMachine.I386;
+                               break;
+                       case Platform.Arm:
+                               machine = ImageFileMachine.ARM;
+                               break;
+                       case Platform.AnyCPU:
+                       default:
+                               machine = ImageFileMachine.I386;
+                               break;
+                       }
+
                        try {
-                               ab.Save (fileName);
+                               ab.Save (fileName, pekind, machine);
                        }
                        catch (Exception ex) {
                                Report (1019, "Metadata failure creating assembly -- " + ex);
@@ -733,17 +821,14 @@ namespace Mono.AssemblyLinker
                {
                        // LAMESPEC: according to MSDN, the template assembly must have a
                        // strong name but this is not enforced
-                       const IKR.UniverseOptions options = IKR.UniverseOptions.MetadataOnly;
-
-                       var universe = new IKR.Universe (options);
                        var asm = universe.LoadFile (templateFile);
 
                        // Create missing assemblies, we don't want to load them!
                        // Code taken from ikdasm
                        var names = new HashSet<string> ();
-                       IKR.AssemblyName[] assembly_refs = asm.ManifestModule.__GetReferencedAssemblies ();
+                       AssemblyName[] assembly_refs = asm.ManifestModule.__GetReferencedAssemblies ();
 
-                       var resolved_assemblies = new IKR.Assembly [assembly_refs.Length];
+                       var resolved_assemblies = new Assembly [assembly_refs.Length];
                        for (int i = 0; i < resolved_assemblies.Length; i++) {
                                string name = assembly_refs [i].Name;
 
@@ -798,6 +883,85 @@ namespace Mono.AssemblyLinker
                                                        keyname = key_name_value;
                                        }
                                        break;
+
+                                       case "System.Reflection.AssemblyTitleAttribute": {
+                                               if (title != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyTitleAttribute .ctor(string title)
+                                               string title_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (title_value))
+                                                       title = title_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyDescriptionAttribute": {
+                                               if (description != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyDescriptionAttribute .ctor(string description)
+                                               string description_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (description_value))
+                                                       description = description_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyProductAttribute": {
+                                               if (product != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyProductAttribute .ctor(string product)
+                                               string product_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (product_value))
+                                                       product = product_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyCompanyAttribute": {
+                                               if (company != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyCompanyAttribute .ctor(string company)
+                                               string company_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (company_value))
+                                                       company = company_value;
+
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyCopyrightAttribute": {
+                                               if (copyright != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyCopyrightAttribute .ctor(string copyright)
+                                               string copyright_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (copyright_value))
+                                                       copyright = copyright_value;
+                                       }
+                                       break;
+
+                                       case "System.Reflection.AssemblyTrademarkAttribute": {
+                                               if (trademark != null)
+                                                       // ignore if specified on command line
+                                                       continue;
+
+                                               // AssemblyTrademarkAttribute .ctor(string trademark)
+                                               string trademark_value = (string) attr_data.ConstructorArguments [0].Value;
+
+                                               if (!String.IsNullOrEmpty (trademark_value))
+                                                       trademark = trademark_value;
+                                       }
+                                       break;
                                }
                        }
 
@@ -877,6 +1041,9 @@ namespace Mono.AssemblyLinker
                        "  /main:<method>            Specifies the method name of the entry point",
                        "  /nologo                   Suppress the startup banner and copyright message",
                        "  /out:<filename>           Output file name for the assembly manifest",
+                       "  /platform:<text>          Limit which platforms this code can run on; must be",
+                       "                            one of x86, Itanium, x64, arm, anycpu32bitpreferred,",
+                       "                            or anycpu (the default)",
                        "  /prod[uct]:<text>         Product name",
                        "  /productv[ersion]:<text>  Product version",
                        "  /t[arget]:lib[rary]       Create a library",
index 0597bdd7882fdd994391eadbe65c84ca58c0c181..09224b2f15be171f37d2107b293af76b76c47d38 100644 (file)
@@ -33,9 +33,16 @@ void sgen_bridge_describe_pointer (GCObject *object);
 gboolean sgen_is_bridge_object (GCObject *obj);
 void sgen_mark_bridge_object (GCObject *obj);
 
+gboolean sgen_bridge_handle_gc_param (const char *opt);
 gboolean sgen_bridge_handle_gc_debug (const char *opt);
 void sgen_bridge_print_gc_debug_usage (void);
 
+typedef struct {
+       char *dump_prefix;
+       gboolean accounting;
+       gboolean scc_precise_merge; // Used by Tarjan
+} SgenBridgeProcessorConfig;
+
 typedef struct {
        void (*reset_data) (void);
        void (*processing_stw_step) (void);
@@ -44,10 +51,9 @@ typedef struct {
        MonoGCBridgeObjectKind (*class_kind) (MonoClass *klass);
        void (*register_finalized_object) (GCObject *object);
        void (*describe_pointer) (GCObject *object);
-       void (*enable_accounting) (void);
 
-       // Optional-- used for debugging
-       void (*set_dump_prefix) (const char *prefix);
+       /* Should be called once, immediately after init */
+       void (*set_config) (const SgenBridgeProcessorConfig *);
 
        /*
         * These are set by processing_build_callback_data().
index 006e68c50121f32e9de1a776a9f164ead82907dd..7ec2d4386dfb5f4934169182128e402931b4f397 100644 (file)
@@ -33,6 +33,8 @@ typedef enum {
 static BridgeProcessorSelection bridge_processor_selection = BRIDGE_PROCESSOR_DEFAULT;
 // Most recently requested callbacks
 static MonoGCBridgeCallbacks pending_bridge_callbacks;
+// Configuration to be passed to bridge processor after init
+static SgenBridgeProcessorConfig bridge_processor_config;
 // Currently-in-use callbacks
 MonoGCBridgeCallbacks bridge_callbacks;
 
@@ -84,6 +86,12 @@ bridge_processor_name (const char *name)
        }
 }
 
+static gboolean
+bridge_processor_started ()
+{
+       return bridge_processor.reset_data != NULL;
+}
+
 // Initialize a single bridge processor
 static void
 init_bridge_processor (SgenBridgeProcessor *processor, BridgeProcessorSelection selection)
@@ -133,9 +141,17 @@ sgen_init_bridge ()
                bridge_callbacks = pending_bridge_callbacks;
 
                // If a bridge was registered but there is no bridge processor yet
-               if (bridge_callbacks.cross_references && !bridge_processor.reset_data)
+               if (bridge_callbacks.cross_references && !bridge_processor_started ()) {
                        init_bridge_processor (&bridge_processor, bridge_processor_selection);
 
+                       if (bridge_processor.set_config)
+                               bridge_processor.set_config (&bridge_processor_config);
+
+                       // Config is no longer needed so free its memory
+                       free (bridge_processor_config.dump_prefix);
+                       bridge_processor_config.dump_prefix = NULL;
+               }
+
                sgen_gc_unlock ();
        }
 }
@@ -147,7 +163,7 @@ sgen_set_bridge_implementation (const char *name)
 
        if (selection == BRIDGE_PROCESSOR_INVALID)
                g_warning ("Invalid value for bridge processor implementation, valid values are: 'new', 'old' and 'tarjan'.");
-       else if (bridge_processor.reset_data)
+       else if (bridge_processor_started ())
                g_warning ("Cannot set bridge processor implementation once bridge has already started");
        else
                bridge_processor_selection = selection;
@@ -480,12 +496,9 @@ sgen_bridge_describe_pointer (GCObject *obj)
 static void
 set_dump_prefix (const char *prefix)
 {
-       if (!bridge_processor.set_dump_prefix) {
-               fprintf (stderr, "Warning: Bridge implementation does not support dumping - ignoring.\n");
-               return;
-       }
-
-       bridge_processor.set_dump_prefix (prefix);
+       if (bridge_processor_config.dump_prefix)
+               free (bridge_processor_config.dump_prefix);
+       bridge_processor_config.dump_prefix = strdup (prefix);
 }
 
 /* Test support code */
@@ -652,22 +665,39 @@ register_test_bridge_callbacks (const char *bridge_class_name)
        mono_gc_register_bridge_callbacks (&callbacks);
 }
 
+gboolean
+sgen_bridge_handle_gc_param (const char *opt)
+{
+       g_assert (!bridge_processor_started ());
+
+       if (!strcmp (opt, "bridge-require-precise-merge")) {
+               bridge_processor_config.scc_precise_merge = TRUE;
+       } else {
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
 gboolean
 sgen_bridge_handle_gc_debug (const char *opt)
 {
+       g_assert (!bridge_processor_started ());
+
        if (g_str_has_prefix (opt, "bridge=")) {
                opt = strchr (opt, '=') + 1;
                register_test_bridge_callbacks (g_strdup (opt));
        } else if (!strcmp (opt, "enable-bridge-accounting")) {
-               bridge_processor.enable_accounting ();
+               bridge_processor_config.accounting = TRUE;
        } else if (g_str_has_prefix (opt, "bridge-dump=")) {
                char *prefix = strchr (opt, '=') + 1;
-               set_dump_prefix (prefix);
+               set_dump_prefix(prefix);
        } else if (g_str_has_prefix (opt, "bridge-compare-to=")) {
                const char *name = strchr (opt, '=') + 1;
                BridgeProcessorSelection selection = bridge_processor_name (name);
 
                if (selection != BRIDGE_PROCESSOR_INVALID) {
+                       // Compare processor doesn't get config
                        init_bridge_processor (&compare_to_bridge_processor, selection);
                } else {
                        g_warning ("Invalid bridge implementation to compare against - ignoring.");
index b11df8a17b5e39d83ef82e05e98ca52c5125cf87..a03b0a81bfd508c93bcc82afa65aa3ff6e4ae3da 100644 (file)
@@ -17,8 +17,8 @@
  * When SGen is done marking, it puts together a list of all dead bridged
  * objects.  This is passed to the bridge processor, which does an analysis to
  * simplify the graph: It replaces strongly-connected components with single
- * nodes, and then removes any nodes corresponding to components which do not
- * contain bridged objects.
+ * nodes, and may remove nodes corresponding to components which do not contain
+ * bridged objects.
  *
  * The output of the SCC analysis is passed to the client's `cross_references()`
  * callback.  This consists of 2 arrays, an array of SCCs (MonoGCBridgeSCC),
@@ -54,7 +54,7 @@
 MONO_BEGIN_DECLS
 
 enum {
-       SGEN_BRIDGE_VERSION = 4
+       SGEN_BRIDGE_VERSION = 5
 };
        
 typedef enum {
index 19265f57ef4bf84d41c97a2542253251a0cf2265..f80cc3603191c59483fa1f7e1e82702b6ac9898e 100644 (file)
@@ -2896,7 +2896,7 @@ sgen_client_handle_gc_param (const char *opt)
        } else if (g_str_has_prefix (opt, "toggleref-test")) {
                /* FIXME: This should probably in MONO_GC_DEBUG */
                sgen_register_test_toggleref_callback ();
-       } else {
+       } else if (!sgen_bridge_handle_gc_param (opt)) {
                return FALSE;
        }
        return TRUE;
index 4631c0c5430f2ec946931fee01fee5ae079a6ad7..501ceb76d5b8c5a987d26b28891e01ca701cdb53 100644 (file)
@@ -101,6 +101,8 @@ typedef struct _SCC {
 #endif
 } SCC;
 
+static char *dump_prefix = NULL;
+
 // Maps managed objects to corresponding HashEntry stricts
 static SgenHashTable hash_table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntry), mono_aligned_addr_hash, NULL);
 
@@ -161,11 +163,16 @@ dyn_array_int_contains (DynIntArray *da, int x)
 #endif
 
 static void
-enable_accounting (void)
+set_config (const SgenBridgeProcessorConfig *config)
 {
-       SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-       bridge_accounting_enabled = TRUE;
-       hash_table = table;
+       if (config->accounting) {
+               SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
+               bridge_accounting_enabled = TRUE;
+               hash_table = table;
+       }
+       if (config->dump_prefix) {
+               dump_prefix = strdup (config->dump_prefix);
+       }
 }
 
 static MonoGCBridgeObjectKind
@@ -604,8 +611,6 @@ reset_flags (SCC *scc)
 }
 #endif
 
-static char *dump_prefix = NULL;
-
 static void
 dump_graph (void)
 {
@@ -657,12 +662,6 @@ dump_graph (void)
        fclose (file);
 }
 
-static void
-set_dump_prefix (const char *prefix)
-{
-       dump_prefix = strdup (prefix);
-}
-
 static int
 compare_hash_entries (const HashEntry *e1, const HashEntry *e2)
 {
@@ -1087,8 +1086,7 @@ sgen_new_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
-       collector->set_dump_prefix = set_dump_prefix;
+       collector->set_config = set_config;
 
        bridge_processor = collector;
 }
index d33d5d86815d795db6168cf97b9e0f24b9c3f1ff..346e4b0aeb50a1aff3d8ada64bf8b2042898dd17 100644 (file)
@@ -372,11 +372,13 @@ dyn_array_int_merge_one (DynIntArray *array, int value)
 
 
 static void
-enable_accounting (void)
+set_config (const SgenBridgeProcessorConfig *config)
 {
-       SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-       bridge_accounting_enabled = TRUE;
-       hash_table = table;
+       if (config->accounting) {
+               SgenHashTable table = SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
+               bridge_accounting_enabled = TRUE;
+               hash_table = table;
+       }
 }
 
 static MonoGCBridgeObjectKind
@@ -922,7 +924,7 @@ sgen_old_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
+       collector->set_config = set_config;
 
        bridge_processor = collector;
 }
index 76c5ac64a90d1380e68f88e5e0f1b44f83a7481c..daa983e64ac61ce1a29d534c4f2785d872e5e3ce 100644 (file)
@@ -19,8 +19,6 @@
 
 #include "sgen/sgen-gc.h"
 #include "sgen-bridge-internals.h"
-#include "sgen/sgen-hash-table.h"
-#include "sgen/sgen-qsort.h"
 #include "tabledefs.h"
 #include "utils/mono-logger-internals.h"
 
  *     which colors. The color graph then becomes the reduced SCC graph.
  */
 
-static void
-enable_accounting (void)
-{
-       // bridge_accounting_enabled = TRUE;
-       // hash_table = (SgenHashTable)SGEN_HASH_TABLE_INIT (INTERNAL_MEM_BRIDGE_HASH_TABLE, INTERNAL_MEM_BRIDGE_HASH_TABLE_ENTRY, sizeof (HashEntryWithAccounting), mono_aligned_addr_hash, NULL);
-}
-
 // Is this class bridged or not, and should its dependencies be scanned or not?
 // The result of this callback will be cached for use by is_opaque_object later.
 static MonoGCBridgeObjectKind
@@ -83,6 +74,36 @@ class_kind (MonoClass *klass)
 //enable usage logging
 // #define DUMP_GRAPH 1
 
+/* Used in bridgeless_color_is_heavy:
+ * The idea here is as long as the reference fanin and fanout on a node are both 2 or greater, then
+ * removing that node will result in a net increase in edge count. So the question is which node
+ * removals are counterproductive (i.e., how many edges saved balances out one node added).
+ * The number of edges saved by preserving a node is (fanin*fanout - fanin - fanout).
+ *
+ * With all that in mind:
+ *
+ * - HEAVY_REFS_MIN is the number that *both* fanin and fanout must meet to preserve the node.
+ * - HEAVY_COMBINED_REFS_MIN is the number (fanin*fanout) must meet to preserve the node.
+ *
+ * Note HEAVY_COMBINED_REFS_MIN must be <= 2*INCOMING_COLORS_MAX, or we won't know the true fanin.
+ */
+
+#define HEAVY_REFS_MIN 2
+#define HEAVY_COMBINED_REFS_MIN 60
+
+/* Used in ColorData:
+ * The higher INCOMING_COLORS_BITS is the higher HEAVY_COMBINED_REFS_MIN can be (see above).
+ * However, API_INDEX_BITS + INCOMING_COLORS_BITS must be equal to 31, and if API_INDEX_BITS is too
+ * low then terrible things will happen if too many colors are generated. (The number of colors we
+ * will ever attempt to generate is currently naturally limited by the JNI GREF limit.)
+ */
+
+#define API_INDEX_BITS        26
+#define INCOMING_COLORS_BITS  5
+
+#define API_INDEX_MAX         ((1<<API_INDEX_BITS)-1)
+#define INCOMING_COLORS_MAX   ((1<<INCOMING_COLORS_BITS)-1)
+
 // ScanData state
 enum {
        INITIAL,
@@ -94,13 +115,17 @@ enum {
 /*
 Optimizations:
        We can split this data structure in two, those with bridges and those without
+       (and only bridgeless need to record incoming_colors)
 */
 typedef struct {
-    // Colors (ColorDatas) linked to by objects with this color
+       // Colors (ColorDatas) linked to by objects with this color
        DynPtrArray other_colors;
-    // Bridge objects (GCObjects) held by objects with this color
+       // Bridge objects (GCObjects) held by objects with this color
        DynPtrArray bridges;
-       int api_index    : 31;
+       // Index of this color's MonoGCBridgeSCC in the array passed to the client (or -1 for none)
+       signed api_index         : API_INDEX_BITS;
+       // Count of colors that list this color in their other_colors
+       unsigned incoming_colors : INCOMING_COLORS_BITS;
        unsigned visited : 1;
 } ColorData;
 
@@ -115,7 +140,7 @@ typedef struct _ScanData {
        // Tarjan algorithm index (order visited)
        int index;
        // Tarjan index of lowest-index object known reachable from here
-       int low_index : 27;
+       signed low_index : 27;
 
        // See "ScanData state" enum above
        unsigned state : 2;
@@ -124,7 +149,22 @@ typedef struct _ScanData {
        unsigned obj_state : 2;
 } ScanData;
 
+/* Should color be made visible to client even though it has no bridges?
+ * True if we predict the number of reduced edges to be enough to justify the extra node.
+ */
+static inline gboolean
+bridgeless_color_is_heavy (ColorData *data) {
+       int fanin = data->incoming_colors;
+       int fanout = dyn_array_ptr_size (&data->other_colors);
+       return fanin > HEAVY_REFS_MIN && fanout > HEAVY_REFS_MIN
+               && fanin*fanout >= HEAVY_COMBINED_REFS_MIN;
+}
 
+// Should color be made visible to client?
+static inline gboolean
+color_visible_to_client (ColorData *data) {
+       return dyn_array_ptr_size (&data->bridges) || bridgeless_color_is_heavy (data);
+}
 
 // Stacks of ScanData objects used for tarjan algorithm.
 // The Tarjan algorithm is normally defined recursively; here scan_stack simulates the call stack of a recursive algorithm,
@@ -134,12 +174,21 @@ static DynPtrArray scan_stack, loop_stack;
 // GCObjects on which register_finalized_object has been called
 static DynPtrArray registered_bridges;
 
-// ColorData objects
+// As we traverse the graph, which ColorData objects are accessible from our current position?
 static DynPtrArray color_merge_array;
+// Running hash of the contents of the color_merge_array.
+static unsigned int color_merge_array_hash;
+
+static void color_merge_array_empty ()
+{
+       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_hash = 0;
+}
 
 static int ignored_objects;
 static int object_index;
 static int num_colors_with_bridges;
+static int num_sccs;
 static int xref_count;
 
 static size_t setup_time, tarjan_time, scc_setup_time, gather_xref_time, xref_setup_time, cleanup_time;
@@ -161,6 +210,7 @@ static ObjectBucket *root_object_bucket;
 static ObjectBucket *cur_object_bucket;
 static int object_data_count;
 
+// Arenas to allocate ScanData from
 static ObjectBucket*
 new_object_bucket (void)
 {
@@ -213,7 +263,7 @@ free_object_buckets (void)
 //ColorData buckets
 #define NUM_COLOR_ENTRIES ((BUCKET_SIZE - SIZEOF_VOID_P * 2) / sizeof (ColorData))
 
-// Same as ObjectBucket except NUM_COLOR_ENTRIES and NUM_SCAN_ENTRIES differ
+// Arenas for ColorDatas, same as ObjectBucket except items-per-bucket differs
 typedef struct _ColorBucket ColorBucket;
 struct _ColorBucket {
        ColorBucket *next;
@@ -356,11 +406,13 @@ find_or_create_data (GCObject *obj)
 //----------
 typedef struct {
        ColorData *color;
-       int hash;
+       unsigned int hash;
 } HashEntry;
 
 /*
-We tried 2/32, 2/128, 4/32, 4/128, 6/128 and 8/128.
+The merge cache maps an ordered list of ColorDatas [the color_merge_array] to a single ColorData.
+
+About cache bucket tuning: We tried 2/32, 2/128, 4/32, 4/128, 6/128 and 8/128.
 
 The performance cost between 4/128 and 8/128 is so small since cache movement happens completely in the same cacheline,
 making the extra space pretty much free.
@@ -373,17 +425,39 @@ Memory wise, 4/32 takes 512 and 8/128 takes 8k, so it's quite reasonable.
 #define ELEMENTS_PER_BUCKET 8
 #define COLOR_CACHE_SIZE 128
 static HashEntry merge_cache [COLOR_CACHE_SIZE][ELEMENTS_PER_BUCKET];
+static unsigned int hash_perturb;
+
+// If true, disable an optimization where sometimes SCC nodes are merged without a perfect check
+static gboolean scc_precise_merge;
 
-static int
-mix_hash (size_t hash)
+static unsigned int
+mix_hash (uintptr_t source)
 {
-       return (int)(((hash * 215497) >> 16) ^ ((hash * 1823231) + hash));
+       unsigned int hash = source;
+
+       // The full hash determines whether two colors can be merged-- sometimes exclusively.
+       // This value changes every GC, so XORing it in before performing the hash will make the
+       // chance that two different colors will produce the same hash on successive GCs very low.
+       hash = hash ^ hash_perturb;
+
+       // Actual hash
+       hash = (((hash * 215497) >> 16) ^ ((hash * 1823231) + hash));
+
+       // Mix in highest bits on 64-bit systems only
+       if (sizeof (source) > 4)
+               hash = hash ^ (source >> 32);
+
+       return hash;
 }
 
 static void
 reset_cache (void)
 {
        memset (merge_cache, 0, sizeof (merge_cache));
+
+       // When using the precise merge debug option, we do not want the inconsistency caused by hash_perturb.
+       if (!scc_precise_merge)
+               ++hash_perturb;
 }
 
 
@@ -397,6 +471,13 @@ dyn_array_ptr_contains (DynPtrArray *da, void *x)
        return FALSE;
 }
 
+static gboolean
+match_colors_estimate (DynPtrArray *a, DynPtrArray *b)
+{
+       return dyn_array_ptr_size (a) == dyn_array_ptr_size (b);
+}
+
+
 static gboolean
 match_colors (DynPtrArray *a, DynPtrArray *b)
 {
@@ -411,23 +492,36 @@ match_colors (DynPtrArray *a, DynPtrArray *b)
        return TRUE;
 }
 
-static int cache_hits, cache_misses;
+// If scc_precise_merge, "semihits" refers to find_in_cache calls aborted because the merge array was too large.
+// Otherwise "semihits" refers to cache hits where the match was only estimated.
+static int cache_hits, cache_semihits, cache_misses;
 
+// The cache contains only non-bridged colors.
 static ColorData*
 find_in_cache (int *insert_index)
 {
        HashEntry *bucket;
-       int i, hash, size, index;
+       int i, size, index;
 
        size = dyn_array_ptr_size (&color_merge_array);
-       /* Cache checking is very ineficient with a lot of elements*/
-       if (size > 3)
+
+       /* Color equality checking is very expensive with a lot of elements, so when there are many
+        * elements we switch to a cheap comparison method which allows false positives. When false
+        * positives occur the worst that can happen is two items will be inappropriately merged
+        * and memory will be retained longer than it should be. We assume that will correct itself
+        * on the next GC (the hash_perturb mechanism increases the probability of this).
+        *
+        * Because this has *some* potential to create problems, if the user set the debug option
+        * 'enable-tarjan-precise-merge' we bail out early (and never merge SCCs with >3 colors).
+        */
+       gboolean color_merge_array_large = size > 3;
+       if (scc_precise_merge && color_merge_array_large) {
+               ++cache_semihits;
                return NULL;
+       }
 
-       hash = 0;
-       for (i = 0 ; i < size; ++i)
-               hash += mix_hash ((size_t)dyn_array_ptr_get (&color_merge_array, i));
-       if (!hash)
+       unsigned int hash = color_merge_array_hash;
+       if (!hash) // 0 is used to indicate an empty bucket entry
                hash = 1;
 
        index = hash & (COLOR_CACHE_SIZE - 1);
@@ -435,9 +529,17 @@ find_in_cache (int *insert_index)
        for (i = 0; i < ELEMENTS_PER_BUCKET; ++i) {
                if (bucket [i].hash != hash)
                        continue;
-               if (match_colors (&bucket [i].color->other_colors, &color_merge_array)) {
-                       ++cache_hits;
-                       return bucket [i].color;
+
+               if (color_merge_array_large) {
+                       if (match_colors_estimate (&bucket [i].color->other_colors, &color_merge_array)) {
+                               ++cache_semihits;
+                               return bucket [i].color;
+                       }
+               } else {
+                       if (match_colors (&bucket [i].color->other_colors, &color_merge_array)) {
+                               ++cache_hits;
+                               return bucket [i].color;
+                       }
                }
        }
 
@@ -450,14 +552,16 @@ find_in_cache (int *insert_index)
        return NULL;
 }
 
+// A color is needed for an SCC. If the SCC has bridges, the color MUST be newly allocated.
+// If the SCC lacks bridges, the allocator MAY use the cache to merge it with an existing one.
 static ColorData*
-new_color (gboolean force_new)
+new_color (gboolean has_bridges)
 {
-       int i = -1;
+       int cacheSlot = -1;
        ColorData *cd;
        /* XXX Try to find an equal one and return it */
-       if (!force_new) {
-               cd = find_in_cache (&i);
+       if (!has_bridges) {
+               cd = find_in_cache (&cacheSlot);
                if (cd)
                        return cd;
        }
@@ -465,9 +569,16 @@ new_color (gboolean force_new)
        cd = alloc_color_data ();
        cd->api_index = -1;
        dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
-       /* if i >= 0, it means we prepared a given slot to receive the new color */
-       if (i >= 0)
-               merge_cache [i][0].color = cd;
+
+       // Inform targets
+       for (int i = 0; i < dyn_array_ptr_size (&color_merge_array); ++i) {
+               ColorData *points_to = (ColorData *)dyn_array_ptr_get (&color_merge_array, i);
+               points_to->incoming_colors = MIN (points_to->incoming_colors + 1, INCOMING_COLORS_MAX);
+       }
+
+       /* if cacheSlot >= 0, it means we prepared a given slot to receive the new color */
+       if (cacheSlot >= 0)
+               merge_cache [cacheSlot][0].color = cd;
 
        return cd;
 }
@@ -587,6 +698,7 @@ compute_low_index (ScanData *data, GCObject *obj)
 
        cd = other->color;
        if (!cd->visited) {
+               color_merge_array_hash += mix_hash ((uintptr_t) other->color);
                dyn_array_ptr_add (&color_merge_array, other->color);
                cd->visited = TRUE;
        }
@@ -608,16 +720,24 @@ compute_low (ScanData *data)
        #include "sgen/sgen-scan-object.h"
 }
 
+// A non-bridged object needs a single color describing the current merge array.
 static ColorData*
 reduce_color (void)
 {
        ColorData *color = NULL;
        int size = dyn_array_ptr_size (&color_merge_array);
 
+       // Merge array is empty-- this SCC points to no bridged colors.
+       // This SCC can be ignored completely.
        if (size == 0)
                color = NULL;
+
+       // Merge array has one item-- this SCC points to a single bridged color.
+       // This SCC can be forwarded to the pointed-to color.
        else if (size == 1) {
                color = (ColorData *)dyn_array_ptr_get (&color_merge_array, 0);
+
+       // This SCC gets to talk to the color allocator.
        } else
                color = new_color (FALSE);
 
@@ -694,7 +814,7 @@ create_scc (ScanData *data)
                g_assert (cd->visited);
                cd->visited = FALSE;
        }
-       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_empty ();
        found_bridge = FALSE;
 }
 
@@ -704,7 +824,7 @@ dfs (void)
        g_assert (dyn_array_ptr_size (&scan_stack) == 1);
        g_assert (dyn_array_ptr_size (&loop_stack) == 0);
 
-       dyn_array_ptr_empty (&color_merge_array);
+       color_merge_array_empty ();
 
        while (dyn_array_ptr_size (&scan_stack) > 0) {
                ScanData *data = (ScanData *)dyn_array_ptr_pop (&scan_stack);
@@ -891,7 +1011,7 @@ gather_xrefs (ColorData *color)
                if (src->visited)
                        continue;
                src->visited = TRUE;
-               if (dyn_array_ptr_size (&src->bridges))
+               if (color_visible_to_client (src))
                        dyn_array_ptr_add (&color_merge_array, src);
                else
                        gather_xrefs (src);
@@ -907,7 +1027,7 @@ reset_xrefs (ColorData *color)
                if (!src->visited)
                        continue;
                src->visited = FALSE;
-               if (!dyn_array_ptr_size (&src->bridges))
+               if (!color_visible_to_client (src))
                        reset_xrefs (src);
        }
 }
@@ -915,9 +1035,7 @@ reset_xrefs (ColorData *color)
 static void
 processing_build_callback_data (int generation)
 {
-       int j, api_index;
-       MonoGCBridgeSCC **api_sccs;
-       MonoGCBridgeXRef *api_xrefs;
+       int j;
        gint64 curtime;
        ColorBucket *cur;
 
@@ -936,15 +1054,27 @@ processing_build_callback_data (int generation)
        printf ("number of SCCs %d\n", num_colors_with_bridges);
 #endif
 
+       // Count the number of SCCs visible to the client
+       num_sccs = 0;
+       for (cur = root_color_bucket; cur; cur = cur->next) {
+               ColorData *cd;
+               for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
+                       if (color_visible_to_client (cd))
+                               num_sccs++;
+               }
+       }
+
        /* This is a straightforward translation from colors to the bridge callback format. */
-       api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_colors_with_bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE);
-       api_index = xref_count = 0;
+       MonoGCBridgeSCC **api_sccs = (MonoGCBridgeSCC **)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC*) * num_sccs, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+       int api_index = 0;
+       xref_count = 0;
 
+       // Convert visible SCCs, along with their bridged object list, to MonoGCBridgeSCCs in the client's SCC list
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *cd;
                for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
                        int bridges = dyn_array_ptr_size (&cd->bridges);
-                       if (!bridges)
+                       if (!(bridges || bridgeless_color_is_heavy (cd)))
                                continue;
 
                        api_sccs [api_index] = (MonoGCBridgeSCC *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeSCC) + sizeof (MonoObject*) * bridges, INTERNAL_MEM_BRIDGE_DATA, TRUE);
@@ -955,20 +1085,22 @@ processing_build_callback_data (int generation)
 
                        for (j = 0; j < bridges; ++j)
                                api_sccs [api_index]->objs [j] = (MonoObject *)dyn_array_ptr_get (&cd->bridges, j);
+
+                       g_assert(api_index < API_INDEX_MAX);
                        api_index++;
                }
        }
 
        scc_setup_time = step_timer (&curtime);
 
+       // Eliminate non-visible SCCs from the SCC list and redistribute xrefs
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *cd;
                for (cd = &cur->data [0]; cd < cur->next_data; ++cd) {
-                       int bridges = dyn_array_ptr_size (&cd->bridges);
-                       if (!bridges)
+                       if (!color_visible_to_client (cd))
                                continue;
 
-                       dyn_array_ptr_empty (&color_merge_array);
+                       color_merge_array_empty ();
                        gather_xrefs (cd);
                        reset_xrefs (cd);
                        dyn_array_ptr_set_all (&cd->other_colors, &color_merge_array);
@@ -983,27 +1115,28 @@ processing_build_callback_data (int generation)
        dump_color_table (" after xref pass", TRUE);
 #endif
 
-       api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE);
-       api_index = 0;
+       // Write out xrefs array
+       MonoGCBridgeXRef *api_xrefs = (MonoGCBridgeXRef *)sgen_alloc_internal_dynamic (sizeof (MonoGCBridgeXRef) * xref_count, INTERNAL_MEM_BRIDGE_DATA, TRUE);
+       int xref_index = 0;
        for (cur = root_color_bucket; cur; cur = cur->next) {
                ColorData *src;
                for (src = &cur->data [0]; src < cur->next_data; ++src) {
-                       int bridges = dyn_array_ptr_size (&src->bridges);
-                       if (!bridges)
+                       if (!color_visible_to_client (src))
                                continue;
 
                        for (j = 0; j < dyn_array_ptr_size (&src->other_colors); ++j) {
                                ColorData *dest = (ColorData *)dyn_array_ptr_get (&src->other_colors, j);
-                               g_assert (dyn_array_ptr_size (&dest->bridges)); /* We flattened the color graph, so this must never happen. */
+                               g_assert (color_visible_to_client (dest)); /* Supposedly we already eliminated all xrefs to non-visible objects. */
+
+                               api_xrefs [xref_index].src_scc_index = src->api_index;
+                               api_xrefs [xref_index].dst_scc_index = dest->api_index;
 
-                               api_xrefs [api_index].src_scc_index = src->api_index;
-                               api_xrefs [api_index].dst_scc_index = dest->api_index;
-                               ++api_index;
+                               ++xref_index;
                        }
                }
        }
 
-       g_assert (xref_count == api_index);
+       g_assert (xref_count == xref_index);
        xref_setup_time = step_timer (&curtime);
 
 #if defined (DUMP_GRAPH)
@@ -1013,7 +1146,7 @@ processing_build_callback_data (int generation)
 #endif
 
        //FIXME move half of the cleanup to before the bridge callback?
-       bridge_processor->num_sccs = num_colors_with_bridges;
+       bridge_processor->num_sccs = num_sccs;
        bridge_processor->api_sccs = api_sccs;
        bridge_processor->num_xrefs = xref_count;
        bridge_processor->api_xrefs = api_xrefs;
@@ -1026,7 +1159,7 @@ processing_after_callback (int generation)
        int bridge_count = dyn_array_ptr_size (&registered_bridges);
        int object_count = object_data_count;
        int color_count = color_data_count;
-       int scc_count = num_colors_with_bridges;
+       int colors_with_bridges_count = num_colors_with_bridges;
 
        SGEN_TV_GETTIME (curtime);
 
@@ -1035,10 +1168,10 @@ processing_after_callback (int generation)
 
        cleanup_time = step_timer (&curtime);
 
-       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_TAR_BRIDGE bridges %d objects %d colors %d ignored %d sccs %d xref %d cache %d/%d setup %.2fms tarjan %.2fms scc-setup %.2fms gather-xref %.2fms xref-setup %.2fms cleanup %.2fms",
-               bridge_count, object_count, color_count,
-               ignored_objects, scc_count, xref_count,
-               cache_hits, cache_misses,
+       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_GC, "GC_TAR_BRIDGE bridges %d objects %d opaque %d colors %d colors-bridged %d colors-visible %d xref %d cache-hit %d cache-%s %d cache-miss %d setup %.2fms tarjan %.2fms scc-setup %.2fms gather-xref %.2fms xref-setup %.2fms cleanup %.2fms",
+               bridge_count, object_count, ignored_objects,
+               color_count, colors_with_bridges_count, num_sccs, xref_count,
+               cache_hits, (scc_precise_merge ? "abstain" : "semihit"), cache_semihits, cache_misses,
                setup_time / 10000.0f,
                tarjan_time / 10000.0f,
                scc_setup_time / 10000.0f,
@@ -1046,7 +1179,7 @@ processing_after_callback (int generation)
                xref_setup_time / 10000.0f,
                cleanup_time / 10000.0f);
 
-       cache_hits = cache_misses = 0;
+       cache_hits = cache_semihits = cache_misses = 0;
        ignored_objects = 0;
 }
 
@@ -1072,6 +1205,15 @@ describe_pointer (GCObject *obj)
        // printf ("  is visited: %d\n", (int)entry->is_visited);
 }
 
+static void
+set_config (const SgenBridgeProcessorConfig *config)
+{
+       if (config->scc_precise_merge) {
+               hash_perturb = 0;
+               scc_precise_merge = TRUE;
+       }
+}
+
 void
 sgen_tarjan_bridge_init (SgenBridgeProcessor *collector)
 {
@@ -1082,12 +1224,12 @@ sgen_tarjan_bridge_init (SgenBridgeProcessor *collector)
        collector->class_kind = class_kind;
        collector->register_finalized_object = register_finalized_object;
        collector->describe_pointer = describe_pointer;
-       collector->enable_accounting = enable_accounting;
-       // collector->set_dump_prefix = set_dump_prefix;
+       collector->set_config = set_config;
 
        sgen_register_fixed_internal_mem_type (INTERNAL_MEM_TARJAN_OBJ_BUCKET, BUCKET_SIZE);
        g_assert (sizeof (ObjectBucket) <= BUCKET_SIZE);
        g_assert (sizeof (ColorBucket) <= BUCKET_SIZE);
+       g_assert (API_INDEX_BITS + INCOMING_COLORS_BITS <= 31);
        bridge_processor = collector;
 }
 
index 5a662802771d12efd3ba67f4087f63585654f876..f9a0d5adc8bdfa90c778cbc613c58ecf6d0f4fc0 100644 (file)
@@ -33,7 +33,7 @@
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-tls.h>
-#include <mono/utils/mono-hwcap-x86.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "trace.h"
index 6983398027a5b2bb2e37143c455dceb3db0635cc..7b2e1fa7b48e2438c7e85deeb87108be375a6936 100644 (file)
@@ -18,7 +18,7 @@
 #include <mono/metadata/profiler-private.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-arm.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-threads-coop.h>
 
index d88a6c99a8f362bb690424ace4462d58f3d913d9..357e260799833ed8d4a1bf415c148853bf610e39 100644 (file)
@@ -21,7 +21,7 @@
 #include <mono/metadata/threads.h>
 #include <mono/metadata/profiler-private.h>
 #include <mono/utils/mono-math.h>
-#include <mono/utils/mono-hwcap-ia64.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "trace.h"
 #include "mini-ia64.h"
index 5d6ebc7b6bc126975df54bdc38c29d247d5ca8d0..783896f15681743acb6001dad302705db271bee9 100644 (file)
@@ -19,7 +19,7 @@
 #include <mono/metadata/appdomain.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-mips.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include <mono/arch/mips/mips-codegen.h>
 
index 3089a8546b1d3a4d605535a775c1f57d27eb793f..7d2c0d8b8cfda73cacd3b6847b37f7c5dd523da4 100644 (file)
@@ -17,7 +17,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/utils/mono-proclib.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-ppc.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "mini-ppc.h"
 #ifdef TARGET_POWERPC64
index 3fe40d2cfc28fdd8a055b003ad58785d5cbd3427..a1094afa173fbe0baeb75c2ff221e0e9b73ae7e9 100644 (file)
@@ -268,7 +268,7 @@ if (ins->inst_target_bb->native_offset) {                                   \
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-mmap.h>
-#include <mono/utils/mono-hwcap-s390x.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "mini-s390x.h"
@@ -399,8 +399,6 @@ pthread_key_t lmf_addr_key;
 
 gboolean lmf_addr_key_inited = FALSE; 
 
-facilityList_t facs;
-
 /*
  * The code generated for sequence points reads from this location, 
  * which is made read-only when single stepping is enabled.
@@ -4370,7 +4368,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_ICONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlfbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                s390_llgfr (code, s390_r0, ins->sreg1);
@@ -4379,7 +4377,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                        break;
                case OP_LCONV_TO_R_UN: {
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_cdlgbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                short int *jump;
@@ -4416,7 +4414,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U1:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_lghi  (code, s390_r0, 0xff);
                                s390_ngr   (code, ins->dreg, s390_r0);
@@ -4433,7 +4431,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_ngr   (code, ins->dreg, s390_r0);
                        break;
                case OP_FCONV_TO_U2:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                                s390_llill  (code, s390_r0, 0xffff);
                                s390_ngr    (code, ins->dreg, s390_r0);
@@ -4447,7 +4445,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_FCONV_TO_U4:
                case OP_FCONV_TO_U:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clfdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
@@ -4457,7 +4455,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_cgdbr (code, ins->dreg, 5, ins->sreg1);
                        break;
                case OP_FCONV_TO_U8:
-                       if (facs.fpe) {
+                       if (mono_hwcap_s390x_has_fpe) {
                                s390_clgdbr (code, ins->dreg, 5, ins->sreg1, 0);
                        } else {
                                code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 8, FALSE);
@@ -7077,7 +7075,7 @@ mono_arch_cpu_enumerate_simd_versions (void)
 {
        guint32 sseOpts = 0;
 
-       if (facs.vec != 0) 
+       if (mono_hwcap_s390x_has_vec)
                sseOpts = (SIMD_VERSION_SSE1  | SIMD_VERSION_SSE2 |
                           SIMD_VERSION_SSE3  | SIMD_VERSION_SSSE3 |
                           SIMD_VERSION_SSE41 | SIMD_VERSION_SSE42 |
index 022f8a5e790b8ea9334d4fa61bb7f92c99229c9f..5003bfe025403fa2d02c9709b18d04fa2e26b491 100644 (file)
@@ -28,7 +28,7 @@
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/tokentype.h>
 #include <mono/utils/mono-math.h>
-#include <mono/utils/mono-hwcap-sparc.h>
+#include <mono/utils/mono-hwcap.h>
 
 #include "mini-sparc.h"
 #include "trace.h"
index 9e1702be17c8e32286f5233e2423a4740d2b59ec..288af652434bf9ffc25e4ad0893d5087409de286 100644 (file)
@@ -29,7 +29,7 @@
 #include <mono/utils/mono-counters.h>
 #include <mono/utils/mono-mmap.h>
 #include <mono/utils/mono-memory-model.h>
-#include <mono/utils/mono-hwcap-x86.h>
+#include <mono/utils/mono-hwcap.h>
 #include <mono/utils/mono-threads.h>
 
 #include "trace.h"
index 68fc0a5d0603301897fe4cbad95de05495156d25..7c8dbc087311677c159a0f3b86b57f8e6d62ef6f 100644 (file)
@@ -111,13 +111,29 @@ class Driver {
                var heads = new Bridge [FAN_OUT];
                for (int i = 0; i < FAN_OUT; ++i)
                        heads [i] = new Bridge ();
-               var multiplexer = new Bridge [FAN_OUT];
-               for (int i = 0; i < FAN_OUT; ++i)
-               {
-                       heads [i].Links.Add (multiplexer);
-                       multiplexer [i] = new Bridge ();
+
+               // We make five identical multiplexers to verify Tarjan-bridge can merge them together correctly.
+               var MULTIPLEXER_COUNT = 5;
+               Bridge[] multiplexer0 = null;
+               for(int m = 0; m < MULTIPLEXER_COUNT; m++) {
+                       var multiplexer = new Bridge [FAN_OUT];
+                       if (m == 0) {
+                               multiplexer0 = multiplexer;
+                               for (int i = 0; i < FAN_OUT; ++i)
+                               {
+                                       heads [i].Links.Add (multiplexer);
+                                       multiplexer [i] = new Bridge ();
+                               }
+                       } else {
+                               for (int i = 0; i < FAN_OUT; ++i)
+                               {
+                                       heads [i].Links.Add (multiplexer);
+                                       multiplexer [i] = multiplexer0 [i];
+                               }
+                       }
                }
-               Console.WriteLine ("-double fan done-");
+
+               Console.WriteLine ("-double fan x5 done-");
        }
 
        /*
index 2e873cde79844c8793f096b5913a5cc854e28103..d67b9ff1fed2bb89a6a5697356203fd73b123b95 100644 (file)
@@ -130,6 +130,7 @@ monoutils_sources = \
        atomic.c        \
        mono-hwcap.h    \
        mono-hwcap.c    \
+       mono-hwcap-vars.h       \
        bsearch.h       \
        bsearch.c       \
        mono-signal-handler.h   \
@@ -182,48 +183,56 @@ arch_sources += mach-support-unknown.c
 
 endif
 
+if !CROSS_COMPILE
+
 if X86
-arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
+arch_sources += mono-hwcap-x86.c
 endif
 
 if AMD64
-arch_sources += mono-hwcap-x86.c mono-hwcap-x86.h
+arch_sources += mono-hwcap-x86.c
 endif
 
 if ARM
-arch_sources += mono-hwcap-arm.c mono-hwcap-arm.h
+arch_sources += mono-hwcap-arm.c
 endif
 
 if ARM64
-arch_sources += mono-hwcap-arm64.c mono-hwcap-arm64.h
+arch_sources += mono-hwcap-arm64.c
 endif
 
 if MIPS
-arch_sources += mono-hwcap-mips.c mono-hwcap-mips.h
+arch_sources += mono-hwcap-mips.c
 endif
 
 if POWERPC
-arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
+arch_sources += mono-hwcap-ppc.c
 endif
 
 if POWERPC64
-arch_sources += mono-hwcap-ppc.c mono-hwcap-ppc.h
+arch_sources += mono-hwcap-ppc.c
 endif
 
 if SPARC
-arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
+arch_sources += mono-hwcap-sparc.c
 endif
 
 if SPARC64
-arch_sources += mono-hwcap-sparc.c mono-hwcap-sparc.h
+arch_sources += mono-hwcap-sparc.c
 endif
 
 if IA64
-arch_sources += mono-hwcap-ia64.c mono-hwcap-ia64.h
+arch_sources += mono-hwcap-ia64.c
 endif
 
 if S390X
-arch_sources += mono-hwcap-s390x.c mono-hwcap-s390x.h
+arch_sources += mono-hwcap-s390x.c
+endif
+
+else
+
+arch_sources += mono-hwcap-cross.c
+
 endif
 
 libmonoutils_la_SOURCES = $(monoutils_sources) $(arch_sources)
index 758c3dc6fc2651487fc8cc87fcd97714f1882d13..e51387776b93ed25d0c69b83d1abdd1d77d9b7f9 100644 (file)
@@ -19,7 +19,7 @@
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-arm.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(HAVE_SYS_AUXV_H) && !defined(PLATFORM_ANDROID)
 #include <sys/auxv.h>
 #include <stdio.h>
 #endif
 
-gboolean mono_hwcap_arm_is_v5 = FALSE;
-gboolean mono_hwcap_arm_is_v6 = FALSE;
-gboolean mono_hwcap_arm_is_v7 = FALSE;
-gboolean mono_hwcap_arm_has_vfp = FALSE;
-gboolean mono_hwcap_arm_has_vfp3 = FALSE;
-gboolean mono_hwcap_arm_has_vfp3_d16 = FALSE;
-gboolean mono_hwcap_arm_has_thumb = FALSE;
-gboolean mono_hwcap_arm_has_thumb2 = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
@@ -202,16 +193,3 @@ mono_hwcap_arch_init (void)
        }
 #endif
 }
-
-void
-mono_hwcap_print(FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_arm_is_v5 = %i\n", mono_hwcap_arm_is_v5);
-       g_fprintf (f, "mono_hwcap_arm_is_v6 = %i\n", mono_hwcap_arm_is_v6);
-       g_fprintf (f, "mono_hwcap_arm_is_v7 = %i\n", mono_hwcap_arm_is_v7);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp = %i\n", mono_hwcap_arm_has_vfp);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp3 = %i\n", mono_hwcap_arm_has_vfp3);
-       g_fprintf (f, "mono_hwcap_arm_has_vfp3_d16 = %i\n", mono_hwcap_arm_has_vfp3_d16);
-       g_fprintf (f, "mono_hwcap_arm_has_thumb = %i\n", mono_hwcap_arm_has_thumb);
-       g_fprintf (f, "mono_hwcap_arm_has_thumb2 = %i\n", mono_hwcap_arm_has_thumb2);
-}
diff --git a/mono/utils/mono-hwcap-arm.h b/mono/utils/mono-hwcap-arm.h
deleted file mode 100644 (file)
index 29adf7b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_ARM_H__
-#define __MONO_UTILS_HWCAP_ARM_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_arm_is_v5;
-extern gboolean mono_hwcap_arm_is_v6;
-extern gboolean mono_hwcap_arm_is_v7;
-extern gboolean mono_hwcap_arm_has_vfp;
-extern gboolean mono_hwcap_arm_has_vfp3;
-extern gboolean mono_hwcap_arm_has_vfp3_d16;
-extern gboolean mono_hwcap_arm_has_thumb;
-extern gboolean mono_hwcap_arm_has_thumb2;
-
-#endif /* __MONO_UTILS_HWCAP_ARM_H__ */
index 5491cff96cfd60ec93560dee66aa7343c11c5803..f541ea3df2bebc78f42295ad212f739f63f1982f 100644 (file)
@@ -1,25 +1,13 @@
 /*
- * mono-hwcap-arm64.c: ARM hardware feature detection
+ * mono-hwcap-arm64.c: ARM64 hardware feature detection
  *
  * Copyright 2013 Xamarin Inc
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-arm64.h"
+#include "mono/utils/mono-hwcap.h"
 
-#if defined(MONO_CROSS_COMPILE)
 void
 mono_hwcap_arch_init (void)
 {
 }
-#else
-void
-mono_hwcap_arch_init (void)
-{
-}
-#endif
-
-void
-mono_hwcap_print(FILE *f)
-{
-}
diff --git a/mono/utils/mono-hwcap-arm64.h b/mono/utils/mono-hwcap-arm64.h
deleted file mode 100644 (file)
index 2d41209..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_ARM64_H__
-#define __MONO_UTILS_HWCAP_ARM64_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-#endif
diff --git a/mono/utils/mono-hwcap-cross.c b/mono/utils/mono-hwcap-cross.c
new file mode 100644 (file)
index 0000000..4311a99
--- /dev/null
@@ -0,0 +1,16 @@
+/*
+ * mono-hwcap-cross.c: No-op hardware feature detection
+ *
+ * Author:
+ *  Alex Rønne Petersen (alexrp@xamarin.com)
+ *
+ * Copyright 2015 Xamarin, Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ */
+
+#include "mono/utils/mono-hwcap.h"
+
+void
+mono_hwcap_arch_init (void)
+{
+}
index b5979862208a32a61fc594f5b150a183f225df6d..dd1edbd8d40dcb6d79e62325a157d585845ddd6c 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-ia64.h"
+#include "mono/utils/mono-hwcap.h"
 
 void
 mono_hwcap_arch_init (void)
-{
-       /* Nothing needed here yet. */
-}
-
-void
-mono_hwcap_print (FILE *f)
 {
 }
diff --git a/mono/utils/mono-hwcap-ia64.h b/mono/utils/mono-hwcap-ia64.h
deleted file mode 100644 (file)
index 15b64a8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_IA64_H__
-#define __MONO_UTILS_HWCAP_IA64_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-/* Nothing needed here yet. */
-
-#endif /* __MONO_UTILS_HWCAP_IA64_H__ */
index 6d809a79ac54cf488c61faf587a0f5a5d3e50196..119f930a685a4d0915736d14f4d623b4291deca8 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-mips.h"
+#include "mono/utils/mono-hwcap.h"
 
 void
 mono_hwcap_arch_init (void)
-{
-       /* Nothing needed here yet. */
-}
-
-void
-mono_hwcap_print (FILE *f)
 {
 }
diff --git a/mono/utils/mono-hwcap-mips.h b/mono/utils/mono-hwcap-mips.h
deleted file mode 100644 (file)
index dd0622a..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_MIPS_H__
-#define __MONO_UTILS_HWCAP_MIPS_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-/* Nothing needed here yet. */
-
-#endif /* __MONO_UTILS_HWCAP_MIPS_H__ */
index 174cc620a202c7af27d8012b11075f09d78d93ed..af36c4d5473191c740746c83b47b726e4ddc0524 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-ppc.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(__linux__) && defined(HAVE_SYS_AUXV_H)
 #include <string.h>
 #include <sys/auxv.h>
 #endif
 
-gboolean mono_hwcap_ppc_has_icache_snoop = FALSE;
-gboolean mono_hwcap_ppc_is_isa_2x = FALSE;
-gboolean mono_hwcap_ppc_is_isa_64 = FALSE;
-gboolean mono_hwcap_ppc_has_move_fpr_gpr = FALSE;
-gboolean mono_hwcap_ppc_has_multiple_ls_units = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
@@ -66,13 +60,3 @@ mono_hwcap_arch_init (void)
        }
 #endif
 }
-
-void
-mono_hwcap_print (FILE* f)
-{
-       g_fprintf (f, "mono_hwcap_ppc_has_icache_snoop = %i\n", mono_hwcap_ppc_has_icache_snoop);
-       g_fprintf (f, "mono_hwcap_ppc_is_isa_2x = %i\n", mono_hwcap_ppc_is_isa_2x);
-       g_fprintf (f, "mono_hwcap_ppc_is_isa_64 = %i\n", mono_hwcap_ppc_is_isa_64);
-       g_fprintf (f, "mono_hwcap_ppc_has_move_fpr_gpr = %i\n", mono_hwcap_ppc_has_move_fpr_gpr);
-       g_fprintf (f, "mono_hwcap_ppc_has_multiple_ls_units = %i\n", mono_hwcap_ppc_has_multiple_ls_units);
-}
diff --git a/mono/utils/mono-hwcap-ppc.h b/mono/utils/mono-hwcap-ppc.h
deleted file mode 100644 (file)
index 0ae2578..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_PPC_H__
-#define __MONO_UTILS_HWCAP_PPC_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_ppc_has_icache_snoop;
-extern gboolean mono_hwcap_ppc_is_isa_2x;
-extern gboolean mono_hwcap_ppc_is_isa_64;
-extern gboolean mono_hwcap_ppc_has_move_fpr_gpr;
-extern gboolean mono_hwcap_ppc_has_multiple_ls_units;
-
-#endif /* __MONO_UTILS_HWCAP_PPC_H__ */
index 19a7fba11017251a55864c39a93fa94ff5b5b2de..c578a620d925d87eca46a3709d5df296c5570654 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-s390x.h"
+#include "mono/utils/mono-hwcap.h"
+
 #include <signal.h>
 
-facilityList_t facs;
+typedef struct {
+       uint8_t n3:1;           // 000 - N3 instructions
+       uint8_t zi:1;           // 001 - z/Arch installed
+       uint8_t za:1;           // 002 - z/Arch active
+       uint8_t date:1;         // 003 - DAT-enhancement
+       uint8_t idtes:1;        // 004 - IDTE-segment tables
+       uint8_t idter:1;        // 005 - IDTE-region tables
+       uint8_t asnlx:1;        // 006 - ASN-LX reuse
+       uint8_t stfle:1;        // 007 - STFLE
+       uint8_t edat1:1;        // 008 - EDAT 1
+       uint8_t srs:1;          // 009 - Sense-Running-Status
+       uint8_t csske:1;        // 010 - Conditional SSKE
+       uint8_t ctf:1;          // 011 - Configuration-topology
+       uint8_t ibm01:1;        // 012 - Assigned to IBM
+       uint8_t ipter:1;        // 013 - IPTE-range
+       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
+       uint8_t ibm02:1;        // 015 - Assigned to IBM
+       uint8_t etf2:1;         // 016 - Extended translation 2
+       uint8_t msa:1;          // 017 - Message security assist 1
+       uint8_t ld:1;           // 018 - Long displacement
+       uint8_t ldh:1;          // 019 - Long displacement high perf
+       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
+       uint8_t eif:1;          // 021 - Extended immediate
+       uint8_t etf3:1;         // 022 - Extended translation 3
+       uint8_t hux:1;          // 023 - HFP unnormalized extension
+       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
+       uint8_t stckf:1;        // 025 - Store clock fast
+       uint8_t pe:1;           // 026 - Parsing enhancement
+       uint8_t mvcos:1;        // 027 - Move with optional specs
+       uint8_t tods:1;         // 028 - TOD steering
+       uint8_t x000:1;         // 029 - Undefined
+       uint8_t etf3e:1;        // 030 - ETF3 enhancement
+       uint8_t ecput:1;        // 031 - Extract CPU time
+       uint8_t csst:1;         // 032 - Compare swap and store
+       uint8_t csst2:1;        // 033 - Compare swap and store 2
+       uint8_t gie:1;          // 034 - General instructions extension
+       uint8_t ee:1;           // 035 - Execute extensions
+       uint8_t em:1;           // 036 - Enhanced monitor
+       uint8_t fpe:1;          // 037 - Floating point extension
+       uint8_t x001:1;         // 038 - Undefined
+       uint8_t ibm03:1;        // 039 - Assigned to IBM
+       uint8_t spp:1;          // 040 - Set program parameters
+       uint8_t fpse:1;         // 041 - FP support enhancement
+       uint8_t dfp:1;          // 042 - DFP
+       uint8_t dfph:1;         // 043 - DFP high performance
+       uint8_t pfpo:1;         // 044 - PFPO instruction
+       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
+       uint8_t ibm04:1;        // 046 - Assigned to IBM
+       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
+       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
+       uint8_t misc:1;         // 049 - Multiple inc load and trap
+       uint8_t ctx:1;          // 050 - Constrained transactional-execution
+       uint8_t ltlb:1;         // 051 - Local TLB clearing
+       uint8_t ia:1;           // 052 - Interlocked access
+       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
+       uint8_t x002:1;         // 054 - Undefined
+       uint8_t ibm05:1;        // 055 - Assigned to IBM
+       uint8_t x003:1;         // 056 - Undefined
+       uint8_t msa5:1;         // 057 - Message security assist 5
+       uint8_t x004:1;         // 058 - Undefined
+       uint8_t x005:1;         // 059 - Undefined
+       uint8_t x006:1;         // 060 - Undefined
+       uint8_t x007:1;         // 061 - Undefined
+       uint8_t ibm06:1;        // 062 - Assigned to IBM
+       uint8_t x008:1;         // 063 - Undefined
+       uint8_t x009:1;         // 064 - Undefined
+       uint8_t ibm07:1;        // 065 - Assigned to IBM
+       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
+       uint8_t cmc:1;          // 067 - CPU measurement counter
+       uint8_t cms:1;          // 068 - CPU Measurement sampling
+       uint8_t ibm08:1;        // 069 - Assigned to IBM
+       uint8_t ibm09:1;        // 070 - Assigned to IBM
+       uint8_t ibm10:1;        // 071 - Assigned to IBM
+       uint8_t ibm11:1;        // 072 - Assigned to IBM
+       uint8_t txe:1;          // 073 - Transactional execution
+       uint8_t sthy:1;         // 074 - Store hypervisor information
+       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
+       uint8_t msa3:1;         // 076 - Message security assist 3
+       uint8_t msa4:1;         // 077 - Message security assist 4
+       uint8_t edat2:1;        // 078 - Enhanced DAT 2
+       uint8_t x010:1;         // 079 - Undefined
+       uint8_t dfppc:1;        // 080 - DFP packed conversion
+       uint8_t x011:7;         // 081-87 - Undefined
+       uint8_t x012[5];        // 088-127 - Undefined
+       uint8_t ibm12:1;        // 128 - Assigned to IBM
+       uint8_t vec:1;          // 129 - Vector facility
+       uint8_t x013:6;         // 130-135 - Undefined
+       uint8_t x014:6;         // 136-141 - Undefined
+       uint8_t sccm:1;         // 142 - Store CPU counter multiple
+       uint8_t ibm13:1;        // 143 - Assigned to IBM
+       uint8_t x015[14];       // 144-256 Undefined
+} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
 
 void
 mono_hwcap_arch_init (void)
 {
-       int lFacs = sizeof(facs) / 8;
+       facilityList_t facs;
+       int lFacs = sizeof (facs) / 8;
 
-       __asm__ ("      lgfr    0,%1\n"
-                "      .insn   s,0xb2b00000,%0\n"
-                : "=m" (facs) : "r" (lFacs) : "0", "cc");
-}
+       __asm__ __volatile__ (
+               "lgfr\t0,%1\n\t"
+               ".insn\ts,0xb2b00000,%0\n\t"
+               : "=m" (facs)
+               : "r" (lFacs)
+               : "0", "cc"
+       );
 
-void
-mono_hwcap_print (FILE *f)
-{
+       mono_hwcap_s390x_has_fpe = facs.fpe;
+       mono_hwcap_s390x_has_vec = facs.vec;
 }
diff --git a/mono/utils/mono-hwcap-s390x.h b/mono/utils/mono-hwcap-s390x.h
deleted file mode 100644 (file)
index 7a4522f..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_S390X_H__
-#define __MONO_UTILS_HWCAP_S390X_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-typedef struct __FACLIST__ {
-       uint8_t n3:1;           // 000 - N3 instructions
-       uint8_t zi:1;           // 001 - z/Arch installed
-       uint8_t za:1;           // 002 - z/Arch active
-       uint8_t date:1;         // 003 - DAT-enhancement
-       uint8_t idtes:1;        // 004 - IDTE-segment tables
-       uint8_t idter:1;        // 005 - IDTE-region tables
-       uint8_t asnlx:1;        // 006 - ASN-LX reuse
-       uint8_t stfle:1;        // 007 - STFLE
-       uint8_t edat1:1;        // 008 - EDAT 1
-       uint8_t srs:1;          // 009 - Sense-Running-Status
-       uint8_t csske:1;        // 010 - Conditional SSKE
-       uint8_t ctf:1;          // 011 - Configuration-topology
-       uint8_t ibm01:1;        // 012 - Assigned to IBM
-       uint8_t ipter:1;        // 013 - IPTE-range
-       uint8_t nqks:1;         // 014 - Nonquiescing key-setting
-       uint8_t ibm02:1;        // 015 - Assigned to IBM
-       uint8_t etf2:1;         // 016 - Extended translation 2
-       uint8_t msa:1;          // 017 - Message security assist 1
-       uint8_t ld:1;           // 018 - Long displacement
-       uint8_t ldh:1;          // 019 - Long displacement high perf
-       uint8_t mas:1;          // 020 - HFP multiply-add-subtract
-       uint8_t eif:1;          // 021 - Extended immediate
-       uint8_t etf3:1;         // 022 - Extended translation 3
-       uint8_t hux:1;          // 023 - HFP unnormalized extension
-       uint8_t etf2e:1;        // 024 - Extended translation enhanced 2
-       uint8_t stckf:1;        // 025 - Store clock fast
-       uint8_t pe:1;           // 026 - Parsing enhancement
-       uint8_t mvcos:1;        // 027 - Move with optional specs
-       uint8_t tods:1;         // 028 - TOD steering
-       uint8_t x000:1;         // 029 - Undefined
-       uint8_t etf3e:1;        // 030 - ETF3 enhancement
-       uint8_t ecput:1;        // 031 - Extract CPU time
-       uint8_t csst:1;         // 032 - Compare swap and store
-       uint8_t csst2:1;        // 033 - Compare swap and store 2
-       uint8_t gie:1;          // 034 - General instructions extension
-       uint8_t ee:1;           // 035 - Execute extensions
-       uint8_t em:1;           // 036 - Enhanced monitor
-       uint8_t fpe:1;          // 037 - Floating point extension
-       uint8_t x001:1;         // 038 - Undefined
-       uint8_t ibm03:1;        // 039 - Assigned to IBM
-       uint8_t spp:1;          // 040 - Set program parameters
-       uint8_t fpse:1;         // 041 - FP support enhancement
-       uint8_t dfp:1;          // 042 - DFP
-       uint8_t dfph:1;         // 043 - DFP high performance
-       uint8_t pfpo:1;         // 044 - PFPO instruction
-       uint8_t multi:1;        // 045 - Multiple inc load/store on CC 1
-       uint8_t ibm04:1;        // 046 - Assigned to IBM
-       uint8_t cmpsce:1;       // 047 - CMPSC enhancement
-       uint8_t dfpzc:1;        // 048 - DFP zoned conversion
-       uint8_t misc:1;         // 049 - Multiple inc load and trap
-       uint8_t ctx:1;          // 050 - Constrained transactional-execution
-       uint8_t ltlb:1;         // 051 - Local TLB clearing
-       uint8_t ia:1;           // 052 - Interlocked access
-       uint8_t lsoc2:1;        // 053 - Load/store on CC 2
-       uint8_t x002:1;         // 054 - Undefined
-       uint8_t ibm05:1;        // 055 - Assigned to IBM
-       uint8_t x003:1;         // 056 - Undefined
-       uint8_t msa5:1;         // 057 - Message security assist 5
-       uint8_t x004:1;         // 058 - Undefined
-       uint8_t x005:1;         // 059 - Undefined
-       uint8_t x006:1;         // 060 - Undefined
-       uint8_t x007:1;         // 061 - Undefined
-       uint8_t ibm06:1;        // 062 - Assigned to IBM
-       uint8_t x008:1;         // 063 - Undefined
-       uint8_t x009:1;         // 064 - Undefined
-       uint8_t ibm07:1;        // 065 - Assigned to IBM
-       uint8_t rrbm:1;         // 066 - Reset reference bits multiple
-       uint8_t cmc:1;          // 067 - CPU measurement counter
-       uint8_t cms:1;          // 068 - CPU Measurement sampling
-       uint8_t ibm08:1;        // 069 - Assigned to IBM
-       uint8_t ibm09:1;        // 070 - Assigned to IBM
-       uint8_t ibm10:1;        // 071 - Assigned to IBM
-       uint8_t ibm11:1;        // 072 - Assigned to IBM
-       uint8_t txe:1;          // 073 - Transactional execution
-       uint8_t sthy:1;         // 074 - Store hypervisor information
-       uint8_t aefsi:1;        // 075 - Access exception fetch/store indication
-       uint8_t msa3:1;         // 076 - Message security assist 3
-       uint8_t msa4:1;         // 077 - Message security assist 4
-       uint8_t edat2:1;        // 078 - Enhanced DAT 2
-       uint8_t x010:1;         // 079 - Undefined
-       uint8_t dfppc:1;        // 080 - DFP packed conversion
-       uint8_t x011:7;         // 081-87 - Undefined
-       uint8_t x012[5];        // 088-127 - Undefined
-       uint8_t ibm12:1;        // 128 - Assigned to IBM
-       uint8_t vec:1;          // 129 - Vector facility
-       uint8_t x013:6;         // 130-135 - Undefined
-       uint8_t x014:6;         // 136-141 - Undefined
-       uint8_t sccm:1;         // 142 - Store CPU counter multiple
-       uint8_t ibm13:1;        // 143 - Assigned to IBM
-       uint8_t x015[14];       // 144-256 Undefined
-} __attribute__ ((packed)) __attribute__ ((aligned(8))) facilityList_t;
-
-extern facilityList_t facs;
-
-#endif /* __MONO_UTILS_HWCAP_S390X_H__ */
index ba849873632cf0798c66c34ecddf2990056d9873..75208bdeff7bc02996f188a00eeaed769007d138 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-sparc.h"
+#include "mono/utils/mono-hwcap.h"
 
 #include <string.h>
-
 #if !defined(__linux__)
 #include <sys/systeminfo.h>
 #else
 #include <unistd.h>
 #endif
 
-gboolean mono_hwcap_sparc_is_v9 = FALSE;
-
 void
 mono_hwcap_arch_init (void)
 {
        char buf [1024];
 
 #if !defined(__linux__)
-       if (!sysinfo (SI_ISALIST, buf, 1024))
-               g_assert_not_reached ();
+       g_assert (sysinfo (SI_ISALIST, buf, 1024));
 #else
        /* If the page size is 8192, we're on a 64-bit SPARC, which
         * in turn means a v9 or better.
@@ -51,9 +47,3 @@ mono_hwcap_arch_init (void)
 
        mono_hwcap_sparc_is_v9 = strstr (buf, "sparcv9");
 }
-
-void
-mono_hwcap_print (FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_sparc_is_v9 = %i\n", mono_hwcap_sparc_is_v9);
-}
diff --git a/mono/utils/mono-hwcap-vars.h b/mono/utils/mono-hwcap-vars.h
new file mode 100644 (file)
index 0000000..620a3d4
--- /dev/null
@@ -0,0 +1,56 @@
+#include "config.h"
+
+#if defined (TARGET_ARM)
+
+MONO_HWCAP_VAR(arm_is_v5)
+MONO_HWCAP_VAR(arm_is_v6)
+MONO_HWCAP_VAR(arm_is_v7)
+MONO_HWCAP_VAR(arm_has_vfp)
+MONO_HWCAP_VAR(arm_has_vfp3)
+MONO_HWCAP_VAR(arm_has_vfp3_d16)
+MONO_HWCAP_VAR(arm_has_thumb)
+MONO_HWCAP_VAR(arm_has_thumb2)
+
+#elif defined (TARGET_ARM64)
+
+// Nothing here yet.
+
+#elif defined (TARGET_IA64)
+
+// Nothing here yet.
+
+#elif defined (TARGET_MIPS)
+
+// Nothing here yet.
+
+#elif defined (TARGET_POWERPC) || defined (TARGET_POWERPC64)
+
+MONO_HWCAP_VAR(ppc_has_icache_snoop)
+MONO_HWCAP_VAR(ppc_is_isa_2x)
+MONO_HWCAP_VAR(ppc_is_isa_64)
+MONO_HWCAP_VAR(ppc_has_move_fpr_gpr)
+MONO_HWCAP_VAR(ppc_has_multiple_ls_units)
+
+#elif defined (TARGET_S390X)
+
+MONO_HWCAP_VAR(s390x_has_fpe)
+MONO_HWCAP_VAR(s390x_has_vec)
+
+#elif defined (TARGET_SPARC) || defined (TARGET_SPARC64)
+
+MONO_HWCAP_VAR(sparc_is_v9)
+
+#elif defined (TARGET_X86) || defined (TARGET_AMD64)
+
+MONO_HWCAP_VAR(x86_is_xen)
+MONO_HWCAP_VAR(x86_has_cmov)
+MONO_HWCAP_VAR(x86_has_fcmov)
+MONO_HWCAP_VAR(x86_has_sse1)
+MONO_HWCAP_VAR(x86_has_sse2)
+MONO_HWCAP_VAR(x86_has_sse3)
+MONO_HWCAP_VAR(x86_has_ssse3)
+MONO_HWCAP_VAR(x86_has_sse41)
+MONO_HWCAP_VAR(x86_has_sse42)
+MONO_HWCAP_VAR(x86_has_sse4a)
+
+#endif
index 4a96aa3a088eeb3d6a646c123c603bb305c29296..5d72a4c7e2030260e74b82369ffc82db450636f4 100644 (file)
  * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
-#include "mono/utils/mono-hwcap-x86.h"
+#include "mono/utils/mono-hwcap.h"
 
 #if defined(HAVE_UNISTD_H)
 #include <unistd.h>
 #endif
-
 #if defined(_MSC_VER)
 #include <intrin.h>
 #endif
 
-gboolean mono_hwcap_x86_is_xen = FALSE;
-gboolean mono_hwcap_x86_has_cmov = FALSE;
-gboolean mono_hwcap_x86_has_fcmov = FALSE;
-gboolean mono_hwcap_x86_has_sse1 = FALSE;
-gboolean mono_hwcap_x86_has_sse2 = FALSE;
-gboolean mono_hwcap_x86_has_sse3 = FALSE;
-gboolean mono_hwcap_x86_has_ssse3 = FALSE;
-gboolean mono_hwcap_x86_has_sse41 = FALSE;
-gboolean mono_hwcap_x86_has_sse42 = FALSE;
-gboolean mono_hwcap_x86_has_sse4a = FALSE;
-
 static gboolean
 cpuid (int id, int *p_eax, int *p_ebx, int *p_ecx, int *p_edx)
 {
@@ -162,18 +150,3 @@ mono_hwcap_arch_init (void)
        mono_hwcap_x86_is_xen = !access ("/proc/xen", F_OK);
 #endif
 }
-
-void
-mono_hwcap_print (FILE *f)
-{
-       g_fprintf (f, "mono_hwcap_x86_is_xen = %i\n", mono_hwcap_x86_is_xen);
-       g_fprintf (f, "mono_hwcap_x86_has_cmov = %i\n", mono_hwcap_x86_has_cmov);
-       g_fprintf (f, "mono_hwcap_x86_has_fcmov = %i\n", mono_hwcap_x86_has_fcmov);
-       g_fprintf (f, "mono_hwcap_x86_has_sse1 = %i\n", mono_hwcap_x86_has_sse1);
-       g_fprintf (f, "mono_hwcap_x86_has_sse2 = %i\n", mono_hwcap_x86_has_sse2);
-       g_fprintf (f, "mono_hwcap_x86_has_sse3 = %i\n", mono_hwcap_x86_has_sse3);
-       g_fprintf (f, "mono_hwcap_x86_has_ssse3 = %i\n", mono_hwcap_x86_has_ssse3);
-       g_fprintf (f, "mono_hwcap_x86_has_sse41 = %i\n", mono_hwcap_x86_has_sse41);
-       g_fprintf (f, "mono_hwcap_x86_has_sse42 = %i\n", mono_hwcap_x86_has_sse42);
-       g_fprintf (f, "mono_hwcap_x86_has_sse4a = %i\n", mono_hwcap_x86_has_sse4a);
-}
diff --git a/mono/utils/mono-hwcap-x86.h b/mono/utils/mono-hwcap-x86.h
deleted file mode 100644 (file)
index 5e1f4f7..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef __MONO_UTILS_HWCAP_X86_H__
-#define __MONO_UTILS_HWCAP_X86_H__
-
-#include "mono/utils/mono-hwcap.h"
-
-extern gboolean mono_hwcap_x86_is_xen;
-extern gboolean mono_hwcap_x86_has_cmov;
-extern gboolean mono_hwcap_x86_has_fcmov;
-extern gboolean mono_hwcap_x86_has_sse1;
-extern gboolean mono_hwcap_x86_has_sse2;
-extern gboolean mono_hwcap_x86_has_sse3;
-extern gboolean mono_hwcap_x86_has_ssse3;
-extern gboolean mono_hwcap_x86_has_sse41;
-extern gboolean mono_hwcap_x86_has_sse42;
-extern gboolean mono_hwcap_x86_has_sse4a;
-
-#endif /* __MONO_UTILS_HWCAP_X86_H__ */
index a3d2b6078bfdb0d3e401d6e2854497e5ec7f3b8f..00fad690193a5f8415f4afc317b1c28afa97fd99 100644 (file)
 
 #include "mono/utils/mono-hwcap.h"
 
+#define MONO_HWCAP_VAR(NAME) gboolean mono_hwcap_ ## NAME = FALSE;
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
 static gboolean hwcap_inited = FALSE;
 
 void
@@ -35,19 +39,21 @@ mono_hwcap_init (void)
        if (hwcap_inited)
                return;
 
-#ifdef MONO_CROSS_COMPILE
-       /*
-        * If we're cross-compiling, we want to be as
-        * conservative as possible so that we produce
-        * code that's portable. Default to that.
-        */
-       if (!conservative)
-               conservative = "1";
-#endif
-
        if (!conservative || strncmp (conservative, "1", 1))
                mono_hwcap_arch_init ();
 
        if (verbose && !strncmp (verbose, "1", 1))
-               mono_hwcap_print (stdout);
+               mono_hwcap_print ();
+}
+
+void
+mono_hwcap_print (void)
+{
+       g_print ("[mono-hwcap] Detected following hardware capabilities:\n\n");
+
+#define MONO_HWCAP_VAR(NAME) g_print ("\t" #NAME " = %s\n", mono_hwcap_ ## NAME ? "yes" : "no");
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
+       g_print ("\n");
 }
index af5d665426905beefe8e3e89318e82e1a2610f49..1867d3d258a62bbb0c0e4d8b820892a691781586 100644 (file)
@@ -8,6 +8,10 @@
 
 #include "mono/utils/mono-compiler.h"
 
+#define MONO_HWCAP_VAR(NAME) extern gboolean mono_hwcap_ ## NAME;
+#include "mono/utils/mono-hwcap-vars.h"
+#undef MONO_HWCAP_VAR
+
 /* Call this function to perform hardware feature detection. Until
  * this function has been called, all feature variables will be
  * FALSE as a default.
  * result in an inconsistent state of the variables. Further,
  * feature variables should not be read *while* this function is
  * executing.
- *
- * To get at feature variables, include the appropriate header,
- * e.g. mono-hwcap-x86.h for x86(-64).
  */
 void mono_hwcap_init (void);
 
 /* Implemented in mono-hwcap-$TARGET.c. Do not call. */
 void mono_hwcap_arch_init (void);
 
-/* Print detected features to the given file. */
-void mono_hwcap_print (FILE *f);
+/* Print detected features to stdout. */
+void mono_hwcap_print (void);
 
 /* Please note: If you're going to use the Linux auxiliary vector
  * to detect CPU features, don't use any of the constant names in