Merge pull request #1388 from schani/fix-23401
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 17 Nov 2014 22:17:04 +0000 (17:17 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 17 Nov 2014 22:17:04 +0000 (17:17 -0500)
Fix 23401

124 files changed:
mcs/Makefile
mcs/build/Makefile
mcs/build/profiles/xbuild_14.make [new file with mode: 0644]
mcs/class/Makefile
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Engine.cs
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/Consts.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollection.cs
mcs/class/Mono.CSharp/Test/Evaluator/TypesTest.cs
mcs/class/Mono.Posix/Mono.Unix.Native/NativeConvert.cs
mcs/class/Mono.Posix/Mono.Unix/UnixFileSystemInfo.cs
mcs/class/System.Security/Mono.Xml/XmlCanonicalizer.cs
mcs/class/System.Security/Test/System.Security.Cryptography.Xml/SignedXmlTest.cs
mcs/class/System.Security/Test/System.Security.Cryptography.Xml/XmlDsigC14NTransformTest.cs
mcs/class/System.XML/System.Xml/XmlElement.cs
mcs/class/System/System.Net.NetworkInformation/NetworkInterface.cs
mcs/class/System/System.Net.WebSockets/ClientWebSocket.cs
mcs/class/System/System/Platform.cs
mcs/class/System/Test/System.Net.WebSockets/ClientWebSocketTest.cs
mcs/class/corlib/System.Globalization/CultureInfo.cs
mcs/class/corlib/System.Runtime.InteropServices/Marshal.cs
mcs/errors/cs0121-26.cs [new file with mode: 0644]
mcs/errors/cs0170.cs
mcs/errors/cs0188-9.cs [deleted file]
mcs/errors/cs0200-4.cs [new file with mode: 0644]
mcs/errors/cs0200-5.cs [new file with mode: 0644]
mcs/errors/cs0200-6.cs [new file with mode: 0644]
mcs/errors/cs0843-2.cs [deleted file]
mcs/errors/cs0843-3.cs [deleted file]
mcs/errors/cs1692.cs
mcs/errors/cs8051.cs
mcs/errors/cs8052.cs
mcs/errors/cs8053.cs [deleted file]
mcs/errors/cs8079.cs [new file with mode: 0644]
mcs/mcs/assembly.cs
mcs/mcs/assign.cs
mcs/mcs/attribute.cs
mcs/mcs/cs-tokenizer.cs
mcs/mcs/decl.cs
mcs/mcs/delegate.cs
mcs/mcs/ecore.cs
mcs/mcs/eval.cs
mcs/mcs/flowanalysis.cs
mcs/mcs/ikvm.cs
mcs/mcs/namespace.cs
mcs/mcs/property.cs
mcs/tests/gtest-autoproperty-11.cs [new file with mode: 0644]
mcs/tests/gtest-autoproperty-12.cs [new file with mode: 0644]
mcs/tests/gtest-autoproperty-13.cs [new file with mode: 0644]
mcs/tests/gtest-autoproperty-14.cs [new file with mode: 0644]
mcs/tests/test-868.cs
mcs/tests/test-908.cs [new file with mode: 0644]
mcs/tests/test-909.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml
mcs/tools/corcompare/mono-api-html/ApiDiff.cs
mcs/tools/corcompare/mono-api-html/ConstructorComparer.cs
mcs/tools/corcompare/mono-api-html/MemberComparer.cs
mcs/tools/corcompare/mono-api-html/PropertyComparer.cs
mcs/tools/mdoc/Test/en.expected.importecmadoc/System/Action`1.xml
mcs/tools/mdoc/Test/en.expected.importecmadoc/System/Array.xml
mcs/tools/mdoc/Test/en.expected.importecmadoc/System/AsyncCallback.xml
mcs/tools/mdoc/Test/en.expected.importecmadoc/System/Environment.xml
mcs/tools/xbuild/Makefile
mcs/tools/xbuild/SolutionParser.cs
mcs/tools/xbuild/XBuildConsts.cs
mcs/tools/xbuild/data/14.0/Microsoft.CSharp.targets [new file with mode: 0644]
mcs/tools/xbuild/data/14.0/Microsoft.Common.targets [new file with mode: 0644]
mcs/tools/xbuild/data/14.0/Microsoft.Common.tasks [new file with mode: 0644]
mcs/tools/xbuild/xbuild.make
mcs/tools/xbuild/xbuild_test.make
mono/metadata/appdomain.c
mono/metadata/boehm-gc.c
mono/metadata/class.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/loader.h
mono/metadata/lock-tracer.h
mono/metadata/marshal.c
mono/metadata/metadata-internals.h
mono/metadata/metadata.c
mono/metadata/mono-perfcounters.c
mono/metadata/mono-perfcounters.h
mono/metadata/null-gc.c
mono/metadata/sgen-fin-weak-hash.c
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-internal.c
mono/metadata/sgen-pinning.c
mono/metadata/sgen-pointer-queue.c
mono/metadata/sgen-pointer-queue.h
mono/metadata/socket-io.c
mono/mini/debugger-agent.c
mono/mini/driver.c
mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-mips.c
mono/mini/exceptions-ppc.c
mono/mini/exceptions-s390x.c
mono/mini/exceptions-x86.c
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h
mono/mini/mini-arm.c
mono/mini/mini-exceptions.c
mono/mini/mini-gc.c
mono/mini/mini-posix.c
mono/mini/mini-x86.c
mono/mini/mini.c
mono/mini/mini.h
mono/mini/tramp-arm.c
mono/profiler/decode.c
mono/profiler/proflog.c
mono/profiler/proflog.h
mono/tests/synchronized.cs
mono/utils/mono-context.c
mono/utils/mono-counters.c
mono/utils/mono-counters.h
mono/utils/mono-threads-mach.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
runtime/Makefile.am

index 9bcf32ea2fbfbe292037fee9077a50c53ba86ec8..49423b4a15f23a7d4a49c4c410f24abce50cc57e 100644 (file)
@@ -17,6 +17,7 @@ net_3_5_SUBDIRS := build class tools/xbuild
 net_4_0_SUBDIRS := build class
 net_4_5_SUBDIRS := build mcs class nunit24 ilasm tools tests errors docs
 xbuild_12_SUBDIRS := build class tools/xbuild
+xbuild_14_SUBDIRS := build class tools/xbuild
 
 # List of test subdirs that should pass 100%
 centum_tests := \
@@ -87,7 +88,7 @@ dir-check:
 
 # fun specialty targets
 
-PROFILES = net_2_0 net_3_5 net_4_0 net_4_5 xbuild_12
+PROFILES = net_2_0 net_3_5 net_4_0 net_4_5 xbuild_12 xbuild_14
 
 .PHONY: all-profiles $(STD_TARGETS:=-profiles)
 all-profiles $(STD_TARGETS:=-profiles): %-profiles: profiles-do--%
@@ -106,6 +107,7 @@ profiles-do--run-test:
 
 # Orchestrate the bootstrap here.
 _boot_ = all clean install
+$(_boot_:%=profile-do--xbuild_14--%):         profile-do--xbuild_14--%:         profile-do--net_4_5--%
 $(_boot_:%=profile-do--xbuild_12--%):         profile-do--xbuild_12--%:         profile-do--net_4_5--%
 $(_boot_:%=profile-do--net_4_5--%):           profile-do--net_4_5--%:           profile-do--build--%
 $(_boot_:%=profile-do--net_4_0--%):           profile-do--net_4_0--%:           profile-do--build--%
index ce026ae275fd57a1ad44b124c96abf5fd35b5f6b..34d857a65f552632e95a88665f9a35f7ce82bd8b 100644 (file)
@@ -22,7 +22,8 @@ PROFILES = \
        net_3_5 \
        net_4_0 \
        net_4_5 \
-       xbuild_12
+       xbuild_12 \
+       xbuild_14
 
 COMMON_SRCS = \
        Consts.cs.in                    \
diff --git a/mcs/build/profiles/xbuild_14.make b/mcs/build/profiles/xbuild_14.make
new file mode 100644 (file)
index 0000000..cc55a1d
--- /dev/null
@@ -0,0 +1,7 @@
+# -*- makefile -*-
+
+include $(topdir)/build/profiles/net_4_5.make
+
+PROFILE_MCS_FLAGS := $(PROFILE_MCS_FLAGS) -d:XBUILD_12 -d:XBUILD_14 -lib:$(topdir)/class/lib/net_4_5
+
+XBUILD_VERSION = 14.0
index 3ab5668acc7c326a84403efac5c91cd6486dad6a..33a7dd8ae7b7a2d59603a2d910453e9721d629e0 100644 (file)
@@ -242,6 +242,7 @@ net_3_5_SUBDIRS := $(xbuild_2_0_dirs)
 net_4_0_SUBDIRS := $(net_2_0_dirs) $(net_4_0_dirs) $(net_4_0_only_dirs) $(xbuild_4_0_dirs)
 net_4_5_SUBDIRS := $(net_2_0_dirs) $(net_4_0_dirs) $(net_4_5_dirs) $(xbuild_4_0_dirs) aot-compiler
 xbuild_12_SUBDIRS := $(xbuild_4_0_dirs)
+xbuild_14_SUBDIRS := $(xbuild_4_0_dirs)
 
 include ../build/rules.make
 
index 25c04e1aab33037a5e50658e47050579161581ca..ec3ddd731b08faca1c252a5973bff5327a7902b7 100644 (file)
@@ -560,11 +560,8 @@ namespace Microsoft.Build.BuildEngine {
                        get {
                                // This is used as the fall back version if the
                                // project can't find a version to use
-                               // Hard-coded to 2.0, so it allows even vs2005 projects
-                               // to build correctly, as they won't have a ToolsVersion
-                               // set!
                                return String.IsNullOrEmpty (defaultToolsVersion)
-                                               ? "2.0"
+                                               ? "4.0"
                                                : defaultToolsVersion;
                        }
                        set {
index 8db3be70a9df673c0ef434dd73d96699152a3b57..e17d6dc53e5f5e77856654865e8e22c44ee87b2f 100644 (file)
@@ -39,7 +39,9 @@ public static class Consts {
        public static string BinPath {
                get {
                        if (RunningOnMono ()) {
-#if XBUILD_12
+#if XBUILD_14
+                               string profile = "xbuild_14";
+#elif XBUILD_12
                                string profile = "xbuild_12";
 #elif NET_4_5
                                string profile = "net_4_5";
@@ -54,7 +56,9 @@ public static class Consts {
                                var lib = Path.GetDirectoryName (Path.GetDirectoryName (corlib));
                                return Path.Combine (lib, profile);
                        } else {
-#if XBUILD_12
+#if XBUILD_14
+                               return ToolLocationHelper.GetPathToBuildTools ("14.0");
+#elif XBUILD_12
                                return ToolLocationHelper.GetPathToBuildTools ("12.0");
 #elif NET_4_5
                                return ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version45);
@@ -71,7 +75,9 @@ public static class Consts {
 
        public static string ToolsVersionString {
                get {
-#if XBUILD_12
+#if XBUILD_14
+                       return " ToolsVersion='14.0'";
+#elif XBUILD_12
                        return " ToolsVersion='12.0'";
 #elif NET_4_0
                        return " ToolsVersion='4.0'";
@@ -85,7 +91,9 @@ public static class Consts {
 
        public static string GetTasksAsmPath ()
        {
-#if XBUILD_12
+#if XBUILD_14
+               return Path.Combine (BinPath, "Microsoft.Build.Tasks.Core.dll");
+#elif XBUILD_12
                return Path.Combine (BinPath, "Microsoft.Build.Tasks.v12.0.dll");
 #elif NET_4_0
                return Path.Combine (BinPath, "Microsoft.Build.Tasks.v4.0.dll");
index 8b667ced1ba6ecee695aa67cfd269be4a91bbcc6..0a894e7b0f6a36eda8cf3856ff61e2d4f4986e7c 100644 (file)
@@ -53,8 +53,13 @@ namespace Microsoft.Build.Utilities
 #if XBUILD_12
                Version451,
 #endif
+#if XBUILD_14
+               Version453,
+#endif
 
-#if XBUILD_12
+#if XBUILD_14
+               VersionLatest = Version453
+#elif XBUILD_12
                VersionLatest = Version451
 #elif NET_4_5
                VersionLatest = Version45
index f3aa310c09b00323c8952f631e32ecd9f0bd9de7..736b8ad0c4a4ad76cbccd18e642c8fc600b70315 100644 (file)
@@ -233,11 +233,20 @@ namespace Microsoft.Build.Utilities
 
                public static string GetPathToBuildTools (string toolsVersion)
                {
-                       if (toolsVersion != "12.0")
+                       string path;
+                       switch (toolsVersion) {
+                       case "12.0":
+                               path = "xbuild_12";
+                               break;
+                       case "14.0":
+                               path = "xbuild_14";
+                               break;
+                       default:
                                return null;
+                       }
 
                        if (Environment.GetEnvironmentVariable ("TESTING_MONO") != null)
-                               return Path.Combine (lib_mono_dir, "xbuild_12");
+                               return Path.Combine (lib_mono_dir, path);
 
                        if (runningOnDotNet) {
                                //see http://msdn.microsoft.com/en-us/library/vstudio/bb397428(v=vs.120).aspx
index 4170fa00253e29343e428b1e8bcd9534e5b8ca7c..11343933971adf05106698d5efd0ed573954fb52 100644 (file)
@@ -263,6 +263,9 @@ namespace Microsoft.Build.Evaluation
 #endif
 #if XBUILD_12
                        AddToolset (new Toolset ("12.0", ToolLocationHelper.GetPathToBuildTools ("12.0"), this, null));
+#endif
+#if XBUILD_14
+                       AddToolset (new Toolset ("14.0", ToolLocationHelper.GetPathToBuildTools ("14.0"), this, null));
 #endif
                        default_tools_version = toolsets.First ().ToolsVersion;
                }
index 970aa33443d459a23509d782e18ede555c9b8ab1..c124ad3739feaa4306b1096c8f4f248096b4840e 100644 (file)
@@ -104,7 +104,15 @@ namespace MonoTests.EvaluatorTest
                {
                        Evaluator.Run ("class A { class B { } }");
                        Evaluator.Run ("var x = new A ();");
+               }
 
+               [Test]
+               public void DelegateType ()
+               {
+                       Evaluator.Run ("public delegate int D();");
+                       Evaluator.Run ("D d = delegate () { return 7; };");
+                       object res = Evaluator.Evaluate ("d();");
+                       Assert.AreEqual (7, res);
                }
        }
 }
\ No newline at end of file
index 7951d08ae17377a58246b6f81b3df14cdecaf317..ffa329f1b5bf3d5fa7cc75a7a6e93355b118d117 100644 (file)
@@ -195,6 +195,11 @@ namespace Mono.Unix.Native {
                        return FromTimeT (time);
                }
 
+               public static DateTime ToDateTime (long time, long nanoTime)
+               {
+                       return FromTimeT (time).AddMilliseconds (nanoTime / 1000);
+               }
+
                public static long FromDateTime (DateTime time)
                {
                        return ToTimeT (time);
index c6a9b283b5f193b5a061d1c6108777522d75bd1c..149f79b84ed966bff1e74d466dd82a066acfd8e8 100644 (file)
@@ -192,7 +192,7 @@ namespace Mono.Unix {
                }
 
                public DateTime LastAccessTime {
-                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime);}
+                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_atime, stat.st_atime_nsec);}
                }
 
                public DateTime LastAccessTimeUtc {
@@ -200,7 +200,7 @@ namespace Mono.Unix {
                }
 
                public DateTime LastWriteTime {
-                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime);}
+                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_mtime, stat.st_mtime_nsec);}
                }
 
                public DateTime LastWriteTimeUtc {
@@ -208,7 +208,7 @@ namespace Mono.Unix {
                }
 
                public DateTime LastStatusChangeTime {
-                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime);}
+                       get {AssertValid (); return Native.NativeConvert.ToDateTime (stat.st_ctime, stat.st_ctime_nsec);}
                }
 
                public DateTime LastStatusChangeTimeUtc {
index ae267a93856c6fac3fe75814a225d151a4216aee..8f0ec9735398c7feb561ede9f018b1c067872e68 100644 (file)
@@ -637,7 +637,7 @@ namespace Mono.Xml {
                        else if (n2 == null) 
                                return 1;
                        else if (n1.Prefix == n2.Prefix) 
-                               return string.Compare (n1.LocalName, n2.LocalName);
+                               return string.CompareOrdinal (n1.LocalName, n2.LocalName);
        
                        // Attributes in the default namespace are first
                        // because the default namespace is not applied to
index a20b3bc3a2e28c21b073b5efec5c9bd597815f1f..4c7c6131087421c389d77eecf6fffed7aa64f5d7 100644 (file)
@@ -213,6 +213,87 @@ namespace MonoTests.System.Security.Cryptography.Xml {
                        Assert.IsTrue (vrfy.CheckSignature (), "RSA-Compute/Verify");
                }
 
+               // The same as MSDNSample(), but adding a few attributes
+               public SignedXml MSDNSampleMixedCaseAttributes ()
+               {
+                       // Create example data to sign.
+                       XmlDocument document = new XmlDocument ();
+                       XmlNode node = document.CreateNode (XmlNodeType.Element, "", "MyElement", "samples");
+                       node.InnerText = "This is some text";
+                       XmlAttribute a1 = document.CreateAttribute ("Aa");
+                       XmlAttribute a2 = document.CreateAttribute ("Bb");
+                       XmlAttribute a3 = document.CreateAttribute ("aa");
+                       XmlAttribute a4 = document.CreateAttribute ("bb");
+                       a1.Value = "one";
+                       a2.Value = "two";
+                       a3.Value = "three";
+                       a4.Value = "four";
+                       node.Attributes.Append (a1);
+                       node.Attributes.Append (a2);
+                       node.Attributes.Append (a3);
+                       node.Attributes.Append (a4);
+                       document.AppendChild (node);
+
+                       // Create the SignedXml message.
+                       SignedXml signedXml = new SignedXml ();
+
+                       // Create a data object to hold the data to sign.
+                       DataObject dataObject = new DataObject ();
+                       dataObject.Data = document.ChildNodes;
+                       dataObject.Id = "MyObjectId";
+
+                       // Add the data object to the signature.
+                       signedXml.AddObject (dataObject);
+
+                       // Create a reference to be able to package everything into the
+                       // message.
+                       Reference reference = new Reference ();
+                       reference.Uri = "#MyObjectId";
+
+                       // Add it to the message.
+                       signedXml.AddReference (reference);
+
+                       return signedXml;
+               }
+
+               public string AsymmetricRSAMixedCaseAttributes ()
+               {
+                       SignedXml signedXml = MSDNSampleMixedCaseAttributes ();
+
+                       RSA key = RSA.Create ();
+                       signedXml.SigningKey = key;
+
+                       // Add a KeyInfo.
+                       KeyInfo keyInfo = new KeyInfo ();
+                       keyInfo.AddClause (new RSAKeyValue (key));
+                       signedXml.KeyInfo = keyInfo;
+
+                       // Compute the signature.
+                       signedXml.ComputeSignature ();
+
+                       // Get the XML representation of the signature.
+                       XmlElement xmlSignature = signedXml.GetXml ();
+
+                       StringWriter sw = new StringWriter ();
+                       XmlWriter w = new XmlTextWriter (sw);
+                       xmlSignature.WriteTo (w);
+                       return sw.ToString ();
+               }
+
+               // Example output from Windows for AsymmetricRSAMixedCaseAttributes()
+               private const string AsymmetricRSAMixedCaseAttributesResult = "<Signature xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><SignedInfo><CanonicalizationMethod Algorithm=\"http://www.w3.org/TR/2001/REC-xml-c14n-20010315\" /><SignatureMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#rsa-sha1\" /><Reference URI=\"#MyObjectId\"><DigestMethod Algorithm=\"http://www.w3.org/2000/09/xmldsig#sha1\" /><DigestValue>0j1xLsePFtuRHfXEnVdTSLWtAm4=</DigestValue></Reference></SignedInfo><SignatureValue>hmrEBgns5Xx14aDhzqOyIh0qLNMUldtW8+fNPcvtD/2KtEhNZQGctnhs90CRa1NZ08TqzW2pUaEwmqvMAtF4v8KtWzC/zTuc1jH6nxQvQSQo0ABhuXdu7/hknZkXJ4yKBbdgbKjAsKfULwbWrP/PacLPoYfCO+wXSrt+wLMTTWU=</SignatureValue><KeyInfo><KeyValue><RSAKeyValue><Modulus>4h/rHDr54r6SZWk2IPCeHX7N+wR1za0VBLshuS6tq3RSWap4PY2BM8VdbKH2T9RzyZoiHufjng+1seUx430iMsXisOLUkPP+yGtMQOSZ3CQHAa+IYA+fplXipixI0rV1J1wJNXQm3HxXQqKWpIv5fkwBtj8o2k6CWMgPNgFCnxc=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue></KeyValue></KeyInfo><Object Id=\"MyObjectId\"><MyElement Aa=\"one\" Bb=\"two\" aa=\"three\" bb=\"four\" xmlns=\"samples\">This is some text</MyElement></Object></Signature>";
+
+               [Test]
+               public void AsymmetricRSAMixedCaseAttributesVerifyWindows ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       doc.LoadXml (AsymmetricRSAMixedCaseAttributesResult);
+
+                       SignedXml v1 = new SignedXml ();
+                       v1.LoadXml (doc.DocumentElement);
+                       Assert.IsTrue (v1.CheckSignature ());
+               }
+
                [Test]
                public void AsymmetricDSASignature () 
                {
index 816df3e9809e04c12d24f1caa25b01667a21215d..43cf7df2afcaea4d61af5c7339cf9123f377231e 100644 (file)
@@ -494,6 +494,19 @@ namespace MonoTests.System.Security.Cryptography.Xml {
                        Assert.AreEqual (new StreamReader (s, Encoding.UTF8).ReadToEnd (), expected);
                }
 
+               [Test]
+               public void OrdinalSortForAttributes ()
+               {
+                       XmlDocument doc = new XmlDocument ();
+                       string xml = "<foo Aa=\"one\" Bb=\"two\" aa=\"three\" bb=\"four\"><bar></bar></foo>";
+                       doc.LoadXml (xml);
+
+                       transform.LoadInput (doc);
+                       Stream s = (Stream) transform.GetOutput ();
+                       string output = Stream2String (s);
+                       Assert.AreEqual (xml, output);
+               }
+
 #if NET_2_0
                [Test]
                public void PrefixlessNamespaceOutput ()
index 120355f584344ae22da34359b7ef1fcf23c48079..2d9d1e0e930df9f97f6ac9493a49927917374a58 100644 (file)
@@ -152,11 +152,17 @@ namespace System.Xml
                                XmlTextReader xmlReader = new XmlTextReader (value, XmlNodeType.Element, ctx);
                                xmlReader.XmlResolver = OwnerDocument.Resolver;
 
-                               do {
-                                       XmlNode n = OwnerDocument.ReadNode (xmlReader);
-                                       if(n == null) break;
-                                       AppendChild (n);
-                               } while (true);
+                               bool pw = OwnerDocument.PreserveWhitespace;
+                               OwnerDocument.PreserveWhitespace = true;
+                               try {
+                                       do {
+                                               XmlNode n = OwnerDocument.ReadNode (xmlReader);
+                                               if(n == null) break;
+                                               AppendChild (n);
+                                       } while (true);
+                               } finally {
+                                       OwnerDocument.PreserveWhitespace = pw;
+                               }
                        }
                }
 
index edaa12dafb3aef8dbe606e78e59bc48ffb6aec4d..46cf7d8cbdfcc2ecf543b20e7f1a5fef80052992 100644 (file)
@@ -58,7 +58,7 @@ namespace System.Net.NetworkInformation {
 #else
                        if (runningOnUnix) {
                                try {
-                                       if (Platform.IsMacOS)
+                                       if (Platform.IsMacOS || Platform.IsFreeBSD)
                                                return MacOsNetworkInterface.ImplGetAllNetworkInterfaces ();
                                        else
                                                return LinuxNetworkInterface.ImplGetAllNetworkInterfaces ();
index d7e999c46f36b4624cea92e5ad32c920a791308b..ff011d2f93044da4f6f28a9a7966e2800004572d 100644 (file)
@@ -318,7 +318,7 @@ namespace System.Net.WebSockets
                        var opCode = MessageTypeToWire (type);
                        var length = buffer.Count;
 
-                       headerBuffer[0] = (byte)(opCode | (endOfMessage ? 0 : 0x80));
+                       headerBuffer[0] = (byte)(opCode | (endOfMessage ? 0x80 : 0));
                        if (length < 126) {
                                headerBuffer[1] = (byte)length;
                        } else if (length <= ushort.MaxValue) {
index c45a33e66005cff43b6a826cd74b85c3c8c77128..b687c590f580272959a8304c787d3149524a6838 100644 (file)
@@ -28,36 +28,56 @@ using System.Runtime.InteropServices;
 
 namespace System {
        internal static class Platform {
+               static bool checkedOS;
+               static bool isMacOS;
+               static bool isFreeBSD;
+
 #if MONOTOUCH || XAMMAC
-               public static bool IsMacOS {
-                       get { return true; }
+               private static void CheckOS() {
+                       isMacOS = true;
+                       checkedOS = true;
                }
 #else
                [DllImport ("libc")]
                static extern int uname (IntPtr buf);
-               
-               static bool checkedIsMacOS;
-               static bool isMacOS;
-               
-               public static bool IsMacOS {
-                       get {
-                               if (Environment.OSVersion.Platform != PlatformID.Unix)
-                                       return false;
 
-                               if (!checkedIsMacOS) {
-                                       IntPtr buf = Marshal.AllocHGlobal (8192);
-                                       if (uname (buf) == 0) {
-                                               string os = Marshal.PtrToStringAnsi (buf);
-                                               if (os == "Darwin")
-                                                       isMacOS = true;
-                                       }
-                                       Marshal.FreeHGlobal (buf);
-                                       checkedIsMacOS = true;
+               private static void CheckOS() {
+                       if (Environment.OSVersion.Platform != PlatformID.Unix) {
+                               checkedOS = true;
+                               return;
+                       }
+
+                       IntPtr buf = Marshal.AllocHGlobal (8192);
+                       if (uname (buf) == 0) {
+                               string os = Marshal.PtrToStringAnsi (buf);
+                               switch (os) {
+                               case "Darwin":
+                                       isMacOS = true;
+                                       break;
+                               case "FreeBSD":
+                                       isFreeBSD = true;
+                                       break;
                                }
-                               
-                               return isMacOS;
                        }
+                       Marshal.FreeHGlobal (buf);
+                       checkedOS = true;
                }
 #endif
+
+               public static bool IsMacOS {
+                       get {
+                               if (!checkedOS)
+                                       CheckOS();
+                               return isMacOS;
+                       }
+               }
+
+               public static bool IsFreeBSD {
+                       get {
+                               if (!checkedOS)
+                                       CheckOS();
+                               return isFreeBSD;
+                       }
+               }
        }
 }
index 2140daac9bb866aa77fb5dcebd666424dcff6f1d..6ac81723d256323574d1fe207424f04c333676b0 100644 (file)
@@ -101,6 +101,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
+               [Ignore ("See bug #24340")]
                public void EchoTest ()
                {
                        const string Payload = "This is a websocket test";
@@ -125,6 +126,7 @@ namespace MonoTests.System.Net.WebSockets
                }
 
                [Test]
+               [Ignore ("See bug #24340")]
                public void CloseOutputAsyncTest ()
                {
                        Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
@@ -218,6 +220,45 @@ namespace MonoTests.System.Net.WebSockets
                        Assert.Fail ("Should have thrown");
                }
 
+               [Test]
+               [Category ("NotWorking")]  // FIXME: test relies on unimplemented HttpListenerContext.AcceptWebSocketAsync (), reenable it when the method is implemented
+               public void SendAsyncEndOfMessageTest ()
+               {
+                       var cancellationToken = new CancellationTokenSource (TimeSpan.FromSeconds (30)).Token;
+                       SendAsyncEndOfMessageTest (false, WebSocketMessageType.Text, cancellationToken).Wait (5000);
+                       SendAsyncEndOfMessageTest (true, WebSocketMessageType.Text, cancellationToken).Wait (5000);
+                       SendAsyncEndOfMessageTest (false, WebSocketMessageType.Binary, cancellationToken).Wait (5000);
+                       SendAsyncEndOfMessageTest (true, WebSocketMessageType.Binary, cancellationToken).Wait (5000);
+               }
+
+               public async Task SendAsyncEndOfMessageTest (bool expectedEndOfMessage, WebSocketMessageType webSocketMessageType, CancellationToken cancellationToken)
+               {
+                       using (var client = new ClientWebSocket ()) {
+                               // Configure the listener.
+                               var serverReceive = HandleHttpWebSocketRequestAsync<WebSocketReceiveResult> (async socket => await socket.ReceiveAsync (new ArraySegment<byte> (new byte[32]), cancellationToken), cancellationToken);
+
+                               // Connect to the listener and make the request.
+                               await client.ConnectAsync (new Uri ("ws://localhost:" + Port + "/"), cancellationToken);
+                               await client.SendAsync (new ArraySegment<byte> (Encoding.UTF8.GetBytes ("test")), webSocketMessageType, expectedEndOfMessage, cancellationToken);
+
+                               // Wait for the listener to handle the request and return its result.
+                               var result = await serverReceive;
+
+                               // Cleanup and check results.
+                               await client.CloseAsync (WebSocketCloseStatus.NormalClosure, "Finished", cancellationToken);
+                               Assert.AreEqual (expectedEndOfMessage, result.EndOfMessage, "EndOfMessage should be " + expectedEndOfMessage);
+                       }
+               }
+
+               async Task<T> HandleHttpWebSocketRequestAsync<T> (Func<WebSocket, Task<T>> action, CancellationToken cancellationToken)
+               {
+                       var ctx = await this.listener.GetContextAsync ();
+                       var wsContext = await ctx.AcceptWebSocketAsync (null);
+                       var result = await action (wsContext.WebSocket);
+                       await wsContext.WebSocket.CloseOutputAsync (WebSocketCloseStatus.NormalClosure, "Finished", cancellationToken);
+                       return result;
+               }
+
                async Task HandleHttpRequestAsync (Action<HttpListenerRequest, HttpListenerResponse> handler)
                {
                        var ctx = await listener.GetContextAsync ();
index ea7c6affa4aba7fac6818cf50c95c6405c97b830..5edf1fab803ff9f9743d644515f995d8aebe7df8 100644 (file)
@@ -670,7 +670,7 @@ namespace System.Globalization
                                //
                                // Be careful not to cause recursive CultureInfo initialization
                                //
-                               var msg = string.Format (InvariantCulture, "Culture ID {0} (0x{0:X4}) is not a supported culture.", culture.ToString (InvariantCulture));
+                               var msg = string.Format (InvariantCulture, "Culture ID {0} (0x{1}) is not a supported culture.", culture.ToString (InvariantCulture), culture.ToString ("X4", InvariantCulture));
 #if NET_4_0
                                throw new CultureNotFoundException ("culture", msg);
 #else
index 48c5db2ea62adb508e662063fc3fca9e4ad276a6..e861f50df632e239d7dadb3a7106d6356d66f38e 100644 (file)
@@ -1585,6 +1585,7 @@ namespace System.Runtime.InteropServices
 
                public static Exception GetExceptionForHR (int errorCode, IntPtr errorInfo)
                {
+#if !MOBILE
                        IErrorInfo info = null;
                        if (errorInfo != (IntPtr)(-1)) {
                                if (errorInfo == IntPtr.Zero) {
@@ -1618,6 +1619,9 @@ namespace System.Runtime.InteropServices
                                }
                        }
                        return e;
+#else
+                       return ConvertHrToException (errorCode);
+#endif
                }
 
 #if !FULL_AOT_RUNTIME
diff --git a/mcs/errors/cs0121-26.cs b/mcs/errors/cs0121-26.cs
new file mode 100644 (file)
index 0000000..a1ca019
--- /dev/null
@@ -0,0 +1,43 @@
+// CS0121: The call is ambiguous between the following methods or properties: `A.B.X.Test(this int)' and `A.C.X.Test(this int)'
+// Line: 37
+
+using System;
+
+namespace A.B
+{
+       static class X
+       {
+               public static int Test (this int o)
+               {
+                       return 1;
+               }
+       }
+}
+
+namespace A.C
+{
+       static class X
+       {
+               public static int Test (this int o)
+               {
+                       return 2;
+               }
+       }
+}
+
+namespace C
+{
+       using A.B;
+       using A.C.X;
+
+       class M
+       {
+               public static int Main ()
+               {
+                       if (1.Test () != 1)
+                               return 1;
+
+                       return 0;
+               }
+       }
+}
\ No newline at end of file
index f388a037eced6f200483931ed0e75479b5a7ea2b..366b485d184ec7f3ae944995c8c6ed9aae997398 100644 (file)
@@ -1,7 +1,5 @@
 // CS0170: Use of possibly unassigned field `a'
-// Line: 23
-
-using System;
+// Line: 21
 
 namespace CS0170
 {
@@ -21,7 +19,6 @@ namespace CS0170
                        Foo f;
                        Bar b = new Bar();
                        b.Inc (f.a);
-                       Console.WriteLine (f.a);
                }
        }
 }
diff --git a/mcs/errors/cs0188-9.cs b/mcs/errors/cs0188-9.cs
deleted file mode 100644 (file)
index fc0d3ad..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// CS0188: The `this' object cannot be used before all of its fields are assigned to
-// Line: 11
-
-using System;
-
-public struct S
-{
-       public int A { get; private set;}
-       public event EventHandler eh;
-
-       public S (int a)
-       {
-               this.eh = null;
-               A = a;
-       }
-}
diff --git a/mcs/errors/cs0200-4.cs b/mcs/errors/cs0200-4.cs
new file mode 100644 (file)
index 0000000..bf2cbff
--- /dev/null
@@ -0,0 +1,15 @@
+// CS0200: Property or indexer `A.X' cannot be assigned to (it is read-only)
+// Line: 13
+
+public class A
+{
+       public int X { get; }
+}
+
+public class B : A
+{
+       public B ()
+       {
+               base.X = 1;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0200-5.cs b/mcs/errors/cs0200-5.cs
new file mode 100644 (file)
index 0000000..4657362
--- /dev/null
@@ -0,0 +1,12 @@
+// CS0200: Property or indexer `C.S' cannot be assigned to (it is read-only)
+// Line: 10
+
+class C
+{
+       public static int S { get; }
+
+       public C ()
+       {
+               S = 3;
+       }
+}
diff --git a/mcs/errors/cs0200-6.cs b/mcs/errors/cs0200-6.cs
new file mode 100644 (file)
index 0000000..dcfe2d2
--- /dev/null
@@ -0,0 +1,12 @@
+// CS0200: Property or indexer `C.P' cannot be assigned to (it is read-only)
+// Line: 10
+
+class C
+{
+       public int P { get; }
+
+       public void Foo ()
+       {
+               P = 10;
+       }
+}
diff --git a/mcs/errors/cs0843-2.cs b/mcs/errors/cs0843-2.cs
deleted file mode 100644 (file)
index eb90055..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// CS0843: An automatically implemented property `S.A' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer
-// Line: 8
-
-public struct S
-{
-       public int A { get; set;}
-
-       public S (int a)
-       {
-               this.A = a;
-       }
-}
diff --git a/mcs/errors/cs0843-3.cs b/mcs/errors/cs0843-3.cs
deleted file mode 100644 (file)
index 696ef16..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-// CS0843: An automatically implemented property `S.A' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer
-// Line: 11
-
-using System;
-
-public struct S
-{
-       public int A { get; set;}
-       event EventHandler eh;
-
-       public S (int a)
-       {
-               this.eh = null;
-               A = a;
-       }
-}
index 0041787be04dac5b10925741f22fc41976d5fdb9..043d58ea408681f95d1a1820fcbf7bb42b2f2d1a 100644 (file)
@@ -2,6 +2,6 @@
 // Line: 5
 // Compiler options: -warnaserror
 
-#pragma warning disable AAA
+#pragma warning disable 1AAA
 class MainClass {
 }
index 7935efbe6084844f2b225b08aabf9fabe9e17f60..1bd716c4b82baecf2e5b98f5c3572aaa2b050535 100644 (file)
@@ -1,7 +1,7 @@
-// CS8051: Auto-implemented property `Test.Property' must have set accessor or initializer
+// CS8051: Auto-implemented property `V.P' must have get accessor
 // Line: 6
 
-public abstract class Test
+class V
 {
-       public string Property { get; }
-}
+       public object P { set; } = 1;
+}
\ No newline at end of file
index bccf0157faf0807cb216a29b5aa3fe8d4ab6686b..d3f6a219653a206e9e9dacc343e5759284b624e1 100644 (file)
@@ -1,7 +1,7 @@
-// CS8052: Auto-implemented property `V.P' must have get accessor
+// CS8052: `I.P': Properties inside interfaces cannot have initializers
 // Line: 6
 
-class V
+interface I
 {
-       public object P { set; } = 1;
+       int P { get; } = 4;
 }
\ No newline at end of file
diff --git a/mcs/errors/cs8053.cs b/mcs/errors/cs8053.cs
deleted file mode 100644 (file)
index 319835f..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-// CS8053: `I.P': Properties inside interfaces cannot have initializers
-// Line: 6
-
-interface I
-{
-       int P { get; } = 4;
-}
\ No newline at end of file
diff --git a/mcs/errors/cs8079.cs b/mcs/errors/cs8079.cs
new file mode 100644 (file)
index 0000000..18a7810
--- /dev/null
@@ -0,0 +1,14 @@
+// CS8079: Use of possibly unassigned auto-implemented property `X'
+// Line: 11
+
+public struct S
+{
+       public int X { get; set; }
+       public int Y;
+
+       public S ()
+       {
+               Y = X;
+               X = 0;
+       }
+}
\ No newline at end of file
index f93c0383962a4849b5613d916007241aa79a2fa1..dd5af064062b446d686d94ec6e56e027e99df84e 100644 (file)
@@ -372,8 +372,6 @@ namespace Mono.CSharp
                                vi_product = a.GetString ();
                        } else if (a.Type == pa.AssemblyCompany) {
                                vi_company = a.GetString ();
-                       } else if (a.Type == pa.AssemblyDescription) {
-                               // TODO: Needs extra api
                        } else if (a.Type == pa.AssemblyCopyright) {
                                vi_copyright = a.GetString ();
                        } else if (a.Type == pa.AssemblyTrademark) {
@@ -382,6 +380,12 @@ namespace Mono.CSharp
                                has_user_debuggable = true;
                        }
 
+                       //
+                       // Win32 version info attributes AssemblyDescription and AssemblyTitle cannot be
+                       // set using public API and because we have blob like attributes we need to use
+                       // special option DecodeVersionInfoAttributeBlobs to support values extraction
+                       //
+
                        SetCustomAttribute (ctor, cdata);
                }
 
index 472a393739f1a8cd0f5f68576f7bc57c1ddc2547..5650d054c2be3607cc0ec91a1b40c9271f06c0fa 100644 (file)
@@ -421,7 +421,13 @@ namespace Mono.CSharp {
                {
                        source.FlowAnalysis (fc);
 
-                       if (target is ArrayAccess || target is IndexerExpr || target is PropertyExpr)
+                       if (target is ArrayAccess || target is IndexerExpr) {
+                               target.FlowAnalysis (fc);
+                               return;
+                       }
+
+                       var pe = target as PropertyExpr;
+                       if (pe != null && !pe.IsAutoPropertyAccess)
                                target.FlowAnalysis (fc);
                }
 
@@ -491,6 +497,12 @@ namespace Mono.CSharp {
                                fe.SetFieldAssigned (fc);
                                return;
                        }
+
+                       var pe = target as PropertyExpr;
+                       if (pe != null) {
+                               pe.SetBackingFieldAssigned (fc);
+                               return;
+                       }
                }
 
                public override void MarkReachable (Reachability rc)
index 7318f2605931c273b9f8f094e0a7dcaed9ab672c..f05e513ef4a366aa559a640b26d5d31676c2456c 100644 (file)
@@ -1698,7 +1698,6 @@ namespace Mono.CSharp {
                public readonly PredefinedAttribute FieldOffset;
                public readonly PredefinedAttribute AssemblyProduct;
                public readonly PredefinedAttribute AssemblyCompany;
-               public readonly PredefinedAttribute AssemblyDescription;
                public readonly PredefinedAttribute AssemblyCopyright;
                public readonly PredefinedAttribute AssemblyTrademark;
                public readonly PredefinedAttribute CallerMemberNameAttribute;
@@ -1758,7 +1757,6 @@ namespace Mono.CSharp {
                        FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
                        AssemblyProduct = new PredefinedAttribute (module, "System.Reflection", "AssemblyProductAttribute");
                        AssemblyCompany = new PredefinedAttribute (module, "System.Reflection", "AssemblyCompanyAttribute");
-                       AssemblyDescription = new PredefinedAttribute (module, "System.Reflection", "AssemblyDescriptionAttribute");
                        AssemblyCopyright = new PredefinedAttribute (module, "System.Reflection", "AssemblyCopyrightAttribute");
                        AssemblyTrademark = new PredefinedAttribute (module, "System.Reflection", "AssemblyTrademarkAttribute");
 
index 9647a4bd7e64a1f2407da61f5bde02a195dfe797..b3f8b32a707631b938fb8d86fc6e7c859d3ff05f 100644 (file)
@@ -1989,7 +1989,7 @@ namespace Mono.CSharp
                        return current_token;
                }
 
-               int TokenizePreprocessorIdentifier (out int c)
+               int TokenizePreprocessorKeyword (out int c)
                {
                        // skip over white space
                        do {
@@ -2026,7 +2026,7 @@ namespace Mono.CSharp
                        tokens_seen = false;
                        arg = "";
 
-                       var cmd = GetPreprocessorDirective (id_builder, TokenizePreprocessorIdentifier (out c));
+                       var cmd = GetPreprocessorDirective (id_builder, TokenizePreprocessorKeyword (out c));
 
                        if ((cmd & PreprocessorDirective.CustomArgumentsParsing) != 0)
                                return cmd;
@@ -2098,7 +2098,7 @@ namespace Mono.CSharp
 
                        int c;
 
-                       int length = TokenizePreprocessorIdentifier (out c);
+                       int length = TokenizePreprocessorKeyword (out c);
                        if (length == line_default.Length) {
                                if (!IsTokenIdentifierEqual (line_default))
                                        return false;
@@ -2431,16 +2431,60 @@ namespace Mono.CSharp
                        return string_builder.ToString ();
                }
 
-               int TokenizePragmaNumber (ref int c)
+               int TokenizePragmaWarningIdentifier (ref int c, ref bool identifier)
                {
-                       number_pos = 0;
 
-                       int number;
+                       if ((c >= '0' && c <= '9') || is_identifier_start_character (c)) {
+                               int number;
 
-                       if (c >= '0' && c <= '9') {
-                               number = TokenizeNumber (c);
+                               if (c >= '0' && c <= '9') {
+                                       number_pos = 0;
+                                       number = TokenizeNumber (c);
 
-                               c = get_char ();
+                                       c = get_char ();
+
+                                       if (c != ' ' && c != '\t' && c != ',' && c != '\n' && c != -1 && c != UnicodeLS && c != UnicodePS) {
+                                               return ReadPragmaWarningComment (c);
+                                       }
+                               } else {
+                                       //
+                                       // LAMESPEC v6: No spec what identifier really is in this context, it seems keywords are allowed too
+                                       //
+                                       int pos = 0;
+                                       number = -1;
+                                       id_builder [pos++] = (char)c;
+                                       while (c < MaxIdentifierLength) {
+                                               c = reader.Read ();
+                                               id_builder [pos] = (char)c;
+
+                                               if (c >= '0' && c <= '9') {
+                                                       if (pos == 6 && id_builder [0] == 'C' && id_builder [1] == 'S') {
+                                                               // Recognize CSXXXX as C# XXXX warning
+                                                               number = 0;
+                                                               int pow = 1000;
+                                                               for (int i = 0; i < 4; ++i) {
+                                                                       var ch = id_builder [i + 2];
+                                                                       if (ch < '0' || ch > '9') {
+                                                                               number = -1;
+                                                                               break;
+                                                                       }
+
+                                                                       number += (ch - '0') * pow;
+                                                                       pow /= 10;
+                                                               }
+                                                       }
+                                               } else if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && c != '_') {
+                                                       break;
+                                               }
+
+                                               ++pos;
+                                       }
+
+                                       if (number < 0) {
+                                               identifier = true;
+                                               number = pos;
+                                       }
+                               }
 
                                // skip over white space
                                while (c == ' ' || c == '\t')
@@ -2453,19 +2497,25 @@ namespace Mono.CSharp
                                // skip over white space
                                while (c == ' ' || c == '\t')
                                        c = get_char ();
+
+                               return number;
+                       }
+
+                       return ReadPragmaWarningComment (c);
+               }
+
+               int ReadPragmaWarningComment (int c)
+               {
+                       if (c == '/') {
+                               ReadSingleLineComment ();
                        } else {
-                               number = -1;
-                               if (c == '/') {
-                                       ReadSingleLineComment ();
-                               } else {
-                                       Report.Warning (1692, 1, Location, "Invalid number");
+                               Report.Warning (1692, 1, Location, "Invalid number");
 
-                                       // Read everything till the end of the line or file
-                                       ReadToEndOfLine ();
-                               }
+                               // Read everything till the end of the line or file
+                               ReadToEndOfLine ();
                        }
 
-                       return number;
+                       return -1;
                }
 
                void ReadToEndOfLine ()
@@ -2491,9 +2541,9 @@ namespace Mono.CSharp
                void ParsePragmaDirective ()
                {
                        int c;
-                       int length = TokenizePreprocessorIdentifier (out c);
+                       int length = TokenizePreprocessorKeyword (out c);
                        if (length == pragma_warning.Length && IsTokenIdentifierEqual (pragma_warning)) {
-                               length = TokenizePreprocessorIdentifier (out c);
+                               length = TokenizePreprocessorKeyword (out c);
 
                                //
                                // #pragma warning disable
@@ -2526,9 +2576,12 @@ namespace Mono.CSharp
                                                        //
                                                        int code;
                                                        do {
-                                                               code = TokenizePragmaNumber (ref c);
+                                                               bool identifier = false;
+                                                               code = TokenizePragmaWarningIdentifier (ref c, ref identifier);
                                                                if (code > 0) {
-                                                                       if (disable) {
+                                                                       if (identifier) {
+                                                                               // no-op, custom warnings cannot occur in mcs
+                                                                       } else if (disable) {
                                                                                Report.RegisterWarningRegion (loc).WarningDisable (loc, code, context.Report);
                                                                        } else {
                                                                                Report.RegisterWarningRegion (loc).WarningEnable (loc, code, context);
index 302c21a2c7a7d585b16bf1c8d5c68f279e83f2b6..99476d291c7b671047ac0329a843ce900327812b 100644 (file)
@@ -1125,7 +1125,7 @@ namespace Mono.CSharp {
 
                public virtual string GetSignatureForError ()
                {
-                       var bf = MemberDefinition as Property.BackingField;
+                       var bf = MemberDefinition as Property.BackingFieldDeclaration;
                        string name;
                        if (bf == null) {
                                name = Name;
index 0dd759823f184fcb95f003920619a26939796c8a..b50e65e007777bd2a87ce765ce12071da9188ab8 100644 (file)
@@ -294,6 +294,9 @@ namespace Mono.CSharp {
 
                public override void PrepareEmit ()
                {
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
+
                        if (!Parameters.IsEmpty) {
                                parameters.ResolveDefaultValues (this);
                        }
index 3143908b63accad973ddba473d1f532987e364e5..387bac8617f12ea1f6450ca2177212c22ce33673 100644 (file)
@@ -3208,6 +3208,11 @@ namespace Mono.CSharp {
                {
                        return ns.LookupTypeOrNamespace (ctx, name, arity, mode, loc);
                }
+
+               public override string ToString ()
+               {
+                       return Namespace.Name;
+               }
     }
 
        /// <summary>
@@ -6584,6 +6589,7 @@ namespace Mono.CSharp {
        sealed class PropertyExpr : PropertyOrIndexerExpr<PropertySpec>
        {
                Arguments arguments;
+               FieldExpr backing_field;
 
                public PropertyExpr (PropertySpec spec, Location l)
                        : base (l)
@@ -6615,6 +6621,13 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsAutoPropertyAccess {
+                       get {
+                               var prop = best_candidate.MemberDefinition as Property;
+                               return prop != null && prop.BackingField != null;
+                       }
+               }
+
                public override bool IsInstance {
                        get {
                                return !IsStatic;
@@ -6756,6 +6769,11 @@ namespace Mono.CSharp {
 
                public override void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool isCompound)
                {
+                       if (backing_field != null) {
+                               backing_field.EmitAssign (ec, source, false, false);
+                               return;
+                       }
+
                        Arguments args;
                        LocalTemporary await_source_arg = null;
 
@@ -6825,6 +6843,21 @@ namespace Mono.CSharp {
 
                public override void FlowAnalysis (FlowAnalysisContext fc)
                {
+                       var prop = best_candidate.MemberDefinition as Property;
+                       if (prop != null && prop.BackingField != null) {
+                               var var = InstanceExpression as IVariableReference;
+                               if (var != null) {
+                                       var vi = var.VariableInfo;
+                                       if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, prop.BackingField.Name)) {
+                                               fc.Report.Error (8079, loc, "Use of possibly unassigned auto-implemented property `{0}'", Name);
+                                               return;
+                                       }
+
+                                       if (TypeSpec.IsValueType (InstanceExpression.Type) && InstanceExpression is VariableReference)
+                                               return;
+                               }
+                       }
+
                        base.FlowAnalysis (fc);
 
                        if (conditional_access_receiver)
@@ -6869,6 +6902,52 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               protected override bool ResolveAutopropertyAssignment (ResolveContext rc, Expression rhs)
+               {
+                       var prop = best_candidate.MemberDefinition as Property;
+                       if (prop == null)
+                               return false;
+
+                       if (!rc.HasSet (ResolveContext.Options.ConstructorScope))
+                               return false;
+
+                       var spec = prop.BackingField;
+                       if (spec == null)
+                               return false;
+
+                       if (rc.IsStatic != spec.IsStatic)
+                               return false;
+
+                       if (!spec.IsStatic && (!(InstanceExpression is This) || InstanceExpression is BaseThis))
+                               return false;
+
+                       backing_field = new FieldExpr (prop.BackingField, loc);
+                       backing_field.ResolveLValue (rc, rhs);
+                       return true;
+               }
+
+               public void SetBackingFieldAssigned (FlowAnalysisContext fc)
+               {
+                       if (backing_field != null) {
+                               backing_field.SetFieldAssigned (fc);
+                               return;
+                       }
+
+                       if (!IsAutoPropertyAccess)
+                               return;
+
+                       var prop = best_candidate.MemberDefinition as Property;
+                       if (prop != null && prop.BackingField != null) {
+                               bool lvalue_instance = best_candidate.DeclaringType.IsStruct;
+                               if (lvalue_instance) {
+                                       var var = InstanceExpression as IVariableReference;
+                                       if (var != null && var.VariableInfo != null) {
+                                               fc.SetStructFieldAssigned (var.VariableInfo, prop.BackingField.Name);
+                                       }
+                               }
+                       }
+               }
+
                public override void SetTypeArguments (ResolveContext ec, TypeArguments ta)
                {
                        Error_TypeArgumentsCannotBeUsed (ec, "property", GetSignatureForError (), loc);
@@ -6938,7 +7017,7 @@ namespace Mono.CSharp {
                        return this;
                }
 
-               public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
+               public override Expression DoResolveLValue (ResolveContext rc, Expression right_side)
                {
                        if (ConditionalAccess)
                                throw new NotSupportedException ("null propagating operator assignment");
@@ -6946,29 +7025,50 @@ namespace Mono.CSharp {
                        if (right_side == EmptyExpression.OutAccess) {
                                // TODO: best_candidate can be null at this point
                                INamedBlockVariable variable = null;
-                               if (best_candidate != null && ec.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, ec.CurrentBlock, ref variable) && variable is Linq.RangeVariable) {
-                                       ec.Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
+                               if (best_candidate != null && rc.CurrentBlock.ParametersBlock.TopBlock.GetLocalName (best_candidate.Name, rc.CurrentBlock, ref variable) && variable is Linq.RangeVariable) {
+                                       rc.Report.Error (1939, loc, "A range variable `{0}' may not be passes as `ref' or `out' parameter",
                                                best_candidate.Name);
                                } else {
-                                       right_side.DoResolveLValue (ec, this);
+                                       right_side.DoResolveLValue (rc, this);
                                }
                                return null;
                        }
 
                        if (eclass == ExprClass.Unresolved) {
-                               var expr = OverloadResolve (ec, right_side);
+                               var expr = OverloadResolve (rc, right_side);
                                if (expr == null)
                                        return null;
 
                                if (expr != this)
-                                       return expr.ResolveLValue (ec, right_side);
+                                       return expr.ResolveLValue (rc, right_side);
                        } else {
-                               ResolveInstanceExpression (ec, right_side);
+                               ResolveInstanceExpression (rc, right_side);
                        }
 
-                       if (!ResolveSetter (ec))
+                       if (!best_candidate.HasSet) {
+                               if (ResolveAutopropertyAssignment (rc, right_side))
+                                       return this;
+
+                               rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)",
+                                       GetSignatureForError ());
                                return null;
+                       }
+
+                       if (!best_candidate.Set.IsAccessible (rc) || !best_candidate.Set.DeclaringType.IsAccessible (rc)) {
+                               if (best_candidate.HasDifferentAccessibility) {
+                                       rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
+                                       rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
+                                               GetSignatureForError ());
+                               } else {
+                                       rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
+                                       ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
+                               }
+                       }
 
+                       if (best_candidate.HasDifferentAccessibility)
+                               CheckProtectedMemberAccess (rc, best_candidate.Set);
+
+                       setter = CandidateToBaseOverride (rc, best_candidate.Set);
                        return this;
                }
 
@@ -7058,30 +7158,9 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               bool ResolveSetter (ResolveContext rc)
+               protected virtual bool ResolveAutopropertyAssignment (ResolveContext rc, Expression rhs)
                {
-                       if (!best_candidate.HasSet) {
-                               rc.Report.Error (200, loc, "Property or indexer `{0}' cannot be assigned to (it is read-only)",
-                                       GetSignatureForError ());
-                               return false;
-                       }
-
-                       if (!best_candidate.Set.IsAccessible (rc) || !best_candidate.Set.DeclaringType.IsAccessible (rc)) {
-                               if (best_candidate.HasDifferentAccessibility) {
-                                       rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
-                                       rc.Report.Error (272, loc, "The property or indexer `{0}' cannot be used in this context because the set accessor is inaccessible",
-                                               GetSignatureForError ());
-                               } else {
-                                       rc.Report.SymbolRelatedToPreviousError (best_candidate.Set);
-                                       ErrorIsInaccesible (rc, best_candidate.GetSignatureForError (), loc);
-                               }
-                       }
-
-                       if (best_candidate.HasDifferentAccessibility)
-                               CheckProtectedMemberAccess (rc, best_candidate.Set);
-
-                       setter = CandidateToBaseOverride (rc, best_candidate.Set);
-                       return true;
+                       return false;
                }
        }
 
index 059ffb82d1db25721330f26f96b1ba6fd321ab9e..c1ea5aaa576529d7963787e2f9a7736cf9900871 100644 (file)
@@ -863,13 +863,19 @@ namespace Mono.CSharp
 
                public string GetUsing ()
                {
+                       if (source_file == null || source_file.Usings == null)
+                               return string.Empty;
+
                        StringBuilder sb = new StringBuilder ();
                        // TODO:
                        //foreach (object x in ns.using_alias_list)
                        //    sb.AppendFormat ("using {0};\n", x);
 
                        foreach (var ue in source_file.Usings) {
-                               sb.AppendFormat ("using {0};", ue.ToString ());
+                               if (ue.Alias != null || ue.ResolvedExpression == null)
+                                       continue;
+
+                               sb.AppendFormat("using {0};", ue.ToString ());
                                sb.Append (Environment.NewLine);
                        }
 
@@ -880,7 +886,11 @@ namespace Mono.CSharp
                {
                        var res = new List<string> ();
 
-                       foreach (var ue in source_file.Usings) {
+                       if (source_file == null || source_file.Usings == null)
+                               return res;
+
+                       foreach (var ue in source_file.Usings)
+                       {
                                if (ue.Alias != null || ue.ResolvedExpression == null)
                                        continue;
 
index dbb74a7515a0d930a37c4832521afe6acb04c247..a28434d6bc27bd40c6d3ba4da44060c0b1643848 100644 (file)
@@ -139,7 +139,7 @@ namespace Mono.CSharp
                                var field = struct_info.Fields[i];
 
                                if (!fc.IsStructFieldDefinitelyAssigned (vi, field.Name)) {
-                                       var bf = field.MemberDefinition as Property.BackingField;
+                                       var bf = field.MemberDefinition as Property.BackingFieldDeclaration;
                                        if (bf != null) {
                                                if (bf.Initializer != null)
                                                        continue;
index c2e247037ef2f62e9ad16ca51a0b16f0ef2674dd..3bf9599a3d591559f084f7663165ddd4d7e82f03 100644 (file)
@@ -246,7 +246,7 @@ namespace Mono.CSharp
                        : base (compiler)
                {
                        this.importer = importer;
-                       domain = new Universe (UniverseOptions.MetadataOnly | UniverseOptions.ResolveMissingMembers | UniverseOptions.DisableFusion);
+                       domain = new Universe (UniverseOptions.MetadataOnly | UniverseOptions.ResolveMissingMembers | UniverseOptions.DisableFusion | UniverseOptions.DecodeVersionInfoAttributeBlobs);
                        domain.AssemblyResolve += AssemblyReferenceResolver;
                        loaded_names = new List<Tuple<AssemblyName, string, Assembly>> ();
 
index 0a35cc4c61e7fd8212c58c7a81277026a4193cd2..f5ca0a818a4480e5080a67945f414dca21fd4a2e 100644 (file)
@@ -951,22 +951,18 @@ namespace Mono.CSharp {
                                                candidates.AddRange (a);
                                }
 
-                               if (candidates != null)
-                                       return new ExtensionMethodCandidates (invocationContext, candidates, this, position);
-                       }
+                               if (types_using_table != null) {
+                                       foreach (var t in types_using_table) {
 
-                       // LAMESPEC: TODO no spec about priority over normal extension methods yet
-                       if (types_using_table != null) {
-                               foreach (var t in types_using_table) {
-
-                                       var res = t.MemberCache.FindExtensionMethods (invocationContext, name, arity);
-                                       if (res == null)
-                                               continue;
+                                               var res = t.MemberCache.FindExtensionMethods (invocationContext, name, arity);
+                                               if (res == null)
+                                                       continue;
 
-                                       if (candidates == null)
-                                               candidates = res;
-                                       else
-                                               candidates.AddRange (res);
+                                               if (candidates == null)
+                                                       candidates = res;
+                                               else
+                                                       candidates.AddRange (res);
+                                       }
                                }
 
                                if (candidates != null)
index ebe8aca2ea9745a899726d0cbb7371eeb761bd3d..35f4cd74a03fc3a148e3144c0a15f096740fbbfa 100644 (file)
@@ -728,12 +728,12 @@ namespace Mono.CSharp
                        
        public class Property : PropertyBase
        {
-               public sealed class BackingField : Field
+               public sealed class BackingFieldDeclaration : Field
                {
                        readonly Property property;
                        const Modifiers DefaultModifiers = Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | Modifiers.DEBUGGER_HIDDEN;
 
-                       public BackingField (Property p, bool readOnly)
+                       public BackingFieldDeclaration (Property p, bool readOnly)
                                : base (p.Parent, p.type_expr, DefaultModifiers | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
                                new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
                        {
@@ -756,8 +756,6 @@ namespace Mono.CSharp
 
                static readonly string[] attribute_target_auto = new string[] { "property", "field" };
 
-               Field backing_field;
-
                public Property (TypeDefinition parent, FullNamedExpression type, Modifiers mod,
                                 MemberName name, Attributes attrs)
                        : base (parent, type, mod,
@@ -768,6 +766,8 @@ namespace Mono.CSharp
                {
                }
 
+               public BackingFieldDeclaration BackingField { get; private set; }
+
                public Expression Initializer { get; set; }
 
                public override void Accept (StructuralVisitor visitor)
@@ -778,7 +778,7 @@ namespace Mono.CSharp
                public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
                {
                        if (a.Target == AttributeTargets.Field) {
-                               backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa);
+                               BackingField.ApplyAttributeBuilder (a, ctor, cdata, pa);
                                return;
                        }
 
@@ -788,20 +788,20 @@ namespace Mono.CSharp
                void CreateAutomaticProperty ()
                {
                        // Create backing field
-                       backing_field = new BackingField (this, Initializer != null && Set == null);
-                       if (!backing_field.Define ())
+                       BackingField = new BackingFieldDeclaration (this, Initializer == null && Set == null);
+                       if (!BackingField.Define ())
                                return;
 
                        if (Initializer != null) {
-                               backing_field.Initializer = Initializer;
-                               Parent.RegisterFieldForInitialization (backing_field, new FieldInitializer (backing_field, Initializer, Location));
-                               backing_field.ModFlags |= Modifiers.READONLY;
+                               BackingField.Initializer = Initializer;
+                               Parent.RegisterFieldForInitialization (BackingField, new FieldInitializer (BackingField, Initializer, Location));
+                               BackingField.ModFlags |= Modifiers.READONLY;
                        }
 
-                       Parent.PartialContainer.Members.Add (backing_field);
+                       Parent.PartialContainer.Members.Add (BackingField);
 
-                       FieldExpr fe = new FieldExpr (backing_field, Location);
-                       if ((backing_field.ModFlags & Modifiers.STATIC) == 0)
+                       FieldExpr fe = new FieldExpr (BackingField, Location);
+                       if ((BackingField.ModFlags & Modifiers.STATIC) == 0)
                                fe.InstanceExpression = new CompilerGeneratedThis (Parent.CurrentType, Location);
 
                        //
@@ -839,7 +839,7 @@ namespace Mono.CSharp
                                                GetSignatureForError ());
 
                                if (IsInterface)
-                                       Report.Error (8053, Location, "`{0}': Properties inside interfaces cannot have initializers",
+                                       Report.Error (8052, Location, "`{0}': Properties inside interfaces cannot have initializers",
                                                GetSignatureForError ());
 
                                if (Compiler.Settings.Version < LanguageVersion.V_6)
@@ -848,16 +848,11 @@ namespace Mono.CSharp
 
                        if (auto) {
                                if (Get == null) {
-                                       Report.Error (8052, Location, "Auto-implemented property `{0}' must have get accessor",
+                                       Report.Error (8051, Location, "Auto-implemented property `{0}' must have get accessor",
                                                GetSignatureForError ());
                                        return false;
                                }
 
-                               if (Initializer == null && AccessorSecond == null) {
-                                       Report.Error (8051, Location, "Auto-implemented property `{0}' must have set accessor or initializer",
-                                               GetSignatureForError ());
-                               }
-
                                if (Compiler.Settings.Version < LanguageVersion.V_3 && Initializer == null)
                                        Report.FeatureIsNotAvailable (Compiler, Location, "auto-implemented properties");
 
diff --git a/mcs/tests/gtest-autoproperty-11.cs b/mcs/tests/gtest-autoproperty-11.cs
new file mode 100644 (file)
index 0000000..dae2ebe
--- /dev/null
@@ -0,0 +1,30 @@
+using System;
+using System.Reflection;
+
+public class Test
+{
+       public string Property1 { get; }
+
+       public int Property2 { get; }
+
+       public static int Main ()
+       {
+               var t = new Test ();
+               if (t.Property1 != null)
+                       return 1;
+
+               if (t.Property2 != 0)
+                       return 2;
+
+               var fields = typeof (Test).GetFields(BindingFlags.NonPublic | BindingFlags.Instance);
+               if (fields.Length != 2)
+                       return 3;
+
+               foreach (var fi in fields) {
+                       if ((fi.Attributes & FieldAttributes.InitOnly) == 0)
+                               return 4;
+               }
+
+               return 0;
+       }       
+}
diff --git a/mcs/tests/gtest-autoproperty-12.cs b/mcs/tests/gtest-autoproperty-12.cs
new file mode 100644 (file)
index 0000000..c738c39
--- /dev/null
@@ -0,0 +1,48 @@
+using System;
+
+public class A
+{
+       public int X { get; }
+       public virtual int Y { get; }
+
+       public A ()
+       {
+               X = 4;
+               X++;
+
+               Y = 2;
+               Y++;
+       }
+}
+
+class B : A
+{
+       int i_get;
+
+       public override int Y { get { ++i_get; return base.Y; } }
+
+       public static int Main ()
+       {
+               var a = new A ();
+               if (a.X != 5)
+                       return 1;
+
+               if (a.Y != 3)
+                       return 2;
+
+               var b = new B ();
+               if (b.X != 5)
+                       return 3;
+
+               if (b.i_get != 1)
+                       return 4;
+
+               if (b.Y != 3)
+                       return 5;
+
+               if (b.i_get != 2)
+                       return 6;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/gtest-autoproperty-13.cs b/mcs/tests/gtest-autoproperty-13.cs
new file mode 100644 (file)
index 0000000..b6d84be
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+public struct S
+{
+       public int X { get; }
+       public int Y { get; }
+
+       public S ()
+       {
+               X = 4;
+               Y = X;
+       }
+
+       public static int Main()
+       {
+               var s = new S ();
+               if (s.Y != 4)
+                       return 1;
+
+               return 0;
+       }
+}
diff --git a/mcs/tests/gtest-autoproperty-14.cs b/mcs/tests/gtest-autoproperty-14.cs
new file mode 100644 (file)
index 0000000..8b250de
--- /dev/null
@@ -0,0 +1,14 @@
+public struct S
+{
+       public int A { get; set;}
+
+       public S (int a)
+       {
+               this.A = a;
+       }
+
+       public static void Main ()
+       {
+               
+       }
+}
\ No newline at end of file
index 3ca6157597266dd62aa2fe3f1aa4af429f1e6ff6..987869d2aad05fa2ee1edb48dc9848239b90a6f1 100644 (file)
@@ -8,6 +8,7 @@ using System.Reflection;
 [assembly: AssemblyTrademark ("Trademark")]
 [assembly: AssemblyVersion ("5.4.3.1")]
 [assembly: AssemblyFileVersion ("8.9")]
+[assembly: AssemblyTitle ("Title")]
 
 class C
 {
@@ -22,8 +23,8 @@ class C
                if (fv.CompanyName != "Company")
                        return 2;
 
-//             if (fv.Comments != "Description")
-//                     return 3;
+               if (fv.Comments != "Description")
+                       return 3;
 
                if (fv.LegalCopyright != "Copyright")
                        return 4;
@@ -34,6 +35,9 @@ class C
                if (fv.ProductVersion != "8.9")
                        return 6;
 
+               if (fv.FileDescription != "Title")
+                       return 7;
+
                return 0;
        }
 }
\ No newline at end of file
diff --git a/mcs/tests/test-908.cs b/mcs/tests/test-908.cs
new file mode 100644 (file)
index 0000000..fdc40f6
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -warnaserror
+
+public class Test
+{
+#pragma warning disable public
+#pragma warning disable CS1685
+#pragma warning disable CS1700, 1701
+
+       public static void Main ()
+       {
+       }
+#pragma warning restore CS1685
+#pragma warning restore public, 1701
+}
\ No newline at end of file
diff --git a/mcs/tests/test-909.cs b/mcs/tests/test-909.cs
new file mode 100644 (file)
index 0000000..8527bb9
--- /dev/null
@@ -0,0 +1,17 @@
+using System;
+
+public struct S
+{
+       public int A { get; private set;}
+       public event EventHandler eh;
+
+       public S (int a)
+       {
+               this.eh = null;
+               A = a;
+       }
+
+       public static void Main ()
+       {
+       }
+}
index ca08bdcbbb12cd27124bfe3c960929147e4d6e01..cd8b13f82e0a83d1bcd56425ee8afa8d470c097e 100644 (file)
       </method>\r
     </type>\r
   </test>\r
+  <test name="gtest-autoproperty-11.cs">\r
+    <type name="Test">\r
+      <method name="System.String get_Property1()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Int32 get_Property2()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>144</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="gtest-autoproperty-12.cs">\r
+    <type name="A">\r
+      <method name="Int32 get_X()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Int32 get_Y()" attrs="2502">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>50</size>\r
+      </method>\r
+    </type>\r
+    <type name="B">\r
+      <method name="Int32 get_Y()" attrs="2246">\r
+        <size>29</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>136</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="gtest-autoproperty-13.cs">\r
+    <type name="S">\r
+      <method name="Int32 get_X()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Int32 get_Y()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>37</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>21</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="gtest-autoproperty-14.cs">\r
+    <type name="S">\r
+      <method name="Int32 get_A()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Void set_A(Int32)" attrs="2182">\r
+        <size>8</size>\r
+      </method>\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void .ctor(Int32)" attrs="6278">\r
+        <size>9</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="gtest-collectioninit-01.cs">\r
     <type name="Test">\r
       <method name="Void TestList(System.Collections.Generic.List`1[System.Int32], Int32)" attrs="145">\r
   <test name="test-868.cs">\r
     <type name="C">\r
       <method name="Int32 Main()" attrs="150">\r
-        <size>168</size>\r
+        <size>224</size>\r
       </method>\r
       <method name="Void .ctor()" attrs="6278">\r
         <size>7</size>\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-908.cs">\r
+    <type name="Test">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-909.cs">\r
+    <type name="S">\r
+      <method name="Int32 get_A()" attrs="2182">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Void set_A(Int32)" attrs="2177">\r
+        <size>8</size>\r
+      </method>\r
+      <method name="Void add_eh(System.EventHandler)" attrs="2182">\r
+        <size>42</size>\r
+      </method>\r
+      <method name="Void remove_eh(System.EventHandler)" attrs="2182">\r
+        <size>42</size>\r
+      </method>\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void .ctor(Int32)" attrs="6278">\r
+        <size>16</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-91.cs">\r
     <type name="Abstract">\r
       <method name="Void .ctor()" attrs="6276">\r
index b79dd7b886a96bee9efbf21a1ea07a8176236729..fb326624ba5dfe312dd8fc557b53e6cf7a836285 100644 (file)
@@ -74,6 +74,10 @@ namespace Xamarin.ApiDiff {
                        get { return ignoreRemoved; }
                }
 
+               public  static  bool    IgnoreParameterNameChanges  { get; set; }
+               public  static  bool    IgnoreVirtualChanges        { get; set; }
+               public  static  bool    IgnoreAddedPropertySetters  { get; set; }
+
                public static bool Lax;
        }
 
@@ -105,6 +109,15 @@ namespace Xamarin.ApiDiff {
                                { "n|ignore-new=", "Ignore new namespaces and types whose description matches a given C# regular expression (see below).",
                                        v => State.IgnoreNew.Add (new Regex (v))
                                },
+                               { "ignore-changes-parameter-names", "Ignore changes to parameter names for identically prototyped methods.",
+                                       v => State.IgnoreParameterNameChanges   = v != null
+                               },
+                               { "ignore-changes-property-setters", "Ignore adding setters to properties.",
+                                       v => State.IgnoreAddedPropertySetters = v != null
+                               },
+                               { "ignore-changes-virtual", "Ignore changing non-`virtual` to `virtual` or adding `override`.",
+                                       v => State.IgnoreVirtualChanges = v != null
+                               },
                                { "x|lax", "Ignore duplicate XML entries", v => State.Lax = true }
                        };
 
index ffef2e010509c78982f8c44178a5fe9e1a9fb0e0..66dfeb004375965a77add19d7abd98754e5e53a5 100644 (file)
@@ -99,7 +99,10 @@ namespace Xamarin.ApiDiff {
                        if (parameters != null) {
                                var list = new List<string> ();
                                foreach (var p in parameters.Elements ("parameter")) {
-                                       list.Add (p.GetTypeName ("type") + " " + p.GetAttribute ("name"));
+                                       var pTypeName   = p.GetTypeName ("type");
+                                       list.Add (State.IgnoreParameterNameChanges
+                                               ? pTypeName
+                                               : pTypeName + " " + p.GetAttribute ("name"));
                                }
                                sb.Append (String.Join (", ", list));
                        }
index 0a646c7a2a26f392cacef89ef548c252f4aa28c1..839de88a4a2698620c7ab4102d77a74878728682 100644 (file)
@@ -177,7 +177,25 @@ namespace Xamarin.ApiDiff {
                        if (base.Equals (source, target))
                                return true;
 
-                       return GetDescription (source) == GetDescription (target);
+                       string sourceDescription = GetDescription (source);
+                       string targetDescription = GetDescription (target);
+
+                       return CheckVirtualChanges (sourceDescription, targetDescription) ||
+                               (State.IgnoreAddedPropertySetters &&
+                                       CheckVirtualChanges (sourceDescription, targetDescription.Replace (" set; ", " ")));
+               }
+
+               static bool CheckVirtualChanges (string sourceDescription, string targetDescription)
+               {
+                       return (sourceDescription == targetDescription) ||
+                               // *adding* virtual or override to target is acceptable; *removing* them is NOT
+                               (State.IgnoreVirtualChanges &&
+                                       // non-virtual to virtual is fine
+                                       (sourceDescription == targetDescription.Replace ("virtual ", "")) ||
+                                       // non-virtual to override is fine
+                                       (sourceDescription == targetDescription.Replace ("override ", "")) ||
+                                       // virtual to override is fine
+                                       (sourceDescription.Replace (" virtual ", " override ") == targetDescription));
                }
 
                bool IsNowObsoleted (XElement source, XElement target)
index 0d0a9bdd548dc3112d54a97d2760affc8cff90ee..4a5f34fd2ec8978d0b94cf5788e4f03ec1be8bca 100644 (file)
@@ -77,7 +77,7 @@ namespace Xamarin.ApiDiff {
                        var sb = new StringBuilder ();
 
                        sb.Append (family ? "protected " : "public ");
-                       if (virt)
+                       if (virt && !State.IgnoreVirtualChanges)
                                sb.Append (over ? "override " : "virtual ");
                        else if (stat)
                                sb.Append ("static ");
index 745c51531f0ded0d5d42cac68ce4a6d0f7af2265..9337d6d75453778d6a0c8e9210ad32414a7fc7a1 100644 (file)
     <typeparam name="T">To be added.</typeparam>
     <param name="obj">The object on which to perform an action.</param>
     <summary>
-      <para> Represents the method that performs an action on the specified object.</para>
-    </summary>
+                                       <para> Represents the method that performs an action on the specified object.</para>
+                               </summary>
     <remarks>
-      <block subset="none" type="note">
-        <para>This delegate is used by the method <see cref="M:System.Array.ForEach" /><see langword="(T[], Action&lt;T&gt;)" />, and in <see cref="T:System.Collections.Generic.List&lt;T&gt;" /> to perform an action on each element of the collection.</para>
-      </block>
-    </remarks>
+                                       <block subset="none" type="note">
+                                               <para>This delegate is used by the method <see cref="M:System.Array.ForEach" />
+                                                       <see langword="(T[], Action&lt;T&gt;)" />, and in <see cref="T:System.Collections.Generic.List&lt;T&gt;" /> to perform an action on each element of the collection.</para>
+                                       </block>
+                               </remarks>
   </Docs>
 </Type>
index 96aee607a9951683ebd223f8b5efe2fde0c539cd..91084a09c58f6ed99724bb8df72bcb139569480e 100644 (file)
   <Interfaces />
   <Docs>
     <summary>
-      <para> Serves as the base class for arrays. Provides methods for creating,
+                                       <para> Serves as the base class for arrays. Provides methods for creating,
       copying, manipulating, searching, and sorting arrays.</para>
-    </summary>
+                               </summary>
     <remarks>
-      <para>This class is intended to be used as a base class by
+                                       <para>This class is intended to be used as a base class by
       language implementations that support arrays. Only the system can derive from
       this type: derived classes of <see cref="T:System.Array" /> are not to be created by the developer.</para>
-      <block subset="none" type="note">
-        <para>An array is a collection of
+                                       <block subset="none" type="note">
+                                               <para>An array is a collection of
          identically typed data <paramref name="elements" /> that are accessed and referenced by
          sets of integral <paramref name="indices" />. </para>
-        <para>The <paramref name="rank" /> of an array is the number
+                                               <para>The <paramref name="rank" /> of an array is the number
       of dimensions in the array. Each dimension has its own set of indices. An array
       with a rank greater than one can have a different lower
       bound and a different number of elements for each dimension. Multidimensional
       arrays (i.e. arrays with a rank greater than one) are processed in row-major
       order. </para>
-        <para>The <paramref name="lower bound" /> of a dimension
+                                               <para>The <paramref name="lower bound" /> of a dimension
    is the starting index of that dimension. </para>
-        <para>The <paramref name="length" /> of an array is the total number of elements contained in all of its
+                                               <para>The <paramref name="length" /> of an array is the total number of elements contained in all of its
 dimensions. </para>
-        <para>A <paramref name="vector" /> is a
+                                               <para>A <paramref name="vector" /> is a
 one-dimensional array with a <paramref name="lower bound" /> of '0'. </para>
-        <para>If the implementer creates a derived class of <see cref="T:System.Array" />, expected <see cref="T:System.Array" /> behavior
+                                               <para>If the implementer creates a derived class of <see cref="T:System.Array" />, expected <see cref="T:System.Array" /> behavior
 cannot be guaranteed. For information on array-like objects with increased
 functionality, see the <see cref="T:System.Collections.IList" /> and <see cref="T:System.Collections.Generic.IList&lt;T&gt;" /> interfaces. For more information regarding the use of arrays versus the use
 of collections, see Partition V of the CLI Specification. </para>
-      </block>
-      <para>Every specific <see cref="T:System.Array" /> type has three instance methods defined on it.
+                                       </block>
+                                       <para>Every specific <see cref="T:System.Array" /> type has three instance methods defined on it.
    While some programming languages allow direct access to these methods, they are
    primarily intended to be called by the output of compilers based on language
    syntax that deals with arrays. </para>
-      <list type="bullet">
-        <item>
-          <term>
-            <para>
-              <c>Get</c>: Takes as many <see cref="T:System.Int32" /> arguments as the array
+                                       <list type="bullet">
+                                               <item>
+                                                       <term>
+                                                               <para>
+                                                                       <c>Get</c>: Takes as many <see cref="T:System.Int32" /> arguments as the array
    has dimensions and returns the value stored at the given index. It throws a
 <see cref="T:System.IndexOutOfRangeException" /> 
 exception for invalid indices. </para>
-          </term>
-        </item>
-        <item>
-          <term>
-            <para>
-              <c>Set</c>: Takes as many <see cref="T:System.Int32" /> arguments as the array
+                                                       </term>
+                                               </item>
+                                               <item>
+                                                       <term>
+                                                               <para>
+                                                                       <c>Set</c>: Takes as many <see cref="T:System.Int32" /> arguments as the array
    has dimensions, plus one additional argument (the last argument) which has the
    same type as an array element. It stores the final value in the specified
    index of the array. It throws a <see cref="T:System.IndexOutOfRangeException" />
    exception for invalid indices. </para>
-          </term>
-        </item>
-        <item>
-          <term>
-            <para>
-              <c>Address</c>: Takes as many <see cref="T:System.Int32" /> arguments as the
+                                                       </term>
+                                               </item>
+                                               <item>
+                                                       <term>
+                                                               <para>
+                                                                       <c>Address</c>: Takes as many <see cref="T:System.Int32" /> arguments as the
    array has dimensions and returns the address of the element at the given index.
    It throws a <see cref="T:System.IndexOutOfRangeException" />
    exception for invalid indices. </para>
-          </term>
-        </item>
-      </list>
-      <para>In addition, every specific <see cref="T:System.Array" /> type has a constructor on it that takes as many non-negative 
+                                                       </term>
+                                               </item>
+                                       </list>
+                                       <para>In addition, every specific <see cref="T:System.Array" /> type has a constructor on it that takes as many non-negative 
 <see cref="T:System.Int32" /> 
 arguments as the array has dimensions. The arguments specify the
 number of elements in each dimension, and a lower bound of 0. Thus, a
 two-dimensional array of <see cref="T:System.Int32" /> objects would have a constructor that could be called with
 <c>(2, 4)</c> as its arguments to create an array of eight zeros with the first dimension indexed
 with 0 and 1 and the second dimension indexed with 0, 1, 2, and 3. </para>
-      <para>For all specific array types except vectors (i.e. those
+                                       <para>For all specific array types except vectors (i.e. those
    permitted to have non-zero lower bounds and those with more than one dimension)
    there is an additional constructor. It takes twice as many arguments as the
    array has dimensions. The arguments are considered in pairs, with the first of
@@ -91,9 +91,9 @@ with 0 and 1 and the second dimension indexed with 0, 1, 2, and 3. </para>
    objects would also have a constructor that could be called with <c>(-1, 2, 1, 3)</c> as its arguments,
 specifying an array of 6 zeros, with the first dimension indexed by -1 and 0,
 and the second dimension indexed by 1, 2, and 3. </para>
-      <para>Enumeration over an array occurs in ascending row-major order, starting from the first element. (For example, a 2x3 array is traversed in the order [0,0], [0,1], [0,2], [1,0], [1,1], and [1,2].)</para>
-      <para>Parallel implementation of methods taking a <see cref="T:System.Predicate" /> argument are not permitted.</para>
-    </remarks>
+                                       <para>Enumeration over an array occurs in ascending row-major order, starting from the first element. (For example, a 2x3 array is traversed in the order [0,0], [0,1], [0,2], [1,0], [1,1], and [1,2].)</para>
+                                       <para>Parallel implementation of methods taking a <see cref="T:System.Predicate" /> argument are not permitted.</para>
+                               </remarks>
   </Docs>
   <Members>
     <Member MemberName=".ctor">
@@ -158,21 +158,21 @@ and the second dimension indexed by 1, 2, and 3. </para>
         <typeparam name="TOutput">To be added.</typeparam>
         <param name="array">The one-dimensional array to convert.</param>
         <param name="converter">
-          <para>A <see cref="T:System.Converter&lt;T,U&gt;" /> that converts each element from one type to another type.</para>
-        </param>
+                                                       <para>A <see cref="T:System.Converter&lt;T,U&gt;" /> that converts each element from one type to another type.</para>
+                                               </param>
         <summary>
-          <para>Converts an array of one type to an array of another type.</para>
-        </summary>
+                                                       <para>Converts an array of one type to an array of another type.</para>
+                                               </summary>
         <returns>
-          <para>A new array of the target type containing the converted elements from <paramref name="array" />.</para>
-        </returns>
+                                                       <para>A new array of the target type containing the converted elements from <paramref name="array" />.</para>
+                                               </returns>
         <remarks>
-          <para>The <see cref="T:System.Converter&lt;T,U&gt;" /> is a delegate that converts an array element to the target type.  The elements of  <paramref name="array" /> are individually passed to this converter, and the converted elements are saved in the new array. The source array remains unchanged.</para>
-        </remarks>
+                                                       <para>The <see cref="T:System.Converter&lt;T,U&gt;" /> is a delegate that converts an array element to the target type.  The elements of  <paramref name="array" /> are individually passed to this converter, and the converted elements are saved in the new array. The source array remains unchanged.</para>
+                                               </remarks>
         <exception cref="T:System.InvalidOperationException">To be added; from:
           <see cref="M:System.Array.ConvertAll``2(``0[],System.Converter{``0,``1})" /></exception>
         <exception cref="T:System.ArgumentNullException">
-          <paramref name="array" /> is <see langword="null" /> or <paramref name="converter" /> is <see langword="null" />.</exception>
+                                                       <paramref name="array" /> is <see langword="null" /> or <paramref name="converter" /> is <see langword="null" />.</exception>
       </Docs>
     </Member>
     <Member MemberName="Resize&lt;T&gt;">
index a232e3c2499f9c5a33844cbcc36a7b24be2df886..b5bcde6da4089d96ff3b68da1a0937650bf6c1e7 100644 (file)
@@ -17,8 +17,8 @@
   <Docs>
     <param name="ar">A <see cref="T:System.IAsyncResult" /> object containing information about the asynchronous operation that has completed.</param>
     <summary>
-      <para> References one or more methods called when an asynchronous operation completes.</para>
-    </summary>
+                                       <para> References one or more methods called when an asynchronous operation completes.</para>
+                               </summary>
     <remarks>To be added.</remarks>
   </Docs>
 </Type>
index f7a5f40c8f45795f4b9a60438039b3eebeba5e4d..40a9735e1164df25d895fb0cd903598c71f7a846 100644 (file)
   <Interfaces />
   <Docs>
     <summary>
-      <para> Provides the current settings for, and information about, the execution environment.</para>
-    </summary>
+                                       <para> Provides the current settings for, and information about, the execution environment.</para>
+                               </summary>
     <remarks>
-      <block subset="none" type="note">
-        <para>Use this class to retrieve the following 
+                                       <block subset="none" type="note">
+                                               <para>Use this class to retrieve the following 
  information:</para>
-        <list type="bullet">
-          <item>
-            <term>Command line arguments</term>
-          </item>
-          <item>
-            <term>Exit codes</term>
-          </item>
-          <item>
-            <term>Environment variable settings</term>
-          </item>
-          <item>
-            <term>Contents of the call stack</term>
-          </item>
-          <item>
-            <term>Time since last system boot</term>
-          </item>
-          <item>
-            <term>Version of the execution engine</term>
-          </item>
-        </list>
-      </block>
-    </remarks>
+                                               <list type="bullet">
+                                                       <item>
+                                                               <term>Command line arguments</term>
+                                                       </item>
+                                                       <item>
+                                                               <term>Exit codes</term>
+                                                       </item>
+                                                       <item>
+                                                               <term>Environment variable settings</term>
+                                                       </item>
+                                                       <item>
+                                                               <term>Contents of the call stack</term>
+                                                       </item>
+                                                       <item>
+                                                               <term>Time since last system boot</term>
+                                                       </item>
+                                                       <item>
+                                                               <term>Version of the execution engine</term>
+                                                       </item>
+                                               </list>
+                                       </block>
+                               </remarks>
   </Docs>
   <Members>
     <Member MemberName="GetFolderPath">
       </Parameters>
       <Docs>
         <param name="folder">
-          <para>A <see cref="T:System.Environment+SpecialFolder" />.</para>
-        </param>
+                                                       <para>A <see cref="T:System.Environment+SpecialFolder" />.</para>
+                                               </param>
         <summary>
-          <para> Returns the arguments specified on the command
+                                                       <para> Returns the arguments specified on the command
       line.</para>
-        </summary>
+                                               </summary>
         <returns>
-          <para> Returns a <see cref="T:System.String" /> array. Each <see cref="T:System.String" /> in the array
+                                                       <para> Returns a <see cref="T:System.String" /> array. Each <see cref="T:System.String" /> in the array
    contains a single command line argument.</para>
-        </returns>
+                                               </returns>
         <remarks>
-          <para>The first element in the array contains the filename of
+                                                       <para>The first element in the array contains the filename of
       the executing program. If the filename is not available, the first element is
       equal to <see cref="F:System.String.Empty" />. The remaining elements contain any additional tokens
       entered on the command line.</para>
-          <block subset="none" type="note">
-            <para>The program filename can, but is not required to,
+                                                       <block subset="none" type="note">
+                                                               <para>The program filename can, but is not required to,
          include path information.</para>
-            <para>To obtain the command line as a single <see cref="T:System.String" />, use the <see cref="P:System.Environment.CommandLine" />
+                                                               <para>To obtain the command line as a single <see cref="T:System.String" />, use the <see cref="P:System.Environment.CommandLine" />
    property.</para>
-          </block>
-        </remarks>
+                                                       </block>
+                                               </remarks>
         <exception cref="T:System.NotSupportedException">To be added; from:
           <see cref="M:System.Environment.GetFolderPath(System.Environment.SpecialFolder)" /></exception>
         <exception cref="T:System.ArgumentException">foo</exception>
index 5e8dd82bd0a4cc507a116193f215b5f0e967b128..05c24763cdeaed4ac7bfc12aa0b87e441e5792e0 100644 (file)
@@ -76,14 +76,17 @@ EXTRA_DISTFILES = \
        data/3.5/Microsoft.Common.tasks \
        data/4.0/Microsoft.Common.tasks \
        data/12.0/Microsoft.Common.tasks \
+       data/14.0/Microsoft.Common.tasks \
        data/2.0/Microsoft.Common.targets \
        data/3.5/Microsoft.Common.targets \
        data/4.0/Microsoft.Common.targets \
        data/12.0/Microsoft.Common.targets \
+       data/14.0/Microsoft.Common.targets \
        data/2.0/Microsoft.CSharp.targets \
        data/3.5/Microsoft.CSharp.targets \
        data/4.0/Microsoft.CSharp.targets \
        data/12.0/Microsoft.CSharp.targets \
+       data/14.0/Microsoft.CSharp.targets \
        data/Microsoft.VisualBasic.targets \
        data/MSBuild/Microsoft.Build.CommonTypes.xsd \
        data/MSBuild/Microsoft.Build.Core.xsd \
index 47ae1d9c0448332bba287d202e754d40e6929974..738ca70791c52e8fc50bbdef7ed9ec81c1fdd1c9 100644 (file)
@@ -121,7 +121,9 @@ namespace Mono.XBuild.CommandLine {
                        string slnVersion = GetSlnFileVersion (reader);
 
                        if (slnVersion == "12.00")
-#if XBUILD_12
+#if XBUILD_14
+                               p.DefaultToolsVersion = "14.0";
+#elif XBUILD_12
                                p.DefaultToolsVersion = "12.0";
 #else
                                p.DefaultToolsVersion = "4.0";
index dec250204d2cb204e1538ef110e1eedcd03ceaa0..5ea1279f034c34e896e4dc8417b970b756d9dafa 100644 (file)
@@ -1,6 +1,10 @@
-class XBuildConsts
+static class XBuildConsts
 {
-#if XBUILD_12
+#if XBUILD_14
+       public const string Version = "14.0";
+       public const string AssemblyVersion = "14.0.0.0";
+       public const string FileVersion     = "14.0.22310.1";
+#elif XBUILD_12
        public const string Version = "12.0";
        public const string AssemblyVersion = "12.0.0.0";
        public const string FileVersion     = "12.0.21005.1";
diff --git a/mcs/tools/xbuild/data/14.0/Microsoft.CSharp.targets b/mcs/tools/xbuild/data/14.0/Microsoft.CSharp.targets
new file mode 100644 (file)
index 0000000..11b40d6
--- /dev/null
@@ -0,0 +1,142 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+       <PropertyGroup>
+               <DefaultLanguageSourceExtension>.cs</DefaultLanguageSourceExtension>
+               <Language>C#</Language>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <DebugSymbols Condition=" '$(DebugType)' == 'none' ">false</DebugSymbols>
+               <DebugType    Condition=" '$(DebugType)' == 'none' "></DebugType>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <CreateManifestResourceNamesDependsOn></CreateManifestResourceNamesDependsOn>
+               <CoreCompileDependsOn></CoreCompileDependsOn>
+
+               <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildToolsPath)\Microsoft.CSharp.targets</MSBuildAllProjects>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <NoCompilerStandardLib Condition="'$(NoCompilerStandardLib)'==''">true</NoCompilerStandardLib>
+       </PropertyGroup>
+
+       <ItemGroup>
+               <DocFileItem Include="$(DocumentationFile)" Condition="'$(DocumentationFile)' != ''"/>
+       </ItemGroup>
+
+       <Target Name="_AddCorlibReference" DependsOnTargets="GetReferenceAssemblyPaths">
+               <!--
+               HACK: We don't yet support property functions, so can't calculate FrameworkPathOverride
+               by calling ToolLocationHelper.GetPathToStandardLibraries. Instead, we search the framework
+               directories for mscorlib.dll by constructing a filtered item set, and assume it only has
+               one item.
+               -->
+               <ItemGroup Condition="'$(MonoUseMicrosoftBuildDll)' != 'True'">
+                       <_ExplicitReference Include="@(_TargetFrameworkDirectories->'%(FullPath)\mscorlib.dll')" Condition="Exists('%(FullPath)\mscorlib.dll')">
+                               <Private>false</Private>
+                       </_ExplicitReference>
+               </ItemGroup>
+               <PropertyGroup Condition="'$(MonoUseMicrosoftBuildDll)' == 'True'">
+                       <_ExplicitMSCorlibPath>$([Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToStandardLibraries ('$(TargetFrameworkIdentifier)', '$(TargetFrameworkVersion)', '$(TargetFrameworkProfile)'))\mscorlib.dll</_ExplicitMSCorlibPath>
+               </PropertyGroup>
+               <ItemGroup Condition="'$(MonoUseMicrosoftBuildDll)' == 'True'">
+                       <_ExplicitReference Include="@(_TargetFrameworkDirectories->'%(FullPath)\mscorlib.dll')" Condition="Exists('%(FullPath)\mscorlib.dll')">
+                               <Private>false</Private>
+                       </_ExplicitReference>
+               </ItemGroup>
+               <ItemGroup Condition="'$(MonoUseMicrosoftBuildDll)' == 'True'">
+                       <_ExplicitReference Include="$(_ExplicitMSCorlibPath)" Condition="Exists('$(_ExplicitMSCorlibPath)')">
+                               <Private>false</Private>
+                       </_ExplicitReference>
+               </ItemGroup>
+       </Target>
+
+       <Target
+               Name="CoreCompile"
+               Inputs="$(MSBuildAllProjects);@(Compile);@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile);
+                       $(KeyOriginatorFile);@(ReferencePath);$(Win32Icon);$(Win32Resource)"
+               Outputs="@(DocFileItem);@(IntermediateAssembly)"
+               DependsOnTargets="$(CoreCompileDependsOn)"
+       >
+               <Csc
+                       AdditionalLibPaths="$(AdditionalLibPaths)"
+                       AddModules="@(AddModules)"
+                       AllowUnsafeBlocks="$(AllowUnsafeBlocks)"
+                       BaseAddress="$(BaseAddress)"
+                       CheckForOverflowUnderflow="$(CheckForOverflowUnderflow)"
+                       CodePage="$(CodePage)"
+                       DebugType="$(DebugType)"
+                       DefineConstants="$(DefineConstants)"
+                       DelaySign="$(DelaySign)"
+                       DisabledWarnings="$(NoWarn)"
+                       DocumentationFile="@(DocFileItem)"
+                       EmitDebugInformation="$(DebugSymbols)"
+                       ErrorReport="$(ErrorReport)"
+                       FileAlignment="$(FileAlignment)"
+                       GenerateFullPaths="$(GenerateFullPaths)"
+                       KeyContainer="$(KeyContainerName)"
+                       KeyFile="$(KeyOriginatorFile)"
+                       LangVersion="$(LangVersion)"
+                       MainEntryPoint="$(StartupObject)"
+                       ModuleAssemblyName="$(ModuleAssemblyName)"
+                       NoConfig="true"
+                       NoLogo="$(NoLogo)"
+                       NoStandardLib="$(NoCompilerStandardLib)"
+                       Optimize="$(Optimize)"
+                       OutputAssembly="@(IntermediateAssembly)"
+                       PdbFile="$(PdbFile)"
+                       Platform="$(PlatformTarget)"
+                       References="@(ReferencePath)"
+                       ResponseFiles="$(CompilerResponseFile)"
+                       Sources="@(Compile)"
+                       TargetType="$(OutputType)"
+                       TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
+                       UseHostCompilerIfAvailable="$(UseHostCompilerIfAvailable)"
+                       Utf8Output="$(Utf8Output)"
+                       WarningLevel="$(WarningLevel)"
+                       WarningsAsErrors="$(WarningsAsErrors)"
+                       WarningsNotAsErrors="$(WarningsNotAsErrors)"
+                       Win32Icon="$(Win32Icon)"
+                       Win32Resource="$(Win32Resource)"
+                       Resources="@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile)"
+                       ToolExe="$(CscToolExe)"
+                       ToolPath="$(CscToolPath)" />
+
+       </Target>
+
+       <Target Name="CreateManifestResourceNames">
+               <CreateCSharpManifestResourceName Condition="'@(ResxWithNoCulture)' != ''"
+                       ResourceFiles="@(ResxWithNoCulture)" RootNamespace="$(RootNamespace)">
+                       <Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestResourceWithNoCultureName" />
+               </CreateCSharpManifestResourceName>
+
+               <CreateCSharpManifestResourceName Condition="'@(NonResxWithNoCulture)' != ''"
+                       ResourceFiles="@(NonResxWithNoCulture)" RootNamespace="$(RootNamespace)">
+                       <Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestNonResxWithNoCulture" />
+               </CreateCSharpManifestResourceName>
+
+               <CreateCSharpManifestResourceName Condition="'@(ResxWithCulture)' != ''"
+                       ResourceFiles="@(ResxWithCulture)" RootNamespace="$(RootNamespace)">
+                       <Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestResourceWithCultureName" />
+               </CreateCSharpManifestResourceName>
+
+               <CreateCSharpManifestResourceName Condition="'@(NonResxWithCulture)' != ''"
+                       ResourceFiles="@(NonResxWithCulture)" RootNamespace="$(RootNamespace)">
+                       <Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestNonResxWithCulture" />
+               </CreateCSharpManifestResourceName>
+       </Target>
+
+       <Import Project="Microsoft.Common.targets" />
+
+       <PropertyGroup Condition="'$(NoCompilerStandardLib)'=='true' and '$(NoStdLib)'!='true'">
+               <ResolveAssemblyReferencesDependsOn>$(ResolveAssemblyReferencesDependsOn);_AddCorlibReference</ResolveAssemblyReferencesDependsOn>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <TargetFrameworkMonikerAssemblyAttributeText Condition="'$(TargetFrameworkMoniker)' != '' and '$(TargetingClr2Framework)' != 'true'">
+// &lt;autogenerated /&gt;
+[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(&quot;$(TargetFrameworkMoniker)&quot;, FrameworkDisplayName = &quot;$(TargetFrameworkMonikerDisplayName)&quot;)]
+               </TargetFrameworkMonikerAssemblyAttributeText>
+       </PropertyGroup>
+
+</Project>
diff --git a/mcs/tools/xbuild/data/14.0/Microsoft.Common.targets b/mcs/tools/xbuild/data/14.0/Microsoft.Common.targets
new file mode 100644 (file)
index 0000000..d420c09
--- /dev/null
@@ -0,0 +1,922 @@
+<Project DefaultTargets="Build" InitialTargets="_ValidateEssentialProperties" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+       <PropertyGroup>
+               <ImportByWildcardBeforeMicrosoftCommonTargets Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == ''">true</ImportByWildcardBeforeMicrosoftCommonTargets>
+               <ImportByWildcardAfterMicrosoftCommonTargets Condition="'$(ImportByWildcardAfterMicrosoftCommonTargets)' == ''">true</ImportByWildcardAfterMicrosoftCommonTargets>
+       </PropertyGroup>
+
+       <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\*"
+               Condition="'$(ImportByWildcardBeforeMicrosoftCommonTargets)' == 'true' and Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore')"/>
+
+       <Import Project="$(MSBuildProjectFullPath).user" Condition="Exists('$(MSBuildProjectFullPath).user')"/>
+
+       <PropertyGroup>
+               <OutputType Condition="'$(OutputType)' == ''">Exe</OutputType>
+               <TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
+               <TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
+               <TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
+               <TargetExt Condition="'$(OutputType)' == 'Netmodule'">.netmodule</TargetExt>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <ProjectDir Condition="'$(ProjectDir)' == ''">$(MSBuildProjectDirectory)\</ProjectDir>
+       </PropertyGroup>
+
+       <!-- MSBuild defines this even outside of VS, and F# projects depend on it -->
+       <PropertyGroup>
+               <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
+               <OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath>
+               <OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
+               <WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
+
+               <TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">.NETFramework</TargetFrameworkIdentifier>
+               <TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v4.0</TargetFrameworkVersion>
+
+               <TargetFrameworkMoniker Condition="'$(TargetFrameworkMoniker)' == '' and '$(TargetFrameworkProfile)' != ''">$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion),Profile=$(TargetFrameworkProfile)</TargetFrameworkMoniker>
+               <TargetFrameworkMoniker Condition="'$(TargetFrameworkMoniker)' == ''">$(TargetFrameworkIdentifier),Version=$(TargetFrameworkVersion)</TargetFrameworkMoniker>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <OutDir Condition="'$(OutDir)' == ''">$(OutputPath)</OutDir>
+               <OutDir Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')">$(OutDir)\</OutDir>
+
+               <_OriginalConfiguration>$(Configuration)</_OriginalConfiguration>
+               <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+               <ConfigurationName Condition="'$(ConfigurationName)' == ''">$(Configuration)</ConfigurationName>
+
+               <_OriginalPlatform>$(Platform)</_OriginalPlatform>
+               <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+               <PlatformName Condition="'$(PlatformName)' == ''">$(Platform)</PlatformName>
+
+               <AddAdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == ''">true</AddAdditionalExplicitAssemblyReferences>
+               <AdditionalExplicitAssemblyReferences Condition="'$(AddAdditionalExplicitAssemblyReferences)' == 'true' and '$(TargetFrameworkVersion)' != 'v2.0' and '$(TargetFrameworkVersion)' != 'v3.0'">System.Core;$(AdditionalExplicitAssemblyReferences)</AdditionalExplicitAssemblyReferences>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <SkipCopyUnchangedFiles Condition="'$(SkipCopyUnchangedFiles)' == ''">true</SkipCopyUnchangedFiles>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' == ''">obj\</BaseIntermediateOutputPath>
+               <BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)' != '' and !HasTrailingSlash('$(BaseIntermediateOutputPath)')">$(BaseIntermediateOutputPath)\</BaseIntermediateOutputPath>
+               <CleanFile Condition="'$(CleanFile)'==''">$(MSBuildProjectFile).FilesWrittenAbsolute.txt</CleanFile>
+       </PropertyGroup>
+
+       <PropertyGroup Condition="'$(IntermediateOutputPath)' == ''">
+               <IntermediateOutputPath Condition=" '$(PlatformName)' == 'AnyCPU'">$(BaseIntermediateOutputPath)$(Configuration)\</IntermediateOutputPath>
+               <IntermediateOutputPath Condition=" '$(PlatformName)' != 'AnyCPU'">$(BaseIntermediateOutputPath)$(PlatformName)\$(Configuration)\</IntermediateOutputPath>
+       </PropertyGroup>
+
+       <PropertyGroup>
+               <IntermediateOutputPath Condition="'$(IntermediateOutputPath)' != '' and !HasTrailingSlash('$(IntermediateOutputPath)')">$(IntermediateOutputPath)\</IntermediateOutputPath>
+       </PropertyGroup>
+
+       <ItemGroup>
+               <IntermediateAssembly Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt)" />
+
+               <!-- creating this as a item to use FullPath on it, to build TargetPath -->
+               <_OutDirItem Include="$(OutDir)"/>
+       </ItemGroup>
+
+       <PropertyGroup>
+               <TargetName Condition="'$(TargetName)' == '' ">$(AssemblyName)</TargetName>
+               <TargetFileName Condition="'$(TargetFileName)' == '' ">$(TargetName)$(TargetExt)</TargetFileName>
+               <TargetDir Condition=" '$(TargetDir)' == '' ">@(_OutDirItem->'%(FullPath)')</TargetDir>
+               <TargetPath Condition=" '$(TargetPath)' == '' ">@(_OutDirItem->'%(FullPath)\$(TargetFileName)')</TargetPath>
+               <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildProjectFullPath);$(MSBuildToolsPath)\Microsoft.Common.targets</MSBuildAllProjects>
+               <KeyOriginatorFile Condition=" '$(SignAssembly)' == 'true' ">$(AssemblyOriginatorKeyFile)</KeyOriginatorFile>
+               <TargetingClr2Framework Condition="('$(TargetFrameworkIdentifier)' == '.NETFramework') and ('$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5')">true</TargetingClr2Framework>
+       </PropertyGroup>
+
+       <Target Name="_ValidateEssentialProperties">
+               <Error Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' != 'true'"
+                       Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+               <Warning Condition=" '$(OutputPath)' == '' and '$(SkipInvalidConfigurations)' == 'true'"
+                       Text="'OutputPath' property is not set for this project. Usually this is caused by invalid Configuration/Platform combination. Original values: Configuration: $(_OriginalConfiguration) Platform: $(_OriginalPlatform)."/>
+
+               <!-- If OutDir is specified via the command line, then the earlier check
+                    to add a trailing slash won't have any affect, so error here. -->
+               <Error
+                       Condition="'$(OutDir)' != '' and !HasTrailingSlash('$(OutDir)')"
+                       Text="OutDir property must end with a slash."/>
+       </Target>
+
+       <Target Name="PrepareForBuild">
+               <Message Importance="High" Text="Configuration: $(Configuration) Platform: $(Platform)"/>
+
+               <!-- Look for app.config, if $(AppConfig) is specified, then use that. Else look in
+                    @(None) and @(Content) -->
+               <CreateItem Include="$(AppConfig)" Condition="'$(AppConfig)' != ''"
+                       AdditionalMetadata="TargetPath=$(TargetFileName).config">
+                       <Output TaskParameter="Include" ItemName="AppConfigWithTargetPath" />
+               </CreateItem>
+
+               <FindAppConfigFile PrimaryList="@(None)" SecondaryList="@(Content)" TargetPath="$(TargetFileName).config"
+                       Condition="'$(AppConfig)' == ''">
+                       <Output TaskParameter="AppConfigFile" ItemName="AppConfigWithTargetPath"/>
+               </FindAppConfigFile>
+
+               <MakeDir
+                       Directories="$(OutDir);$(IntermediateOutputPath);@(DocFileItem->'%(RelativeDir)')"
+               />
+       </Target>
+
+       <PropertyGroup>
+               <GetFrameworkPathsDependsOn />
+       </PropertyGroup>
+       <Target Name="GetFrameworkPaths"
+               Condition="'$(TargetFrameworkIdentifier)' == '' or '$(TargetFrameworkIdentifier)' == '.NETFramework'"
+               DependsOnTargets="$(GetFrameworkPathsDependsOn)">
+               <GetFrameworkPath>
+                       <Output Condition="'$(TargetFrameworkVersion)' == 'v4.5' and '$(TargetFrameworkVersion)' == 'v4.5.1'"
+                               TaskParameter="FrameworkVersion45Path"
+                               ItemName="_CombinedTargetFrameworkDirectoriesItem"/>
+                       <Output Condition="'$(TargetFrameworkVersion)' == 'v4.0'"
+                               TaskParameter="FrameworkVersion40Path"
+                               ItemName="_CombinedTargetFrameworkDirectoriesItem"/>
+                       <Output Condition="'$(TargetFrameworkVersion)' == 'v3.5'"
+                               TaskParameter="FrameworkVersion35Path"
+                               ItemName="_CombinedTargetFrameworkDirectoriesItem"/>
+                       <Output Condition="'$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'"
+                               TaskParameter="FrameworkVersion30Path"
+                               ItemName="_CombinedTargetFrameworkDirectoriesItem"/>
+                       <Output Condition="'$(TargetFrameworkVersion)' == 'v2.0' or '$(TargetFrameworkVersion)' == 'v3.0' or '$(TargetFrameworkVersion)' == 'v3.5'"
+                               TaskParameter="FrameworkVersion20Path"
+                               ItemName="_CombinedTargetFrameworkDirectoriesItem"/>
+               </GetFrameworkPath>
+               <CreateProperty Value="@(_CombinedTargetFrameworkDirectoriesItem)">
+                       <Output TaskParameter="Value" PropertyName="TargetFrameworkDirectory"/>
+               </CreateProperty>
+
+               <Warning Text="TargetFrameworkVersion '$(TargetFrameworkVersion)' not supported by this toolset (ToolsVersion: $(MSBuildToolsVersion))."
+                       Condition="'$(TargetFrameworkVersion)' != 'v4.5.1' and '$(TargetFrameworkVersion)' != 'v4.5' and '$(TargetFrameworkVersion)' != 'v4.0' and '$(TargetFrameworkVersion)' != 'v3.5' and '$(TargetFrameworkVersion)' != 'v3.0' and '$(TargetFrameworkVersion)' != 'v2.0'"/>
+       </Target>
+
+       <PropertyGroup>
+               <GetReferenceAssemblyPathsDependsOn />
+       </PropertyGroup>
+       <Target Name="GetReferenceAssemblyPaths" DependsOnTargets="$(GetReferenceAssemblyPathsDependsOn)">
+               <!-- in case of .NETFramework, $(TargetFrameworkDirectory) would have been set by
+               GetFrameworkPaths, if it hasn't been changed, then clear it, to avoid duplicates -->
+               <CreateProperty Value="" Condition="'@(_CombinedTargetFrameworkDirectoriesItem)' == '$(TargetFrameworkDirectory)'">
+                       <Output TaskParameter="Value" PropertyName="TargetFrameworkDirectory"/>
+               </CreateProperty>
+
+               <GetReferenceAssemblyPaths
+                       Condition="'$(TargetFrameworkMoniker)' != '' and '$(_TargetFrameworkDirectories)' == ''"
+                       TargetFrameworkMoniker="$(TargetFrameworkMoniker)"
+                       RootPath="$(TargetFrameworkRootPath)">
+
+                       <Output TaskParameter="ReferenceAssemblyPaths" PropertyName="_TargetFrameworkDirectories"/>
+                       <Output TaskParameter="FullFrameworkReferenceAssemblyPaths" PropertyName="_FullFrameworkReferenceAssemblyPaths"/>
+                       <Output TaskParameter="TargetFrameworkMonikerDisplayName" PropertyName="TargetFrameworkMonikerDisplayName"/>
+               </GetReferenceAssemblyPaths>
+
+
+               <!-- Remove duplicates. -->
+               <ItemGroup>
+                       <_TargetFrameworkDirectories Include="$(_TargetFrameworkDirectories);$(TargetFrameworkDirectory)" KeepDuplicates="false" />
+               </ItemGroup>
+               <PropertyGroup>
+                       <TargetFrameworkDirectory>@(_TargetFrameworkDirectories)</TargetFrameworkDirectory>
+               </PropertyGroup>
+
+               <ItemGroup Condition="'$(ImplicitlyExpandDesignTimeFacades)' == 'true'">
+                       <DesignTimeFacadeDirectoryRoots Include="$(TargetFrameworkDirectory)" />
+                       <DesignTimeFacadeDirectories Include="%(DesignTimeFacadeDirectoryRoots.Identity)\Facades\" Condition="Exists('%(DesignTimeFacadeDirectoryRoots.Identity)\Facades\')" />
+                       <_DesignTimeFacadeAssemblies Include="%(DesignTimeFacadeDirectories.Identity)\*.dll"/>
+               </ItemGroup>
+
+               <PropertyGroup Condition="'@(DesignTimeFacadeDirectories)' != ''">
+                       <TargetFrameworkDirectory>$(TargetFrameworkDirectory);@(DesignTimeFacadeDirectories)</TargetFrameworkDirectory>
+               </PropertyGroup>
+
+       </Target>
+
+       <PropertyGroup>
+               <AllowedReferenceAssemblyFileExtensions Condition=" '$(AllowedReferenceAssemblyFileExtensions)' == '' ">
+                       .exe;
+                       .dll
+               </AllowedReferenceAssemblyFileExtensions>
+
+               <AllowedReferenceRelatedFileExtensions Condition=" '$(AllowedReferenceRelatedFileExtensions)' == '' ">
+                       .exe.mdb;
+                       .dll.mdb;
+                       .xml
+               </AllowedReferenceRelatedFileExtensions>
+
+               <AssemblySearchPaths Condition="'$(AssemblySearchPaths)' == ''">
+                       {CandidateAssemblyFiles};
+                       $(ReferencePath);
+                       @(AdditionalReferencePath);
+                       {HintPathFromItem};
+                       {TargetFrameworkDirectory};
+                       {PkgConfig};
+                       {GAC};
+                       {RawFileName};
+                       $(OutDir)
+               </AssemblySearchPaths>
+
+               <ResolveReferencesDependsOn>
+                       BeforeResolveReferences;
+                       ResolveProjectReferences;
+                       ResolveAssemblyReferences;
+                       AfterResolveReferences
+               </ResolveReferencesDependsOn>
+
+               <ResolveAssemblyReferencesDependsOn>
+                       GetFrameworkPaths;
+                       GetReferenceAssemblyPaths;
+                       PrepareForBuild
+               </ResolveAssemblyReferencesDependsOn>
+       </PropertyGroup>
+
+       <PropertyGroup Condition="'$(TargetFrameworkMoniker)' != ''">
+               <TargetFrameworkMonikerAssemblyAttributesPath Condition="'$(TargetFrameworkMonikerAssemblyAttributesPath)' == ''">$(IntermediateOutputPath)$(TargetFrameworkMoniker).AssemblyAttribute$(DefaultLanguageSourceExtension)</TargetFrameworkMonikerAssemblyAttributesPath>
+               <GenerateTargetFrameworkAttribute Condition="'$(GenerateTargetFrameworkAttribute)' == '' and '$(TargetFrameworkMoniker)'
+       != '' and '$(TargetingClr2Framework)' != 'true'">true</GenerateTargetFrameworkAttribute>
+       </PropertyGroup>
+
+       <ItemGroup Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
+               <FileWrites Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" />
+       </ItemGroup>
+
+       <Target Name="GenerateTargetFrameworkMonikerAttribute"
+               DependsOnTargets="PrepareForBuild;GetReferenceAssemblyPaths"
+               Inputs="$(MSBuildToolsPath)\Microsoft.Common.targets"
+               Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)"
+               Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
+
+               <WriteLinesToFile
+                       File="$(TargetFrameworkMonikerAssemblyAttributesPath)"
+                       Lines="$(TargetFrameworkMonikerAssemblyAttributeText)"
+                       Overwrite="true"
+                       ContinueOnError="true"
+                       Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''"
+               />
+
+               <ItemGroup Condition="'@(Compile)' != '' and '$(TargetFrameworkMonikerAssemblyAttributeText)' != ''">
+                       <Compile Include="$(TargetFrameworkMonikerAssemblyAttributesPath)"/>
+               </ItemGroup>
+       </Target>
+
+       <Target Name="ResolveReferences" DependsOnTargets="$(ResolveReferencesDependsOn)"/>
+
+       <Target Name="BeforeResolveReferences" />
+       <Target Name="AfterResolveReferences" />
+
+       <Target Name="ResolveAssemblyReferences" DependsOnTargets="$(ResolveAssemblyReferencesDependsOn)">
+               <CreateItem Include="@(Reference)" Exclude="$(AdditionalExplicitAssemblyReferences)">
+                       <Output TaskParameter="Include" ItemName="_Reference"/>
+               </CreateItem>
+
+               <CreateItem Include="$(AdditionalExplicitAssemblyReferences)">
+                       <Output TaskParameter="Include" ItemName="_Reference"/>
+               </CreateItem>
+
+               <ResolveAssemblyReference
+                       Assemblies="@(_Reference)"
+                       AssemblyFiles="@(ChildProjectReferences);@(_ExplicitReference)"
+                       SearchPaths="$(AssemblySearchPaths)"
+                       CandidateAssemblyFiles="@(Content);@(None)"
+                       TargetFrameworkDirectories="$(TargetFrameworkDirectory)"
+                       AllowedAssemblyExtensions="$(AllowedReferenceAssemblyFileExtensions)"
+                       AllowedRelatedFileExtensions="$(AllowedReferenceRelatedFileExtensions)"
+                       FindDependencies="true"
+                       FindSatellites="true"
+                       FindRelatedFiles="true"
+                       TargetFrameworkMoniker="$(TargetFrameworkMoniker)"
+                       TargetFrameworkMonikerDisplayName="$(TargetFrameworkMonikerDisplayName)"
+                       TargetFrameworkVersion="$(TargetFrameworkVersion)"
+               >
+                       <Output TaskParameter="ResolvedFiles" ItemName="ResolvedFiles"/>
+                       <Output TaskParameter="ResolvedFiles" ItemName="ReferencePath"/>
+                       <Output TaskParameter="ResolvedDependencyFiles" ItemName="ReferenceDependencyPaths"/>
+                       <Output TaskParameter="RelatedFiles" ItemName="_ReferenceRelatedPaths"/>
+                       <Output TaskParameter="SatelliteFiles" ItemName="ReferenceSatellitePaths"/>
+                       <Output TaskParameter="CopyLocalFiles" ItemName="ReferenceCopyLocalPaths"/>
+
+                       <!-- FIXME: backwards compatibility -->
+                       <Output TaskParameter="ResolvedDependencyFiles" ItemName="_ResolvedDependencyFiles"/>
+               </ResolveAssemblyReference>
+       </Target>
+
+       <Target
+               Name="AssignProjectConfiguration"
+               Condition="'@(ProjectReference)' != ''">
+
+               <!-- assign configs if building a solution file -->
+               <AssignProjectConfiguration
+                       ProjectReferences = "@(ProjectReference)"
+                       SolutionConfigurationContents = "$(CurrentSolutionConfigurationContents)"
+                       Condition="'$(BuildingSolutionFile)' == 'true'">
+
+                       <Output TaskParameter = "AssignedProjects" ItemName = "ProjectReferenceWithConfiguration"/>
+               </AssignProjectConfiguration>
+
+               <!-- Else, just -->
+               <CreateItem Include="@(ProjectReference)" Condition="'$(BuildingSolutionFile)' != 'true'">
+                       <Output TaskParameter="Include" ItemName="ProjectReferenceWithConfiguration"/>
+               </CreateItem>
+
+       </Target>
+
+       <!-- Split projects into 2 lists
+               ProjectReferenceWithConfigurationExistent: Projects existent on disk
+               ProjectReferenceWithConfigurationNonExistent: Projects non-existent on disk -->
+
+       <Target Name="SplitProjectReferencesByExistent"
+               DependsOnTargets="AssignProjectConfiguration">
+
+               <CreateItem Include="@(ProjectReferenceWithConfiguration)" Condition="'@(ProjectReferenceWithConfiguration)' != ''">
+                       <Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationExistent"
+                               Condition="Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+
+                       <Output TaskParameter="Include" ItemName="ProjectReferenceWithConfigurationNonExistent"
+                               Condition="!Exists ('%(ProjectReferenceWithConfiguration.Identity)')"/>
+               </CreateItem>
+       </Target>
+
+       <Target
+               Name="ResolveProjectReferences"
+               DependsOnTargets="SplitProjectReferencesByExistent"
+       >
+               <!-- If building from a .sln.proj or from IDE, then referenced projects have already
+                    been built, so just get the target paths -->
+               <MSBuild
+                       Projects="@(ProjectReferenceWithConfigurationExistent)"
+                       Targets="GetTargetPath"
+                       Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+                       Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and ('$(BuildingSolutionFile)' == 'true' or '$(BuildingInsideVisualStudio)' == 'true')">
+
+                       <Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" Condition="'%(ProjectReferenceWithConfigurationExistent.ReferenceOutputAssembly)' != 'false'"/>
+               </MSBuild>
+
+               <!-- Building a project directly, build the referenced the projects also -->
+               <MSBuild
+                       Projects="@(ProjectReferenceWithConfigurationExistent)"
+                       Properties="%(ProjectReferenceWithConfigurationExistent.SetConfiguration); %(ProjectReferenceWithConfigurationExistent.SetPlatform)"
+                       Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' ">
+
+                       <Output TaskParameter="TargetOutputs" ItemName="ChildProjectReferences" Condition="'%(ProjectReferenceWithConfigurationExistent.ReferenceOutputAssembly)' != 'false'"/>
+               </MSBuild>
+
+               <Warning Text="Referenced Project %(ProjectReferenceWithConfigurationNonExistent.Identity) not found, ignoring."
+                        Condition="'@(ProjectReferenceWithConfigurationNonExistent)' != ''"/>
+       </Target>
+
+       <Target Name = "CopyFilesMarkedCopyLocal">
+               <Copy
+                       SourceFiles="@(ReferenceCopyLocalPaths)"
+                       DestinationFiles="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter = "DestinationFiles" ItemName = "FileWritesShareable"/>
+               </Copy>
+       </Target>
+
+       <Target Name="_ComputeNonExistentFileProperty" Condition='false'>
+               <CreateProperty Value="__NonExistentSubDir__\__NonExistentFile__">
+                       <Output TaskParameter="Value" PropertyName="NonExistentFile"/>
+               </CreateProperty>
+       </Target>
+
+       <PropertyGroup>
+               <BuildDependsOn>
+                       BuildOnlySettings;
+                       BeforeBuild;
+                       CoreBuild;
+                       AfterBuild
+               </BuildDependsOn>
+       </PropertyGroup>
+
+       <Target Name="BuildOnlySettings"/>
+       <Target Name="BeforeBuild"/>
+       <Target Name="AfterBuild"/>
+
+       <Target Name="Build" DependsOnTargets="$(BuildDependsOn)" Outputs="$(TargetPath)"/>
+
+       <PropertyGroup>
+               <CoreBuildDependsOn>
+                       PrepareForBuild;
+                       GetFrameworkPaths;
+                       GetReferenceAssemblyPaths;
+                       PreBuildEvent;
+                       ResolveReferences;
+                       CopyFilesMarkedCopyLocal;
+                       PrepareResources;
+                       Compile;
+                       PrepareForRun;
+                       DeployOutputFiles;
+                       _RecordCleanFile;
+                       PostBuildEvent
+               </CoreBuildDependsOn>
+       </PropertyGroup>
+
+       <Target
+               Name="CoreBuild"
+               DependsOnTargets="$(CoreBuildDependsOn)"
+               Outputs="$(OutDir)$(AssemblyName)$(TargetExt)">
+
+               <OnError ExecuteTargets="_TimestampAfterCompile;PostBuildEvent"
+                       Condition=" '$(RunPostBuildEvent)' == 'Always' or '$(RunPostBuildEvent)' == 'OnOutputUpdated'"/>
+
+               <OnError ExecuteTargets="_RecordCleanFile" />
+       </Target>
+
+       <PropertyGroup>
+               <CompileDependsOn>
+                       ResolveReferences;
+                       GenerateTargetFrameworkMonikerAttribute;
+                       BeforeCompile;
+                       _TimestampBeforeCompile;
+                       CoreCompile;
+                       _TimestampAfterCompile;
+                       AfterCompile
+               </CompileDependsOn>
+       </PropertyGroup>
+
+       <Target Name="BeforeCompile" />
+       <Target Name="AfterCompile" />
+
+       <Target Name="Compile" DependsOnTargets="$(CompileDependsOn)"/>
+
+       <PropertyGroup>
+               <PrepareForRunDependsOn>
+                       DeployOutputFiles
+               </PrepareForRunDependsOn>
+       </PropertyGroup>
+       <Target Name="PrepareForRun" DependsOnTargets="$(PrepareForRunDependsOn)"/>
+
+       <PropertyGroup>
+               <PrepareResourcesDependsOn>
+                       AssignTargetPaths;
+                       SplitResourcesByCulture;
+                       CreateManifestResourceNames;
+                       CopyNonResxEmbeddedResources;
+                       GenerateResources;
+                       GenerateSatelliteAssemblies;
+                       CompileLicxFiles
+               </PrepareResourcesDependsOn>
+       </PropertyGroup>
+       <Target Name="PrepareResources" DependsOnTargets="$(PrepareResourcesDependsOn)" />
+
+       <Target Name="SplitResourcesByCulture" DependsOnTargets="AssignTargetPaths">
+               <!-- Extract .licx files into @(LicxFiles) -->
+               <CreateItem Include="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' == '.licx'">
+                       <Output TaskParameter="Include" ItemName="LicxFiles"/>
+               </CreateItem>
+
+               <!-- Split *remaining* resource files into various groups.. -->
+               <AssignCulture Files="@(EmbeddedResourceWithTargetPath)" Condition="'%(Extension)' != '.licx'">
+                       <Output TaskParameter="AssignedFilesWithNoCulture" ItemName="ResourcesWithNoCulture"/>
+                       <Output TaskParameter="AssignedFilesWithCulture" ItemName="ResourcesWithCulture"/>
+               </AssignCulture>
+
+               <CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' == '.resx'">
+                       <Output TaskParameter="Include" ItemName="ResxWithNoCulture"/>
+               </CreateItem>
+
+               <CreateItem Include="@(ResourcesWithNoCulture)" Condition="'%(Extension)' != '.resx'">
+                       <Output TaskParameter="Include" ItemName="NonResxWithNoCulture"/>
+               </CreateItem>
+
+               <CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' == '.resx'">
+                       <Output TaskParameter="Include" ItemName="ResxWithCulture"/>
+               </CreateItem>
+
+               <CreateItem Include="@(ResourcesWithCulture)" Condition="'%(Extension)' != '.resx'">
+                       <Output TaskParameter="Include" ItemName="NonResxWithCulture"/>
+               </CreateItem>
+       </Target>
+
+       <!-- Copy non-resx resources to their manifest resource names, this is what the compiler expects -->
+       <Target Name = "CopyNonResxEmbeddedResources"
+               Condition = "'@(NonResxWithCulture)' != '' or '@(NonResxWithNoCulture)' != '' or '@(ManifestNonResxWithCulture)' != '' or '@(ManifestNonResxWithNoCulture)' != ''">
+
+               <MakeDir Directories="$(IntermediateOutputPath)%(ManifestNonResxWithCulture.Culture)"/>
+               <Copy SourceFiles = "@(NonResxWithCulture)"
+                       DestinationFiles = "@(ManifestNonResxWithCulture->'$(IntermediateOutputPath)%(Identity)')"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithCultureOnDisk"/>
+                       <Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+               </Copy>
+
+               <Copy SourceFiles = "@(NonResxWithNoCulture)"
+                       DestinationFiles = "@(ManifestNonResxWithNoCulture->'$(IntermediateOutputPath)%(Identity)')"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter = "DestinationFiles" ItemName = "ManifestNonResxWithNoCultureOnDisk"/>
+                       <Output TaskParameter = "DestinationFiles" ItemName = "FileWrites"/>
+               </Copy>
+       </Target>
+
+       <Target Name = "GenerateResources">
+               <GenerateResource
+                       Sources = "@(ResxWithNoCulture)"
+                       UseSourcePath = "true"
+                       OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+                       Condition = "'@(ResxWithNoCulture)' != '' ">
+
+                       <Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithNoCulture"/>
+                       <Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+               </GenerateResource>
+
+               <GenerateResource
+                       Sources = "@(ResxWithCulture)"
+                       UseSourcePath = "true"
+                       OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
+                       Condition = "'@(ResxWithCulture)' != '' ">
+
+                       <Output TaskParameter = "OutputResources" ItemName = "ManifestResourceWithCulture"/>
+                       <Output TaskParameter = "FilesWritten" ItemName = "FileWrites"/>
+               </GenerateResource>
+       </Target>
+
+       <Target Name="GenerateSatelliteAssemblies"
+               Inputs="@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+               Outputs="$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+               <!-- @(NonResxWithCulture) - rename files to ManifestNon.. and then use for AL -->
+               <MakeDir Directories = "$(IntermediateOutputPath)%(ManifestResourceWithCulture.Culture)" Condition = "'@(ManifestResourceWithCulture)' != ''" />
+               <MakeDir Directories = "$(IntermediateOutputPath)%(ManifestNonResxWithCultureOnDisk.Culture)" Condition = "'@(ManifestNonResxWithCultureOnDisk)' != ''" />
+
+               <AL
+                       Culture = "%(Culture)"
+                       DelaySign="$(DelaySign)"
+                       EmbedResources = "@(ManifestResourceWithCulture);@(ManifestNonResxWithCultureOnDisk)"
+                       KeyFile="$(KeyOriginatorFile)"
+                       ToolExe="$(AlToolExe)"
+                       ToolPath="$(AlToolPath)"
+                       OutputAssembly = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll" >
+                       <Output TaskParameter="OutputAssembly" ItemName="FileWrites"/>
+               </AL>
+
+
+               <CreateItem
+                       Include = "$(IntermediateOutputPath)%(Culture)\$(AssemblyName).resources.dll"
+                       AdditionalMetadata = "Culture=%(Culture)"
+                       Condition = "'@(ManifestResourceWithCulture)' != '' or '@(ManifestNonResxWithCultureOnDisk)' != ''">
+                       <Output TaskParameter = "Include" ItemName = "IntermediateSatelliteAssemblies" />
+               </CreateItem>
+       </Target>
+
+       <PropertyGroup>
+               <CompileLicxFilesDependsOn></CompileLicxFilesDependsOn>
+       </PropertyGroup>
+
+       <Target Name = "CompileLicxFiles"
+               Condition = "'@(LicxFiles)' != ''"
+               DependsOnTargets = "$(CompileLicxFilesDependsOn)"
+               Outputs = "$(IntermediateOutputPath)$(TargetFileName).licenses">
+               <LC
+                       Sources = "@(LicxFiles)"
+                       LicenseTarget = "$(TargetFileName)"
+                       OutputDirectory = "$(IntermediateOutputPath)"
+                       OutputLicense = "$(IntermediateOutputPath)$(TargetFileName).licenses"
+                       ReferencedAssemblies = "@(ReferencePath);@(ReferenceDependencyPaths)"
+                       ToolPath = "$(LCToolPath)"
+                       ToolExe = "$(LCToolExe)">
+
+                       <Output TaskParameter="OutputLicense" ItemName="CompiledLicenseFile"/>
+                       <Output TaskParameter="OutputLicense" ItemName="FileWrites"/>
+               </LC>
+       </Target>
+
+       <!-- Assign target paths to files that will need to be copied along with the project -->
+       <Target Name = "AssignTargetPaths">
+               <AssignTargetPath Files="@(None)" RootFolder="$(MSBuildProjectDirectory)">
+                       <Output TaskParameter="AssignedFiles" ItemName="NoneWithTargetPath"/>
+               </AssignTargetPath>
+
+               <AssignTargetPath Files="@(Content)" RootFolder="$(MSBuildProjectDirectory)">
+                       <Output TaskParameter="AssignedFiles" ItemName="ContentWithTargetPath"/>
+               </AssignTargetPath>
+
+               <AssignTargetPath Files="@(EmbeddedResource)" RootFolder="$(MSBuildProjectDirectory)">
+                       <Output TaskParameter="AssignedFiles" ItemName="EmbeddedResourceWithTargetPath"/>
+               </AssignTargetPath>
+       </Target>
+
+       <Target Name="DeployOutputFiles"
+               DependsOnTargets="PrepareResources;CoreCompile;_CopyDeployFilesToOutputDirectory;_CopyAppConfigFile">
+
+               <Copy
+                       SourceFiles="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+                       Condition="'$(OutDir)' != '' and Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')"
+                       DestinationFolder="$(OutDir)"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)" >
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+
+               <Copy SourceFiles="@(IntermediateAssembly)" Condition="'$(OutDir)' != '' and Exists ('@(IntermediateAssembly)')" DestinationFolder="$(OutDir)" SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+
+               <Copy
+                       SourceFiles = "@(IntermediateSatelliteAssemblies)"
+                       DestinationFiles = "@(IntermediateSatelliteAssemblies->'$(OutDir)\%(Culture)\$(AssemblyName).resources.dll')"
+                       Condition = "'@(IntermediateSatelliteAssemblies)' != ''"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+       </Target>
+
+       <Target Name="_CopyDeployFilesToOutputDirectory"
+               DependsOnTargets="GetCopyToOutputDirectoryItems;
+                       _CopyDeployFilesToOutputDirectoryAlways;
+                       _CopyDeployFilesToOutputDirectoryPreserveNewest"/>
+
+       <Target Name="_CopyDeployFilesToOutputDirectoryPreserveNewest"
+               Condition="'@(ItemsToCopyToOutputDirectoryPreserveNewest)' != ''"
+               Inputs="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+               Outputs="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')">
+
+               <Copy SourceFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest)"
+                       DestinationFiles="@(ItemsToCopyToOutputDirectoryPreserveNewest->'$(OutDir)%(TargetPath)')"
+                       SkipUnchangedFiles="$(SkipCopyUnchangedFiles)">
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+       </Target>
+
+       <!-- Copy if newer -->
+       <Target Name="_CopyDeployFilesToOutputDirectoryAlways"
+               Condition="'@(ItemsToCopyToOutputDirectoryAlways)' != ''">
+
+               <Copy SourceFiles="@(ItemsToCopyToOutputDirectoryAlways)"
+                       DestinationFiles="@(ItemsToCopyToOutputDirectoryAlways->'$(OutDir)%(TargetPath)')">
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+       </Target>
+
+
+       <Target Name="_CopyAppConfigFile" Condition="'@(AppConfigWithTargetPath)' != ''"
+               Inputs="@(AppConfigWithTargetPath)"
+               Outputs="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+
+               <Copy SourceFiles="@(AppConfigWithTargetPath)"
+                       DestinationFiles="@(AppConfigWithTargetPath->'$(OutDir)%(TargetPath)')">
+                       <Output TaskParameter="DestinationFiles" ItemName="FileWrites"/>
+               </Copy>
+       </Target>
+
+       <Target Name="GetTargetPath" Outputs="$(TargetPath)"/>
+
+       <Target Name="GetCopyToOutputDirectoryItems"
+               Outputs="@(AllItemsFullPathWithTargetPath)"
+               DependsOnTargets="AssignTargetPaths;SplitProjectReferencesByExistent">
+
+               <!-- FIXME: handle .vcproj
+                    FIXME: Private ProjectReferences are honored only in 3.5
+               -->
+               <MSBuild
+                       Projects="@(ProjectReferenceWithConfigurationExistent)"
+                       Targets="GetCopyToOutputDirectoryItems"
+                       Condition="'@(ProjectReferenceWithConfigurationExistent)' != '' and '%(ProjectReferenceWithConfigurationExistent.Private)' != 'false'">
+
+                       <Output TaskParameter="TargetOutputs" ItemName="AllChildProjectItemsWithTargetPath"/>
+               </MSBuild>
+
+               <!-- Process items from child project. The outputs need to have full path
+                    as they'll be used from other projects -->
+
+               <CreateItem
+                       Include="@(AllChildProjectItemsWithTargetPath->'%(FullPath)')"
+                       Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+
+                       <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+                               Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+                               Condition="'%(AllChildProjectItemsWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+
+               </CreateItem>
+
+               <!-- Process _this_ project's items -->
+
+               <CreateItem
+                       Include="@(NoneWithTargetPath->'%(FullPath)')"
+                       Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(NoneWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+                       <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+                               Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+                               Condition="'%(NoneWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+               </CreateItem>
+
+               <CreateItem
+                       Include="@(ContentWithTargetPath->'%(FullPath)')"
+                       Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(ContentWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+                       <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+                               Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+                               Condition="'%(ContentWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+               </CreateItem>
+
+               <CreateItem
+                       Include="@(EmbeddedResourceWithTargetPath->'%(FullPath)')"
+                       Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'Always' or '%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)' == 'PreserveNewest'">
+                       <Output TaskParameter="Include" ItemName="AllItemsFullPathWithTargetPath"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryAlways"
+                               Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='Always'"/>
+                       <Output TaskParameter="Include" ItemName="ItemsToCopyToOutputDirectoryPreserveNewest"
+                               Condition="'%(EmbeddedResourceWithTargetPath.CopyToOutputDirectory)'=='PreserveNewest'"/>
+               </CreateItem>
+
+       </Target>
+
+       <!-- Pre/Post BuildEvents -->
+       <PropertyGroup>
+               <PreBuildEventDependsOn />
+       </PropertyGroup>
+
+       <Target Name="PreBuildEvent"
+               Condition="'$(PreBuildEvent)' != ''"
+               DependsOnTargets="$(PreBuildEventDependsOn)">
+
+               <Exec WorkingDirectory="$(OutDir)" Command="$(PreBuildEvent)" />
+       </Target>
+
+       <!-- PostBuildEvent depends on $(RunPostBuildEvent)
+
+               Default: OnBuildSuccess
+               OnBuildSuccess: Run after a successful build
+               OnOutputUpdated: Run only if the output assembly got updates
+               Always: Run always
+       -->
+       <PropertyGroup>
+               <PostBuildEventDependsOn />
+       </PropertyGroup>
+
+       <!-- this gets invoked in two cases, from CoreBuildDependsOn, if the build completes
+            successfully, OR from OnError in CoreBuild, if the build failed and $(RunPostBuildEvent)
+            is 'Always' or 'OnOutputUpdated'. Invoke $(PostBuildEvent) if its either Empty (== OnBuildSuccess)
+            or OnBuildSuccess or Always OR (OnOutputUpdated and output assembly got updated) -->
+       <Target Name="PostBuildEvent"
+               Condition="'$(PostBuildEvent)' != '' and
+                       ('$(RunPostBuildEvent)' != 'OnOutputUpdated' or
+                         '$(_AssemblyModifiedTimeBeforeCompile)' != '$(_AssemblyModifiedTimeAfterCompile)')"
+               DependsOnTargets="$(PostBuildEventDependsOn)">
+
+               <Exec WorkingDirectory="$(OutDir)" Command="$(PostBuildEvent)" />
+       </Target>
+
+       <!-- Timestamp the output assemblies, required for PostBuildEvent -->
+       <Target Name="_TimestampBeforeCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+               <CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+                       <Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeBeforeCompile" />
+               </CreateItem>
+       </Target>
+       <Target Name="_TimestampAfterCompile" Condition="'$(RunPostBuildEvent)' == 'OnOutputUpdated'">
+               <CreateItem Include="%(IntermediateAssembly.ModifiedTime)">
+                       <Output TaskParameter="Include" PropertyName="_AssemblyModifiedTimeAfterCompile" />
+               </CreateItem>
+       </Target>
+
+       <!-- Rebuild -->
+       <PropertyGroup>
+               <RebuildDependsOn>
+                       BeforeRebuild;
+                       Clean;
+                       $(MSBuildProjectDefaultTargets);
+                       AfterRebuild;
+               </RebuildDependsOn>
+
+               <RebuildDependsOn Condition="'$(MSBuildProjectDefaultTargets)' == 'Rebuild'">
+                       BeforeRebuild;
+                       Clean;
+                       Build;
+                       AfterRebuild;
+               </RebuildDependsOn>
+       </PropertyGroup>
+
+       <Target Name="BeforeRebuild" />
+       <Target Name="AfterRebuild" />
+
+       <Target Name="Rebuild"
+               DependsOnTargets="$(RebuildDependsOn)"
+               Outputs="$(TargetPath)"/>
+
+       <!-- Clean -->
+       <Target Name="_RecordCleanFile"
+               DependsOnTargets="_GetCompileOutputsForClean">
+
+               <!-- add to list of previous writes for this platform/config -->
+
+               <ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+                       <Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+               </ReadLinesFromFile>
+
+               <!-- CopyLocal files: In case all the projects build to common output
+                    directory, then other projects might depend on some of these
+                    CopyLocal files, so delete only the ones under *this* project
+                    directory -->
+               <FindUnderPath Path="$(MSBuildProjectDirectory)" Files="@(FileWritesShareable)">
+                       <Output TaskParameter="InPath" ItemName="FileWrites"/>
+               </FindUnderPath>
+
+               <RemoveDuplicates Inputs="@(PreviousFileWrites);@(FileWrites->'%(FullPath)')">
+                       <Output TaskParameter="Filtered" ItemName="CombinedFileWrites"/>
+               </RemoveDuplicates>
+
+               <WriteLinesToFile
+                       File="$(IntermediateOutputPath)$(CleanFile)"
+                       Lines="@(CombinedFileWrites)"
+                       Overwrite="true"/>
+       </Target>
+
+       <PropertyGroup>
+               <CleanDependsOn>
+                       BeforeClean;
+                       CleanReferencedProjects;
+                       CoreClean;
+                       AfterClean
+               </CleanDependsOn>
+       </PropertyGroup>
+
+       <Target Name="_GetCompileOutputsForClean">
+               <!-- assembly and debug file in the *intermediate output path* -->
+               <CreateItem Include="@(IntermediateAssembly)" Condition="Exists('@(IntermediateAssembly)')">
+                       <Output TaskParameter="Include" ItemName="FileWrites"/>
+               </CreateItem>
+
+               <CreateItem Include="$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb"
+                       Condition="Exists('$(IntermediateOutputPath)$(AssemblyName)$(TargetExt).mdb')">
+                       <Output TaskParameter="Include" ItemName="FileWrites"/>
+               </CreateItem>
+       </Target>
+
+       <!-- Get the list of files written, for clean -->
+       <Target Name="_GetCleanFileWrites"
+               DependsOnTargets="_GetCompileOutputsForClean">
+               <ReadLinesFromFile File="$(IntermediateOutputPath)$(CleanFile)">
+                       <Output TaskParameter="Lines" ItemName="PreviousFileWrites"/>
+               </ReadLinesFromFile>
+       </Target>
+
+       <Target Name="CleanReferencedProjects"
+               DependsOnTargets="AssignProjectConfiguration">
+
+               <!-- If building from .sln.proj or from IDE, clean will get handled by them,
+                    else we are building a project directly, from the command line, so
+                    clean the referenced projects -->
+               <MSBuild Projects="@(ProjectReferenceWithConfigurationExistent)"
+                       Targets="Clean"
+                       Condition=" '$(BuildingSolutionFile)' != 'true' and '$(BuildingInsideVisualStudio)' != 'true' and '@(ProjectReferenceWithConfigurationExistent)' != ''" />
+
+       </Target>
+
+       <Target Name="Clean" DependsOnTargets="$(CleanDependsOn)"/>
+
+       <!-- Override in project to run before/after clean tasks -->
+       <Target Name="BeforeClean" />
+       <Target Name="AfterClean" />
+
+       <Target Name="CoreClean" DependsOnTargets="_GetCleanFileWrites">
+               <Delete Files="@(PreviousFileWrites);@(FileWrites)" TreatErrorsAsWarnings="true"/>
+
+               <!-- all previous files written for this platform/config have been deleted,
+                    we can safely remove the file list now -->
+               <Delete Files="$(IntermediateOutputPath)$(CleanFile)" TreatErrorsAsWarnings="true" />
+       </Target>
+
+       <PropertyGroup>
+               <ImplicitlyExpandDesignTimeFacades>true</ImplicitlyExpandDesignTimeFacades>
+
+               <ResolveReferencesDependsOn>
+                       $(ResolveReferencesDependsOn);
+                       ImplicitlyExpandDesignTimeFacades
+               </ResolveReferencesDependsOn>
+
+               <ImplicitlyExpandDesignTimeFacadesDependsOn>
+                       $(ImplicitlyExpandDesignTimeFacadesDependsOn);
+                       GetReferenceAssemblyPaths
+               </ImplicitlyExpandDesignTimeFacadesDependsOn>
+       </PropertyGroup>
+
+       <Target Name="ImplicitlyExpandDesignTimeFacades" Condition="'$(ImplicitlyExpandDesignTimeFacades)' == 'true'" DependsOnTargets="$(ImplicitlyExpandDesignTimeFacadesDependsOn)">
+
+               <PropertyGroup>
+                       <_HasReferenceToSystemRuntime Condition="'%(_ResolvedDependencyFiles.Filename)' == 'System.Runtime'">true</_HasReferenceToSystemRuntime>
+               </PropertyGroup>
+
+               <ItemGroup Condition="'$(_HasReferenceToSystemRuntime)' == 'true'">
+                       <!-- If the user has manually referenced these assemblies, remove them so we don't end up with duplicates -->
+                       <ReferencePath Remove="@(_DesignTimeFacadeAssemblies)"/>
+                       <ReferencePath Include="%(_DesignTimeFacadeAssemblies.Identity)">
+                               <WinMDFile>false</WinMDFile>
+                               <CopyLocal>false</CopyLocal>
+                               <ResolvedFrom>ImplicitlyExpandDesignTimeFacades</ResolvedFrom>
+                       </ReferencePath>
+                       <_ResolveAssemblyReferenceResolvedFiles Include="@(ReferencePath)" Condition="'%(ReferencePath.ResolvedFrom)' == 'ImplicitlyExpandDesignTimeFacades'" />
+               </ItemGroup>
+
+               <Message Importance="Low" Text="Including @(ReferencePath)" Condition="'%(ReferencePath.ResolvedFrom)' == 'ImplicitlyExpandDesignTimeFacades'" />
+
+       </Target>
+
+       <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportAfter\*"
+               Condition="'$(ImportByWildcardAfterMicrosoftCommonTargets)' == 'true' and Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportAfter')"/>
+</Project>
diff --git a/mcs/tools/xbuild/data/14.0/Microsoft.Common.tasks b/mcs/tools/xbuild/data/14.0/Microsoft.Common.tasks
new file mode 100644 (file)
index 0000000..b5cede2
--- /dev/null
@@ -0,0 +1,37 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" >
+       <UsingTask TaskName="Microsoft.Build.Tasks.AL"                  AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.AssignTargetPath"    AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.AssignCulture"       AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.AssignProjectConfiguration"  AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.CallTarget"          AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.CombinePath"         AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Copy"                AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.CreateCSharpManifestResourceName"    AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
+       <UsingTask TaskName="Microsoft.Build.Tasks.CreateItem"          AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.CreateProperty"      AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Csc"                 AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Delete"              AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Error"               AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Exec"                AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.FindAppConfigFile"   AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.FindUnderPath"       AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.GenerateResource"    AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.GetAssemblyIdentity" AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkPath"    AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.GetFrameworkSdkPath" AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.GetReferenceAssemblyPaths"   AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.LC"                  AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.MakeDir"             AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Message"             AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.MSBuild"             AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.ReadLinesFromFile"   AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.RemoveDir"           AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.RemoveDuplicates"            AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.ResolveAssemblyReference"            AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.SignFile"            AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Touch"               AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Vbc"                 AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.Warning"             AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+       <UsingTask TaskName="Microsoft.Build.Tasks.WriteCodeFragment"   AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
+       <UsingTask TaskName="Microsoft.Build.Tasks.WriteLinesToFile"    AssemblyName="Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
+</Project>
index 7cb5065f2d01270753b5d9e11d6b0a711035f790..e17dcb2b4538128157ad40dc3a9b8b4edd19ccbe 100644 (file)
@@ -2,6 +2,10 @@ ifneq (2.0, $(XBUILD_VERSION))
 NAME_SUFFIX = .v$(XBUILD_VERSION)
 endif
 
+ifeq (14.0, $(XBUILD_VERSION))
+NAME_SUFFIX = .Core
+endif
+
 XBUILD_FRAMEWORK := $(topdir)/class/lib/$(PROFILE)/Microsoft.Build.Framework.dll
 XBUILD_ENGINE := $(topdir)/class/lib/$(PROFILE)/Microsoft.Build.Engine.dll
 XBUILD_UTILITIES := $(topdir)/class/lib/$(PROFILE)/Microsoft.Build.Utilities$(NAME_SUFFIX).dll
index bddc59c6c21ea963cfddff6588093943335f4ca6..033cf4fede9c4bc5e0b977cdb646cbb62e8c6d92 100644 (file)
@@ -29,6 +29,7 @@ XBUILD_2_0_PROFILE_DIR=$(topdir)/class/lib/net_2_0
 XBUILD_3_5_PROFILE_DIR=$(topdir)/class/lib/net_3_5
 XBUILD_4_0_PROFILE_DIR=$(topdir)/class/lib/net_4_5
 XBUILD_12_0_PROFILE_DIR=$(topdir)/class/lib/xbuild_12
+XBUILD_14_0_PROFILE_DIR=$(topdir)/class/lib/xbuild_14
 
 copy-targets-2.0:
        cp $(XBUILD_DATA_DIR)/2.0/Microsoft.Common.targets $(XBUILD_2_0_PROFILE_DIR)
@@ -54,6 +55,12 @@ copy-targets-12.0:
        cp $(XBUILD_DATA_DIR)/12.0/Microsoft.CSharp.targets $(XBUILD_12_0_PROFILE_DIR)
        cp $(XBUILD_DATA_DIR)/Microsoft.VisualBasic.targets $(XBUILD_12_0_PROFILE_DIR)
 
+copy-targets-14.0:
+       cp $(XBUILD_DATA_DIR)/14.0/Microsoft.Common.targets $(XBUILD_14_0_PROFILE_DIR)
+       cp $(XBUILD_DATA_DIR)/14.0/Microsoft.Common.tasks $(XBUILD_14_0_PROFILE_DIR)
+       cp $(XBUILD_DATA_DIR)/14.0/Microsoft.CSharp.targets $(XBUILD_14_0_PROFILE_DIR)
+       cp $(XBUILD_DATA_DIR)/Microsoft.VisualBasic.targets $(XBUILD_14_0_PROFILE_DIR)
+
 clean-targets-2.0:
        rm -f $(XBUILD_2_0_PROFILE_DIR)/Microsoft.Common.targets
        rm -f $(XBUILD_2_0_PROFILE_DIR)/Microsoft.Common.tasks
@@ -78,6 +85,12 @@ clean-targets-12.0:
        rm -f $(XBUILD_12_0_PROFILE_DIR)/Microsoft.CSharp.targets
        rm -f $(XBUILD_12_0_PROFILE_DIR)/Microsoft.VisualBasic.targets
 
+clean-targets-14.0:
+       rm -f $(XBUILD_14_0_PROFILE_DIR)/Microsoft.Common.targets
+       rm -f $(XBUILD_14_0_PROFILE_DIR)/Microsoft.Common.tasks
+       rm -f $(XBUILD_14_0_PROFILE_DIR)/Microsoft.CSharp.targets
+       rm -f $(XBUILD_14_0_PROFILE_DIR)/Microsoft.VisualBasic.targets
+
 #allow tests to find older versions of libs and targets
 ifneq (2.0, $(XBUILD_VERSION))
 TEST_MONO_PATH := $(topdir)/class/lib/net_2_0
index c46bdfa2db4c9b762d643ebd4d2d64c3167a300e..c40af5a98f562911e5dd024c548c7faf35504e46 100644 (file)
@@ -2321,7 +2321,7 @@ unload_thread_main (void *arg)
         * class->runtime_info.
         */
 
-       mono_loader_lock ();
+       mono_loader_lock (); //FIXME why do we need the loader lock here?
        mono_domain_lock (domain);
 #ifdef HAVE_SGEN_GC
        /*
index 090f2f7a1dc98e9296d02c829debb4cba317c11c..bbebb14a1d3b9a937e2e974717e44855d5b98ee0 100644 (file)
@@ -30,6 +30,7 @@
 #include <mono/utils/dtrace.h>
 #include <mono/utils/gc_wrapper.h>
 #include <mono/utils/mono-mutex.h>
+#include <mono/utils/mono-counters.h>
 
 #if HAVE_BOEHM_GC
 
@@ -78,6 +79,8 @@ mono_gc_base_init (void)
        if (gc_initialized)
                return;
 
+       mono_counters_init ();
+
        /*
         * Handle the case when we are called from a thread different from the main thread,
         * confusing libgc.
index e9ff58249ef34610b39221c1f0cb51752a500f00..d2bf676bfc32ea3d6cd17b8d387d63e66f16d558 100644 (file)
@@ -1082,10 +1082,8 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
                        iresult->context.class_inst = iresult->declaring->klass->generic_class->context.class_inst;
        }
 
-       mono_loader_lock ();
        cached = mono_method_inflated_lookup (iresult, FALSE);
        if (cached) {
-               mono_loader_unlock ();
                g_free (iresult);
                return (MonoMethod*)cached;
        }
@@ -1156,12 +1154,9 @@ mono_class_inflate_generic_method_full_checked (MonoMethod *method, MonoClass *k
         * is_generic_method_definition().
         */
 
-       mono_method_inflated_lookup (iresult, TRUE);
-       mono_loader_unlock ();
-       return result;
+       return (MonoMethod*)mono_method_inflated_lookup (iresult, TRUE);
 
 fail:
-       mono_loader_unlock ();
        g_free (iresult);
        return NULL;
 }
@@ -1241,7 +1236,7 @@ mono_method_get_generic_container (MonoMethod *method)
  * mono_method_set_generic_container:
  *
  *   Sets the generic container of METHOD to CONTAINER.
- * LOCKING: Acquires the loader lock.
+ * LOCKING: Acquires the image lock.
  */
 void
 mono_method_set_generic_container (MonoMethod *method, MonoGenericContainer* container)
@@ -6118,8 +6113,11 @@ make_generic_param_class (MonoGenericParam *param, MonoImage *image, gboolean is
 
 #define FAST_CACHE_SIZE 16
 
+/*
+ * LOCKING: Takes the image lock depending on @take_lock.
+ */
 static MonoClass *
-get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
+get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, gboolean take_lock)
 {
        int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
        MonoImage *image = param->image;
@@ -6133,26 +6131,33 @@ get_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar)
                else
                        return image->var_cache_fast ? image->var_cache_fast [n] : NULL;
        } else {
+               MonoClass *klass = NULL;
                ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
-               return ht ? g_hash_table_lookup (ht, GINT_TO_POINTER (n)) : NULL;
+               if (ht) {
+                       if (take_lock)
+                               mono_image_lock (image);
+                       klass = g_hash_table_lookup (ht, GINT_TO_POINTER (n));
+                       if (take_lock)
+                               mono_image_unlock (image);
+               }
+               return klass;
        }
 }
 
 /*
- * LOCKING: Acquires the loader lock.
+ * LOCKING: Image lock (param->image) must be held
  */
 static void
 set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *klass)
 {
        int n = mono_generic_param_num (param) | ((guint32)param->serial << 16);
        MonoImage *image = param->image;
-       GHashTable *ht;
 
        g_assert (image);
 
        if (n < FAST_CACHE_SIZE) {
                if (is_mvar) {
-                       /* No locking needed */
+                       /* Requires locking to avoid droping an already published class */
                        if (!image->mvar_cache_fast)
                                image->mvar_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
                        image->mvar_cache_fast [n] = klass;
@@ -6161,54 +6166,42 @@ set_anon_gparam_class (MonoGenericParam *param, gboolean is_mvar, MonoClass *kla
                                image->var_cache_fast = mono_image_alloc0 (image, sizeof (MonoClass*) * FAST_CACHE_SIZE);
                        image->var_cache_fast [n] = klass;
                }
-               return;
-       }
-       ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
-       if (!ht) {
-               mono_image_lock (image);
-               ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+       } else {
+               GHashTable *ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
                if (!ht) {
-                       ht = g_hash_table_new (NULL, NULL);
-                       mono_memory_barrier ();
-                       if (is_mvar)
-                               image->mvar_cache_slow = ht;
-                       else
-                               image->var_cache_slow = ht;
+                       ht = is_mvar ? image->mvar_cache_slow : image->var_cache_slow;
+                       if (!ht) {
+                               ht = g_hash_table_new (NULL, NULL);
+                               mono_memory_barrier ();
+                               if (is_mvar)
+                                       image->mvar_cache_slow = ht;
+                               else
+                                       image->var_cache_slow = ht;
+                       }
                }
-               mono_image_unlock (image);
+               g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
        }
-
-       g_hash_table_insert (ht, GINT_TO_POINTER (n), klass);
 }
 
 /*
- * LOCKING: Acquires the loader lock.
+ * LOCKING: Acquires the image lock (@image).
  */
 MonoClass *
 mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gboolean is_mvar)
 {
        MonoGenericContainer *container = mono_generic_param_owner (param);
-       MonoGenericParamInfo *pinfo;
-       MonoClass *klass;
-
-       mono_loader_lock ();
+       MonoGenericParamInfo *pinfo = NULL;
+       MonoClass *klass, *klass2;
 
        if (container) {
                pinfo = mono_generic_param_info (param);
-               if (pinfo->pklass) {
-                       mono_loader_unlock ();
-                       return pinfo->pklass;
-               }
+               klass = pinfo->pklass;
        } else {
-               pinfo = NULL;
                image = NULL;
-
-               klass = get_anon_gparam_class (param, is_mvar);
-               if (klass) {
-                       mono_loader_unlock ();
-                       return klass;
-               }
+               klass = get_anon_gparam_class (param, is_mvar, TRUE);
        }
+       if (klass)
+               return klass;
 
        if (!image && container) {
                if (is_mvar) {
@@ -6226,15 +6219,30 @@ mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, gb
 
        mono_memory_barrier ();
 
+       if (!image) //FIXME is this only needed by monodis? Can't we fix monodis instead of having this hack?
+               image = mono_defaults.corlib;
+
+       mono_image_lock (image);
        if (container)
-               pinfo->pklass = klass;
+               klass2 = pinfo->pklass;
        else
-               set_anon_gparam_class (param, is_mvar, klass);
+               klass2 = get_anon_gparam_class (param, is_mvar, FALSE);
 
-       mono_loader_unlock ();
+       if (klass2) {
+               klass = klass2;
+       } else {
+               if (container)
+                       pinfo->pklass = klass;
+               else
+                       set_anon_gparam_class (param, is_mvar, klass);
+       }
+       mono_image_unlock (image);
 
        /* FIXME: Should this go inside 'make_generic_param_klass'? */
-       mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+       if (klass2)
+               mono_profiler_class_loaded (klass2, MONO_PROFILE_FAILED);
+       else
+               mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
 
        return klass;
 }
@@ -6250,15 +6258,15 @@ mono_ptr_class_get (MonoType *type)
        el_class = mono_class_from_mono_type (type);
        image = el_class->image;
 
-       mono_loader_lock ();
-
-       if (!image->ptr_cache)
-               image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
-
-       if ((result = g_hash_table_lookup (image->ptr_cache, el_class))) {
-               mono_loader_unlock ();
-               return result;
+       mono_image_lock (image);
+       if (image->ptr_cache) {
+               if ((result = g_hash_table_lookup (image->ptr_cache, el_class))) {
+                       mono_image_unlock (image);
+                       return result;
+               }
        }
+       mono_image_unlock (image);
+       
        result = mono_image_alloc0 (image, sizeof (MonoClass));
 
        classes_size += sizeof (MonoClass);
@@ -6285,9 +6293,19 @@ mono_ptr_class_get (MonoType *type)
 
        mono_class_setup_supertypes (result);
 
+       mono_image_lock (image);
+       if (image->ptr_cache) {
+               MonoClass *result2;
+               if ((result2 = g_hash_table_lookup (image->ptr_cache, el_class))) {
+                       mono_image_unlock (image);
+                       mono_profiler_class_loaded (result, MONO_PROFILE_FAILED);
+                       return result2;
+               }
+       } else {
+               image->ptr_cache = g_hash_table_new (mono_aligned_addr_hash, NULL);
+       }
        g_hash_table_insert (image->ptr_cache, el_class, result);
-
-       mono_loader_unlock ();
+       mono_image_unlock (image);
 
        mono_profiler_class_loaded (result, MONO_PROFILE_OK);
 
index d5c05bef527831e5190aa8f95b0a5c931dbc8671..c7c0756dc71614ce706def2d30d65e1cc5610f0d 100644 (file)
@@ -1998,21 +1998,27 @@ mono_image_load_file_for_image (MonoImage *image, int fileidx)
        if (fileidx < 1 || fileidx > t->rows)
                return NULL;
 
-       mono_loader_lock ();
+       mono_image_lock (image);
        if (image->files && image->files [fileidx - 1]) {
-               mono_loader_unlock ();
+               mono_image_unlock (image);
                return image->files [fileidx - 1];
        }
 
-       if (!image->files)
-               image->files = g_new0 (MonoImage*, t->rows);
-
        fname_id = mono_metadata_decode_row_col (t, fileidx - 1, MONO_FILE_NAME);
        fname = mono_metadata_string_heap (image, fname_id);
        base_dir = g_path_get_dirname (image->name);
        name = g_build_filename (base_dir, fname, NULL);
        res = mono_image_open (name, NULL);
-       if (res) {
+       if (!res)
+               goto done;
+
+       mono_image_lock (image);
+       if (image->files && image->files [fileidx - 1]) {
+               MonoImage *old = res;
+               res = image->files [fileidx - 1];
+               mono_loader_unlock ();
+               mono_image_close (old);
+       } else {
                int i;
                /* g_print ("loaded file %s from %s (%p)\n", name, image->name, image->assembly); */
                res->assembly = image->assembly;
@@ -2021,13 +2027,18 @@ mono_image_load_file_for_image (MonoImage *image, int fileidx)
                                res->modules [i]->assembly = image->assembly;
                }
 
+               if (!image->files)
+                       image->files = g_new0 (MonoImage*, t->rows);
                image->files [fileidx - 1] = res;
+               mono_loader_unlock ();
+               /* vtable fixup can't happen with the image lock held */
 #ifdef HOST_WIN32
                if (res->is_module_handle)
                        mono_image_fixup_vtable (res);
 #endif
        }
-       mono_loader_unlock ();
+
+done:
        g_free (name);
        g_free (base_dir);
        return res;
index f7dc1497a016f82819a51cc235f723aaa9b29327..a6b94357c3759ad1fc48176c19c991da8239357c 100644 (file)
@@ -55,7 +55,7 @@ MonoDefaults mono_defaults;
  * See domain-internals.h for locking policy in combination with the
  * domain lock.
  */
-static mono_mutex_t loader_mutex;
+static mono_mutex_t loader_mutex, global_loader_data_mutex;
 static gboolean loader_lock_inited;
 
 /* Statistics */
@@ -77,6 +77,19 @@ MonoNativeTlsKey loader_lock_nest_id;
 
 static void dllmap_cleanup (void);
 
+
+static void
+global_loader_data_lock (void)
+{
+       mono_locks_acquire (&global_loader_data_mutex, LoaderGlobalDataLock);
+}
+
+static void
+global_loader_data_unlock (void)
+{
+       mono_locks_release (&global_loader_data_mutex, LoaderGlobalDataLock);
+}
+
 void
 mono_loader_init ()
 {
@@ -84,6 +97,7 @@ mono_loader_init ()
 
        if (!inited) {
                mono_mutex_init_recursive (&loader_mutex);
+               mono_mutex_init_recursive (&global_loader_data_mutex);
                loader_lock_inited = TRUE;
 
                mono_native_tls_alloc (&loader_error_thread_id, NULL);
@@ -111,6 +125,7 @@ mono_loader_cleanup (void)
        mono_native_tls_free (loader_lock_nest_id);
 
        mono_mutex_destroy (&loader_mutex);
+       mono_mutex_destroy (&global_loader_data_mutex);
        loader_lock_inited = FALSE;     
 }
 
@@ -1164,7 +1179,7 @@ mono_dllmap_lookup_list (MonoDllMap *dll_map, const char *dll, const char* func,
        if (!dll_map)
                return 0;
 
-       mono_loader_lock ();
+       global_loader_data_lock ();
 
        /* 
         * we use the first entry we find that matches, since entries from
@@ -1191,7 +1206,7 @@ mono_dllmap_lookup_list (MonoDllMap *dll_map, const char *dll, const char* func,
                }
        }
 
-       mono_loader_unlock ();
+       global_loader_data_unlock ();
        return found;
 }
 
@@ -1250,10 +1265,10 @@ mono_dllmap_insert (MonoImage *assembly, const char *dll, const char *func, cons
                entry->func = func? g_strdup (func): NULL;
                entry->target_func = tfunc? g_strdup (tfunc): NULL;
 
-               mono_loader_lock ();
+               global_loader_data_lock ();
                entry->next = global_dll_map;
                global_dll_map = entry;
-               mono_loader_unlock ();
+               global_loader_data_unlock ();
        } else {
                entry = mono_image_alloc0 (assembly, sizeof (MonoDllMap));
                entry->dll = dll? mono_image_strdup (assembly, dll): NULL;
@@ -1299,18 +1314,18 @@ cached_module_load (const char *name, int flags, char **err)
 
        if (err)
                *err = NULL;
-       mono_loader_lock ();
+       global_loader_data_lock ();
        if (!global_module_map)
                global_module_map = g_hash_table_new (g_str_hash, g_str_equal);
        res = g_hash_table_lookup (global_module_map, name);
        if (res) {
-               mono_loader_unlock ();
+               global_loader_data_unlock ();
                return res;
        }
        res = mono_dl_open (name, flags, err);
        if (res)
                g_hash_table_insert (global_module_map, g_strdup (name), res);
-       mono_loader_unlock ();
+       global_loader_data_unlock ();
        return res;
 }
 
@@ -2278,16 +2293,49 @@ mono_stack_walk_no_il (MonoStackWalk func, gpointer user_data)
        mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (stack_walk_adapter, NULL, MONO_UNWIND_DEFAULT, &ud);
 }
 
+typedef struct {
+       MonoStackWalkAsyncSafe func;
+       gpointer user_data;
+} AsyncStackWalkUserData;
+
+
+static gboolean
+async_stack_walk_adapter (MonoStackFrameInfo *frame, MonoContext *ctx, gpointer data)
+{
+       AsyncStackWalkUserData *d = data;
+
+       switch (frame->type) {
+       case FRAME_TYPE_DEBUGGER_INVOKE:
+       case FRAME_TYPE_MANAGED_TO_NATIVE:
+               return FALSE;
+       case FRAME_TYPE_MANAGED:
+               if (!frame->ji)
+                       return FALSE;
+               if (frame->ji->async)
+                       return d->func (NULL, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
+               else
+                       return d->func (mono_jit_info_get_method (frame->ji), frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
+               break;
+       default:
+               g_assert_not_reached ();
+               return FALSE;
+       }
+}
+
+
 /*
  * mono_stack_walk_async_safe:
  *
  *   Async safe version callable from signal handlers.
  */
 void
-mono_stack_walk_async_safe (MonoStackWalk func, gpointer user_data)
+mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_context, void *user_data)
 {
-       StackWalkUserData ud = { func, user_data };
-       mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (stack_walk_adapter, NULL, MONO_UNWIND_NONE, &ud);
+       MonoContext ctx;
+       AsyncStackWalkUserData ud = { func, user_data };
+
+       mono_sigctx_to_monoctx (initial_sig_context, &ctx);
+       mono_get_eh_callbacks ()->mono_walk_stack_with_ctx (async_stack_walk_adapter, NULL, MONO_UNWIND_SIGNAL_SAFE, &ud);
 }
 
 static gboolean
index ae0ca4417737da07e3487f333c08cbc8fd0eaa95..74d82817bb896c9208e4a755d2c28b0c538532ed 100644 (file)
@@ -90,8 +90,9 @@ mono_stack_walk         (MonoStackWalk func, void* user_data);
 MONO_API void
 mono_stack_walk_no_il   (MonoStackWalk func, void* user_data);
 
+typedef mono_bool (*MonoStackWalkAsyncSafe)     (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void* data);
 MONO_API void
-mono_stack_walk_async_safe   (MonoStackWalk func, void* user_data);
+mono_stack_walk_async_safe   (MonoStackWalkAsyncSafe func, void *initial_sig_context, void* user_data);
 
 MONO_END_DECLS
 
index 4069e97173fe1a355aff3aac47a22c93d5eed9f5..4130fae8f17a8348e7fa6bc9642a81172f36400e 100644 (file)
@@ -17,7 +17,8 @@ typedef enum {
        DomainJitCodeHashLock,
        IcallLock,
        AssemblyBindingLock,
-       MarshalLock
+       MarshalLock,
+       LoaderGlobalDataLock,
 } RuntimeLocks;
 
 #ifdef LOCK_TRACER
index 0c8fe33f219deadaed0965bed82c58d1a3c880ba..3fb7b1d2b445a26e6c454252fda8d44691ed3150 100644 (file)
@@ -8958,6 +8958,8 @@ mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions,
 #ifndef DISABLE_COM
                return mono_cominterop_get_native_wrapper (method);
 #else
+               if (aot)
+                       return method;
                g_assert_not_reached ();
 #endif
        }
index c738d53654ef315d6035d05158b4c962725a5962..a5c8991744564878e1c6a1f736c128d8d3947801 100644 (file)
@@ -204,7 +204,7 @@ struct _MonoImage {
        guint32 module_count;
        gboolean *modules_loaded;
 
-       MonoImage **files;
+       MonoImage **files; /*protected by the image lock*/
 
        gpointer aot_module;
 
index 6b598020f031767fa058d2d195344f146200aaab..c548a120980f15ba5af1fae0f4f2b9cfcd4bdf5a 100644 (file)
@@ -2735,9 +2735,6 @@ free_inflated_signature (MonoInflatedMethodSignature *sig)
        g_free (sig);
 }
 
-/*
- * LOCKING: assumes the loader lock is held.
- */
 MonoMethodInflated*
 mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache)
 {
@@ -2753,19 +2750,15 @@ mono_method_inflated_lookup (MonoMethodInflated* method, gboolean cache)
 
        collect_data_free (&data);
 
-       if (cache) {
-               mono_image_set_lock (set);
+       mono_image_set_lock (set);
+       res = g_hash_table_lookup (set->gmethod_cache, method);
+       if (!res && cache) {
                g_hash_table_insert (set->gmethod_cache, method, method);
-               mono_image_set_unlock (set);
-
-               return method;
-       } else {
-               mono_image_set_lock (set);
-               res = g_hash_table_lookup (set->gmethod_cache, method);
-               mono_image_set_unlock (set);
-
-               return res;
+               res = method;
        }
+
+       mono_image_set_unlock (set);
+       return res;
 }
 
 /*
index f28839fa1d2cd59d9c0a9ccc70e5c778125a888b..c9dfc05d3a44c75bf21991febafc1ce7e556633b 100644 (file)
@@ -224,6 +224,9 @@ typedef struct {
        int num_instances;
        /* variable length data follows */
        char name [1];
+       // string name
+       // string help
+       // SharedCounter counters_info [num_counters]
 } SharedCategory;
 
 typedef struct {
@@ -231,6 +234,7 @@ typedef struct {
        unsigned int category_offset;
        /* variable length data follows */
        char instance_name [1];
+       // string name
 } SharedInstance;
 
 typedef struct {
@@ -238,6 +242,8 @@ typedef struct {
        guint8 seq_num;
        /* variable length data follows */
        char name [1];
+       // string name
+       // string help
 } SharedCounter;
 
 typedef struct {
@@ -478,9 +484,10 @@ perfctr_type_compress (int type)
        return 2;
 }
 
-static unsigned char*
-shared_data_find_room (int size)
+static SharedHeader*
+shared_data_reserve_room (int size, int ftype)
 {
+       SharedHeader* header;
        unsigned char *p = (unsigned char *)shared_area + shared_area->data_start;
        unsigned char *end = (unsigned char *)shared_area + shared_area->size;
 
@@ -490,7 +497,7 @@ shared_data_find_room (int size)
                unsigned short *next;
                if (*p == FTYPE_END) {
                        if (size < (end - p))
-                               return p;
+                               goto res;
                        return NULL;
                }
                if (p + 4 > end)
@@ -499,12 +506,20 @@ shared_data_find_room (int size)
                if (*p == FTYPE_DELETED) {
                        /* we reuse only if it's the same size */
                        if (*next == size) {
-                               return p;
+                               goto res;
                        }
                }
                p += *next;
        }
        return NULL;
+
+res:
+       header = (SharedHeader*)p;
+       header->ftype = ftype;
+       header->extra = 0; /* data_offset could overflow here, so we leave this field unused */
+       header->size = size;
+
+       return header;
 }
 
 typedef gboolean (*SharedFunc) (SharedHeader *header, void *data);
@@ -610,7 +625,8 @@ find_custom_counter (SharedCategory* cat, MonoString *name)
                SharedCounter *counter = (SharedCounter*)p;
                if (mono_string_compare_ascii (name, counter->name) == 0)
                        return counter;
-               p += 1 + strlen (p + 1) + 1; /* skip counter type and name */
+               p += 2; /* skip counter type */
+               p += strlen (p) + 1; /* skip counter name */
                p += strlen (p) + 1; /* skip counter help */
        }
        return NULL;
@@ -619,7 +635,7 @@ find_custom_counter (SharedCategory* cat, MonoString *name)
 typedef struct {
        unsigned int cat_offset;
        SharedCategory* cat;
-       MonoString *instance;
+       char *name;
        SharedInstance* result;
        GSList *list;
 } InstanceSearch;
@@ -631,8 +647,8 @@ instance_search (SharedHeader *header, void *data)
        if (header->ftype == FTYPE_INSTANCE) {
                SharedInstance *ins = (SharedInstance*)header;
                if (search->cat_offset == ins->category_offset) {
-                       if (search->instance) {
-                               if (mono_string_compare_ascii (search->instance, ins->instance_name) == 0) {
+                       if (search->name) {
+                               if (strcmp (search->name, ins->instance_name) == 0) {
                                        search->result = ins;
                                        return FALSE;
                                }
@@ -645,12 +661,12 @@ instance_search (SharedHeader *header, void *data)
 }
 
 static SharedInstance*
-find_custom_instance (SharedCategory* cat, MonoString *instance)
+find_custom_instance (SharedCategory* cat, char *name)
 {
        InstanceSearch search;
        search.cat_offset = (char*)cat - (char*)shared_area;
        search.cat = cat;
-       search.instance = instance;
+       search.name = name;
        search.list = NULL;
        search.result = NULL;
        foreach_shared_item (instance_search, &search);
@@ -663,7 +679,7 @@ get_custom_instances_list (SharedCategory* cat)
        InstanceSearch search;
        search.cat_offset = (char*)cat - (char*)shared_area;
        search.cat = cat;
-       search.instance = NULL;
+       search.name = NULL;
        search.list = NULL;
        search.result = NULL;
        foreach_shared_item (instance_search, &search);
@@ -1140,41 +1156,33 @@ custom_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
 }
 
 static SharedInstance*
-custom_get_instance (SharedCategory *cat, SharedCounter *scounter, MonoString* instance)
+custom_get_instance (SharedCategory *cat, SharedCounter *scounter, char* name)
 {
        SharedInstance* inst;
-       unsigned char *ptr;
        char *p;
        int size, data_offset;
-       char *name;
-       inst = find_custom_instance (cat, instance);
+       inst = find_custom_instance (cat, name);
        if (inst)
                return inst;
-       name = mono_string_to_utf8 (instance);
        size = sizeof (SharedInstance) + strlen (name);
        size += 7;
        size &= ~7;
        data_offset = size;
        size += (sizeof (guint64) * cat->num_counters);
        perfctr_lock ();
-       ptr = shared_data_find_room (size);
-       if (!ptr) {
+       inst = (SharedInstance*) shared_data_reserve_room (size, FTYPE_INSTANCE);
+       if (!inst) {
                perfctr_unlock ();
                g_free (name);
                return NULL;
        }
-       inst = (SharedInstance*)ptr;
-       inst->header.extra = 0; /* data_offset could overflow here, so we leave this field unused */
-       inst->header.size = size;
        inst->category_offset = (char*)cat - (char*)shared_area;
        cat->num_instances++;
        /* now copy the variable data */
        p = inst->instance_name;
        strcpy (p, name);
        p += strlen (name) + 1;
-       inst->header.ftype = FTYPE_INSTANCE;
        perfctr_unlock ();
-       g_free (name);
 
        return inst;
 }
@@ -1193,24 +1201,33 @@ custom_vtable (SharedCounter *scounter, SharedInstance* inst, char *data)
        return (ImplVtable*)vtable;
 }
 
+static gpointer
+custom_get_value_address (SharedCounter *scounter, SharedInstance* sinst)
+{
+       int offset = sizeof (SharedInstance) + strlen (sinst->instance_name);
+       offset += 7;
+       offset &= ~7;
+       offset += scounter->seq_num * sizeof (guint64);
+       return (char*)sinst + offset;
+}
+
 static void*
 custom_get_impl (SharedCategory *cat, MonoString* counter, MonoString* instance, int *type)
 {
        SharedCounter *scounter;
        SharedInstance* inst;
-       int size;
+       char *name;
 
        scounter = find_custom_counter (cat, counter);
        if (!scounter)
                return NULL;
        *type = simple_type_to_type [scounter->type];
-       inst = custom_get_instance (cat, scounter, instance);
+       name = mono_string_to_utf8 (counter);
+       inst = custom_get_instance (cat, scounter, name);
+       g_free (name);
        if (!inst)
                return NULL;
-       size = sizeof (SharedInstance) + strlen (inst->instance_name);
-       size += 7;
-       size &= ~7;
-       return custom_vtable (scounter, inst, (char*)inst + size + scounter->seq_num * sizeof (guint64));
+       return custom_vtable (scounter, inst, custom_get_value_address (scounter, inst));
 }
 
 static const CategoryDesc*
@@ -1383,7 +1400,6 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
        char *name = NULL;
        char *chelp = NULL;
        char **counter_info = NULL;
-       unsigned char *ptr;
        char *p;
        SharedCategory *cat;
 
@@ -1419,14 +1435,11 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
        if (size > 65535)
                goto failure;
        perfctr_lock ();
-       ptr = shared_data_find_room (size);
-       if (!ptr) {
+       cat = (SharedCategory*) shared_data_reserve_room (size, FTYPE_CATEGORY);
+       if (!cat) {
                perfctr_unlock ();
                goto failure;
        }
-       cat = (SharedCategory*)ptr;
-       cat->header.extra = type;
-       cat->header.size = size;
        cat->num_counters = num_counters;
        cat->counters_data_size = counters_data_size;
        /* now copy the vaiable data */
@@ -1445,7 +1458,6 @@ mono_perfcounter_create (MonoString *category, MonoString *help, int type, MonoA
                strcpy (p, counter_info [i * 2 + 1]);
                p += strlen (counter_info [i * 2 + 1]) + 1;
        }
-       cat->header.ftype = FTYPE_CATEGORY;
 
        perfctr_unlock ();
        result = TRUE;
@@ -1466,6 +1478,8 @@ int
 mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, MonoString *machine)
 {
        const CategoryDesc *cdesc;
+       SharedInstance *sinst;
+       char *name;
        /* no support for counters on other machines */
        /*FIXME: machine appears to be wrong
        if (mono_string_compare_ascii (machine, "."))
@@ -1476,7 +1490,10 @@ mono_perfcounter_instance_exists (MonoString *instance, MonoString *category, Mo
                scat = find_custom_category (category);
                if (!scat)
                        return FALSE;
-               if (find_custom_instance (scat, instance))
+               name = mono_string_to_utf8 (instance);
+               sinst = find_custom_instance (scat, name);
+               g_free (name);
+               if (sinst)
                        return TRUE;
        } else {
                /* FIXME: search instance */
@@ -1539,7 +1556,8 @@ mono_perfcounter_counter_names (MonoString *category, MonoString *machine)
                res = mono_array_new (domain, mono_get_string_class (), scat->num_counters);
                for (i = 0; i < scat->num_counters; ++i) {
                        mono_array_setref (res, i, mono_string_new (domain, p + 1));
-                       p += 1 + strlen (p + 1) + 1; /* skip counter type and name */
+                       p += 2; /* skip counter type */
+                       p += strlen (p) + 1; /* skip counter name */
                        p += strlen (p) + 1; /* skip counter help */
                }
                perfctr_unlock ();
@@ -1691,6 +1709,65 @@ mono_perfcounter_instance_names (MonoString *category, MonoString *machine)
                return mono_array_new (mono_domain_get (), mono_get_string_class (), 0);
        }
 }
+
+typedef struct {
+       PerfCounterEnumCallback cb;
+       void *data;
+} PerfCounterForeachData;
+
+static gboolean
+mono_perfcounter_foreach_shared_item (SharedHeader *header, gpointer data)
+{
+       int i;
+       char *p, *name, *help;
+       unsigned char type;
+       int seq_num;
+       void *addr;
+       SharedCategory *cat;
+       SharedCounter *counter;
+       SharedInstance *inst;
+       PerfCounterForeachData *foreach_data = data;
+
+       if (header->ftype == FTYPE_CATEGORY) {
+               cat = (SharedCategory*)header;
+
+               p = cat->name;
+               p += strlen (p) + 1; /* skip category name */
+               p += strlen (p) + 1; /* skip category help */
+
+               for (i = 0; i < cat->num_counters; ++i) {
+                       counter = (SharedCounter*) p;
+                       type = (unsigned char)*p++;
+                       seq_num = (int)*p++;
+                       name = p;
+                       p += strlen (p) + 1;
+                       help = p;
+                       p += strlen (p) + 1;
+
+                       inst = custom_get_instance (cat, counter, name);
+                       if (!inst)
+                               return FALSE;
+                       addr = custom_get_value_address (counter, inst);
+                       if (!foreach_data->cb (cat->name, name, type, addr ? *(gint64*)addr : 0, foreach_data->data))
+                               return FALSE;
+               }
+       }
+
+       return TRUE;
+}
+
+void
+mono_perfcounter_foreach (PerfCounterEnumCallback cb, gpointer data)
+{
+       PerfCounterForeachData foreach_data = { cb, data };
+
+       perfctr_lock ();
+
+       foreach_shared_item (mono_perfcounter_foreach_shared_item, &foreach_data);
+
+       perfctr_unlock ();
+}
+
 #else
 void*
 mono_perfcounter_get_impl (MonoString* category, MonoString* counter, MonoString* instance, MonoString* machine, int *type, MonoBoolean *custom)
index 3cf5e8f58297a5fe5a41f2df57d4ab20d17b492c..c9f3fc2be09a0497032354c12f4d7fcb435a960f 100644 (file)
@@ -2,8 +2,8 @@
 #define __MONO_PERFCOUNTERS_H__
 
 #include <glib.h>
-#include <metadata/object.h>
-#include <utils/mono-compiler.h>
+#include <mono/metadata/object.h>
+#include <mono/utils/mono-compiler.h>
 
 typedef struct _MonoCounterSample MonoCounterSample;
 
@@ -25,6 +25,8 @@ MonoArray*  mono_perfcounter_category_names  (MonoString *machine) MONO_INTERNAL
 MonoArray*  mono_perfcounter_counter_names   (MonoString *category, MonoString *machine) MONO_INTERNAL;
 MonoArray*  mono_perfcounter_instance_names  (MonoString *category, MonoString *machine) MONO_INTERNAL;
 
+typedef gboolean (*PerfCounterEnumCallback) (char *category_name, char *name, unsigned char type, gint64 value, gpointer user_data);
+MONO_API void mono_perfcounter_foreach (PerfCounterEnumCallback cb, gpointer user_data);
 
 #endif /* __MONO_PERFCOUNTERS_H__ */
 
index 397f3849f3d62e0d425a0301fd586d44f3af79df..54b2ddbeea4f055e77ca4ca7aabb144ae799247e 100644 (file)
@@ -13,6 +13,7 @@
 #include <mono/metadata/runtime.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-counters.h>
 
 #ifdef HAVE_NULL_GC
 
@@ -22,6 +23,8 @@ mono_gc_base_init (void)
        MonoThreadInfoCallbacks cb;
        int dummy;
 
+       mono_counters_init ();
+
        memset (&cb, 0, sizeof (cb));
        /* TODO: This casts away an incompatible pointer type warning in the same
                 manner that boehm-gc does it. This is probably worth investigating
index 3793c9435be4b084f443ac9633bbce498cc61c5f..996394326835ae6a6316c95d0076a595de8cee00 100644 (file)
@@ -30,6 +30,7 @@
 #include "metadata/sgen-gc.h"
 #include "metadata/sgen-gray.h"
 #include "metadata/sgen-protocol.h"
+#include "metadata/sgen-pointer-queue.h"
 #include "utils/dtrace.h"
 #include "utils/mono-counters.h"
 
@@ -73,7 +74,7 @@ tagged_object_apply (void *object, int tag_bits)
 static int
 tagged_object_hash (MonoObject *o)
 {
-       return mono_object_hash (tagged_object_get_object (o));
+       return mono_aligned_addr_hash (tagged_object_get_object (o));
 }
 
 static gboolean
@@ -116,6 +117,9 @@ sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
        MonoObject *object;
        gpointer dummy;
        char *copy;
+       SgenPointerQueue moved_fin_objects;
+
+       sgen_pointer_queue_init (&moved_fin_objects, INTERNAL_MEM_TEMPORARY);
 
        if (no_finalize)
                return;
@@ -154,12 +158,24 @@ sgen_collect_bridge_objects (int generation, ScanCopyContext ctx)
                        SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_safe_name (copy), object);
 
                        continue;
-               } else {
+               } else if (copy != (char*)object) {
                        /* update pointer */
+                       SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
+
+                       /* register for reinsertion */
+                       sgen_pointer_queue_add (&moved_fin_objects, tagged_object_apply (copy, tag));
+
                        SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_safe_name (copy), object);
-                       SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag));
+
+                       continue;
                }
        } SGEN_HASH_TABLE_FOREACH_END;
+
+       while (!sgen_pointer_queue_is_empty (&moved_fin_objects)) {
+               sgen_hash_table_replace (hash_table, sgen_pointer_queue_pop (&moved_fin_objects), NULL, NULL);
+       }
+
+       sgen_pointer_queue_free (&moved_fin_objects);
 }
 
 
@@ -172,6 +188,9 @@ sgen_finalize_in_range (int generation, ScanCopyContext ctx)
        SgenHashTable *hash_table = get_finalize_entry_hash_table (generation);
        MonoObject *object;
        gpointer dummy;
+       SgenPointerQueue moved_fin_objects;
+
+       sgen_pointer_queue_init (&moved_fin_objects, INTERNAL_MEM_TEMPORARY);
 
        if (no_finalize)
                return;
@@ -201,14 +220,26 @@ sgen_finalize_in_range (int generation, ScanCopyContext ctx)
                                        SGEN_LOG (5, "Promoting finalization of object %p (%s) (was at %p) to major table", copy, sgen_safe_name (copy), object);
 
                                        continue;
-                               } else {
+                               } else if (copy != object) {
                                        /* update pointer */
+                                       SGEN_HASH_TABLE_FOREACH_REMOVE (TRUE);
+
+                                       /* register for reinsertion */
+                                       sgen_pointer_queue_add (&moved_fin_objects, tagged_object_apply (copy, tag));
+
                                        SGEN_LOG (5, "Updating object for finalization: %p (%s) (was at %p)", copy, sgen_safe_name (copy), object);
-                                       SGEN_HASH_TABLE_FOREACH_SET_KEY (tagged_object_apply (copy, tag));
+
+                                       continue;
                                }
                        }
                }
        } SGEN_HASH_TABLE_FOREACH_END;
+
+       while (!sgen_pointer_queue_is_empty (&moved_fin_objects)) {
+               sgen_hash_table_replace (hash_table, sgen_pointer_queue_pop (&moved_fin_objects), NULL, NULL);
+       }
+
+       sgen_pointer_queue_free (&moved_fin_objects);
 }
 
 /* LOCKING: requires that the GC lock is held */
index eee258638dc44a3ff94b4229c04d95508ee70ba4..2ea2bf033f5df12f021c9107e887f44bd36de4f4 100644 (file)
@@ -4630,6 +4630,8 @@ mono_gc_base_init (void)
        gboolean have_split_nursery = FALSE;
        gboolean cement_enabled = TRUE;
 
+       mono_counters_init ();
+
        do {
                result = InterlockedCompareExchange (&gc_initialized, -1, 0);
                switch (result) {
index c77f05c6e84825ca3a4f0a0ab071a2a94812662e..32e878d0fe86085388d755391cbe043ecd19d513 100644 (file)
@@ -437,6 +437,7 @@ enum {
        INTERNAL_MEM_TOGGLEREF_DATA,
        INTERNAL_MEM_CARDTABLE_MOD_UNION,
        INTERNAL_MEM_BINARY_PROTOCOL,
+       INTERNAL_MEM_TEMPORARY,
        INTERNAL_MEM_MAX
 };
 
index 333f8c3ee419261cdd9e103d4b7b4779cf1dce0f..f5b8995355fe58edeb341cb656fd8c0763ade96b 100644 (file)
@@ -150,6 +150,7 @@ description_for_type (int type)
        case INTERNAL_MEM_TOGGLEREF_DATA: return "toggleref-data";
        case INTERNAL_MEM_CARDTABLE_MOD_UNION: return "cardtable-mod-union";
        case INTERNAL_MEM_BINARY_PROTOCOL: return "binary-protocol";
+       case INTERNAL_MEM_TEMPORARY: return "temporary";
        default:
                g_assert_not_reached ();
        }
index 937bfd8722244e449d2e74729bf040d15106a9ea..66d5c7d9b8365cabb9b0c9ea12a09926c7cb0dd1 100644 (file)
@@ -37,6 +37,7 @@ void
 sgen_init_pinning (void)
 {
        memset (pin_hash_filter, 0, sizeof (pin_hash_filter));
+       pin_queue.mem_type = INTERNAL_MEM_PIN_QUEUE;
 }
 
 void
index 3c1d8fb6c61d8d036a670924fd68f6c768984acb..7ace7dfa4b68d598c76e95b8ff72e91485f5a447 100644 (file)
@@ -28,13 +28,23 @@ sgen_pointer_queue_clear (SgenPointerQueue *queue)
        queue->next_slot = 0;
 }
 
+void
+sgen_pointer_queue_init (SgenPointerQueue *queue, int mem_type)
+{
+       queue->next_slot = 0;
+       queue->size = 0;
+       queue->data = NULL;
+       queue->mem_type = mem_type;
+}
+
 static void
 realloc_queue (SgenPointerQueue *queue)
 {
        size_t new_size = queue->size ? queue->size + queue->size/2 : 1024;
-       void **new_data = sgen_alloc_internal_dynamic (sizeof (void*) * new_size, INTERNAL_MEM_PIN_QUEUE, TRUE);
+       void **new_data = sgen_alloc_internal_dynamic (sizeof (void*) * new_size, queue->mem_type, TRUE);
+
        memcpy (new_data, queue->data, sizeof (void*) * queue->next_slot);
-       sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, INTERNAL_MEM_PIN_QUEUE);
+       sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);
        queue->data = new_data;
        queue->size = new_size;
        SGEN_LOG (4, "Reallocated pointer queue to size: %lu", new_size);
@@ -49,6 +59,14 @@ sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr)
        queue->data [queue->next_slot++] = ptr;
 }
 
+void*
+sgen_pointer_queue_pop (SgenPointerQueue *queue)
+{
+       g_assert (queue->next_slot);
+
+       return queue->data [--queue->next_slot];
+}
+
 size_t
 sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr)
 {
@@ -120,4 +138,16 @@ sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr)
        return (size_t)-1;
 }
 
+gboolean
+sgen_pointer_queue_is_empty (SgenPointerQueue *queue)
+{
+       return !queue->next_slot;
+}
+
+void
+sgen_pointer_queue_free (SgenPointerQueue *queue)
+{
+       sgen_free_internal_dynamic (queue->data, sizeof (void*) * queue->size, queue->mem_type);
+}
+
 #endif
index d972f3cc92e235f04cb200d33622846f9ed53bd8..0bbeedfdd67f21a71d20a2f7c1335b50481f5421 100644 (file)
 #ifndef __MONO_SGEN_POINTER_QUEUE_H__
 #define __MONO_SGEN_POINTER_QUEUE_H__
 
+#include <glib.h>
+
 typedef struct {
        void **data;
        size_t size;
        size_t next_slot;
+       int mem_type;
 } SgenPointerQueue;
 
 void sgen_pointer_queue_add (SgenPointerQueue *queue, void *ptr) MONO_INTERNAL;
@@ -32,5 +35,9 @@ void sgen_pointer_queue_remove_nulls (SgenPointerQueue *queue) MONO_INTERNAL;
 void sgen_pointer_queue_sort_uniq (SgenPointerQueue *queue) MONO_INTERNAL;
 size_t sgen_pointer_queue_search (SgenPointerQueue *queue, void *addr) MONO_INTERNAL;
 size_t sgen_pointer_queue_find (SgenPointerQueue *queue, void *ptr) MONO_INTERNAL;
+void sgen_pointer_queue_init (SgenPointerQueue *queue, int mem_type) MONO_INTERNAL;
+void* sgen_pointer_queue_pop (SgenPointerQueue *queue) MONO_INTERNAL;
+gboolean sgen_pointer_queue_is_empty (SgenPointerQueue *queue) MONO_INTERNAL;
+void sgen_pointer_queue_free (SgenPointerQueue *queue) MONO_INTERNAL;
 
 #endif
index 949164e5548c4e82fcc5f27f9c524c9963c825ba..0b75405bd0acd42aca213b10a011e745d1ecc636 100644 (file)
@@ -13,7 +13,7 @@
 
 #ifndef DISABLE_SOCKETS
 
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__FreeBSD__)
 #define __APPLE_USE_RFC_3542
 #endif
 
 #define AI_ADDRCONFIG 0
 #endif
 
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(__FreeBSD__)
 /*
  * We remove this until we have a Darwin implementation
  * that can walk the result of struct ifconf.  The current
@@ -2051,7 +2051,7 @@ static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
 #endif /* AF_INET6 */
 #endif
 
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(__FreeBSD__)
 
 #if defined(HAVE_GETIFADDRS) && defined(HAVE_IF_NAMETOINDEX)
 static int
@@ -2089,7 +2089,7 @@ get_local_interface_id (int family)
 }
 #endif
 
-#endif /* __APPLE__ */
+#endif /* defined(__APPLE__) || defined(__FreeBSD__) */
 
 void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, gint32 level, gint32 name, MonoObject *obj_val, MonoArray *byte_val, gint32 int_val, gint32 *error)
 {
@@ -2187,7 +2187,7 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                                field=mono_class_get_field_from_name(obj_val->vtable->klass, "ifIndex");
                                mreq6.ipv6mr_interface =*(guint64 *)(((char *)obj_val)+field->offset);
                                
-#if defined(__APPLE__)
+#if defined(__APPLE__) || defined(__FreeBSD__)
                                /*
                                * Bug #5504:
                                *
index 63e39501fe1e4dcdb43880f2f267ccf72402d713..1599f6aba13bf4f0c5b2fb803e49a7c02c871176 100644 (file)
@@ -2652,7 +2652,7 @@ thread_interrupt (DebuggerTlsData *tls, MonoThreadInfo *info, void *sigctx, Mono
                         */
                        data.last_frame_set = FALSE;
                        if (sigctx) {
-                               mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+                               mono_sigctx_to_monoctx (sigctx, &ctx);
                                /* 
                                 * Don't pass MONO_UNWIND_ACTUAL_METHOD, its not signal safe, and
                                 * get_last_frame () doesn't need it, the last frame cannot be a ginst
@@ -4907,14 +4907,14 @@ resume_from_signal_handler (void *sigctx, void *func)
        // clobbered by a single step/breakpoint event. If this turns out to be a problem,
        // clob:c could be added to op_seq_point.
 
-       mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+       mono_sigctx_to_monoctx (sigctx, &ctx);
        memcpy (&tls->handler_ctx, &ctx, sizeof (MonoContext));
 #ifdef MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX
        mono_arch_setup_resume_sighandler_ctx (&ctx, func);
 #else
        MONO_CONTEXT_SET_IP (&ctx, func);
 #endif
-       mono_arch_monoctx_to_sigctx (&ctx, sigctx);
+       mono_monoctx_to_sigctx (&ctx, sigctx);
 
 #ifdef PPC_USES_FUNCTION_DESCRIPTOR
        mono_ppc_set_func_into_sigctx (sigctx, func);
@@ -5104,9 +5104,9 @@ mono_debugger_agent_single_step_event (void *sigctx)
                 */
                MonoContext ctx;
 
-               mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+               mono_sigctx_to_monoctx (sigctx, &ctx);
                mono_arch_skip_single_step (&ctx);
-               mono_arch_monoctx_to_sigctx (&ctx, sigctx);
+               mono_monoctx_to_sigctx (&ctx, sigctx);
                return;
        }
 
index c6c8e20628c78b84242ab2d4c20270d31a23db79..76abae4a20b8b9e4e94d19feaf33fb255326c46f 100644 (file)
@@ -1868,6 +1868,8 @@ mono_main (int argc, char* argv[])
                g_set_prgname (argv[i]);
        }
 
+       mono_counters_init ();
+
        if (enable_profile)
                mono_profiler_load (profile_options);
 
index a0865b7e2b68dcfce72c596b361a61eb3be8ab17..b8cfe9ad463265a03875569e72534542ce1cb2e4 100644 (file)
@@ -759,7 +759,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
 
        mctx = jit_tls->ex_ctx;
        mono_arch_setup_async_callback (&mctx, handle_signal_exception, obj);
@@ -769,28 +769,16 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
 #else
        MonoContext mctx;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &mctx);
+       mono_sigctx_to_monoctx (sigctx, &mctx);
 
        mono_handle_exception (&mctx, obj);
 
-       mono_arch_monoctx_to_sigctx (&mctx, sigctx);
+       mono_monoctx_to_sigctx (&mctx, sigctx);
 
        return TRUE;
 #endif
 }
 
-void
-mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx (sigctx, mctx);
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
-{
-       mono_monoctx_to_sigctx (mctx, sigctx);
-}
-
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
index e39248ceda12e75453048aa4d042450f7d4b20cd..2c9e748454e8d57a30fe6fa725542e64e4f01b5a 100644 (file)
@@ -501,20 +501,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
        return FALSE;
 }
 
-#if MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
-void
-mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx (sigctx, mctx);
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
-{
-       mono_monoctx_to_sigctx (mctx, ctx);
-}
-#endif /* MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX */
-
 /*
  * handle_exception:
  *
@@ -562,7 +548,7 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        guint64 sp = UCONTEXT_REG_SP (sigctx);
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
        /* The others in registers */
        UCONTEXT_REG_R0 (sigctx) = (gsize)obj;
 
@@ -585,13 +571,13 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        MonoContext mctx;
        gboolean result;
 
-       mono_arch_sigctx_to_monoctx (ctx, &mctx);
+       mono_sigctx_to_monoctx (ctx, &mctx);
 
        result = mono_handle_exception (&mctx, obj);
        /* restore the context so that returning from the signal handler will invoke
         * the catch clause 
         */
-       mono_arch_monoctx_to_sigctx (&mctx, ctx);
+       mono_monoctx_to_sigctx (&mctx, ctx);
        return result;
 #endif
 }
index 34197145048468a709de54e097cead753f06a2f0..8ab97bf5a30068e487b4fd27e97ca02fd8fed0ca 100644 (file)
@@ -478,18 +478,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
        return FALSE;
 }
 
-void
-mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx (sigctx, mctx);
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
-{
-       mono_monoctx_to_sigctx (mctx, sigctx);
-}
-
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
@@ -534,7 +522,7 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        guint64 sp = UCONTEXT_GREGS (sigctx) [mips_sp];
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
        /* The others in registers */
        UCONTEXT_GREGS (sigctx)[mips_a0] = (gsize)obj;
 
@@ -549,13 +537,13 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        MonoContext mctx;
        gboolean result;
 
-       mono_arch_sigctx_to_monoctx (ctx, &mctx);
+       mono_sigctx_to_monoctx (ctx, &mctx);
 
        result = mono_handle_exception (&mctx, obj);
        /* restore the context so that returning from the signal handler will invoke
         * the catch clause 
         */
-       mono_arch_monoctx_to_sigctx (&mctx, ctx);
+       mono_monoctx_to_sigctx (&mctx, ctx);
        return result;
 #endif
 }
index 6c3878e97b8e4df6102126330851adae5cea167f..8ba3bf083d831c19cd13bb1354962a19b8b394da 100644 (file)
@@ -594,39 +594,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
        return FALSE;
 }
 
-/*
- * This is the function called from the signal handler
- */
-void
-mono_arch_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
-{
-#ifdef MONO_CROSS_COMPILE
-       g_assert_not_reached ();
-#else
-       os_ucontext *uc = ctx;
-
-       mctx->sc_ir = UCONTEXT_REG_NIP(uc);
-       mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
-       memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
-       memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
-#endif
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
-{
-#ifdef MONO_CROSS_COMPILE
-       g_assert_not_reached ();
-#else
-       os_ucontext *uc = ctx;
-
-       UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
-       UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
-       memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
-       memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
-#endif
-}
-
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
@@ -659,7 +626,7 @@ altstack_handle_and_restore (void *sigctx, gpointer obj)
 {
        MonoContext mctx;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &mctx);
+       mono_sigctx_to_monoctx (sigctx, &mctx);
        mono_handle_exception (&mctx, obj);
        mono_restore_context (&mctx);
 }
@@ -782,7 +749,7 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        void *uc = sigctx;
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
        /* The others in registers */
        UCONTEXT_REG_Rn (sigctx, PPC_FIRST_ARG_REG) = (gsize)obj;
 
@@ -801,13 +768,13 @@ mono_arch_handle_exception (void *ctx, gpointer obj)
        MonoContext mctx;
        gboolean result;
 
-       mono_arch_sigctx_to_monoctx (ctx, &mctx);
+       mono_sigctx_to_monoctx (ctx, &mctx);
 
        result = mono_handle_exception (&mctx, obj);
        /* restore the context so that returning from the signal handler will invoke
         * the catch clause 
         */
-       mono_arch_monoctx_to_sigctx (&mctx, ctx);
+       mono_monoctx_to_sigctx (&mctx, ctx);
        return result;
 #endif
 }
index 74c8a0f37a3dfc9fb29813eb87029ad251f7421f..bc05005d01df7b59f324f642fd315180b22af035 100644 (file)
@@ -532,39 +532,6 @@ mono_arch_handle_exception (void *uc, gpointer obj)
 
 /*========================= End of Function ========================*/
 
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_sigctx_to_monoctx.                      */
-/*                                                                  */
-/* Function    - Called from the signal handler to convert signal  */
-/*                context to MonoContext.                           */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_sigctx_to_monoctx (void *ctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx(ctx, mctx);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_monoctx_to_sigctx.                      */
-/*                                                                  */
-/* Function    - Convert MonoContext structure to signal context.  */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *ctx)
-{
-       mono_monoctx_to_sigctx(mctx, ctx);
-}
-
-/*========================= End of Function ========================*/
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_ip_from_context                         */
index 615b3f2371f3788b2d96bf8c0f280f0e9ea63ae5..5b91a476dac2594ca10f24b7c33e6c15c9cc20de 100755 (executable)
@@ -139,8 +139,7 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx)
        guint32 free_stack = 0;
        StackFrameInfo frame;
 
-       /* convert sigcontext to MonoContext (due to reuse of stack walking helpers */
-       mono_arch_sigctx_to_monoctx (sctx, &ctx);
+       mono_sigctx_to_monoctx (sctx, &ctx);
        
        /* get our os page size */
        GetSystemInfo(&si);
@@ -172,8 +171,7 @@ win32_handle_stack_overflow (EXCEPTION_POINTERS* ep, struct sigcontext *sctx)
                ctx = new_ctx;
        } while (free_stack < 64 * 1024 && frame.ji != (gpointer) -1);
 
-       /* convert into sigcontext to be used in mono_arch_handle_exception */
-       mono_arch_monoctx_to_sigctx (&ctx, sctx);
+       mono_monoctx_to_sigctx (&ctx, sctx);
 
        /* todo: install new stack-guard page */
 
@@ -855,21 +853,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                if ((guint32)((*lmf)->previous_lmf) & 1) {
                        /* lmf->esp is set by the trampoline code */
                        new_ctx->esp = (*lmf)->esp;
-
-                       /* Pop arguments off the stack */
-                       /* FIXME: Handle the delegate case too ((*lmf)->method == NULL) */
-                       /* FIXME: Handle the IMT/vtable case too */
-#if 0
-#ifndef ENABLE_LLVM
-                       if ((*lmf)->method) {
-                               MonoMethod *method = (*lmf)->method;
-                               MonoJitArgumentInfo *arg_info = g_newa (MonoJitArgumentInfo, mono_method_signature (method)->param_count + 1);
-
-                               guint32 stack_to_pop = mono_arch_get_argument_info (NULL, mono_method_signature (method), mono_method_signature (method)->param_count, arg_info);
-                               new_ctx->esp += stack_to_pop;
-                       }
-#endif
-#endif
                }
                else
                        /* the lmf is always stored on the stack, so the following
@@ -884,18 +867,6 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
        return FALSE;
 }
 
-void
-mono_arch_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
-{
-       mono_sigctx_to_monoctx (sigctx, mctx);
-}
-
-void
-mono_arch_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
-{
-       mono_monoctx_to_sigctx (mctx, sigctx);
-}
-
 gpointer
 mono_arch_ip_from_context (void *sigctx)
 {
@@ -1012,7 +983,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
 
        /* Pass the ctx parameter in TLS */
-       mono_arch_sigctx_to_monoctx (ctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (ctx, &jit_tls->ex_ctx);
 
        mctx = jit_tls->ex_ctx;
        mono_setup_async_callback (&mctx, handle_signal_exception, obj);
@@ -1024,7 +995,7 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
        MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id);
        struct sigcontext *ctx = (struct sigcontext *)sigctx;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
+       mono_sigctx_to_monoctx (sigctx, &jit_tls->ex_ctx);
 
        mctx = jit_tls->ex_ctx;
        mono_setup_async_callback (&mctx, handle_signal_exception, obj);
@@ -1034,11 +1005,11 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
 #else
        MonoContext mctx;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &mctx);
+       mono_sigctx_to_monoctx (sigctx, &mctx);
 
        mono_handle_exception (&mctx, obj);
 
-       mono_arch_monoctx_to_sigctx (&mctx, sigctx);
+       mono_monoctx_to_sigctx (&mctx, sigctx);
 
        return TRUE;
 #endif
index 9a78a549a313057464ae22c86351402b670e9c92..de016eff717b3c54fb51a6be1276a383f4849e75 100755 (executable)
@@ -3582,11 +3582,11 @@ static void
 save_cast_details (MonoCompile *cfg, MonoClass *klass, int obj_reg, gboolean null_check, MonoBasicBlock **out_bblock)
 {
        if (mini_get_debug_options ()->better_cast_details) {
-               int to_klass_reg = alloc_preg (cfg);
                int vtable_reg = alloc_preg (cfg);
                int klass_reg = alloc_preg (cfg);
                MonoBasicBlock *is_null_bb = NULL;
                MonoInst *tls_get;
+               int to_klass_reg, context_used;
 
                if (null_check) {
                        NEW_BBLOCK (cfg, is_null_bb);
@@ -3606,7 +3606,17 @@ save_cast_details (MonoCompile *cfg, MonoClass *klass, int obj_reg, gboolean nul
                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, klass_reg, vtable_reg, MONO_STRUCT_OFFSET (MonoVTable, klass));
 
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, MONO_STRUCT_OFFSET (MonoJitTlsData, class_cast_from), klass_reg);
-               MONO_EMIT_NEW_PCONST (cfg, to_klass_reg, klass);
+
+               context_used = mini_class_check_context_used (cfg, klass);
+               if (context_used) {
+                       MonoInst *class_ins;
+
+                       class_ins = emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
+                       to_klass_reg = class_ins->dreg;
+               } else {
+                       to_klass_reg = alloc_preg (cfg);
+                       MONO_EMIT_NEW_CLASSCONST (cfg, to_klass_reg, klass);
+               }
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, tls_get->dreg, MONO_STRUCT_OFFSET (MonoJitTlsData, class_cast_to), to_klass_reg);
 
                if (null_check) {
@@ -4097,6 +4107,7 @@ emit_castclass_with_cache (MonoCompile *cfg, MonoClass *klass, MonoInst **args,
        save_cast_details (cfg, klass, args [0]->dreg, TRUE, out_bblock);
        res = mono_emit_method_call (cfg, mono_castclass, args, NULL);
        reset_cast_details (cfg);
+       *out_bblock = cfg->cbb;
 
        return res;
 }
@@ -4190,7 +4201,7 @@ handle_castclass (MonoCompile *cfg, MonoClass *klass, MonoInst *src, guint8 *ip,
                        /* cache */
                        args [2] = cache_ins;
 
-                       return emit_castclass_with_cache (cfg, klass, args, NULL);
+                       return emit_castclass_with_cache (cfg, klass, args, out_bb);
                }
 
                klass_inst = emit_get_rgctx_klass (cfg, context_used, klass, MONO_RGCTX_INFO_KLASS);
@@ -11079,14 +11090,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                           typeof(Gen<>). */
                                        context_used = 0;
                                } else if (handle_class == mono_defaults.typehandle_class) {
-                                       /* If we get a MONO_TYPE_CLASS
-                                          then we need to provide the
-                                          open type, not an
-                                          instantiation of it. */
-                                       if (mono_type_get_type (handle) == MONO_TYPE_CLASS)
-                                               context_used = 0;
-                                       else
-                                               context_used = mini_class_check_context_used (cfg, mono_class_from_mono_type (handle));
+                                       context_used = mini_class_check_context_used (cfg, mono_class_from_mono_type (handle));
                                } else if (handle_class == mono_defaults.fieldhandle_class)
                                        context_used = mini_class_check_context_used (cfg, ((MonoClassField*)handle)->parent);
                                else if (handle_class == mono_defaults.methodhandle_class)
index a809de49e052aefd2748248d86abab00ede6d530..73a226cfd48e2afe4eb075c09fd765c8cc4efc1a 100755 (executable)
@@ -5022,8 +5022,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_STORER4_MEMBASE_REG:
                        /* This requires a double->single conversion */
-                       amd64_sse_cvtsd2ss_reg_reg (code, AMD64_XMM15, ins->sreg1);
-                       amd64_sse_movss_membase_reg (code, ins->inst_destbasereg, ins->inst_offset, AMD64_XMM15);
+                       amd64_sse_cvtsd2ss_reg_reg (code, MONO_ARCH_FP_SCRATCH_REG, ins->sreg1);
+                       amd64_sse_movss_membase_reg (code, ins->inst_destbasereg, ins->inst_offset, MONO_ARCH_FP_SCRATCH_REG);
                        break;
                case OP_LOADR4_MEMBASE:
                        amd64_sse_movss_reg_membase (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
@@ -6070,8 +6070,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_EXTRACT_I8:
                        if (ins->inst_c0) {
-                               amd64_movhlps_reg_reg (code, AMD64_XMM15, ins->sreg1);
-                               amd64_movd_reg_xreg_size (code, ins->dreg, AMD64_XMM15, 8);
+                               amd64_movhlps_reg_reg (code, MONO_ARCH_FP_SCRATCH_REG, ins->sreg1);
+                               amd64_movd_reg_xreg_size (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG, 8);
                        } else {
                                amd64_movd_reg_xreg_size (code, ins->dreg, ins->sreg1, 8);
                        }
@@ -6123,11 +6123,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_sse_pinsrw_reg_reg_imm (code, ins->dreg, ins->sreg2, ins->inst_c0 * 2 + 1);
                        break;
                case OP_INSERTX_I8_SLOW:
-                       amd64_movd_xreg_reg_size(code, AMD64_XMM15, ins->sreg2, 8);
+                       amd64_movd_xreg_reg_size(code, MONO_ARCH_FP_SCRATCH_REG, ins->sreg2, 8);
                        if (ins->inst_c0)
-                               amd64_movlhps_reg_reg (code, ins->dreg, AMD64_XMM15);
+                               amd64_movlhps_reg_reg (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG);
                        else
-                               amd64_sse_movsd_reg_reg (code, ins->dreg, AMD64_XMM15);
+                               amd64_sse_movsd_reg_reg (code, ins->dreg, MONO_ARCH_FP_SCRATCH_REG);
                        break;
 
                case OP_INSERTX_R4_SLOW:
@@ -7484,7 +7484,7 @@ mono_arch_is_int_overflow (void *sigctx, void *info)
        int reg;
        gint64 value;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+       mono_sigctx_to_monoctx (sigctx, &ctx);
 
        rip = (guint8*)ctx.rip;
 
index ebd2638727b7b5ba04c3a42807e2dece11a4558d..dc43eb731a2a1988db0316f52aeb5896327e4a74 100755 (executable)
@@ -122,14 +122,23 @@ struct sigcontext {
 
 #define MONO_ARCH_FP_RETURN_REG AMD64_XMM0
 
-/* xmm15 is reserved for use by some opcodes */
+#ifdef TARGET_WIN32
+/* xmm5 is used as a scratch register */
+#define MONO_ARCH_CALLEE_FREGS 0x1f
+/* xmm6:xmm15 */
+#define MONO_ARCH_CALLEE_SAVED_FREGS (0xffff - 0x3f)
+#define MONO_ARCH_FP_SCRATCH_REG AMD64_XMM5
+#else
+/* xmm15 is used as a scratch register */
 #define MONO_ARCH_CALLEE_FREGS 0x7fff
 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
+#define MONO_ARCH_FP_SCRATCH_REG AMD64_XMM15
+#endif
 
 #define MONO_MAX_XREGS MONO_MAX_FREGS
 
-#define MONO_ARCH_CALLEE_XREGS 0x7fff
-#define MONO_ARCH_CALLEE_SAVED_XREGS 0
+#define MONO_ARCH_CALLEE_XREGS MONO_ARCH_CALLEE_FREGS
+#define MONO_ARCH_CALLEE_SAVED_XREGS MONO_ARCH_CALLEE_SAVED_FREGS
 
 
 #define MONO_ARCH_CALLEE_REGS AMD64_CALLEE_REGS
index 7e7c5937b974dc6615418c63d4a1bedc2714ab3c..9ccc982e37afa2a4c89b20cc93e05f4a08cf3f1a 100644 (file)
@@ -1183,6 +1183,8 @@ mono_arch_flush_icache (guint8 *code, gint size)
 #ifdef MONO_CROSS_COMPILE
 #elif __APPLE__
        sys_icache_invalidate (code, size);
+#elif __GNUC_PREREQ(4, 3)
+    __builtin___clear_cache (code, code + size);
 #elif __GNUC_PREREQ(4, 1)
        __clear_cache (code, code + size);
 #elif defined(PLATFORM_ANDROID)
index db4a1ce4b0c98834c4fd8cad0dd4f569c90c215a..616ebc46bf363e6db420ffc14d4d0ce54be47bd8 100644 (file)
@@ -2183,7 +2183,7 @@ mono_handle_hard_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx,
        mono_runtime_printf_err ("Stack overflow: IP: %p, fault addr: %p", mono_arch_ip_from_context (ctx), fault_addr);
 
 #ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
-       mono_arch_sigctx_to_monoctx (ctx, &mctx);
+       mono_sigctx_to_monoctx (ctx, &mctx);
                        
        mono_runtime_printf_err ("Stacktrace:");
 
@@ -2379,13 +2379,17 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx)
 #ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
        MonoContext ctx;
 #endif
-       GString* text = g_string_new (0);
+       GString* text;
        char *name;
 #ifndef HOST_WIN32
        char *wapi_desc;
 #endif
        GError *error = NULL;
 
+       if (!thread)
+               return;
+
+       text = g_string_new (0);
        if (thread->name) {
                name = g_utf16_to_utf8 (thread->name, thread->name_len, NULL, NULL, &error);
                g_assert (!error);
@@ -2409,7 +2413,7 @@ mono_print_thread_dump_internal (void *sigctx, MonoContext *start_ctx)
        } else if (!sigctx)
                MONO_INIT_CONTEXT_FROM_FUNC (&ctx, mono_print_thread_dump);
        else
-               mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+               mono_sigctx_to_monoctx (sigctx, &ctx);
 
        mono_walk_stack_with_ctx (print_stack_frame_to_string, &ctx, MONO_UNWIND_LOOKUP_ALL, text);
 #else
@@ -2606,7 +2610,7 @@ mono_thread_state_init_from_sigctx (MonoThreadUnwindState *ctx, void *sigctx)
        }
 
        if (sigctx)
-               mono_arch_sigctx_to_monoctx (sigctx, &ctx->ctx);
+               mono_sigctx_to_monoctx (sigctx, &ctx->ctx);
        else
 #if MONO_ARCH_HAS_MONO_CONTEXT && !defined(MONO_CROSS_COMPILE)
                MONO_CONTEXT_GET_CURRENT (ctx->ctx);
index a528b3fea6d5ed651627453ed3450e17512bec0a..6c616a5f6f234db359eafe663c1173dce555000f 100644 (file)
@@ -609,7 +609,7 @@ thread_suspend_func (gpointer user_data, void *sigctx, MonoContext *ctx)
                tls->unwind_state.unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
                if (sigctx) {
 #ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
-                       mono_arch_sigctx_to_monoctx (sigctx, &tls->unwind_state.ctx);
+                       mono_sigctx_to_monoctx (sigctx, &tls->unwind_state.ctx);
                        tls->unwind_state.valid = TRUE;
 #else
                        tls->unwind_state.valid = FALSE;
index 5831d0976b69d4b0d1c321f2334c7d0ccf8fb267..1889eeaeaeadc9886335e41ba718ab4ca98db723 100644 (file)
@@ -309,36 +309,7 @@ MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler)
 
 #else
 
-static int
-get_stage2_signal_handler (void)
-{
-#if defined(PLATFORM_ANDROID)
-       return SIGINFO;
-#elif !defined (SIGRTMIN)
-#ifdef SIGUSR2
-       return SIGUSR2;
-#else
-       return -1;
-#endif /* SIGUSR2 */
-#else
-       static int prof2_signum = -1;
-       int i;
-       if (prof2_signum != -1)
-               return prof2_signum;
-       /* we try to avoid SIGRTMIN and any one that might have been set already */
-       for (i = SIGRTMIN + 2; i < SIGRTMAX; ++i) {
-               struct sigaction sinfo;
-               sigaction (i, NULL, &sinfo);
-               if (sinfo.sa_handler == SIG_DFL && (void*)sinfo.sa_sigaction == (void*)SIG_DFL) {
-                       prof2_signum = i;
-                       return i;
-               }
-       }
-       /* fallback to the old way */
-       return SIGRTMIN + 2;
-#endif
-}
-
+static int profiling_signal_in_use;
 
 static void
 per_thread_profiler_hit (void *ctx)
@@ -354,7 +325,7 @@ per_thread_profiler_hit (void *ctx)
                MonoContext mono_context;
                guchar *ips [call_chain_depth + 1];
 
-               mono_arch_sigctx_to_monoctx (ctx, &mono_context);
+               mono_sigctx_to_monoctx (ctx, &mono_context);
                ips [0] = MONO_CONTEXT_GET_IP (&mono_context);
                
                if (jit_tls != NULL) {
@@ -414,29 +385,32 @@ per_thread_profiler_hit (void *ctx)
        }
 }
 
-MONO_SIG_HANDLER_FUNC (static, sigprof_stage2_signal_handler)
-{
-       MONO_SIG_HANDLER_GET_CONTEXT;
-
-       per_thread_profiler_hit (ctx);
-
-       mono_chain_signal (MONO_SIG_HANDLER_PARAMS);
-}
-
 MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler)
 {
        MonoThreadInfo *info;
        int old_errno = errno;
-       int hp_save_index = mono_hazard_pointer_save_for_signal_handler ();
+       int hp_save_index;
        MONO_SIG_HANDLER_GET_CONTEXT;
 
-       FOREACH_THREAD_SAFE (info) {
-               if (mono_thread_info_get_tid (info) == mono_native_thread_id_get ())
-                       continue;
-               mono_threads_pthread_kill (info, get_stage2_signal_handler ());
-       } END_FOREACH_THREAD_SAFE;
+       if (mono_thread_info_get_small_id () == -1)
+               return; //an non-attached thread got the signal
+
+       hp_save_index = mono_hazard_pointer_save_for_signal_handler ();
+
+       /* If we can't consume a profiling request it means we're the initiator. */
+       if (!(mono_threads_consume_async_jobs () & MONO_SERVICE_REQUEST_SAMPLE)) {
+               FOREACH_THREAD_SAFE (info) {
+                       if (mono_thread_info_get_tid (info) == mono_native_thread_id_get ())
+                               continue;
+
+                       mono_threads_add_async_job (info, MONO_SERVICE_REQUEST_SAMPLE);
+                       mono_threads_pthread_kill (info, profiling_signal_in_use);
+               } END_FOREACH_THREAD_SAFE;
+       }
 
+       mono_thread_info_set_is_async_context (TRUE);
        per_thread_profiler_hit (ctx);
+       mono_thread_info_set_is_async_context (FALSE);
 
        mono_hazard_pointer_restore_for_signal_handler (hp_save_index);
        errno = old_errno;
@@ -706,7 +680,8 @@ mono_runtime_setup_stat_profiler (void)
                        perror ("open /dev/rtc");
                        return;
                }
-               add_signal_handler (SIGPROF, sigprof_signal_handler);
+               profiling_signal_in_use = SIGPROF;
+               add_signal_handler (profiling_signal_in_use, sigprof_signal_handler);
                if (ioctl (rtc_fd, RTC_IRQP_SET, freq) == -1) {
                        perror ("set rtc freq");
                        return;
@@ -736,8 +711,8 @@ mono_runtime_setup_stat_profiler (void)
        if (inited)
                return;
        inited = 1;
-       add_signal_handler (get_itimer_signal (), sigprof_signal_handler);
-       add_signal_handler (get_stage2_signal_handler (), sigprof_stage2_signal_handler);
+       profiling_signal_in_use = get_itimer_signal ();
+       add_signal_handler (profiling_signal_in_use, sigprof_signal_handler);
        setitimer (get_itimer_mode (), &itval, NULL);
 #endif
 }
index 05b72c05f6b237f9350d8b9cb3496ff7a9d1ec49..77bc6b7241f44bd119e1c9b6c0be98535582e80d 100644 (file)
@@ -868,7 +868,7 @@ mono_arch_is_int_overflow (void *sigctx, void *info)
        MonoContext ctx;
        guint8* ip;
 
-       mono_arch_sigctx_to_monoctx (sigctx, &ctx);
+       mono_sigctx_to_monoctx (sigctx, &ctx);
 
        ip = (guint8*)ctx.eip;
 
index dd40298565b71964ed4a32248f601f04bc875c1c..b4f04231f574ca812ee94b1ca2e02de8114d20f8 100755 (executable)
@@ -6835,7 +6835,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler)
        if (fault_addr == NULL) {
                MonoContext mctx;
 
-               mono_arch_sigctx_to_monoctx (ctx, &mctx);
+               mono_sigctx_to_monoctx (ctx, &mctx);
 
                fault_addr = MONO_CONTEXT_GET_SP (&mctx);
        }
index 658f2701c60e8559d08adcb7878da24ca1fbec59..6c2bf9b65dca7268ecf269dfcb378a191f43524f 100755 (executable)
@@ -2432,8 +2432,6 @@ void     mono_arch_handle_altstack_exception    (void *sigctx, gpointer fault_ad
 gboolean mono_handle_soft_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
 void     mono_handle_hard_stack_ovf             (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr) MONO_INTERNAL;
 gpointer mono_arch_ip_from_context              (void *sigctx) MONO_INTERNAL;
-void     mono_arch_sigctx_to_monoctx            (void *sigctx, MonoContext *ctx) MONO_INTERNAL;
-void     mono_arch_monoctx_to_sigctx            (MonoContext *mctx, void *ctx) MONO_INTERNAL;
 mgreg_t mono_arch_context_get_int_reg              (MonoContext *ctx, int reg) MONO_INTERNAL;
 void     mono_arch_context_set_int_reg             (MonoContext *ctx, int reg, mgreg_t val) MONO_INTERNAL;
 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
index f9e651093b46e07958d0068840b5361de5487998..40c3baae06c777ca0930ff14526b0f4b722cd764 100644 (file)
@@ -519,6 +519,7 @@ mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_ty
                mono_domain_unlock (domain);
        } else {
                code = buf = mono_global_codeman_reserve (size);
+               short_branch = FALSE;
        }
 
 #ifdef USE_JUMP_TABLES
index 2a674e579a2910519757e86ea1ff2d71e2b4b1ea..c06eb91a161c96d8f76582d2c37eedbb5bd02e08 100644 (file)
@@ -101,7 +101,7 @@ struct _CounterValue {
 typedef struct _Counter Counter;
 struct _Counter {
        int index;
-       int section;
+       const char *section;
        const char *name;
        int type;
        int unit;
@@ -118,7 +118,7 @@ struct _CounterList {
 
 typedef struct _CounterSection CounterSection;
 struct _CounterSection {
-       int value;
+       const char *value;
        CounterList *counters;
        CounterList *counters_last;
        CounterSection *next;
@@ -153,7 +153,7 @@ add_counter_to_section (Counter *counter)
        clist->counter = counter;
 
        for (csection = counters_sections; csection; csection = csection->next) {
-               if (csection->value == counter->section) {
+               if (strcmp (csection->value, counter->section) == 0) {
                        /* If section exist */
                        if (!csection->counters)
                                csection->counters = clist;
@@ -181,7 +181,7 @@ add_counter_to_section (Counter *counter)
 }
 
 static void
-add_counter (int section, const char *name, int type, int unit, int variance, int index)
+add_counter (const char *section, const char *name, int type, int unit, int variance, int index)
 {
        CounterList *list, *l;
        Counter *counter;
@@ -227,7 +227,7 @@ add_counter_to_timestamp (uint64_t timestamp, Counter *counter)
        for (ctimestamp = counters_timestamps; ctimestamp; ctimestamp = ctimestamp->next) {
                if (ctimestamp->value == timestamp) {
                        for (csection = ctimestamp->sections; csection; csection = csection->next) {
-                               if (csection->value == counter->section) {
+                               if (strcmp (csection->value, counter->section) == 0) {
                                        /* if timestamp exist and section exist */
                                        if (!csection->counters)
                                                csection->counters = clist;
@@ -446,7 +446,7 @@ dump_counters (void)
                                for (i = 0; counters_to_print [i][0] != 0; i++) {
                                        if (strcmp (counters_to_print [i], counter->name) == 0) {
                                                if (!section_printed) {
-                                                       fprintf (outfile, "\t%s:\n", section_name (csection->value));
+                                                       fprintf (outfile, "\t%s:\n", csection->value);
                                                        section_printed = 1;
                                                }
 
@@ -466,7 +466,7 @@ dump_counters (void)
                                (unsigned long long) (ctimestamp->value % 1000));
 
                        for (csection = ctimestamp->sections; csection; csection = csection->next) {
-                               fprintf (outfile, "\t\t%s:\n", section_name (csection->value));
+                               fprintf (outfile, "\t\t%s:\n", csection->value);
 
                                for (clist = csection->counters; clist; clist = clist->next) {
                                        counter = clist->counter;
@@ -481,7 +481,7 @@ dump_counters (void)
                }
        } else if (counters_sort_mode == COUNTERS_SORT_CATEGORY) {
                for (csection = counters_sections; csection; csection = csection->next) {
-                       fprintf (outfile, "\t%s:\n", section_name (csection->value));
+                       fprintf (outfile, "\t%s:\n", csection->value);
 
                        for (clist = csection->counters; clist; clist = clist->next) {
                                counter = clist->counter;
@@ -2412,13 +2412,20 @@ decode_buffer (ProfContext *ctx)
                                for (i = 0; i < len; i++) {
                                        uint64_t type, unit, variance, index;
                                        uint64_t section = decode_uleb128 (p, &p);
-                                       char *name = pstrdup ((char*)p);
+                                       char *section_str, *name;
+                                       if (section != MONO_COUNTER_PERFCOUNTERS) {
+                                               section_str = (char*) section_name (section);
+                                       } else {
+                                               section_str = pstrdup ((char*)p);
+                                               while (*p++);
+                                       }
+                                       name = pstrdup ((char*)p);
                                        while (*p++);
                                        type = decode_uleb128 (p, &p);
                                        unit = decode_uleb128 (p, &p);
                                        variance = decode_uleb128 (p, &p);
                                        index = decode_uleb128 (p, &p);
-                                       add_counter ((int)section, name, (int)type, (int)unit, (int)variance, (int)index);
+                                       add_counter (section_str, name, (int)type, (int)unit, (int)variance, (int)index);
                                }
                        } else if (subtype == TYPE_SAMPLE_COUNTERS) {
                                int i;
index edf903a7442d604deab53af852b0b0a5ea0a7d9a..882a17f678ef47ec380acd8eed88f1bf683fb5b5 100644 (file)
 #include <mono/metadata/threads.h>
 #include <mono/metadata/mono-gc.h>
 #include <mono/metadata/debug-helpers.h>
+#include <mono/metadata/mono-perfcounters.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-membar.h>
 #include <mono/utils/mono-counters.h>
+#include <mono/utils/mono-mutex.h>
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
@@ -314,11 +316,13 @@ typedef struct _LogBuffer LogBuffer;
  * if exinfo == TYPE_SAMPLE_COUNTERS_DESC
  *     [len: uleb128] number of counters
  *     for i = 0 to len
- *             [section: uleb128] section name of counter
+ *             [section: uleb128] section of counter
+ *             if section == MONO_COUNTER_PERFCOUNTERS:
+ *                     [section_name: string] section name of counter
  *             [name: string] name of counter
- *             [type: uleb128] type name of counter
- *             [unit: uleb128] unit name of counter
- *             [variance: uleb128] variance name of counter
+ *             [type: uleb128] type of counter
+ *             [unit: uleb128] unit of counter
+ *             [variance: uleb128] variance of counter
  *             [index: uleb128] unique index of counter
  * if exinfo == TYPE_SAMPLE_COUNTERS
  *     [timestamp: uleb128] sampling timestamp
@@ -677,6 +681,7 @@ process_requests (MonoProfiler *profiler)
 }
 
 static void counters_init (MonoProfiler *profiler);
+static void counters_sample (MonoProfiler *profiler, uint64_t timestamp);
 
 static void
 runtime_initialized (MonoProfiler *profiler)
@@ -684,6 +689,7 @@ runtime_initialized (MonoProfiler *profiler)
        runtime_inited = 1;
 #ifndef DISABLE_HELPER_THREAD
        counters_init (profiler);
+       counters_sample (profiler, 0);
 #endif
        /* ensure the main thread data and startup are available soon */
        safe_dump (profiler, ensure_logbuf (0));
@@ -832,13 +838,10 @@ walk_stack (MonoMethod *method, int32_t native_offset, int32_t il_offset, mono_b
  * event, hence the collect_bt/emit_bt split.
  */
 static void
-collect_bt (FrameData *data, gboolean async_safe)
+collect_bt (FrameData *data)
 {
        data->count = 0;
-       if (async_safe)
-               mono_stack_walk_async_safe (walk_stack, data);
-       else
-               mono_stack_walk_no_il (walk_stack, data);
+       mono_stack_walk_no_il (walk_stack, data);
 }
 
 static void
@@ -871,7 +874,7 @@ gc_alloc (MonoProfiler *prof, MonoObject *obj, MonoClass *klass)
        len += 7;
        len &= ~7;
        if (do_bt)
-               collect_bt (&data, FALSE);
+               collect_bt (&data);
        logbuffer = ensure_logbuf (32 + MAX_FRAMES * 8);
        now = current_time ();
        ENTER_LOG (logbuffer, "gcalloc");
@@ -1136,7 +1139,7 @@ throw_exc (MonoProfiler *prof, MonoObject *object)
        FrameData data;
        LogBuffer *logbuffer;
        if (do_bt)
-               collect_bt (&data, FALSE);
+               collect_bt (&data);
        logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8);
        now = current_time ();
        ENTER_LOG (logbuffer, "throw");
@@ -1172,7 +1175,7 @@ monitor_event (MonoProfiler *profiler, MonoObject *object, MonoProfilerMonitorEv
        FrameData data;
        LogBuffer *logbuffer;
        if (do_bt)
-               collect_bt (&data, FALSE);
+               collect_bt (&data);
        logbuffer = ensure_logbuf (16 + MAX_FRAMES * 8);
        now = current_time ();
        ENTER_LOG (logbuffer, "monitor");
@@ -1221,11 +1224,44 @@ thread_name (MonoProfiler *prof, uintptr_t tid, const char *name)
        EXIT_LOG (logbuffer);
 }
 
+typedef struct {
+       MonoMethod *method;
+       MonoDomain *domain;
+       void *base_address;
+       int offset;
+} AsyncFrameInfo;
+
+typedef struct {
+       int count;
+       AsyncFrameInfo *data;
+} AsyncFrameData;
+
+static mono_bool
+async_walk_stack (MonoMethod *method, MonoDomain *domain, void *base_address, int offset, void *data)
+{
+       AsyncFrameData *frame = data;
+       if (frame->count < num_frames) {
+               frame->data [frame->count].method = method;
+               frame->data [frame->count].domain = domain;
+               frame->data [frame->count].base_address = base_address;
+               frame->data [frame->count].offset = offset;
+               // printf ("In %d at %p (dom %p) (native: %p)\n", frame->count, method, domain, base_address);
+               frame->count++;
+       }
+       return frame->count == num_frames;
+}
+
+/*
+(type | frame count), tid, time, ip, [method, domain, base address, offset] * frames
+*/
+#define SAMPLE_EVENT_SIZE_IN_SLOTS(FRAMES) (4 + (FRAMES) * 4)
+
 static void
 mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
 {
        StatBuffer *sbuf;
-       FrameData bt_data;
+       AsyncFrameInfo frames [num_frames];
+       AsyncFrameData bt_data = { 0, &frames [0]};
        uint64_t now;
        uintptr_t *data, *new_data, *old_data;
        uintptr_t elapsed;
@@ -1234,7 +1270,9 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
        if (in_shutdown)
                return;
        now = current_time ();
-       collect_bt (&bt_data, TRUE);
+
+       mono_stack_walk_async_safe (&async_walk_stack, context, &bt_data);
+
        elapsed = (now - profiler->startup_time) / 10000;
        if (do_debug) {
                int len;
@@ -1273,7 +1311,7 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
        }
        do {
                old_data = sbuf->data;
-               new_data = old_data + 4 + bt_data.count * 3;
+               new_data = old_data + SAMPLE_EVENT_SIZE_IN_SLOTS (bt_data.count);
                data = InterlockedCompareExchangePointer ((void * volatile*)&sbuf->data, new_data, old_data);
        } while (data != old_data);
        if (old_data >= sbuf->data_end)
@@ -1283,9 +1321,10 @@ mono_sample_hit (MonoProfiler *profiler, unsigned char *ip, void *context)
        old_data [2] = elapsed;
        old_data [3] = (uintptr_t)ip;
        for (i = 0; i < bt_data.count; ++i) {
-               old_data [4+3*i] = (uintptr_t)bt_data.methods [i];
-               old_data [4+3*i+1] = (uintptr_t)bt_data.il_offsets [i];
-               old_data [4+3*i+2] = (uintptr_t)bt_data.native_offsets [i];
+               old_data [4 + 4 * i + 0] = (uintptr_t)frames [i].method;
+               old_data [4 + 4 * i + 1] = (uintptr_t)frames [i].domain;
+               old_data [4 + 4 * i + 2] = (uintptr_t)frames [i].base_address;
+               old_data [4 + 4 * i + 3] = (uintptr_t)frames [i].offset;
        }
 }
 
@@ -1625,8 +1664,22 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf, int recurse)
                int count = sample [0] & 0xff;
                int mbt_count = (sample [0] & 0xff00) >> 8;
                int type = sample [0] >> 16;
-               if (sample + count + 3 + mbt_count * 3 > sbuf->data)
+               uintptr_t *managed_sample_base = sample + count + 3;
+
+               if (sample + SAMPLE_EVENT_SIZE_IN_SLOTS (mbt_count) > sbuf->data)
                        break;
+
+               for (i = 0; i < mbt_count; ++i) {
+                       MonoMethod *method = (MonoMethod*)managed_sample_base [i * 4 + 0];
+                       MonoDomain *domain = (MonoDomain*)managed_sample_base [i * 4 + 1];
+                       void *address = (void*)managed_sample_base [i * 4 + 2];
+
+                       if (!method) {
+                               MonoJitInfo *ji = mono_jit_info_table_find (domain, address);
+                               if (ji)
+                                       managed_sample_base [i * 4 + 0] = (uintptr_t)mono_jit_info_get_method (ji);
+                       }
+               }
                logbuffer = ensure_logbuf (20 + count * 8);
                emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
                emit_value (logbuffer, type);
@@ -1636,15 +1689,16 @@ dump_sample_hits (MonoProfiler *prof, StatBuffer *sbuf, int recurse)
                        emit_ptr (logbuffer, (void*)sample [i + 3]);
                        add_code_pointer (sample [i + 3]);
                }
+
                sample += count + 3;
                /* new in data version 6 */
                emit_uvalue (logbuffer, mbt_count);
                for (i = 0; i < mbt_count; ++i) {
-                       emit_method (logbuffer, (void*)sample [i * 3]); /* method */
-                       emit_svalue (logbuffer, sample [i * 3 + 1]); /* il offset */
-                       emit_svalue (logbuffer, sample [i * 3 + 2]); /* native offset */
+                       emit_method (logbuffer, (void*)sample [i * 4]); /* method */
+                       emit_svalue (logbuffer, 0); /* il offset will always be 0 from now on */
+                       emit_svalue (logbuffer, sample [i * 4 + 3]); /* native offset */
                }
-               sample += 3 * mbt_count;
+               sample += 4 * mbt_count;
        }
        dump_unmanaged_coderefs (prof);
 }
@@ -1910,21 +1964,35 @@ typedef struct MonoCounterAgent {
        void *value;
        size_t value_size;
        short index;
+       short emitted;
        struct MonoCounterAgent *next;
 } MonoCounterAgent;
 
 static MonoCounterAgent* counters;
 static gboolean counters_initialized = FALSE;
 static int counters_index = 1;
+static mono_mutex_t counters_mutex;
 
-static mono_bool
-counters_init_add_counter (MonoCounter *counter, gpointer data)
+static void
+counters_add_agent (MonoCounter *counter)
 {
        MonoCounterAgent *agent, *item;
 
+       if (!counters_initialized)
+               return;
+
+       mono_mutex_lock (&counters_mutex);
+
        for (agent = counters; agent; agent = agent->next) {
-               if (agent->counter == counter)
-                       return TRUE;
+               if (agent->counter == counter) {
+                       agent->value_size = 0;
+                       if (agent->value) {
+                               free (agent->value);
+                               agent->value = NULL;
+                       }
+                       mono_mutex_unlock (&counters_mutex);
+                       return;
+               }
        }
 
        agent = malloc (sizeof (MonoCounterAgent));
@@ -1932,6 +2000,7 @@ counters_init_add_counter (MonoCounter *counter, gpointer data)
        agent->value = NULL;
        agent->value_size = 0;
        agent->index = counters_index++;
+       agent->emitted = 0;
        agent->next = NULL;
 
        if (!counters) {
@@ -1943,29 +2012,63 @@ counters_init_add_counter (MonoCounter *counter, gpointer data)
                item->next = agent;
        }
 
+       mono_mutex_unlock (&counters_mutex);
+}
+
+static mono_bool
+counters_init_foreach_callback (MonoCounter *counter, gpointer data)
+{
+       counters_add_agent (counter);
        return TRUE;
 }
 
 static void
 counters_init (MonoProfiler *profiler)
+{
+       assert (!counters_initialized);
+
+       mono_mutex_init (&counters_mutex);
+
+       counters_initialized = TRUE;
+
+       mono_counters_on_register (&counters_add_agent);
+       mono_counters_foreach (counters_init_foreach_callback, NULL);
+}
+
+static void
+counters_emit (MonoProfiler *profiler)
 {
        MonoCounterAgent *agent;
        LogBuffer *logbuffer;
        int size = 1 + 5, len = 0;
 
-       mono_counters_foreach (counters_init_add_counter, NULL);
+       if (!counters_initialized)
+               return;
+
+       mono_mutex_lock (&counters_mutex);
 
        for (agent = counters; agent; agent = agent->next) {
+               if (agent->emitted)
+                       continue;
+
                size += strlen (mono_counter_get_name (agent->counter)) + 1 + 5 * 5;
                len += 1;
        }
 
+       if (!len) {
+               mono_mutex_unlock (&counters_mutex);
+               return;
+       }
+
        logbuffer = ensure_logbuf (size);
 
        ENTER_LOG (logbuffer, "counters");
        emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
        emit_value (logbuffer, len);
        for (agent = counters; agent; agent = agent->next) {
+               if (agent->emitted)
+                       continue;
+
                const char *name = mono_counter_get_name (agent->counter);
                emit_value (logbuffer, mono_counter_get_section (agent->counter));
                emit_string (logbuffer, name, strlen (name) + 1);
@@ -1973,10 +2076,14 @@ counters_init (MonoProfiler *profiler)
                emit_value (logbuffer, mono_counter_get_unit (agent->counter));
                emit_value (logbuffer, mono_counter_get_variance (agent->counter));
                emit_value (logbuffer, agent->index);
+
+               agent->emitted = 1;
        }
        EXIT_LOG (logbuffer);
 
-       counters_initialized = TRUE;
+       safe_dump (profiler, ensure_logbuf (0));
+
+       mono_mutex_unlock (&counters_mutex);
 }
 
 static void
@@ -1993,9 +2100,13 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        if (!counters_initialized)
                return;
 
+       counters_emit (profiler);
+
        buffer_size = 8;
        buffer = calloc (1, buffer_size);
 
+       mono_mutex_lock (&counters_mutex);
+
        size = 1 + 10 + 5;
        for (agent = counters; agent; agent = agent->next)
                size += 10 * 2 + mono_counter_get_size (agent->counter);
@@ -2089,6 +2200,163 @@ counters_sample (MonoProfiler *profiler, uint64_t timestamp)
        EXIT_LOG (logbuffer);
 
        safe_dump (profiler, ensure_logbuf (0));
+
+       mono_mutex_unlock (&counters_mutex);
+}
+
+typedef struct _PerfCounterAgent PerfCounterAgent;
+struct _PerfCounterAgent {
+       PerfCounterAgent *next;
+       int index;
+       char *category_name;
+       char *name;
+       int type;
+       gint64 value;
+       guint8 emitted;
+       guint8 updated;
+       guint8 deleted;
+};
+
+static PerfCounterAgent *perfcounters = NULL;
+
+static void
+perfcounters_emit (MonoProfiler *profiler)
+{
+       PerfCounterAgent *pcagent;
+       LogBuffer *logbuffer;
+       int size = 1 + 5, len = 0;
+
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
+               if (pcagent->emitted)
+                       continue;
+
+               size += strlen (pcagent->name) + 1 + 5 * 5;
+               len += 1;
+       }
+
+       if (!len)
+               return;
+
+       logbuffer = ensure_logbuf (size);
+
+       ENTER_LOG (logbuffer, "perfcounters");
+       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS_DESC | TYPE_SAMPLE);
+       emit_value (logbuffer, len);
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
+               if (pcagent->emitted)
+                       continue;
+
+               emit_value (logbuffer, MONO_COUNTER_PERFCOUNTERS);
+               emit_string (logbuffer, pcagent->category_name, strlen (pcagent->category_name) + 1);
+               emit_string (logbuffer, pcagent->name, strlen (pcagent->name) + 1);
+               emit_value (logbuffer, MONO_COUNTER_LONG);
+               emit_value (logbuffer, MONO_COUNTER_RAW);
+               emit_value (logbuffer, MONO_COUNTER_VARIABLE);
+               emit_value (logbuffer, pcagent->index);
+
+               pcagent->emitted = 1;
+       }
+       EXIT_LOG (logbuffer);
+
+       safe_dump (profiler, ensure_logbuf (0));
+}
+
+static gboolean
+perfcounters_foreach (char *category_name, char *name, unsigned char type, gint64 value, gpointer user_data)
+{
+       PerfCounterAgent *pcagent;
+
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
+               if (strcmp (pcagent->category_name, category_name) != 0 || strcmp (pcagent->name, name) != 0)
+                       continue;
+               if (pcagent->value == value)
+                       return TRUE;
+
+               pcagent->value = value;
+               pcagent->updated = 1;
+               pcagent->deleted = 0;
+               return TRUE;
+       }
+
+       pcagent = g_new0 (PerfCounterAgent, 1);
+       pcagent->next = perfcounters;
+       pcagent->index = counters_index++;
+       pcagent->category_name = g_strdup (category_name);
+       pcagent->name = g_strdup (name);
+       pcagent->type = (int) type;
+       pcagent->value = value;
+       pcagent->emitted = 0;
+       pcagent->updated = 1;
+       pcagent->deleted = 0;
+
+       perfcounters = pcagent;
+
+       return TRUE;
+}
+
+static void
+perfcounters_sample (MonoProfiler *profiler, uint64_t timestamp)
+{
+       PerfCounterAgent *pcagent;
+       LogBuffer *logbuffer;
+       int size;
+
+       if (!counters_initialized)
+               return;
+
+       mono_mutex_lock (&counters_mutex);
+
+       /* mark all perfcounters as deleted, foreach will unmark them as necessary */
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next)
+               pcagent->deleted = 1;
+
+       mono_perfcounter_foreach (perfcounters_foreach, perfcounters);
+
+       perfcounters_emit (profiler);
+
+
+       size = 1 + 10 + 5;
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
+               if (pcagent->deleted || !pcagent->updated)
+                       continue;
+               size += 10 * 2 + sizeof (gint64);
+       }
+
+       logbuffer = ensure_logbuf (size);
+
+       ENTER_LOG (logbuffer, "perfcounters");
+       emit_byte (logbuffer, TYPE_SAMPLE_COUNTERS | TYPE_SAMPLE);
+       emit_uvalue (logbuffer, timestamp);
+       for (pcagent = perfcounters; pcagent; pcagent = pcagent->next) {
+               if (pcagent->deleted || !pcagent->updated)
+                       continue;
+               emit_uvalue (logbuffer, pcagent->index);
+               emit_uvalue (logbuffer, MONO_COUNTER_LONG);
+               emit_svalue (logbuffer, pcagent->value);
+
+               pcagent->updated = 0;
+       }
+
+       emit_value (logbuffer, 0);
+       EXIT_LOG (logbuffer);
+
+       safe_dump (profiler, ensure_logbuf (0));
+
+       mono_mutex_unlock (&counters_mutex);
+}
+
+static void
+counters_and_perfcounters_sample (MonoProfiler *prof)
+{
+       static uint64_t start = -1;
+       uint64_t now;
+
+       if (start == -1)
+               start = current_time ();
+
+       now = current_time ();
+       counters_sample (prof, (now - start) / 1000/ 1000);
+       perfcounters_sample (prof, (now - start) / 1000/ 1000);
 }
 
 #endif /* DISABLE_HELPER_THREAD */
@@ -2098,6 +2366,8 @@ log_shutdown (MonoProfiler *prof)
 {
        in_shutdown = 1;
 #ifndef DISABLE_HELPER_THREAD
+       counters_and_perfcounters_sample (prof);
+
        if (prof->command_port) {
                char c = 1;
                void *res;
@@ -2197,10 +2467,8 @@ helper_thread (void* arg)
        int len;
        char buf [64];
        MonoThread *thread = NULL;
-       uint64_t start, now;
 
        //fprintf (stderr, "Server listening\n");
-       start = current_time ();
        command_socket = -1;
        while (1) {
                fd_set rfds;
@@ -2229,8 +2497,8 @@ helper_thread (void* arg)
                        }
                }
 #endif
-               now = current_time ();
-               counters_sample (prof, (now - start) / 1000/ 1000);
+
+               counters_and_perfcounters_sample (prof);
 
                tv.tv_sec = 1;
                tv.tv_usec = 0;
@@ -2256,9 +2524,11 @@ helper_thread (void* arg)
                                sbufbase->next->next = NULL;
                                if (do_debug)
                                        fprintf (stderr, "stat buffer dump\n");
-                               dump_sample_hits (prof, sbuf, 1);
-                               free_buffer (sbuf, sbuf->size);
-                               safe_dump (prof, ensure_logbuf (0));
+                               if (sbuf) {
+                                       dump_sample_hits (prof, sbuf, 1);
+                                       free_buffer (sbuf, sbuf->size);
+                                       safe_dump (prof, ensure_logbuf (0));
+                               }
                                continue;
                        }
                        /* time to shut down */
@@ -2637,6 +2907,7 @@ mono_profiler_startup (const char *desc)
        int fast_time = 0;
        int calls_enabled = 0;
        int allocs_enabled = 0;
+       int only_counters = 0;
        int events = MONO_PROFILE_GC|MONO_PROFILE_ALLOCATIONS|
                MONO_PROFILE_GC_MOVES|MONO_PROFILE_CLASS_EVENTS|MONO_PROFILE_THREADS|
                MONO_PROFILE_ENTER_LEAVE|MONO_PROFILE_JIT_COMPILATION|MONO_PROFILE_EXCEPTIONS|
@@ -2754,6 +3025,10 @@ mono_profiler_startup (const char *desc)
                        do_counters = 1;
                        continue;
                }
+               if ((opt = match_option (p, "countersonly", NULL)) != p) {
+                       only_counters = 1;
+                       continue;
+               }
                if (opt == p) {
                        usage (0);
                        exit (0);
@@ -2765,6 +3040,8 @@ mono_profiler_startup (const char *desc)
        }
        if (allocs_enabled)
                events |= MONO_PROFILE_ALLOCATIONS;
+       if (only_counters)
+               events = 0;
        utils_init (fast_time);
 
        prof = create_profiler (filename);
@@ -2788,7 +3065,7 @@ mono_profiler_startup (const char *desc)
        mono_profiler_install_runtime_initialized (runtime_initialized);
 
        
-       if (do_mono_sample && sample_type == SAMPLE_CYCLES) {
+       if (do_mono_sample && sample_type == SAMPLE_CYCLES && !only_counters) {
                events |= MONO_PROFILE_STATISTICAL;
                mono_profiler_set_statistical_mode (sampling_mode, 1000000 / sample_freq);
                mono_profiler_install_statistical (mono_sample_hit);
index 034a348effbf4297d0e7dee48b6cf37833b478ec..2d420e911aa9058e4ec391cfeba28744fc39525f 100644 (file)
@@ -5,7 +5,7 @@
 #define LOG_HEADER_ID 0x4D505A01
 #define LOG_VERSION_MAJOR 0
 #define LOG_VERSION_MINOR 4
-#define LOG_DATA_VERSION 6
+#define LOG_DATA_VERSION 7
 /*
  * Changes in data versions:
  * version 2: added offsets in heap walk
index 86ea9a8f02ca45379eba52cd523dbf8c7ce8cf3c..a63b63fa5c6d4c66262f59a661bbcc8710ac771e 100644 (file)
@@ -47,6 +47,14 @@ class Tests {
                return true;
        }
 
+       class Gen<T>
+       {
+               [MethodImpl(MethodImplOptions.Synchronized)]
+               public static void Run ()
+               {
+               }
+       }
+
        public delegate int Delegate1 ();
 
        static public int Main (String[] args) {
@@ -113,6 +121,15 @@ class Tests {
                if (is_synchronized (b))
                        return 1;
 
+               Monitor.Enter (typeof (Gen<>));
+               Thread t = new Thread (() =>
+                       {
+                               Gen<object>.Run ();
+                       });
+               t.Start ();
+               t.Join ();
+               Monitor.Exit (typeof (Gen<>));
+
                return 0;
        }
 }
index c52d0442f465395e66d78eb019fff6c0e634fb0a..689bf86a47d6310bc548099d14da501a8769318b 100644 (file)
@@ -421,4 +421,30 @@ mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
        }
 }
 
+#elif (((defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__)) && !defined(MONO_CROSS_COMPILE))) || (defined(TARGET_POWERPC))
+
+#include <mono/utils/mono-context.h>
+
+void
+mono_sigctx_to_monoctx (void *sigctx, MonoContext *mctx)
+{
+       os_ucontext *uc = sigctx;
+
+       mctx->sc_ir = UCONTEXT_REG_NIP(uc);
+       mctx->sc_sp = UCONTEXT_REG_Rn(uc, 1);
+       memcpy (&mctx->regs, &UCONTEXT_REG_Rn(uc, 13), sizeof (mgreg_t) * MONO_SAVED_GREGS);
+       memcpy (&mctx->fregs, &UCONTEXT_REG_FPRn(uc, 14), sizeof (double) * MONO_SAVED_FREGS);
+}
+
+void
+mono_monoctx_to_sigctx (MonoContext *mctx, void *sigctx)
+{
+       os_ucontext *uc = sigctx;
+
+       UCONTEXT_REG_NIP(uc) = mctx->sc_ir;
+       UCONTEXT_REG_Rn(uc, 1) = mctx->sc_sp;
+       memcpy (&UCONTEXT_REG_Rn(uc, 13), &mctx->regs, sizeof (mgreg_t) * MONO_SAVED_GREGS);
+       memcpy (&UCONTEXT_REG_FPRn(uc, 14), &mctx->fregs, sizeof (double) * MONO_SAVED_FREGS);
+}
+
 #endif /* #if defined(__i386__) */
index 8ab20140cdaeb2ed45da999cf2ada9ed6964f81a..1e0840c6b04a7b539d5854aadbd3874edf8afc2d 100644 (file)
@@ -8,6 +8,7 @@
 #include "config.h"
 #include "mono-counters.h"
 #include "mono-proclib.h"
+#include "mono-mutex.h"
 
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
@@ -22,9 +23,17 @@ struct _MonoCounter {
 };
 
 static MonoCounter *counters = NULL;
+static mono_mutex_t counters_mutex;
+
+static volatile gboolean initialized = FALSE;
+
 static int valid_mask = 0;
 static int set_mask = 0;
 
+static GSList *register_callbacks = NULL;
+
+static void initialize_system_counters (void);
+
 /**
  * mono_counter_get_variance:
  * @counter: counter to get the variance
@@ -123,6 +132,68 @@ mono_counters_enable (int section_mask)
        valid_mask = section_mask & MONO_COUNTER_SECTION_MASK;
 }
 
+void
+mono_counters_init (void)
+{
+       if (initialized)
+               return;
+
+       mono_mutex_init (&counters_mutex);
+
+       initialize_system_counters ();
+
+       initialized = TRUE;
+}
+
+static void
+register_internal (const char *name, int type, void *addr, int size)
+{
+       MonoCounter *counter;
+       GSList *register_callback;
+
+       g_assert (size >= 0);
+       if ((type & MONO_COUNTER_VARIANCE_MASK) == 0)
+               type |= MONO_COUNTER_MONOTONIC;
+
+       mono_mutex_lock (&counters_mutex);
+
+       for (counter = counters; counter; counter = counter->next) {
+               if (counter->addr == addr) {
+                       g_warning ("you are registering twice the same counter address");
+                       mono_mutex_unlock (&counters_mutex);
+                       return;
+               }
+       }
+
+       counter = malloc (sizeof (MonoCounter));
+       if (!counter) {
+               mono_mutex_unlock (&counters_mutex);
+               return;
+       }
+       counter->name = g_strdup (name);
+       counter->type = type;
+       counter->addr = addr;
+       counter->next = NULL;
+       counter->size = size;
+
+       set_mask |= type;
+
+       /* Append */
+       if (counters) {
+               MonoCounter *item = counters;
+               while (item->next)
+                       item = item->next;
+               item->next = counter;
+       } else {
+               counters = counter;
+       }
+
+       for (register_callback = register_callbacks; register_callback; register_callback = register_callback->next)
+               ((MonoCounterRegisterCallback)register_callback->data) (counter);
+
+       mono_mutex_unlock (&counters_mutex);
+}
+
 /**
  * mono_counters_register:
  * @name: The name for this counters.
@@ -170,7 +241,11 @@ mono_counters_register (const char* name, int type, void *addr)
        default:
                g_assert_not_reached ();
        }
-       mono_counters_register_with_size (name, type, addr, size);
+
+       if (!initialized)
+               g_warning ("counters not enabled");
+       else
+               register_internal (name, type, addr, size);
 }
 
 /**
@@ -196,33 +271,29 @@ mono_counters_register (const char* name, int type, void *addr)
 void
 mono_counters_register_with_size (const char *name, int type, void *addr, int size)
 {
-       MonoCounter *counter;
-
-       if ((type & MONO_COUNTER_VARIANCE_MASK) == 0)
-               type |= MONO_COUNTER_MONOTONIC;
-       if (size < 0)
-               size = 0;
+       if (!initialized)
+               g_warning ("counters not enabled");
+       else
+               register_internal (name, type, addr, size);
+}
 
-       counter = malloc (sizeof (MonoCounter));
-       if (!counter)
+/**
+ * mono_counters_on_register
+ * @callback : function to callback when a counter is registered
+ *
+ * Add a callback that is going to be called when a counter is registered
+ */
+void
+mono_counters_on_register (MonoCounterRegisterCallback callback)
+{
+       if (!initialized) {
+               g_warning ("counters not enabled");
                return;
-       counter->name = name;
-       counter->type = type;
-       counter->addr = addr;
-       counter->next = NULL;
-       counter->size = size;
-
-       set_mask |= type;
-
-       /* Append */
-       if (counters) {
-               MonoCounter *item = counters;
-               while (item->next)
-                       item = item->next;
-               item->next = counter;
-       } else {
-               counters = counter;
        }
+
+       mono_mutex_lock (&counters_mutex);
+       register_callbacks = g_slist_append (register_callbacks, callback);
+       mono_mutex_unlock (&counters_mutex);
 }
 
 typedef int (*IntFunc) (void);
@@ -233,45 +304,6 @@ typedef gssize (*PtrFunc) (void);
 typedef double (*DoubleFunc) (void);
 typedef char* (*StrFunc) (void);
 
-#define ENTRY_FMT "%-36s: "
-static void
-dump_counter (MonoCounter *counter, FILE *outfile) {
-       void *buffer = g_malloc0 (counter->size);
-       mono_counters_sample (counter, buffer, counter->size);
-
-       switch (counter->type & MONO_COUNTER_TYPE_MASK) {
-       case MONO_COUNTER_INT:
-               fprintf (outfile, ENTRY_FMT "%d\n", counter->name, *(int*)buffer);
-               break;
-       case MONO_COUNTER_UINT:
-               fprintf (outfile, ENTRY_FMT "%u\n", counter->name, *(guint*)buffer);
-               break;
-       case MONO_COUNTER_LONG:
-               if ((counter->type & MONO_COUNTER_UNIT_MASK) == MONO_COUNTER_TIME)
-                       fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)(*(gint64*)buffer) / 10000.0);
-               else
-                       fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, *(long long *)buffer);
-               break;
-       case MONO_COUNTER_ULONG:
-               fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, *(unsigned long long *)buffer);
-               break;
-       case MONO_COUNTER_WORD:
-               fprintf (outfile, ENTRY_FMT "%zd\n", counter->name, *(gssize*)buffer);
-               break;
-       case MONO_COUNTER_DOUBLE:
-               fprintf (outfile, ENTRY_FMT "%.4f\n", counter->name, *(double*)buffer);
-               break;
-       case MONO_COUNTER_STRING:
-               fprintf (outfile, ENTRY_FMT "%s\n", counter->name, (counter->size == 0) ? "(null)" : (char*)buffer);
-               break;
-       case MONO_COUNTER_TIME_INTERVAL:
-               fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)(*(gint64*)buffer) / 1000.0);
-               break;
-       }
-
-       g_free (buffer);
-}
-
 static gint64
 user_time (void)
 {
@@ -366,8 +398,6 @@ cpu_load_15min (void)
        return cpu_load (2);
 }
 
-static gboolean system_counters_initialized = FALSE;
-
 #define SYSCOUNTER_TIME (MONO_COUNTER_SYSTEM | MONO_COUNTER_LONG | MONO_COUNTER_TIME | MONO_COUNTER_MONOTONIC | MONO_COUNTER_CALLBACK)
 #define SYSCOUNTER_BYTES (MONO_COUNTER_SYSTEM | MONO_COUNTER_LONG | MONO_COUNTER_BYTES | MONO_COUNTER_VARIABLE | MONO_COUNTER_CALLBACK)
 #define SYSCOUNTER_COUNT (MONO_COUNTER_SYSTEM | MONO_COUNTER_LONG | MONO_COUNTER_COUNT | MONO_COUNTER_MONOTONIC | MONO_COUNTER_CALLBACK)
@@ -376,18 +406,16 @@ static gboolean system_counters_initialized = FALSE;
 static void
 initialize_system_counters (void)
 {
-       mono_counters_register ("User Time", SYSCOUNTER_TIME, &user_time);
-       mono_counters_register ("System Time", SYSCOUNTER_TIME, &system_time);
-       mono_counters_register ("Total Time", SYSCOUNTER_TIME, &total_time);
-       mono_counters_register ("Working Set", SYSCOUNTER_BYTES, &working_set);
-       mono_counters_register ("Private Bytes", SYSCOUNTER_BYTES, &private_bytes);
-       mono_counters_register ("Virtual Bytes", SYSCOUNTER_BYTES, &virtual_bytes);
-       mono_counters_register ("Page Faults", SYSCOUNTER_COUNT, &page_faults);
-       mono_counters_register ("CPU Load Average - 1min", SYSCOUNTER_LOAD, &cpu_load_1min);
-       mono_counters_register ("CPU Load Average - 5min", SYSCOUNTER_LOAD, &cpu_load_5min);
-       mono_counters_register ("CPU Load Average - 15min", SYSCOUNTER_LOAD, &cpu_load_15min);
-
-       system_counters_initialized = TRUE;
+       register_internal ("User Time", SYSCOUNTER_TIME, &user_time, sizeof (gint64));
+       register_internal ("System Time", SYSCOUNTER_TIME, &system_time, sizeof (gint64));
+       register_internal ("Total Time", SYSCOUNTER_TIME, &total_time, sizeof (gint64));
+       register_internal ("Working Set", SYSCOUNTER_BYTES, &working_set, sizeof (gint64));
+       register_internal ("Private Bytes", SYSCOUNTER_BYTES, &private_bytes, sizeof (gint64));
+       register_internal ("Virtual Bytes", SYSCOUNTER_BYTES, &virtual_bytes, sizeof (gint64));
+       register_internal ("Page Faults", SYSCOUNTER_COUNT, &page_faults, sizeof (gint64));
+       register_internal ("CPU Load Average - 1min", SYSCOUNTER_LOAD, &cpu_load_1min, sizeof (double));
+       register_internal ("CPU Load Average - 5min", SYSCOUNTER_LOAD, &cpu_load_5min, sizeof (double));
+       register_internal ("CPU Load Average - 15min", SYSCOUNTER_LOAD, &cpu_load_15min, sizeof (double));
 }
 
 /**
@@ -404,24 +432,34 @@ mono_counters_foreach (CountersEnumCallback cb, gpointer user_data)
 {
        MonoCounter *counter;
 
-       if (!system_counters_initialized)
-               initialize_system_counters ();
+       if (!initialized) {
+               g_warning ("counters not enabled");
+               return;
+       }
+
+       mono_mutex_lock (&counters_mutex);
 
        for (counter = counters; counter; counter = counter->next) {
-               if (!cb (counter, user_data))
+               if (!cb (counter, user_data)) {
+                       mono_mutex_unlock (&counters_mutex);
                        return;
+               }
        }
+
+       mono_mutex_unlock (&counters_mutex);
 }
 
 #define COPY_COUNTER(type,functype) do {       \
                size = sizeof (type);   \
                if (buffer_size < size) \
-                       return -1;      \
-               *(type*)buffer = cb ? ((functype)counter->addr) () : *(type*)counter->addr; \
+                       size = -1;      \
+               else                    \
+                       *(type*)buffer = cb ? ((functype)counter->addr) () : *(type*)counter->addr; \
        } while (0);
 
-int
-mono_counters_sample (MonoCounter *counter, void *buffer, int buffer_size)
+/* lockless */
+static int
+sample_internal (MonoCounter *counter, void *buffer, int buffer_size)
 {
        int cb = counter->type & MONO_COUNTER_CALLBACK;
        int size = -1;
@@ -449,21 +487,75 @@ mono_counters_sample (MonoCounter *counter, void *buffer, int buffer_size)
                COPY_COUNTER (double, DoubleFunc);
                break;
        case MONO_COUNTER_STRING:
-               if (buffer_size < counter->size)
-                       return -1;
-               if (counter->size == 0)
-                       return 0;
-               strval = cb ? ((StrFunc)counter->addr) () : (char*)counter->addr;
-               if (!strval)
-                       return 0;
-               size = counter->size;
-               strncpy (buffer, strval, size - 1);
-               ((char*)buffer)[size - 1] = '\0';
+               if (buffer_size < counter->size) {
+                       size = -1;
+               } else if (counter->size == 0) {
+                       size = 0;
+               } else {
+                       strval = cb ? ((StrFunc)counter->addr) () : (char*)counter->addr;
+                       if (!strval) {
+                               size = 0;
+                       } else {
+                               size = counter->size;
+                               strncpy (buffer, strval, size - 1);
+                               ((char*)buffer)[size - 1] = '\0';
+                       }
+               }
        }
 
        return size;
 }
 
+int
+mono_counters_sample (MonoCounter *counter, void *buffer, int buffer_size)
+{
+       if (!initialized) {
+               g_warning ("counters not enabled");
+               return -1;
+       }
+
+       return sample_internal (counter, buffer, buffer_size);
+}
+
+#define ENTRY_FMT "%-36s: "
+static void
+dump_counter (MonoCounter *counter, FILE *outfile) {
+       void *buffer = g_malloc0 (counter->size);
+       int size = sample_internal (counter, buffer, counter->size);
+
+       switch (counter->type & MONO_COUNTER_TYPE_MASK) {
+       case MONO_COUNTER_INT:
+               fprintf (outfile, ENTRY_FMT "%d\n", counter->name, *(int*)buffer);
+               break;
+       case MONO_COUNTER_UINT:
+               fprintf (outfile, ENTRY_FMT "%u\n", counter->name, *(guint*)buffer);
+               break;
+       case MONO_COUNTER_LONG:
+               if ((counter->type & MONO_COUNTER_UNIT_MASK) == MONO_COUNTER_TIME)
+                       fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)(*(gint64*)buffer) / 10000.0);
+               else
+                       fprintf (outfile, ENTRY_FMT "%lld\n", counter->name, *(long long *)buffer);
+               break;
+       case MONO_COUNTER_ULONG:
+               fprintf (outfile, ENTRY_FMT "%llu\n", counter->name, *(unsigned long long *)buffer);
+               break;
+       case MONO_COUNTER_WORD:
+               fprintf (outfile, ENTRY_FMT "%zd\n", counter->name, *(gssize*)buffer);
+               break;
+       case MONO_COUNTER_DOUBLE:
+               fprintf (outfile, ENTRY_FMT "%.4f\n", counter->name, *(double*)buffer);
+               break;
+       case MONO_COUNTER_STRING:
+               fprintf (outfile, ENTRY_FMT "%s\n", counter->name, (size == 0) ? "(null)" : (char*)buffer);
+               break;
+       case MONO_COUNTER_TIME_INTERVAL:
+               fprintf (outfile, ENTRY_FMT "%.2f ms\n", counter->name, (double)(*(gint64*)buffer) / 1000.0);
+               break;
+       }
+
+       g_free (buffer);
+}
+
 static const char
 section_names [][10] = {
        "JIT",
@@ -501,9 +593,17 @@ mono_counters_dump (int section_mask, FILE *outfile)
        int i, j;
        int variance;
        section_mask &= valid_mask;
-       if (!counters)
+
+       if (!initialized)
                return;
 
+       mono_mutex_lock (&counters_mutex);
+
+       if (!counters) {
+               mono_mutex_unlock (&counters_mutex);
+               return;
+       }
+
        variance = section_mask & MONO_COUNTER_VARIANCE_MASK;
 
        /* If no variance mask is supplied, we default to all kinds. */
@@ -519,6 +619,7 @@ mono_counters_dump (int section_mask, FILE *outfile)
        }
 
        fflush (outfile);
+       mono_mutex_unlock (&counters_mutex);
 }
 
 /**
@@ -529,13 +630,21 @@ mono_counters_dump (int section_mask, FILE *outfile)
 void
 mono_counters_cleanup (void)
 {
+       if (!initialized)
+               return;
+
+       mono_mutex_lock (&counters_mutex);
+
        MonoCounter *counter = counters;
        counters = NULL;
        while (counter) {
                MonoCounter *tmp = counter;
                counter = counter->next;
+               free ((void*)tmp->name);
                free (tmp);
        }
+
+       mono_mutex_unlock (&counters_mutex);
 }
 
 static MonoResourceCallback limit_reached = NULL;
index 20676c2ff114015e8d79a9cb748008816dfea6ba..a8e6928dfbe84d036be48f0ef52e79987a24a97c 100644 (file)
@@ -25,6 +25,7 @@ enum {
        MONO_COUNTER_SECURITY = 1 << 12,
        MONO_COUNTER_RUNTIME  = 1 << 13,
        MONO_COUNTER_SYSTEM   = 1 << 14,
+       MONO_COUNTER_PERFCOUNTERS = 1 << 15,
        MONO_COUNTER_LAST_SECTION,
 
        /* Unit, bits 24-27 (4 bits) */
@@ -46,8 +47,8 @@ enum {
 
 typedef struct _MonoCounter MonoCounter;
 
-
 MONO_API void mono_counters_enable (int section_mask);
+MONO_API void mono_counters_init (void);
 
 /* 
  * register addr as the address of a counter of type type.
@@ -57,6 +58,9 @@ MONO_API void mono_counters_enable (int section_mask);
 MONO_API void mono_counters_register (const char* descr, int type, void *addr);
 MONO_API void mono_counters_register_with_size (const char *name, int type, void *addr, int size);
 
+typedef void (*MonoCounterRegisterCallback) (MonoCounter*);
+MONO_API void mono_counters_on_register (MonoCounterRegisterCallback callback);
+
 /* 
  * Create a readable dump of the counters for section_mask sections (ORed section values)
  */
index 4ed6820e900d934de2c45d939021e943a04b02d3..6270c57f1d6c347e300e3da7d0988ba5326eb91b 100644 (file)
@@ -48,7 +48,7 @@ mono_threads_core_needs_abort_syscall (void)
 }
 
 gboolean
-mono_threads_core_suspend (MonoThreadInfo *info)
+mono_threads_core_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
 {
        kern_return_t ret;
        gboolean res;
index 51bdc8df76e3ec8c63b5d9bef1df417edb6a6165..377d522d2502b60de9f9498103cffbd79af8d81a 100644 (file)
@@ -39,6 +39,10 @@ typedef struct {
        HANDLE handle;
 } StartInfo;
 
+#ifdef PLATFORM_ANDROID
+static int no_interrupt_signo;
+#endif
+
 static void*
 inner_start_thread (void *arg)
 {
@@ -325,7 +329,7 @@ suspend_signal_handler (int _dummy, siginfo_t *info, void *context)
 #endif
 
 static void
-mono_posix_add_signal_handler (int signo, gpointer handler)
+mono_posix_add_signal_handler (int signo, gpointer handler, int flags)
 {
 #if !defined(__native_client__)
        /*FIXME, move the code from mini to utils and do the right thing!*/
@@ -335,7 +339,7 @@ mono_posix_add_signal_handler (int signo, gpointer handler)
 
        sa.sa_sigaction = handler;
        sigemptyset (&sa.sa_mask);
-       sa.sa_flags = SA_SIGINFO;
+       sa.sa_flags = SA_SIGINFO | flags;
        ret = sigaction (signo, &sa, &previous_sa);
 
        g_assert (ret != -1);
@@ -346,19 +350,36 @@ void
 mono_threads_init_platform (void)
 {
 #if !defined(__native_client__)
+       int abort_signo;
+
        /*
        FIXME we should use all macros from mini to make this more portable
        FIXME it would be very sweet if sgen could end up using this too.
        */
-       if (mono_thread_info_new_interrupt_enabled ())
-               mono_posix_add_signal_handler (mono_thread_get_abort_signal (), suspend_signal_handler);
+       if (!mono_thread_info_new_interrupt_enabled ())
+               return;
+       abort_signo = mono_thread_get_abort_signal ();
+       mono_posix_add_signal_handler (abort_signo, suspend_signal_handler, 0);
+
+#ifdef PLATFORM_ANDROID
+       /*
+        * Lots of android native code can't handle the EINTR caused by
+        * the normal abort signal, so use a different signal for the
+        * no interruption case, which is used by sdb.
+        * FIXME: Use this on all platforms.
+        * SIGUSR1 is used by dalvik/art.
+        */
+       no_interrupt_signo = SIGUSR2;
+       g_assert (abort_signo != no_interrupt_signo);
+       mono_posix_add_signal_handler (no_interrupt_signo, suspend_signal_handler, SA_RESTART);
+#endif
 #endif
 }
 
-/*nothing to be done here since suspend always abort syscalls due using signals*/
 void
 mono_threads_core_interrupt (MonoThreadInfo *info)
 {
+       /* Handled in mono_threads_core_suspend () */
 }
 
 void
@@ -379,10 +400,17 @@ mono_threads_core_needs_abort_syscall (void)
 }
 
 gboolean
-mono_threads_core_suspend (MonoThreadInfo *info)
+mono_threads_core_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
 {
        /*FIXME, check return value*/
-       mono_threads_pthread_kill (info, mono_thread_get_abort_signal ());
+#ifdef PLATFORM_ANDROID
+       if (!interrupt_kernel)
+               mono_threads_pthread_kill (info, no_interrupt_signo);
+       else
+               mono_threads_pthread_kill (info, mono_thread_get_abort_signal ());
+#else
+               mono_threads_pthread_kill (info, mono_thread_get_abort_signal ());
+#endif
        while (MONO_SEM_WAIT (&info->begin_suspend_semaphore) != 0) {
                /* g_assert (errno == EINTR); */
        }
@@ -406,7 +434,7 @@ mono_threads_platform_register (MonoThreadInfo *info)
        MONO_SEM_INIT (&info->begin_suspend_semaphore, 0);
 
 #if defined (PLATFORM_ANDROID)
-       info->native_handle = (gpointer) gettid ();
+       info->native_handle = gettid ();
 #endif
 }
 
index 04430fb021f274ad99d4312d0290f42df875a5df..02bd26e0c793988c8fc4f2d15ac766df70c5014d 100755 (executable)
@@ -58,7 +58,7 @@ mono_threads_core_self_suspend (MonoThreadInfo *info)
 }
 
 gboolean
-mono_threads_core_suspend (MonoThreadInfo *info)
+mono_threads_core_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
 {
        DWORD id = mono_thread_info_get_tid (info);
        HANDLE handle;
index 9aa70ac20b0b442511afadf97dceedaf4b1302ce..92b84e31266851a85bce1bed9d7d4b3da490a045 100644 (file)
@@ -15,6 +15,7 @@
 #include <mono/utils/hazard-pointer.h>
 #include <mono/utils/mono-memory-model.h>
 #include <mono/utils/mono-mmap.h>
+#include <mono/utils/atomic.h>
 
 #include <errno.h>
 
@@ -426,7 +427,7 @@ mono_thread_info_suspend_sync (MonoNativeThreadId tid, gboolean interrupt_kernel
                return info;
        }
 
-       if (!mono_threads_core_suspend (info)) {
+       if (!mono_threads_core_suspend (info, interrupt_kernel)) {
                MONO_SEM_POST (&info->suspend_semaphore);
                mono_hazard_pointer_clear (hp, 1);
                *error_condition = "Could not suspend thread";
@@ -909,3 +910,27 @@ mono_thread_info_clear_interruption (void)
 {
        mono_threads_core_clear_interruption ();
 }
+
+/* info must be self or be held in a hazard pointer. */
+gboolean
+mono_threads_add_async_job (MonoThreadInfo *info, MonoAsyncJob job)
+{
+       MonoAsyncJob old_job;
+       do {
+               old_job = info->service_requests;
+               if (old_job & job)
+                       return FALSE;
+       } while (InterlockedCompareExchange (&info->service_requests, old_job | job, old_job) != old_job);
+       return TRUE;
+}
+
+MonoAsyncJob
+mono_threads_consume_async_jobs (void)
+{
+       MonoThreadInfo *info = (MonoThreadInfo*)mono_native_tls_get_value (thread_info_key);
+
+       if (!info)
+               return 0;
+
+       return InterlockedExchange (&info->service_requests, 0);
+}
index b26ccbec35c431b37f4e72e79981eef21e493344..f2fd1fe94bbdc3a0786555631049b500a335b48a 100644 (file)
@@ -94,6 +94,13 @@ enum {
        SUSPEND_STATE_MASK              = 0xF0,
 };
 
+/*
+ * This enum tells which async thread service corresponds to which bit.
+ */
+typedef enum {
+       MONO_SERVICE_REQUEST_SAMPLE = 1,
+} MonoAsyncJob;
+
 #define mono_thread_info_run_state(info) (((MonoThreadInfo*)info)->thread_state & RUN_STATE_MASK)
 #define mono_thread_info_suspend_state(info) (((MonoThreadInfo*)info)->thread_state & SUSPEND_STATE_MASK)
 
@@ -155,6 +162,12 @@ typedef struct {
        /* IO layer handle for this thread */
        /* Set when the thread is started, or in _wapi_thread_duplicate () */
        HANDLE handle;
+
+       /* Asynchronous service request. This flag is meant to be consumed by the multiplexing signal handlers to discover what sort of work they need to do.
+        * Use the mono_threads_add_async_job and mono_threads_consume_async_jobs APIs to modify this flag.
+        * In the future the signaling should be part of the API, but for now, it's only for massaging the bits.
+        */
+       volatile gint32 service_requests;
 } MonoThreadInfo;
 
 typedef struct {
@@ -326,6 +339,18 @@ mono_threads_get_max_stack_size (void) MONO_INTERNAL;
 HANDLE
 mono_threads_open_thread_handle (HANDLE handle, MonoNativeThreadId tid) MONO_INTERNAL;
 
+/*
+This is the async job submission/consumption API.
+XXX: This is a PROVISIONAL API only meant to be used by the statistical profiler.
+If you want to use/extend it anywhere else, understand that you'll have to do some API design work to better fit this puppy.
+*/
+gboolean
+mono_threads_add_async_job (THREAD_INFO_TYPE *info, MonoAsyncJob job) MONO_INTERNAL;
+
+MonoAsyncJob
+mono_threads_consume_async_jobs (void) MONO_INTERNAL;
+       
+
 #if !defined(HOST_WIN32)
 
 /*Use this instead of pthread_kill */
@@ -336,7 +361,7 @@ mono_threads_pthread_kill (THREAD_INFO_TYPE *info, int signum) MONO_INTERNAL;
 
 /* Plartform specific functions DON'T use them */
 void mono_threads_init_platform (void) MONO_INTERNAL; //ok
-gboolean mono_threads_core_suspend (THREAD_INFO_TYPE *info) MONO_INTERNAL;
+gboolean mono_threads_core_suspend (THREAD_INFO_TYPE *info, gboolean interrupt_kernel) MONO_INTERNAL;
 gboolean mono_threads_core_resume (THREAD_INFO_TYPE *info) MONO_INTERNAL;
 void mono_threads_platform_register (THREAD_INFO_TYPE *info) MONO_INTERNAL; //ok
 void mono_threads_platform_free (THREAD_INFO_TYPE *info) MONO_INTERNAL;
index ca34a6f396f0db1dd392fecf9cf684482ce7da65..7e5a019b82327daeef91eff2322b36b168ce450a 100644 (file)
@@ -44,7 +44,7 @@ al_profile = net_4_0
 endif
 
 if INSTALL_4_5
-build_profiles += net_4_5 xbuild_12
+build_profiles += net_4_5 xbuild_12 xbuild_14
 al_profile = net_4_5
 endif
 
@@ -138,6 +138,8 @@ mcs-compileall: mono-wrapper etc/mono/config
                  MONO_PATH="$$mcs_topdir/class/lib/$$profile$(PLATFORM_PATH_SEPARATOR)$$mcs_topdir/class/lib/net_2_0$(PLATFORM_PATH_SEPARATOR)$$save_MONO_PATH"; \
          elif [ "xbuild_12" = "$$profile" ]; then \
                  MONO_PATH="$$mcs_topdir/class/lib/$$profile$(PLATFORM_PATH_SEPARATOR)$$mcs_topdir/class/lib/net_4_5$(PLATFORM_PATH_SEPARATOR)$$save_MONO_PATH"; \
+         elif [ "xbuild_14" = "$$profile" ]; then \
+                 MONO_PATH="$$mcs_topdir/class/lib/$$profile$(PLATFORM_PATH_SEPARATOR)$$mcs_topdir/class/lib/net_4_5$(PLATFORM_PATH_SEPARATOR)$$save_MONO_PATH"; \
          else \
                  MONO_PATH="$$mcs_topdir/class/lib/$$profile$(PLATFORM_PATH_SEPARATOR)$$save_MONO_PATH"; \
          fi; \