[sgen] Remove a pointless memory barrier from the middle of the managed allocator.
-Subproject commit 00252c18fc0a4a206e45461736a890acb785a9d8
+Subproject commit 163b37483c08b5310c4e3d4c2e22a1ed59b1e6e0
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventOpcode))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSource))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceSettings))]
//[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventSourceException))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventTask))]
//[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Diagnostics.Tracing.EventWrittenEventArgs))]
}
}
- void AddParameter (System.Data.Common.DbCommand cm, string name, object value)
+ void AddParameter (global::System.Data.Common.DbCommand cm, string name, object value)
{
var param = cm.CreateParameter ();
param.ParameterName = ":" + name;
textP.Value=builder.ToString();
floatP.Value=Convert.ToInt64(random.Next(999));
integerP.Value=random.Next(999);
- blobP.Value=System.Text.Encoding.UTF8.GetBytes("\u05D0\u05D1\u05D2" + builder.ToString());
+ blobP.Value=global::System.Text.Encoding.UTF8.GetBytes("\u05D0\u05D1\u05D2" + builder.ToString());
SqliteCommand selectCmd = new SqliteCommand("SELECT * from t1", _conn);
object compareValue;
if (blobP.Value is byte[])
- compareValue = System.Text.Encoding.UTF8.GetString ((byte[])blobP.Value);
+ compareValue = global::System.Text.Encoding.UTF8.GetString ((byte[])blobP.Value);
else
compareValue = blobP.Value;
Assert.AreEqual(reader["b"], compareValue);
--- /dev/null
+#include monodroid_Mono.Data.Sqlite_test.dll.new-exclude.sources
--- /dev/null
+SqliteDataReaderTest.cs
+SqliteParameterUnitTests.cs
--- /dev/null
+#include Mono.Data.Sqlite_test.dll.sources
ss_step_through ();
ss_non_user_code ();
ss_recursive (1);
+ ss_recursive2 (1);
+ ss_recursive2 (1);
+ ss_recursive_chaotic ();
ss_fp_clobber ();
}
ss_recursive (n + 1);
}
+ // Breakpoint will be placed here
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive2_trap ()
+ {
+ }
+
+ public static void ss_recursive2_at (string s)
+ {
+ // Console.WriteLine (s);
+ }
+
+ // This method is used both for a step over and step out test.
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive2 (int x)
+ {
+ ss_recursive2_at ( "ss_recursive2 in " + x);
+ if (x < 5) {
+ int next = x + 1;
+ ss_recursive2_at ("ss_recursive2 descend " + x);
+ ss_recursive2_trap ();
+ ss_recursive2 (next);
+ }
+ ss_recursive2_at ("ss_recursive2 out " + x);
+ }
+
+ // Breakpoint will be placed here
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic_trap ()
+ {
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic_at (bool exiting, string at, int n)
+ {
+// string indent = "";
+// for (int count = 5 - n; count > 0; count--)
+// indent += "\t";
+// Console.WriteLine (indent + (exiting ? "<--" : "-->") + " " + at + " " + n);
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic_fizz (int n)
+ {
+ ss_recursive_chaotic_at (false, "fizz", n);
+ if (n > 0) {
+ int next = n - 1;
+ ss_recursive_chaotic_buzz (next);
+ ss_recursive_chaotic_fizzbuzz (next);
+ } else {
+ ss_recursive_chaotic_trap ();
+ }
+ ss_recursive_chaotic_at (true, "fizz", n);
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic_buzz (int n)
+ {
+ ss_recursive_chaotic_at (false, "buzz", n);
+ if (n > 0) {
+ int next = n - 1;
+ ss_recursive_chaotic_fizz (next);
+ ss_recursive_chaotic_fizzbuzz (next);
+ }
+ ss_recursive_chaotic_at (true, "buzz", n);
+ }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic_fizzbuzz (int n)
+ {
+ ss_recursive_chaotic_at (false, "fizzbuzz", n);
+ if (n > 0) {
+ int next = n - 1;
+ ss_recursive_chaotic_fizz (next);
+ ss_recursive_chaotic_buzz (next);
+ ss_recursive_chaotic_fizzbuzz (next);
+ }
+ ss_recursive_chaotic_at (true, "fizzbuzz", n);
+ }
+
+ // Call a complex tree of recursive calls that has tripped up "step out" in the past.
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void ss_recursive_chaotic ()
+ {
+ ss_recursive_chaotic_fizz (5);
+ }
+
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public static void ss_fp_clobber () {
double v = ss_fp_clobber_1 (5.0);
public static string runtime = Environment.GetEnvironmentVariable ("DBG_RUNTIME");
public static string agent_args = Environment.GetEnvironmentVariable ("DBG_AGENT_ARGS");
+ // Not currently used, but can be useful when debugging individual tests.
+ void StackTraceDump (Event e)
+ {
+ int i = 0;
+ foreach (var frame in e.Thread.GetFrames ())
+ {
+ i++;
+ Console.WriteLine ("Frame " + i + ", " + frame.Method.Name);
+ }
+ }
+
Event GetNextEvent () {
var es = vm.GetNextEventSet ();
Assert.AreEqual (1, es.Events.Length);
return (e as BreakpointEvent);
}
+ class ReusableBreakpoint {
+ DebuggerTests owner;
+ public string method_name;
+ public BreakpointEventRequest req;
+ public BreakpointEvent lastEvent = null;
+ public ReusableBreakpoint (DebuggerTests owner, string method_name)
+ {
+ this.owner = owner;
+ this.method_name = method_name;
+ MethodMirror m = owner.entry_point.DeclaringType.GetMethod (method_name);
+ Assert.IsNotNull (m);
+ req = owner.vm.SetBreakpoint (m, m.ILOffsets [0]);
+ }
+
+ public void Continue ()
+ {
+ bool survived = false;
+
+ try {
+ Event e = null;
+
+ while (true) {
+ owner.vm.Resume ();
+ e = owner.GetNextEvent ();
+ if (e is BreakpointEvent)
+ break;
+ }
+
+ Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
+ Assert.AreEqual (method_name, (e as BreakpointEvent).Method.Name);
+
+ lastEvent = e as BreakpointEvent;
+
+ survived = true;
+ } finally {
+ if (!survived) { // Ensure cleanup if we triggered an assert
+ Disable ();
+ }
+ }
+ }
+
+ public void Disable ()
+ {
+ req.Disable ();
+ }
+ }
+
+ /* One of the tests executes a complex tree of recursive functions.
+ The only good way to specify how its behavior should appear from this side
+ is to just run the function tree once over here and record what it does. */
+ public struct RecursiveChaoticPoint
+ {
+ public bool breakpoint;
+ public string name;
+ public int depth;
+
+ public RecursiveChaoticPoint (bool breakpoint, string name, int depth)
+ {
+ this.breakpoint = breakpoint;
+ this.name = name;
+ this.depth = depth;
+ }
+ }
+
+ // The breakpoint is placed here in dtest-app.cs
+ public static void ss_recursive_chaotic_trap (int n, List<RecursiveChaoticPoint> trace, ref bool didLast, ref bool didAny)
+ {
+ // Depth is calculated as:
+ // Main + single_stepping + ss_recursive_chaotic + (n is 5 at outermost frame and 0 at innermost frame) + ss_recursive_chaotic_trap
+ trace.Add (new RecursiveChaoticPoint (true, "ss_recursive_chaotic_trap", 5 - n + 5));
+ didLast = true;
+ }
+
+ public static void ss_recursive_chaotic_at (string at, int n, List<RecursiveChaoticPoint> trace, ref bool didLast, ref bool didAny)
+ {
+ // This will be called after every return from a function. The other function will return whether "step out" is currently active, and it will be passed in here as didLast.
+ if (didLast) {
+ // Depth is calculated as:
+ // Main + single_stepping + ss_recursive_chaotic + (n is 5 at outermost frame and 0 at innermost frame)
+ trace.Add (new RecursiveChaoticPoint (false, "ss_recursive_chaotic_" + at, 5 - n + 4));
+ didAny = true;
+ didLast = false;
+ }
+ }
+
+ public static bool ss_recursive_chaotic_fizz (int n, List<RecursiveChaoticPoint> trace)
+ {
+ bool didLast = false, didAny = false;
+ if (n > 0) {
+ int next = n - 1;
+ didLast = ss_recursive_chaotic_buzz (next, trace);
+ ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
+ didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
+ ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
+ } else {
+ ss_recursive_chaotic_trap (n, trace, ref didLast, ref didAny);
+ ss_recursive_chaotic_at ("fizz", n, trace, ref didLast, ref didAny);
+ }
+ return didAny;
+ }
+
+ public static bool ss_recursive_chaotic_buzz (int n, List<RecursiveChaoticPoint> trace)
+ {
+ bool didLast = false, didAny = false;
+ if (n > 0) {
+ int next = n - 1;
+ didLast = ss_recursive_chaotic_fizz (next, trace);
+ ss_recursive_chaotic_at ("buzz", n, trace, ref didLast, ref didAny);
+ didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
+ ss_recursive_chaotic_at ("buzz", n, trace, ref didLast, ref didAny);
+ }
+ return didAny;
+ }
+
+ public static bool ss_recursive_chaotic_fizzbuzz (int n, List<RecursiveChaoticPoint> trace)
+ {
+ bool didLast = false, didAny = false;
+ if (n > 0) {
+ int next = n - 1;
+ didLast = ss_recursive_chaotic_fizz (next, trace);
+ ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
+ didLast = ss_recursive_chaotic_buzz (next, trace);
+ ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
+ didLast = ss_recursive_chaotic_fizzbuzz (next, trace);
+ ss_recursive_chaotic_at ("fizzbuzz", n, trace, ref didLast, ref didAny);
+ }
+ return didAny;
+ }
+
+ public static void trace_ss_recursive_chaotic (List<RecursiveChaoticPoint> trace)
+ {
+ ss_recursive_chaotic_fizz (5, trace);
+ }
+
Event single_step (ThreadMirror t) {
var req = vm.CreateStepRequest (t);
req.Enable ();
Assert.AreEqual (m2.Name, (e as BreakpointEvent).Method.Name);
}
+ // Assert we have stepped to a location
void assert_location (Event e, string method) {
Assert.IsTrue (e is StepEvent);
Assert.AreEqual (method, (e as StepEvent).Method.Name);
}
+ // Assert we have breakpointed at a location
+ void assert_location_at_breakpoint (Event e, string method) {
+ Assert.IsTrue (e is BreakpointEvent);
+ Assert.AreEqual (method, (e as BreakpointEvent).Method.Name);
+ }
+
+ // Assert we have stepped to or breakpointed at a location
+ void assert_location_allow_breakpoint (Event e, string method) {
+ if (e is StepEvent)
+ Assert.AreEqual (method, (e as StepEvent).Method.Name);
+ else if (e is BreakpointEvent)
+ Assert.AreEqual (method, (e as BreakpointEvent).Method.Name);
+ else
+ Assert.Fail ("Neither step nor breakpoint event");
+ }
+
StepEventRequest create_step (Event e) {
var req = vm.CreateStepRequest (e.Thread);
step_req = req;
AssertValue (1, f.GetValue (f.Method.GetLocal ("n")));
req.Disable ();
+ // Check that step-over stops correctly when inner frames with recursive functions contain breakpoints
+ e = run_until ("ss_recursive2");
+ ReusableBreakpoint breakpoint = new ReusableBreakpoint (this, "ss_recursive2_trap");
+ try {
+ breakpoint.Continue ();
+ e = breakpoint.lastEvent;
+ req = create_step (e);
+ for (int c = 1; c <= 4; c++) {
+ // The first five times we try to step over this function, the breakpoint will stop us
+ assert_location_at_breakpoint (e, "ss_recursive2_trap");
+
+ req.Disable ();
+ req = create_step (e);
+ req.Size = StepSize.Line;
+
+ e = step_out ();
+ assert_location (e, "ss_recursive2");
+
+ // Stack should consist of Main + single_stepping + (1 ss_recursive2 frame per loop iteration)
+ Assert.AreEqual (c+2, e.Thread.GetFrames ().Length);
+ e = step_over_or_breakpoint ();
+ }
+ // At this point we should have escaped the breakpoints and this will be a normal step stop
+ assert_location (e, "ss_recursive2");
+ Assert.AreEqual (6, e.Thread.GetFrames ().Length);
+ } finally {
+ req.Disable ();
+ breakpoint.Disable ();
+ }
+
+ // Check that step-out stops correctly when inner frames with recursive functions contain breakpoints
+ e = run_until ("ss_recursive2");
+ breakpoint = new ReusableBreakpoint (this, "ss_recursive2_trap");
+ try {
+ breakpoint.Continue ();
+ e = breakpoint.lastEvent;
+ req = create_step (e);
+ for (int c = 1; c <= 4; c++) {
+ // The first five times we try to step over this function, the breakpoint will stop us
+ assert_location_at_breakpoint (e, "ss_recursive2_trap");
+
+ req.Disable ();
+ req = create_step (e);
+ req.Size = StepSize.Line;
+
+ e = step_out ();
+ assert_location (e, "ss_recursive2");
+
+ // Stack should consist of Main + single_stepping + (1 ss_recursive2 frame per loop iteration)
+ Assert.AreEqual (c+2, e.Thread.GetFrames ().Length);
+ e = step_out_or_breakpoint ();
+ }
+ for (int c = 3; c >= 1; c--) {
+ assert_location (e, "ss_recursive2");
+ Assert.AreEqual (c + 2, e.Thread.GetFrames ().Length);
+
+ e = step_out ();
+ }
+ } finally {
+ req.Disable ();
+ breakpoint.Disable ();
+ }
+
+ // Test step out with a really complicated call tree
+ List<RecursiveChaoticPoint> trace = new List<RecursiveChaoticPoint>();
+ trace_ss_recursive_chaotic (trace);
+ e = run_until ("ss_recursive_chaotic");
+ try {
+ breakpoint = new ReusableBreakpoint (this, "ss_recursive_chaotic_trap");
+ breakpoint.Continue ();
+ e = breakpoint.lastEvent;
+ foreach (RecursiveChaoticPoint point in trace)
+ {
+ if (point.breakpoint)
+ assert_location_at_breakpoint (e, point.name);
+ else
+ assert_location (e, point.name);
+ Assert.AreEqual (point.depth, e.Thread.GetFrames ().Length);
+
+ req.Disable ();
+ req = create_step (e);
+ req.Size = StepSize.Line;
+ e = step_out_or_breakpoint ();
+ }
+ } finally {
+ req.Disable ();
+ breakpoint.Disable ();
+ }
+
// Check that single stepping doesn't clobber fp values
e = run_until ("ss_fp_clobber");
req = create_step (e);
return step_once ();
}
+ Event step_once_or_breakpoint () {
+ vm.Resume ();
+ var e = GetNextEvent ();
+ Assert.IsTrue (e is StepEvent || e is BreakpointEvent);
+ return e;
+ }
+
+ Event step_over_or_breakpoint () {
+ step_req.Disable ();
+ step_req.Depth = StepDepth.Over;
+ step_req.Enable ();
+ return step_once_or_breakpoint ();
+ }
+
+ Event step_out_or_breakpoint () {
+ step_req.Disable ();
+ step_req.Depth = StepDepth.Out;
+ step_req.Enable ();
+ return step_once_or_breakpoint ();
+ }
+
[Test]
public void Locals () {
var be = run_until ("locals1");
Assert.AreEqual (end.Length, bytes.Length, prefix + ": byte length");
- for (int i = 0; i < Math.Min (bytes.Length, end.Length); ++i)
+ for (int i = 0; i < global::System.Math.Min (bytes.Length, end.Length); ++i)
Assert.AreEqual (end [i], bytes [i], prefix + ": byte " + i);
int cc = unix.GetCharCount (end, 0, end.Length);
Assert.AreEqual (start.Length, r, prefix + ": chars length");
- for (int i = 0; i < Math.Min (r, start.Length); ++i) {
+ for (int i = 0; i < global::System.Math.Min (r, start.Length); ++i) {
Assert.AreEqual (start [i], chars [i], prefix + ": char " + i);
}
}
--- /dev/null
+#include monodroid_Mono.Posix_test.dll.new-exclude.sources
+Mono.Unix.Android/TestHelper.cs
--- /dev/null
+Mono.Unix.Native/SocketTest.cs
+Mono.Unix/UnixEndPointTest.cs
+Mono.Unix/UnixListenerTest.cs
--- /dev/null
+#include Mono.Posix_test.dll.sources
--- /dev/null
+# These fail because of reliance on full NUnit framework
+Mono.Math/ArithmeticBigTest.cs
+Mono.Math/BigIntegerSetTest.cs
+Mono.Math/BitwiseTest.cs
+Mono.Math/GcdBigTest.cs
+Mono.Math/ModInverseBigTest.cs
+Mono.Math/ModRingTest.cs
+Mono.Math/PrimeGenerationTest.cs
+Mono.Math/PrimeTestingTest.cs
+Mono.Math/SearchGeneratorTest.cs
+Mono.Security.Authenticode/PrivateKeyTest.cs
+Mono.Security.Cryptography/CryptoConvertTest.cs
+Mono.Security.Cryptography/DiffieHellmanManagedTest.cs
+Mono.Security.Cryptography/PKCS8Test.cs
+Mono.Security.Protocol.Ntlm/ChallengeResponseTest.cs
+Mono.Security.Protocol.Ntlm/MessageBaseTest.cs
+Mono.Security.Protocol.Ntlm/Type1MessageTest.cs
+Mono.Security.Protocol.Ntlm/Type2MessageTest.cs
+Mono.Security.Protocol.Ntlm/Type3MessageTest.cs
+Mono.Security/StrongNameTest.cs
--- /dev/null
+#include monodroid_Mono.Security_test.dll.build-failure-exclude.sources
+#include monodroid_Mono.Data.Sqlite_test.dll.new-exclude.sources
--- /dev/null
+Mono.Security.Authenticode/AuthenticodeDeformatterTest.cs
+Mono.Security.Authenticode/SoftwarePublisherCertificateTest.cs
+Mono.Security/PKCS7Test.cs
+Mono.Security.X509.Extensions/AuthorityKeyIdentifierExtensionTest.cs
+Mono.Security.X509.Extensions/BasicConstraintsExtensionTest.cs
+Mono.Security.X509.Extensions/ExtendedKeyUsageExtensionTest.cs
+Mono.Security.X509.Extensions/KeyUsageExtensionTest.cs
+Mono.Security.X509.Extensions/SubjectAltNameExtensionTest.cs
+Mono.Security.X509.Extensions/SubjectKeyIdentifierExtensionTest.cs
+Mono.Security.X509/PKCS12Test.cs
+Mono.Security.X509/X501NameTest.cs
+Mono.Security.X509/X509CertificateTest.cs
+Mono.Security.X509/X509CrlTest.cs
+Mono.Security.X509/X520AttributesTest.cs
--- /dev/null
+#include Mono.Security_test.dll.sources
--- /dev/null
+#include monodroid_System.ComponentModel.DataAnnotations_test.dll.new-exclude.sources
+../../System.Web.DynamicData/Test/Common/AssertExtensions.cs
--- /dev/null
+System.ComponentModel.DataAnnotations/AssociatedMetadataTypeTypeDescriptionProviderTests.cs
+System.ComponentModel.DataAnnotations/CompareAttributeTest.cs
+System.ComponentModel.DataAnnotations/CreditCardAttributeTest.cs
+System.ComponentModel.DataAnnotations/EmailAddressAttributeTest.cs
+System.ComponentModel.DataAnnotations/FileExtensionsAttributeTest.cs
+System.ComponentModel.DataAnnotations/PhoneAttributeTest.cs
--- /dev/null
+#include System.ComponentModel.DataAnnotations_test.dll.sources
--- /dev/null
+#include mobile_static_System.Core_test.dll.exclude.sources
+#include monodroid_System.Core_test.dll.new-exclude.sources
--- /dev/null
+../../corlib/Test/System.Security.Cryptography/HashAlgorithmTest.cs
+../../corlib/Test/System.Security.Cryptography/SHA1Test.cs
+../../corlib/Test/System.Security.Cryptography/SHA256Test.cs
+../../corlib/Test/System.Security.Cryptography/SHA384Test.cs
+../../corlib/Test/System.Security.Cryptography/SHA512Test.cs
--- /dev/null
+#include System.Core_test.dll.sources
<SchemaVersion>2.0</SchemaVersion>\r
<ProjectGuid>{E6A6B9F7-BD0C-4F8D-8AFE-2EF76A2FB3AD}</ProjectGuid>\r
<OutputType>Library</OutputType>\r
- <NoWarn>1699,1699</NoWarn>\r
+ <NoWarn>1699</NoWarn>\r
<OutputPath>./../../class/lib/net_4_x</OutputPath>\r
<IntermediateOutputPath>obj-net_4_x</IntermediateOutputPath>\r
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>\r
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
<DebugSymbols>true</DebugSymbols>\r
<DebugType>full</DebugType>\r
- <NoWarn>1699,1699</NoWarn>\r
+ <NoWarn>1699</NoWarn>\r
<Optimize>false</Optimize>\r
- <DefineConstants>TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC</DefineConstants>\r
+ <DefineConstants>TRACE;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC</DefineConstants>\r
<ErrorReport>prompt</ErrorReport>\r
<WarningLevel>4</WarningLevel>\r
</PropertyGroup>\r
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
<DebugType>pdbonly</DebugType>\r
- <NoWarn>1699,1699</NoWarn>\r
+ <NoWarn>1699</NoWarn>\r
<Optimize>true</Optimize>\r
- <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC;NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC</DefineConstants>\r
+ <DefineConstants>NET_4_0;NET_4_5;NET_4_6;MONO;DISABLE_CAS_USE;ASPNETMVC;FEATURE_DYNAMIC</DefineConstants>\r
<ErrorReport>prompt</ErrorReport>\r
<WarningLevel>4</WarningLevel>\r
</PropertyGroup>\r
-->\r
<PropertyGroup>\r
<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-
+cp $(ProjectDir)\System.Json\Properties\Resources.resx System.Json.Properties.Resources.resx
</PreBuildEvent>\r
<PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-\r
+cp $(ProjectDir)\System.Json\Properties\Resources.resx System.Json.Properties.Resources.resx\r
</PreBuildEvent>\r
<PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
-->\r
<PropertyGroup>\r
<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
+cp $(ProjectDir)/../../../external/aspnetwebstack/src/Common/CommonWebApiResources.resx $(ProjectDir)/System.Net.Http.Properties.CommonWebApiResources.resx
+cp $(ProjectDir)/../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/Resources.resx $(ProjectDir)/System.Net.Http.Properties.Resources.resx
</PreBuildEvent>\r
<PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
+cp $(ProjectDir)/../../../external/aspnetwebstack/src/Common/CommonWebApiResources.resx $(ProjectDir)/System.Net.Http.Properties.CommonWebApiResources.resx
+cp $(ProjectDir)/../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/Resources.resx $(ProjectDir)/System.Net.Http.Properties.Resources.resx
\r
</PreBuildEvent>\r
<PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
mono $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
-
</PreBuildEvent>\r
<PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
mono $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
-
\r
</PreBuildEvent>\r
<PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
<PreBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
mono $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
-
</PreBuildEvent>\r
<PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
mono $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
-
\r
</PreBuildEvent>\r
<PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
EnableFormsForModalLoop (toplevels, context);
- if (context.MainForm != null && context.MainForm.IsHandleCreated) {
- XplatUI.SetModal (context.MainForm.Handle, false);
+ if (old != null && old.IsHandleCreated) {
+ XplatUI.SetModal (old.Handle, false);
}
#if DebugRunLoop
Console.WriteLine (" Done with the SetModal");
internal static void Enter(TraceSource traceSource, object obj, string method, object paramObject) {
}
+ [Conditional ("TRACE")]
+ internal static void Enter(TraceSource traceSource, string msg) {
+ }
+
[Conditional ("TRACE")]
internal static void Exception(TraceSource traceSource, object obj, string method, Exception e) {
}
internal static void Exit(TraceSource traceSource, object obj, string method, object retObject) {
}
+ [Conditional ("TRACE")]
+ internal static void Exit(TraceSource traceSource, string msg) {
+ }
+
[Conditional ("TRACE")]
internal static void PrintInfo(TraceSource traceSource, object obj, string method, string msg) {
}
public const int WAIT_ABANDONED = 0x00000080;
public const int WAIT_ABANDONED_0 = WAIT_ABANDONED;
+ public const int ERROR_FILE_NOT_FOUND = 2;
+ public const int ERROR_PATH_NOT_FOUND = 3;
+ public const int ERROR_ACCESS_DENIED = 5;
+ public const int ERROR_INVALID_HANDLE = 6;
+ public const int ERROR_SHARING_VIOLATION = 32;
+ public const int ERROR_INVALID_NAME = 0x7B;
+ public const int ERROR_ALREADY_EXISTS = 183;
+ public const int ERROR_FILENAME_EXCED_RANGE = 0xCE;
+
public static bool DuplicateHandle(HandleRef hSourceProcessHandle, SafeHandle hSourceHandle, HandleRef hTargetProcess,
out SafeWaitHandle targetHandle, int dwDesiredAccess, bool bInheritHandle, int dwOptions)
{
public const string mono_net_io_shutdown = "mono_net_io_shutdown";
public const string mono_net_io_renegotiate = "mono_net_io_renegotiate";
- public const string net_log_set_socketoption_reuseport_default_on = "net_log_set_socketoption_reuseport_default_on";
+ public const string net_log_set_socketoption_reuseport_default_on = "net_log_set_socketoption_reuseport_default_on";
+ public const string net_log_set_socketoption_reuseport_not_supported = "net_log_set_socketoption_reuseport_not_supported";
+ public const string net_log_set_socketoption_reuseport = "net_log_set_socketoption_reuseport";
}
internal bool UseNagleAlgorithm { get; set; }
internal bool Expect100Continue { get; set; }
- internal bool CheckCertificateName { get; }
+ internal bool CheckCertificateName { get; private set; }
internal int DnsRefreshTimeout { get; set; }
internal bool EnableDnsRoundRobin { get; set; }
internal bool CheckCertificateRevocationList { get; set; }
- internal EncryptionPolicy EncryptionPolicy { get; }
+ internal EncryptionPolicy EncryptionPolicy { get; private set; }
}
}
<Compile Include="..\referencesource\System\net\System\Net\_LazyAsyncResult.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_LoggingObject.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_NetRes.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_PooledStream.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ProxyChain.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ScatterGatherBuffers.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_Semaphore.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_TimerThread.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_WebProxyDataBuilder.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\AuthenticationScheme.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCacheManager.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCachePolicy.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Configuration\DefaultProxySection.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\connectionpool.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookie.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecollection.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecontainer.cs" />\r
<Compile Include="..\referencesource\System\services\timers\system\timers\TimersDescriptionAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\BlockingCollection.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\ConcurrentBag.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\IO\ports\InternalResources.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\DefaultParameterValueAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\handlecollector.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\versioning\FrameworkName.cs" />\r
<Compile Include="..\referencesource\System\sys\system\threading\Barrier.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\threading\semaphore.cs" />\r
<Compile Include="..\referencesource\System\sys\system\windows\markup\ValueSerializerAttribute.cs" />\r
<Compile Include="Assembly\AssemblyInfo.cs" />\r
<Compile Include="Microsoft.CSharp\CSharpCodeCompiler.cs" />\r
<Compile Include="System.Security.Permissions\StorePermission.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionAttribute.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionFlags.cs" />\r
- <Compile Include="System.Threading\Semaphore.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventArgs.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventHandler.cs" />\r
<Compile Include="System.Timers\ElapsedEventArgs.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_LazyAsyncResult.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_LoggingObject.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_NetRes.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_PooledStream.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ProxyChain.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ScatterGatherBuffers.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_Semaphore.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_TimerThread.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_WebProxyDataBuilder.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\AuthenticationScheme.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCacheManager.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCachePolicy.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Configuration\DefaultProxySection.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\connectionpool.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookie.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecollection.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecontainer.cs" />\r
<Compile Include="..\referencesource\System\services\timers\system\timers\TimersDescriptionAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\BlockingCollection.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\ConcurrentBag.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\IO\ports\InternalResources.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\DefaultParameterValueAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\handlecollector.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\versioning\FrameworkName.cs" />\r
<Compile Include="..\referencesource\System\sys\system\threading\Barrier.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\threading\semaphore.cs" />\r
<Compile Include="..\referencesource\System\sys\system\windows\markup\ValueSerializerAttribute.cs" />\r
<Compile Include="Assembly\AssemblyInfo.cs" />\r
<Compile Include="Microsoft.CSharp\CSharpCodeCompiler.cs" />\r
<Compile Include="System.Security.Permissions\StorePermission.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionAttribute.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionFlags.cs" />\r
- <Compile Include="System.Threading\Semaphore.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventArgs.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventHandler.cs" />\r
<Compile Include="System.Timers\ElapsedEventArgs.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_LazyAsyncResult.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_LoggingObject.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_NetRes.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_PooledStream.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ProxyChain.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_ScatterGatherBuffers.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\_Semaphore.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_TimerThread.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\_WebProxyDataBuilder.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\AuthenticationScheme.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCacheManager.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Cache\RequestCachePolicy.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\Configuration\DefaultProxySection.cs" />\r
+ <Compile Include="..\referencesource\System\net\System\Net\connectionpool.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookie.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecollection.cs" />\r
<Compile Include="..\referencesource\System\net\System\Net\cookiecontainer.cs" />\r
<Compile Include="..\referencesource\System\services\timers\system\timers\TimersDescriptionAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\BlockingCollection.cs" />\r
<Compile Include="..\referencesource\System\sys\system\collections\concurrent\ConcurrentBag.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\IO\ports\InternalResources.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\DefaultParameterValueAttribute.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\interopservices\handlecollector.cs" />\r
<Compile Include="..\referencesource\System\sys\system\runtime\versioning\FrameworkName.cs" />\r
<Compile Include="..\referencesource\System\sys\system\threading\Barrier.cs" />\r
+ <Compile Include="..\referencesource\System\sys\system\threading\semaphore.cs" />\r
<Compile Include="..\referencesource\System\sys\system\windows\markup\ValueSerializerAttribute.cs" />\r
<Compile Include="Assembly\AssemblyInfo.cs" />\r
<Compile Include="Microsoft.CSharp\CSharpCodeCompiler.cs" />\r
<Compile Include="System.Security.Permissions\StorePermission.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionAttribute.cs" />\r
<Compile Include="System.Security.Permissions\StorePermissionFlags.cs" />\r
- <Compile Include="System.Threading\Semaphore.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventArgs.cs" />\r
<Compile Include="System.Threading\ThreadExceptionEventHandler.cs" />\r
<Compile Include="System.Timers\ElapsedEventArgs.cs" />\r
SocketAsyncEventArgs args = new SocketAsyncEventArgs ();
args.UserToken = this;
args.Completed += OnAccept;
- Accept (sock, args);
+ Socket dummy = null;
+ Accept (sock, args, ref dummy);
prefixes = new Hashtable ();
unregistered = new Dictionary<HttpConnection, HttpConnection> ();
}
get { return listener; }
}
- static void Accept (Socket socket, SocketAsyncEventArgs e) {
+ static void Accept (Socket socket, SocketAsyncEventArgs e, ref Socket accepted) {
e.AcceptSocket = null;
- var asyn = socket.AcceptAsync(e);
+ bool asyn;
+ try {
+ asyn = socket.AcceptAsync(e);
+ } catch {
+ if (accepted != null) {
+ try {
+ accepted.Close ();
+ } catch {
+ }
+ accepted = null;
+ }
+ return;
+ }
if (!asyn) {
ProcessAccept(e);
}
EndPointListener epl = (EndPointListener) args.UserToken;
- Accept (epl.sock, args);
+ Accept (epl.sock, args, ref accepted);
if (accepted == null)
return;
}
}
+ public override bool SupportsHeaders {
+ get {
+ return true;
+ }
+ }
+
public string StatusDescription {
get {
return statusDescription;
}
internal WebConnection StoredConnection;
+
+#region referencesource
+ internal static StringBuilder GenerateConnectionGroup(string connectionGroupName, bool unsafeConnectionGroup, bool isInternalGroup)
+ {
+ StringBuilder connectionLine = new StringBuilder(connectionGroupName);
+
+ connectionLine.Append(unsafeConnectionGroup ? "U>" : "S>");
+
+ if (isInternalGroup)
+ {
+ connectionLine.Append("I>");
+ }
+
+ return connectionLine;
+ }
+#endregion
}
}
}
}
+ public override bool SupportsHeaders {
+ get {
+ return true;
+ }
+ }
+
// Methods
public string GetResponseHeader (string headerName)
return true;
}
}
+
+ internal Socket GetConnection(PooledStream PooledStream, object owner, bool async, out IPAddress address, ref Socket abortSocket, ref Socket abortSocket6)
+ {
+ throw new NotImplementedException ();
+ }
}
}
SetAuditRule((AuditRule)rule);
}
- internal new void PersistModifications (SafeHandle handle)
+ internal new void Persist (SafeHandle handle)
{
WriteLock();
try {
+++ /dev/null
-//
-// System.Threading.Semaphore.cs
-//
-// Author:
-// Sebastien Pouliot <sebastien@ximian.com>
-//
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.ConstrainedExecution;
-using System.Runtime.InteropServices;
-using System.Security.AccessControl;
-using System.Security.Permissions;
-using System.Runtime.CompilerServices;
-using System.IO;
-
-namespace System.Threading {
-
- [ComVisible (false)]
- public sealed class Semaphore : WaitHandle {
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern IntPtr CreateSemaphore_internal (
- int initialCount, int maximumCount, string name,
- out bool createdNew);
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- private static extern int ReleaseSemaphore_internal (
- IntPtr handle, int releaseCount, out bool fail);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private static extern IntPtr OpenSemaphore_internal (string name, SemaphoreRights rights, out MonoIOError error);
-
- private Semaphore (IntPtr handle)
- {
- Handle = handle;
- }
-
- public Semaphore (int initialCount, int maximumCount)
- : this (initialCount, maximumCount, null)
- {
- }
-
- public Semaphore (int initialCount, int maximumCount, string name)
- {
- if (initialCount < 0)
- throw new ArgumentOutOfRangeException ("initialCount", "< 0");
- if (maximumCount < 1)
- throw new ArgumentOutOfRangeException ("maximumCount", "< 1");
- if (initialCount > maximumCount)
- throw new ArgumentException ("initialCount > maximumCount");
-
- bool created;
-
- Handle = CreateSemaphore_internal (initialCount,
- maximumCount, name,
- out created);
- }
-
- public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew)
- : this (initialCount, maximumCount, name, out createdNew, null)
- {
- }
-
- [MonoTODO ("CreateSemaphore_internal does not support access control, semaphoreSecurity is ignored")]
- public Semaphore (int initialCount, int maximumCount, string name, out bool createdNew,
- SemaphoreSecurity semaphoreSecurity)
- {
- if (initialCount < 0)
- throw new ArgumentOutOfRangeException ("initialCount", "< 0");
- if (maximumCount < 1)
- throw new ArgumentOutOfRangeException ("maximumCount", "< 1");
- if (initialCount > maximumCount)
- throw new ArgumentException ("initialCount > maximumCount");
-
- Handle = CreateSemaphore_internal (initialCount,
- maximumCount, name,
- out createdNew);
- }
-
- public SemaphoreSecurity GetAccessControl ()
- {
- return new SemaphoreSecurity (SafeWaitHandle,
- AccessControlSections.Owner |
- AccessControlSections.Group |
- AccessControlSections.Access);
- }
-
- [PrePrepareMethod]
- [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
- public int Release ()
- {
- return (Release (1));
- }
-
- [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
- public int Release (int releaseCount)
- {
- if (releaseCount < 1)
- throw new ArgumentOutOfRangeException ("releaseCount");
-
- int ret;
- bool fail;
-
- ret = ReleaseSemaphore_internal (Handle, releaseCount,
- out fail);
-
- if (fail) {
- throw new SemaphoreFullException ();
- }
-
- return (ret);
- }
-
- public void SetAccessControl (SemaphoreSecurity semaphoreSecurity)
- {
- if (semaphoreSecurity == null)
- throw new ArgumentNullException ("semaphoreSecurity");
-
- semaphoreSecurity.PersistModifications (SafeWaitHandle);
- }
-
- // static methods
-
-#if !MOBILE
- public static Semaphore OpenExisting (string name)
- {
- return OpenExisting (name, SemaphoreRights.Synchronize | SemaphoreRights.Modify);
- }
-
- public static Semaphore OpenExisting (string name, SemaphoreRights rights)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
- if ((name.Length ==0) || (name.Length > 260))
- throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
-
- MonoIOError error;
- IntPtr handle = OpenSemaphore_internal (name, rights,
- out error);
- if (handle == (IntPtr)null) {
- if (error == MonoIOError.ERROR_FILE_NOT_FOUND) {
- throw new WaitHandleCannotBeOpenedException (Locale.GetText ("Named Semaphore handle does not exist: ") + name);
- } else if (error == MonoIOError.ERROR_ACCESS_DENIED) {
- throw new UnauthorizedAccessException ();
- } else {
- throw new IOException (Locale.GetText ("Win32 IO error: ") + error.ToString ());
- }
- }
-
- return(new Semaphore (handle));
- }
-
- [SecurityPermissionAttribute (SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static bool TryOpenExisting (string name, out Semaphore result)
- {
- return TryOpenExisting (name, SemaphoreRights.Synchronize | SemaphoreRights.Modify, out result);
- }
-
- [SecurityPermissionAttribute(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
- public static bool TryOpenExisting (string name, SemaphoreRights rights, out Semaphore result)
- {
- if (name == null)
- throw new ArgumentNullException ("name");
- if ((name.Length == 0) || (name.Length > 260))
- throw new ArgumentException ("name", Locale.GetText ("Invalid length [1-260]."));
-
- MonoIOError error;
- IntPtr handle = OpenSemaphore_internal (name, rights, out error);
-
- if (handle == (IntPtr)null) {
- result = null;
- return false;
- }
-
- result = new Semaphore (handle);
- return true;
- }
-#else
- public static Semaphore OpenExisting (string name)
- {
- throw new NotSupportedException ();
- }
-
- public static Semaphore OpenExisting (string name, SemaphoreRights rights)
- {
- throw new NotSupportedException ();
- }
-
- public static bool TryOpenExisting (string name, out Semaphore result)
- {
- throw new NotSupportedException ();
- }
-
- public static bool TryOpenExisting (string name, SemaphoreRights rights, out Semaphore result)
- {
- throw new NotSupportedException ();
- }
-#endif
- }
-}
-
System.Security.Permissions/StorePermission.cs
System.Security.Permissions/StorePermissionFlags.cs
System/SRDescriptionAttribute.cs
-System.Threading/Semaphore.cs
System.Threading/ThreadExceptionEventArgs.cs
System.Threading/ThreadExceptionEventHandler.cs
System.Timers/ElapsedEventArgs.cs
../referencesource/System/net/System/Net/_NetRes.cs
../referencesource/System/net/System/Net/_LazyAsyncResult.cs
../referencesource/System/net/System/Net/_LoggingObject.cs
+../referencesource/System/net/System/Net/_PooledStream.cs
../referencesource/System/net/System/Net/_ProxyChain.cs
../referencesource/System/net/System/Net/_ScatterGatherBuffers.cs
+../referencesource/System/net/System/Net/_Semaphore.cs
../referencesource/System/net/System/Net/_TimerThread.cs
../referencesource/System/net/System/Net/_WebProxyDataBuilder.cs
../referencesource/System/net/System/Net/AuthenticationScheme.cs
../referencesource/System/net/System/Net/cookiecollection.cs
../referencesource/System/net/System/Net/cookiecontainer.cs
../referencesource/System/net/System/Net/cookieexception.cs
+../referencesource/System/net/System/Net/connectionpool.cs
../referencesource/System/net/System/Net/DnsEndPoint.cs
../referencesource/System/net/System/Net/EndPoint.cs
../referencesource/System/net/System/Net/FtpStatusCode.cs
../referencesource/System/net/System/Net/NetworkInformation/nodetype.cs
../referencesource/System/net/System/Net/NetworkInformation/pingexception.cs
+../referencesource/System/sys/system/IO/ports/InternalResources.cs
+
../referencesource/System/sys/system/runtime/interopservices/DefaultParameterValueAttribute.cs
../referencesource/System/sys/system/runtime/interopservices/handlecollector.cs
../referencesource/System/sys/system/runtime/versioning/FrameworkName.cs
../referencesource/System/sys/system/threading/Barrier.cs
+../referencesource/System/sys/system/threading/semaphore.cs
+
../referencesource/System/sys/system/windows/markup/ValueSerializerAttribute.cs
../referencesource/System/security/system/security/Authentication/ExtendedProtection/TokenBinding.cs
[Test]
public void SendAsyncFile ()
{
- Socket serverSocket = StartSocketServer ();
+ Socket serverSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
+
+ serverSocket.Bind (new IPEndPoint (IPAddress.Loopback, 0));
+ serverSocket.Listen (1);
+
+ var mReceived = new ManualResetEvent (false);
+
+ serverSocket.BeginAccept (AsyncCall => {
+ byte[] bytes = new byte [1024];
+
+ Socket listener = (Socket)AsyncCall.AsyncState;
+ Socket client = listener.EndAccept (AsyncCall);
+ client.Receive (bytes, bytes.Length, 0);
+ client.Close ();
+ mReceived.Set ();
+ }, serverSocket);
Socket clientSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
clientSocket.Connect (serverSocket.LocalEndPoint);
sw.Write (buffer);
}
- var m = new ManualResetEvent (false);
+ var mSent = new ManualResetEvent (false);
// Async Send File to server
clientSocket.BeginSendFile(temp, (ar) => {
Socket client = (Socket) ar.AsyncState;
client.EndSendFile (ar);
- m.Set ();
+ mSent.Set ();
}, clientSocket);
- if (!m.WaitOne (1500))
+ if (!mSent.WaitOne (1500))
+ throw new TimeoutException ();
+ if (!mReceived.WaitOne (1500))
throw new TimeoutException ();
- m.Reset ();
} finally {
if (File.Exists (temp))
File.Delete (temp);
}
}
- Socket StartSocketServer ()
- {
-
- Socket listenSocket = new Socket (AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
-
- listenSocket.Bind (new IPEndPoint (IPAddress.Loopback, NetworkHelpers.FindFreePort ()));
- listenSocket.Listen (1);
-
- listenSocket.BeginAccept (new AsyncCallback (ReceiveCallback), listenSocket);
-
- return listenSocket;
- }
-
- public static void ReceiveCallback (IAsyncResult AsyncCall)
- {
- byte[] bytes = new byte [1024];
-
- Socket listener = (Socket)AsyncCall.AsyncState;
- Socket client = listener.EndAccept (AsyncCall);
-
- client.Receive (bytes, bytes.Length, 0);
- client.Close ();
- }
-
[Test]
public void UdpMulticasTimeToLive ()
{
Assert.IsTrue (created, "Created");
}
+ [Test]
+ public void Constructor_CreatedWithSameName ()
+ {
+ var s1 = new Semaphore(1, 5, "name");
+ bool created;
+ var s2 = new Semaphore(1, 5, "name", out created);
+ Assert.IsFalse (created);
+ }
+
[Test]
[Category ("MobileNotWorking")]
public void Constructor_IntIntStringBoolSecurity ()
System.Net/HttpWebResponse.cs
System.Net/ICredentialPolicy.cs
System.Net/IPv6Address.cs
-System.Net/IPv6Address.cs
System.Net/IWebConnectionState.cs
+System.Net/IWebProxyScript.cs
System.Net/ListenerAsyncResult.cs
System.Net/ListenerPrefix.cs
System.Net/MacProxy.cs
System.Security.Cryptography/AsnEncodedData.cs
System.Security.Cryptography/AsnEncodedDataCollection.cs
System.Security.Cryptography/AsnEncodedDataEnumerator.cs
-System.Threading/Semaphore.cs
System.Threading/ThreadExceptionEventArgs.cs
System.Threading/ThreadExceptionEventHandler.cs
System.Timers/ElapsedEventArgs.cs
../referencesource/System/net/System/Net/_NetRes.cs
../referencesource/System/net/System/Net/_LazyAsyncResult.cs
../referencesource/System/net/System/Net/_LoggingObject.cs
+../referencesource/System/net/System/Net/_PooledStream.cs
../referencesource/System/net/System/Net/_ProxyChain.cs
../referencesource/System/net/System/Net/_ScatterGatherBuffers.cs
+../referencesource/System/net/System/Net/_Semaphore.cs
../referencesource/System/net/System/Net/_TimerThread.cs
../referencesource/System/net/System/Net/_WebProxyDataBuilder.cs
../referencesource/System/net/System/Net/AuthenticationScheme.cs
../referencesource/System/net/System/Net/cookiecollection.cs
../referencesource/System/net/System/Net/cookiecontainer.cs
../referencesource/System/net/System/Net/cookieexception.cs
+../referencesource/System/net/System/Net/connectionpool.cs
../referencesource/System/net/System/Net/DnsEndPoint.cs
../referencesource/System/net/System/Net/EndPoint.cs
../referencesource/System/net/System/Net/FtpStatusCode.cs
../referencesource/System/net/System/Net/NetworkInformation/nodetype.cs
../referencesource/System/net/System/Net/NetworkInformation/pingexception.cs
+../referencesource/System/sys/system/IO/ports/InternalResources.cs
+
../referencesource/System/sys/system/runtime/interopservices/DefaultParameterValueAttribute.cs
../referencesource/System/sys/system/runtime/interopservices/handlecollector.cs
../referencesource/System/sys/system/runtime/versioning/FrameworkName.cs
../referencesource/System/sys/system/threading/Barrier.cs
+../referencesource/System/sys/system/threading/semaphore.cs
../referencesource/System/security/system/security/Authentication/ExtendedProtection/TokenBinding.cs
--- /dev/null
+#include mobile_static_System_test.dll.exclude.sources
+#include monodroid_System_test.dll.new-exclude.sources
+Microsoft.Win32/IntranetZoneCredentialPolicyCas.cs
+Microsoft.Win32/IntranetZoneCredentialPolicyTest.cs
+Microsoft.Win32/PowerModeChangedEventArgsCas.cs
+Microsoft.Win32/SessionEndedEventArgsCas.cs
+Microsoft.Win32/SessionEndingEventArgsCas.cs
+Microsoft.Win32/SessionSwitchEventArgsCas.cs
+Microsoft.Win32/SessionSwitchEventArgsTest.cs
+Microsoft.Win32/SystemEventsCas.cs
+Microsoft.Win32/TimerElapsedEventArgsCas.cs
+Microsoft.Win32/UserPreferenceChangedEventArgsCas.cs
+Microsoft.Win32/UserPreferenceChangingEventArgsCas.cs
+System.Collections.Concurrent/CollectionStressTestHelper.cs
+System.Collections.Specialized/BitVector32Cas.cs
+System.Collections.Specialized/CollectionsUtilCas.cs
+System.Collections.Specialized/HybridDictionaryCas.cs
+System.Collections.Specialized/ListDictionaryCas.cs
+System.Collections.Specialized/NameObjectCollectionBaseCas.cs
+System.Collections.Specialized/NameValueCollectionCas.cs
+System.Collections.Specialized/OrderedDictionaryCas.cs
+System.Collections.Specialized/StringCollectionCas.cs
+System.Collections.Specialized/StringDictionaryCas.cs
+System.ComponentModel.Design.Serialization/InstanceDescriptorCas.cs
+System/FileStyleUriParserCas.cs
+System/FtpStyleUriParserCas.cs
+System/GenericUriParserCas.cs
+System/GopherStyleUriParserCas.cs
+System/HttpStyleUriParserCas.cs
+System.IO.Compression/DeflateStreamCas.cs
+System.IO.Compression/GZipStreamCas.cs
+System/LdapStyleUriParserCas.cs
+System.Net/DnsCas.cs
+System.Net/FileWebRequestCas.cs
+System.Net/HttpListener2Test.cs
+System.Net/HttpListenerRequestTest.cs
+System.Net/HttpWebRequestCas.cs
+System/NetPipeStyleUriParserCas.cs
+System.Net.Sockets/NetworkStreamCas.cs
+System.Net.Sockets/SocketCas.cs
+System.Net.Sockets/TcpClientCas.cs
+System/NetTcpStyleUriParserCas.cs
+System/NewsStyleUriParserCas.cs
+System.Security.Cryptography.X509Certificates/PublicKeyCas.cs
+System.Security.Cryptography.X509Certificates/X500DistinguishedNameCas.cs
+System.Security.Cryptography.X509Certificates/X509BasicConstraintsExtensionCas.cs
+System.Security.Cryptography.X509Certificates/X509CertificateCollectionCas.cs
+System.Security.Cryptography.X509Certificates/X509ChainCas.cs
+System.Security.Cryptography.X509Certificates/X509ChainPolicyCas.cs
+System.Security.Cryptography.X509Certificates/X509EnhancedKeyUsageExtensionCas.cs
+System.Security.Cryptography.X509Certificates/X509ExtensionCas.cs
+System.Security.Cryptography.X509Certificates/X509KeyUsageExtensionCas.cs
+System.Security.Cryptography.X509Certificates/X509StoreCas.cs
+System.Security.Cryptography.X509Certificates/X509SubjectKeyIdentifierExtensionCas.cs
+System.Security.Permissions/ResourcePermissionBaseCas.cs
+System.Security.Permissions/ResourcePermissionBaseEntryCas.cs
+System.Security.Permissions/ResourcePermissionBaseEntryTest.cs
+System.Security.Permissions/ResourcePermissionBaseTest.cs
+System.Security.Permissions/StorePermissionAttributeCas.cs
+System.Security.Permissions/StorePermissionAttributeTest.cs
+System.Security.Permissions/StorePermissionCas.cs
+System.Security.Permissions/StorePermissionTest.cs
+System.Text.RegularExpressions/CaptureCas.cs
+System.Text.RegularExpressions/CaptureCollectionCas.cs
+System.Text.RegularExpressions/GroupCas.cs
+System.Text.RegularExpressions/GroupCollectionCas.cs
+System.Text.RegularExpressions/MatchCas.cs
+System.Text.RegularExpressions/MatchCollectionCas.cs
+System.Text.RegularExpressions/RegexCas.cs
+System.Text.RegularExpressions/RegexCompilationInfoCas.cs
+System.Text.RegularExpressions/RegexRunnerCas.cs
+System.Text.RegularExpressions/RegexRunnerFactoryCas.cs
+System.Threading/SemaphoreCas.cs
+System.Threading/SemaphoreFullExceptionCas.cs
+System.Threading/ThreadExceptionEventArgsCas.cs
+System.Timers/ElapsedEventArgsCas.cs
+System.Timers/TimerCas.cs
+System.Timers/TimersDescriptionAttributeCas.cs
+System/UriBuilderCas.cs
+System/UriCas.cs
+System/UriFormatExceptionCas.cs
+System/UriParserCas.cs
+System/UriTypeConverterCas.cs
--- /dev/null
+System.Net/HttpWebRequestTest.cs
+System.Net.Sockets/SocketAcceptAsyncTest.cs
--- /dev/null
+#include System_test.dll.sources
if (!suppressSecurityChecks)
{
+#if !DISABLE_CAS_USE
#pragma warning disable 618
new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
#pragma warning restore 618
+#endif
}
}
{
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public void Assert ()
{
new PermissionSet (this).Assert ();
public abstract IPermission Copy ();
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#endif
public void Demand ()
{
// note: here we're sure it's a CAS demand
new PermissionSet (this).CasOnlyDemand (3);
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public void Deny ()
{
new PermissionSet (this).Deny ();
return null;
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public void PermitOnly ()
{
new PermissionSet (this).PermitOnly ();
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public static void RevertAll ()
{
if (!SecurityManager.SecurityEnabled)
throw new NotImplementedException ();
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public static void RevertAssert ()
{
if (!SecurityManager.SecurityEnabled)
throw new NotImplementedException ();
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public static void RevertDeny ()
{
if (!SecurityManager.SecurityEnabled)
throw new NotImplementedException ();
}
+#if MOBILE && DISABLE_CAS_USE
+ [Obsolete ("CAS support is removed by linker", true)]
+#else
[MonoTODO ("CAS support is experimental (and unsupported). Imperative mode is not implemented.")]
+#endif
public static void RevertPermitOnly ()
{
if (!SecurityManager.SecurityEnabled)
// FIXME what's it doing here? There's probably a reason this was added here.
static public void RevertAssert ()
{
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert ();
+#endif
}
// internal
* of icalls, do not require an increment.
*/
#pragma warning disable 169
- private const int mono_corlib_version = 148;
+ private const int mono_corlib_version = 149;
#pragma warning restore 169
[ComVisible (true)]
// (C) 2004 Motus Technologies Inc. (http://www.motus.com)
//
+#if !DISABLE_CAS_USE
+
using NUnit.Framework;
using System;
using System.Security;
}
}
}
+
+#endif
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
-
+#if !DISABLE_CAS_USE
using System;
using System.Security;
}
}
+#endif
\ No newline at end of file
--- /dev/null
+#include monodroid_corlib_test.dll.new-exclude.sources
+Microsoft.Win32/RegistryKeyTest.cs
+System/ActivatorCas.cs
+System/AppDomainCas.cs
+System/BadImageFormatExceptionCas.cs
+System/ConsoleCas.cs
+System.Diagnostics/StackFrameCas.cs
+System.Diagnostics/StackTraceCas.cs
+System/EnvironmentCas.cs
+System/ExceptionCas.cs
+System.IO/DirectoryCas.cs
+System.IO/FileLoadExceptionCas.cs
+System.IO/FileNotFoundExceptionCas.cs
+System.IO/FileStreamCas.cs
+System.IO.IsolatedStorage/IsolatedStorageFileCas.cs
+System.IO.IsolatedStorage/IsolatedStorageFileStreamCas.cs
+System.IO/PathCas.cs
+System.IO/StreamCas.cs
+System/MarshalByRefObjectCas.cs
+System.Reflection/AssemblyCas.cs
+System.Reflection/AssemblyNameCas.cs
+System.Reflection.Emit/MethodRentalCas.cs
+System.Reflection/ModuleCas.cs
+System.Reflection/StrongNameKeyPairCas.cs
+System.Reflection/VisibilityTest.cs
+System.Resources/ResourceReaderCas.cs
+System.Resources/ResourceSetCas.cs
+System.Runtime.CompilerServices/RuntimeWrappedExceptionCas.cs
+System.Runtime.InteropServices/RuntimeEnvironmentCas.cs
+System/RuntimeMethodHandleCas.cs
+System.Runtime.Serialization.Formatters.Binary/BinaryFormatterCas.cs
+System.Runtime.Versioning/ResourceConsumptionAttributeCas.cs
+System.Runtime.Versioning/ResourceExposureAttributeCas.cs
+System.Runtime.Versioning/VersioningHelperCas.cs
+System.Security.AccessControl/DirectorySecurityTest.cs
+System.Security.AccessControl/EventWaitHandleSecurityTest.cs
+System.Security.AccessControl/FileSecurityTest.cs
+System.Security/CodeAccessPermissionCas.cs
+System.Security.Cryptography/CryptoAPITransformCas.cs
+System.Security.Cryptography/CryptoConfigCas.cs
+System.Security.Cryptography.X509Certificates/X509CertificateCas.cs
+System.Security/PermissionSetCas.cs
+System.Security.Policy/ApplicationSecurityManagerCas.cs
+System.Security/SecureStringCas.cs
+System.Security/SecurityContextCas.cs
+System.Security/SecurityExceptionCas.cs
+System.Security/SecurityManagerCas.cs
+System.Threading/CompressedStackCas.cs
+System.Threading/ExecutionContextCas.cs
+System.Threading/MutexCas.cs
+System.Threading/ThreadCas.cs
+System.Threading/WaitHandleCas.cs
+System/TypedReferenceCas.cs
--- /dev/null
+System/DateTimeOffsetTestCoreFx.cs
+System.Diagnostics.Contracts/ContractAssertTest.cs
+System.Diagnostics.Contracts/ContractCollectionMethodsTest.cs
+System.Diagnostics.Contracts/ContractHelperTest.cs
+System.Diagnostics.Contracts/ContractMustUseRewriterTest.cs
+System.IO/DirectoryTest.cs
+System.Reflection.Emit/MethodBuilderTestIL.cs
+System.Security.AccessControl/AuthorizationRuleTest.cs
+System.Security.AccessControl/CommonAceTest.cs
+System.Security.AccessControl/CommonAclTest.cs
+System.Security.AccessControl/CommonObjectSecurityTest.cs
+System.Security.AccessControl/CommonSecurityDescriptorTest.cs
+System.Security.AccessControl/CryptoKeyAccessRuleTest.cs
+System.Security.AccessControl/DirectoryObjectSecurityTest.cs
+System.Security.AccessControl/DiscretionaryAclTest.cs
+System.Security.AccessControl/MutexAccessRuleTest.cs
+System.Security.AccessControl/MutexSecurityTest.cs
+System.Security.AccessControl/ObjectAceTest.cs
+System.Security.AccessControl/ObjectSecurityTest.cs
+System.Security.AccessControl/ObjectSecurity_TTest.cs
+System.Security.AccessControl/RawAclTest.cs
+System.Security.AccessControl/RawSecurityDescriptorTest.cs
+System.Security.AccessControl/RegistrySecurityTest.cs
+System.Security.AccessControl/SystemAclTest.cs
+System.Security.Claims/ClaimsIdentityTest.cs
+System.Security.Claims/ClaimsPrincipalTest.cs
+System.Security/CodeAccessPermissionTest.cs
+System/TimeZoneTest.cs
--- /dev/null
+#include corlib_test.dll.sources
</PreBuildEvent>\r
<PreBuildEvent Condition=" '$(OS)' == 'Windows_NT' ">\r
-$(ProjectDir)\..\..\jay\jay -ct < $(ProjectDir)\..\..\jay\skeleton.cs $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.jay > $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.cs\r
-\r
+$(ProjectDir)\..\..\jay\jay -ct < $(ProjectDir)\..\..\jay\skeleton.cs $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.jay > $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.cs
+
\r
</PreBuildEvent>\r
<PostBuildEvent Condition=" '$(OS)' != 'Windows_NT' ">
else if(!resourceAssembly.IsDynamic) { // EscapedCodeBase won't be supported by emitted assemblies anyway
Debug.WriteLineIf(RuntimeLicenseContextSwitch.TraceVerbose,"resourceAssembly is not null");
string fileName;
+#if !DISABLE_CAS_USE
FileIOPermission perm = new FileIOPermission(PermissionState.Unrestricted);
perm.Assert();
+#endif
try
{
fileName = GetLocalPath(resourceAssembly.EscapedCodeBase);
}
finally
{
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert();
+#endif
}
fileName = Path.GetFileName(fileName); // we don't want to use FileInfo here... it requests FileIOPermission that we
// might now have... see VSWhidbey 527758
get {
//This check will not allow to use local user credentials at will.
//Hence the username will not be exposed to the network
+#if !DISABLE_CAS_USE
new EnvironmentPermission(EnvironmentPermissionAccess.Read, "USERNAME").Demand();
+#endif
return SystemNetworkCredential.defaultCredential;
}
}
get {
//This check will not allow to use local user credentials at will.
//Hence the username will not be exposed to the network
+#if !DISABLE_CAS_USE
new EnvironmentPermission(EnvironmentPermissionAccess.Read, "USERNAME").Demand();
+#endif
return SystemNetworkCredential.defaultCredential;
}
}
private static void DemandCallback(object state)
{
+#if !DISABLE_CAS_USE
((CodeAccessPermission) state).Demand();
+#endif
}
// This is for checking if a hostname probably refers to this machine without going to DNS.
{
/// Returns objects that describe the network interfaces on the local computer.
public static NetworkInterface[] GetAllNetworkInterfaces(){
+#if !DISABLE_CAS_USE
(new NetworkInformationPermission(NetworkInformationAccess.Read)).Demand();
+#endif
return SystemNetworkInterface.GetNetworkInterfaces();
}
return m_BindIPEndPointDelegate;
}
set {
+#if !DISABLE_CAS_USE
ExceptionHelper.InfrastructurePermission.Demand();
+#endif
m_BindIPEndPointDelegate = value;
}
}
throw new NotSupportedException(SR.GetString(SR.net_servicePointAddressNotSupportedInHostMode));
}
+#if !DISABLE_CAS_USE
// Don't let low-trust apps discover the proxy information.
if (m_ProxyServicePoint)
{
ExceptionHelper.WebPermissionUnrestricted.Demand();
}
+#endif
return m_Address;
}
{
internal Semaphore(int initialCount, int maxCount) : base() {
lock (this) {
+#if MONO
+ int errorCode;
+ Handle = System.Threading.Semaphore.CreateSemaphore_internal(initialCount, maxCount, null, out errorCode);
+#else
//
Handle = UnsafeNclNativeMethods.CreateSemaphore(IntPtr.Zero, initialCount, maxCount, IntPtr.Zero);
+#endif
}
}
*/
internal bool ReleaseSemaphore() {
-#if DEBUG
+#if MONO
+ int previousCount;
+ return System.Threading.Semaphore.ReleaseSemaphore_internal (Handle, 1, out previousCount);
+#else
+#if DEBUG
int previousCount;
bool success = UnsafeNclNativeMethods.ReleaseSemaphore(Handle, 1, out previousCount);
GlobalLog.Print("ReleaseSemaphore#"+ValidationHelper.HashString(this)+" success:"+success+" previousCount:"+previousCount.ToString());
return success;
#else
return UnsafeNclNativeMethods.ReleaseSemaphore(Handle, 1, IntPtr.Zero);
-#endif
+#endif
+#endif
}
/*
#endif
}
finally {
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert();
+#endif
}
}
factory = c.FactoryInstanceFromCode(code, options);
}
finally {
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert();
+#endif
}
return factory;
}
c.GenerateRegexType(pattern, options, fullname, regexes[i].IsPublic, code, tree, factory, mTimeout);
}
finally {
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert();
+#endif
}
}
}
}
finally {
+#if !DISABLE_CAS_USE
CodeAccessPermission.RevertAssert();
+#endif
}
}
#endif
internal static String GetMessage(int errorCode)
{
+#if !MONO
StringBuilder sb = new StringBuilder(512);
int result = SafeNativeMethods.FormatMessage(NativeMethods.FORMAT_MESSAGE_IGNORE_INSERTS |
NativeMethods.FORMAT_MESSAGE_FROM_SYSTEM | NativeMethods.FORMAT_MESSAGE_ARGUMENT_ARRAY,
return s;
}
else
+#endif
{
return SR.GetString(SR.IO_UnknownError, errorCode);
}
+#if MONO
+#undef FEATURE_PAL
+#endif
// ==++==
//
// Copyright (c) Microsoft Corporation. All rights reserved.
#endif
using System.Runtime.Versioning;
using System.Runtime.ConstrainedExecution;
+ using System.Runtime.CompilerServices;
[HostProtection(Synchronization=true, ExternalThreading=true)]
{
throw new ArgumentException(SR.GetString(SR.Argument_WaitHandleNameTooLong));
}
+
+#if MONO
+ int errorCode;
+ var myHandle = new SafeWaitHandle (CreateSemaphore_internal (initialCount, maximumCount, name, out errorCode), true);
+#else
SafeWaitHandle myHandle = SafeNativeMethods.CreateSemaphore(null, initialCount, maximumCount, name);
+#endif
if (myHandle.IsInvalid)
{
+#if !MONO
int errorCode = Marshal.GetLastWin32Error();
+#endif
if(null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
throw new WaitHandleCannotBeOpenedException(SR.GetString(SR.WaitHandleCannotBeOpenedException_InvalidHandle,name));
throw new ArgumentException(SR.GetString(SR.Argument_WaitHandleNameTooLong));
}
SafeWaitHandle myHandle;
+
+#if MONO
+ int errorCode;
+ myHandle = new SafeWaitHandle (CreateSemaphore_internal (initialCount, maximumCount, name, out errorCode), true);
+#else
#if !FEATURE_PAL && !FEATURE_NETCORE
// For ACL's, get the security descriptor from the SemaphoreSecurity.
if (semaphoreSecurity != null) {
#if !FEATURE_PAL && !FEATURE_NETCORE
}
#endif
+
int errorCode = Marshal.GetLastWin32Error();
+#endif
if (myHandle.IsInvalid)
{
if(null != name && 0 != name.Length && NativeMethods.ERROR_INVALID_HANDLE == errorCode)
}
result = null;
+#if MOBILE
+ throw new NotSupportedException ();
+#else
+#if MONO
+ int errorCode;
+ var myHandle = new SafeWaitHandle (OpenSemaphore_internal (name, rights, out errorCode), true);
+#else
//Pass false to OpenSemaphore to prevent inheritedHandles
#if FEATURE_PAL || FEATURE_NETCORE
const int SYNCHRONIZE = 0x00100000;
SafeWaitHandle myHandle = SafeNativeMethods.OpenSemaphore(SEMAPHORE_MODIFY_STATE | SYNCHRONIZE, false, name);
#else
SafeWaitHandle myHandle = SafeNativeMethods.OpenSemaphore((int) rights, false, name);
+#endif
#endif
if (myHandle.IsInvalid)
{
+#if !MONO
int errorCode = Marshal.GetLastWin32Error();
+#endif
if (NativeMethods.ERROR_FILE_NOT_FOUND == errorCode || NativeMethods.ERROR_INVALID_NAME == errorCode)
return OpenExistingResult.NameNotFound;
}
result = new Semaphore(myHandle);
return OpenExistingResult.Success;
+#endif
}
// the semaphore's count to exceed the maximum count set when Semaphore was created
//Non-Zero return
+#if MONO
+ if (!ReleaseSemaphore_internal(Handle, releaseCount, out previousCount))
+#else
if (!SafeNativeMethods.ReleaseSemaphore(SafeWaitHandle, releaseCount, out previousCount))
+#endif
{
throw new SemaphoreFullException();
}
semaphoreSecurity.Persist(SafeWaitHandle);
}
#endif
+
+#if MONO
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern IntPtr CreateSemaphore_internal (
+ int initialCount, int maximumCount, string name, out int errorCode);
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ internal static extern bool ReleaseSemaphore_internal (
+ IntPtr handle, int releaseCount, out int previousCount);
+
+ [MethodImplAttribute (MethodImplOptions.InternalCall)]
+ private static extern IntPtr OpenSemaphore_internal (string name, SemaphoreRights rights, out int errorCode);
+#endif
}
}
[System.Security.SecurityCritical] // auto-generated
internal virtual String InternalToString()
{
+#if !DISABLE_CAS_USE
try
{
#pragma warning disable 618
//under normal conditions there should be no exceptions
//however if something wrong happens we still can call the usual ToString
}
+#endif
// Get the current stack trace string. On CoreCLR we don't bother
// to try and include file/line-number information because all AppDomains
var ifaces = PartialContainer.Interfaces;
if (ifaces != null) {
foreach (TypeSpec t in ifaces){
- if (t == mb.InterfaceType)
+ if (t == mb.InterfaceType || t == null)
return true;
var expanded_base = t.Interfaces;
int TokenizePragmaWarningIdentifier (ref int c, ref bool identifier)
{
-
if ((c >= '0' && c <= '9') || is_identifier_start_character (c)) {
int number;
while (c == ' ' || c == '\t')
c = get_char ();
+ if (c == '\n' || c == UnicodeLS || c == UnicodePS)
+ advance_line ();
+
return number;
}
this.importer = importer;
domain = new Universe (UniverseOptions.MetadataOnly | UniverseOptions.ResolveMissingMembers |
UniverseOptions.DisableFusion | UniverseOptions.DecodeVersionInfoAttributeBlobs |
- UniverseOptions.DeterministicOutput);
+ UniverseOptions.DeterministicOutput | UniverseOptions.DisableDefaultAssembliesLookup);
domain.AssemblyResolve += AssemblyReferenceResolver;
loaded_names = new List<Tuple<AssemblyName, string, Assembly>> ();
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<symbols>
+ <files>
+ <file id="1" name="test-debug-30.cs" checksum="d3addfa69f16faf00991ef839451a975" />
+ </files>
+ <methods>
+ <method token="0x6000001">
+ <sequencepoints />
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000002">
+ <sequencepoints>
+ <entry il="0x0" row="7" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="8" col="3" file_ref="1" hidden="false" />
+ <entry il="0x6" row="9" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
+ <method token="0x6000003">
+ <sequencepoints>
+ <entry il="0x0" row="15" col="2" file_ref="1" hidden="false" />
+ <entry il="0x1" row="16" col="3" file_ref="1" hidden="false" />
+ <entry il="0x6" row="17" col="2" file_ref="1" hidden="false" />
+ </sequencepoints>
+ <locals />
+ <scopes />
+ </method>
+ </methods>
+</symbols>
\ No newline at end of file
--- /dev/null
+class PragmaNewLinesParsing
+{
+#pragma warning disable RECS0029
+#pragma warning restore RECS0029
+
+ void Foo ()
+ {
+ return;
+ }
+
+#pragma warning disable RECS0029 // here
+#pragma warning restore RECS0029 /* end */
+
+ public static void Main ()
+ {
+ return;
+ }
+}
\ No newline at end of file
</method>
</type>
</test>
+ <test name="test-debug-30.cs">
+ <type name="PragmaNewLinesParsing">
+ <method name="Void Foo()" attrs="129">
+ <size>7</size>
+ </method>
+ <method name="Void Main()" attrs="150">
+ <size>7</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-decl-expr-01.cs">
<type name="DeclarationExpression">
<method name="Int32 Main()" attrs="150">
if (res != 0)
return res;
+ if (ma.HasGenericParameters != mb.HasGenericParameters)
+ return ma.HasGenericParameters ? -1 : 1;
+
+ if (ma.HasGenericParameters && mb.HasGenericParameters) {
+ res = ma.GenericParameters.Count - mb.GenericParameters.Count;
+ if (res != 0)
+ return res;
+ }
+
// operators can differ by only return type
return string.CompareOrdinal (ma.ReturnType.FullName, mb.ReturnType.FullName);
}
<opcode name="mono_ldptr_nursery_bits" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x17" flow="next" />
<opcode name="mono_calli_extra_arg" input="VarPop" output="VarPush" args="InlineSig" o1="0xF0" o2="0x18" flow="call" />
<opcode name="mono_lddomain" input="Pop0" output="PushI" args="InlineNone" o1="0xF0" o2="0x19" flow="next" />
+<opcode name="mono_atomic_store_i4" input="PopI+PopI" output="Push0" args="InlineI" o1="0xF0" o2="0x1A" flow="next" />
</opdesc>
OPDEF(CEE_MONO_LDPTR_NURSERY_BITS, "mono_ldptr_nursery_bits", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x17, NEXT)
OPDEF(CEE_MONO_CALLI_EXTRA_ARG, "mono_calli_extra_arg", VarPop, VarPush, InlineSig, X, 2, 0xF0, 0x18, CALL)
OPDEF(CEE_MONO_LDDOMAIN, "mono_lddomain", Pop0, PushI, InlineNone, X, 2, 0xF0, 0x19, NEXT)
+OPDEF(CEE_MONO_ATOMIC_STORE_I4, "mono_atomic_store_i4", PopI+PopI, Push0, InlineI, X, 2, 0xF0, 0x1A, NEXT)
#ifndef OPALIAS
#define _MONO_CIL_OPALIAS_DEFINED_
#define OPALIAS(a,s,r)
endif
if SHARED_MONO
-if SUPPORT_BOEHM
+if SUPPORT_SGEN
bin_PROGRAMS = pedump
endif
endif
PEDUMP_DTRACE_OBJECT = pedump-dtrace.$(OBJEXT)
-pedump-dtrace.$(OBJEXT): $(top_srcdir)/data/mono.d libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la
+pedump-dtrace.$(OBJEXT): $(top_srcdir)/data/mono.d $(shared_sgen_libraries) ../io-layer/libwapi.la ../utils/libmonoutils.la
DTRACE="$(DTRACE)" DTRACEFLAGS="$(DTRACEFLAGS)" AR="$(AR)" $(SHELL) $(top_srcdir)/data/dtrace-prelink.sh \
- --pic pedump-dtrace.$(OBJEXT) $(top_srcdir)/data/mono.d libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la
+ --pic pedump-dtrace.$(OBJEXT) $(top_srcdir)/data/mono.d $(shared_sgen_libraries) ../io-layer/libwapi.la ../utils/libmonoutils.la
else
PEDUMP_DTRACE_OBJECT =
endif
if SHARED_MONO
-if SUPPORT_BOEHM
pedump_SOURCES = \
pedump.c
-pedump_LDADD = libmonoruntime.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
- $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV) $(PEDUMP_DTRACE_OBJECT)
+$(top_srcdir)/mono/sgen/libmonosgen.la:
+ make -w -C $(top_srcdir)/mono/sgen libmonosgen.la
+
+pedump_LDADD = $(sgen_libraries) $(top_srcdir)/mono/sgen/libmonosgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+ $(GLIB_LIBS) -lm $(LIBICONV) $(PEDUMP_DTRACE_OBJECT)
if PLATFORM_DARWIN
pedump_LDFLAGS=-framework CoreFoundation -framework Foundation
endif
endif
-endif
EXTRA_DIST = $(win32_sources) $(unix_sources) $(null_sources) runtime.h \
threadpool-ms-io-poll.c threadpool-ms-io-epoll.c threadpool-ms-io-kqueue.c
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 148
+#define MONO_CORLIB_VERSION 149
typedef struct
{
return NULL;
if (!SMALL_ENOUGH (klass->instance_size))
return NULL;
- if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+ if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass))
+ return NULL;
+ if (mono_profiler_get_events () & (MONO_PROFILE_ALLOCATIONS | MONO_PROFILE_STATISTICAL))
return NULL;
if (klass->rank)
return NULL;
atype = ATYPE_NORMAL;
*/
}
- return mono_gc_get_managed_allocator_by_type (atype, FALSE);
+ return mono_gc_get_managed_allocator_by_type (atype, MANAGED_ALLOCATOR_REGULAR);
}
MonoMethod*
* Return a managed allocator method corresponding to allocator type ATYPE.
*/
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
int offset = -1;
MonoMethod *res;
+ gboolean slowpath = variant != MANAGED_ALLOCATOR_REGULAR;
MonoMethod **cache = slowpath ? slowpath_alloc_method_cache : alloc_method_cache;
MONO_THREAD_VAR_OFFSET (GC_thread_tls, offset);
}
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
return NULL;
}
struct stat buf;
gint64 res;
char *path = mono_string_to_utf8_checked (string, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
MONO_ENTER_GC_SAFE;
if (stat (path, &buf) == -1)
MonoString *destinationBackupFileName, MonoBoolean ignoreMetadataErrors,
gint32 *error);
+MONO_RT_EXTERNAL_ONLY
extern gint64
mono_filesize_from_path (MonoString *path);
/* fast allocation support */
+typedef enum {
+ // Regular fast path allocator.
+ MANAGED_ALLOCATOR_REGULAR,
+ // Managed allocator that just calls into the runtime. Used when allocation profiling w/ AOT.
+ MANAGED_ALLOCATOR_SLOW_PATH,
+} ManagedAllocatorVariant;
+
int mono_gc_get_aligned_size_for_allocator (int size);
MonoMethod* mono_gc_get_managed_allocator (MonoClass *klass, gboolean for_box, gboolean known_instance_size);
MonoMethod* mono_gc_get_managed_array_allocator (MonoClass *klass);
-MonoMethod *mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath);
+MonoMethod *mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant);
guint32 mono_gc_get_managed_allocator_types (void);
#include <mono/utils/mono-time.h>
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-coop-semaphore.h>
#include <mono/utils/hazard-pointer.h>
ICALL(NATIVEC_5, "SetEvent_internal", ves_icall_System_Threading_Events_SetEvent_internal)
ICALL_TYPE(SEMA, "System.Threading.Semaphore", SEMA_1)
-ICALL(SEMA_1, "CreateSemaphore_internal(int,int,string,bool&)", ves_icall_System_Threading_Semaphore_CreateSemaphore_internal)
-ICALL(SEMA_2, "OpenSemaphore_internal(string,System.Security.AccessControl.SemaphoreRights,System.IO.MonoIOError&)", ves_icall_System_Threading_Semaphore_OpenSemaphore_internal)
-ICALL(SEMA_3, "ReleaseSemaphore_internal(intptr,int,bool&)", ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal)
+ICALL(SEMA_1, "CreateSemaphore_internal(int,int,string,int&)", ves_icall_System_Threading_Semaphore_CreateSemaphore_internal)
+ICALL(SEMA_2, "OpenSemaphore_internal(string,System.Security.AccessControl.SemaphoreRights,int&)", ves_icall_System_Threading_Semaphore_OpenSemaphore_internal)
+ICALL(SEMA_3, "ReleaseSemaphore_internal(intptr,int,int&)", ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal)
ICALL_TYPE(THREAD, "System.Threading.Thread", THREAD_1)
ICALL(THREAD_1, "Abort_internal(System.Threading.InternalThread,object)", ves_icall_System_Threading_Thread_Abort)
image->image_info = iinfo;
image->ref_only = refonly;
image->metadata_only = metadata_only;
+ image->ref_count = 1;
image = do_mono_image_load (image, status, TRUE, TRUE);
if (image == NULL)
#include "mono/utils/mono-memory-model.h"
#include "mono/utils/atomic.h"
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/mono-error-internals.h>
#include <string.h>
MonoClass *klass;
int i, argnum, *tmp_locals;
int type, param_shift = 0;
- static MonoMethodSignature *get_last_error_sig = NULL;
int coop_gc_stack_dummy, coop_gc_var;
memset (&m, 0, sizeof (m));
}
}
- if (MONO_TYPE_ISSTRUCT (sig->ret)) {
- MonoClass *klass = mono_class_from_mono_type (sig->ret);
- mono_class_init (klass);
- if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
- /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
- mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
- mono_mb_emit_stloc (mb, m.vtaddr_var);
- }
- }
-
- /* Unblock before converting the result, since that can involve calls into the runtime */
- if (mono_threads_is_coop_enabled ()) {
- mono_mb_emit_ldloc (mb, coop_gc_var);
- mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
- mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
- }
-
/* Set LastError if needed */
if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) {
+#ifdef TARGET_WIN32
+ static MonoMethodSignature *get_last_error_sig = NULL;
if (!get_last_error_sig) {
get_last_error_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
get_last_error_sig->ret = &mono_defaults.int_class->byval_arg;
get_last_error_sig->pinvoke = 1;
}
-#ifdef TARGET_WIN32
/*
* Have to call GetLastError () early and without a wrapper, since various runtime components could
* clobber its value.
#endif
}
+ if (MONO_TYPE_ISSTRUCT (sig->ret)) {
+ MonoClass *klass = mono_class_from_mono_type (sig->ret);
+ mono_class_init (klass);
+ if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+ /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
+ mono_mb_emit_stloc (mb, m.vtaddr_var);
+ }
+ }
+
+ /* Unblock before converting the result, since that can involve calls into the runtime */
+ if (mono_threads_is_coop_enabled ()) {
+ mono_mb_emit_ldloc (mb, coop_gc_var);
+ mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
+ mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
+ }
+
/* convert the result */
if (!sig->ret->byref) {
MonoMarshalSpec *spec = mspecs [0];
#include "mono-hash.h"
#include "metadata/gc-internals.h"
#include <mono/utils/checked-build.h>
+#include <mono/utils/mono-threads-coop.h>
#ifdef HAVE_BOEHM_GC
#define mg_new0(type,n) ((type *) GC_MALLOC(sizeof(type) * (n)))
}
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
return NULL;
}
MonoObject*
mono_property_get_value_checked (MonoProperty *prop, void *obj, void **params, MonoError *error);
+MonoString*
+mono_object_to_string_checked (MonoObject *obj, MonoError *error);
+
+MonoString*
+mono_object_try_to_string (MonoObject *obj, MonoObject **exc, MonoError *error);
+
char *
mono_string_to_utf8_ignore (MonoString *s);
DECL_OFFSET(MonoThreadsSync, status)
DECL_OFFSET(MonoThreadsSync, nest)
-#if defined (HAVE_SGEN_GC) && !defined (HAVE_KW_THREAD)
+#ifdef HAVE_SGEN_GC
+DECL_OFFSET(SgenClientThreadInfo, in_critical_region)
+#ifndef HAVE_KW_THREAD
DECL_OFFSET(SgenThreadInfo, tlab_next_addr)
DECL_OFFSET(SgenThreadInfo, tlab_temp_end)
#endif
+#endif
#endif //DISABLE METADATA OFFSETS
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/checked-build.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include "cominterop.h"
static void
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_start_invoke (method);
- MONO_ENTER_GC_UNSAFE;
-
result = callbacks.runtime_invoke (method, obj, params, exc, error);
- MONO_EXIT_GC_UNSAFE;
-
if (mono_profiler_get_events () & MONO_PROFILE_METHOD_EVENTS)
mono_profiler_method_end_invoke (method);
mono_error_cleanup (&error);
} else {
res = mono_runtime_invoke_checked (method, obj, params, &error);
- mono_error_raise_exception (&error);
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
}
return res;
}
}
} else {
MonoObject *result = mono_runtime_delegate_invoke_checked (delegate, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
return result;
}
}
}
/**
- * mono_object_to_string:
+ * prepare_to_string_method:
* @obj: The object
- * @exc: Any exception thrown by ToString (). May be NULL.
+ * @target: Set to @obj or unboxed value if a valuetype
*
- * Returns: the result of calling ToString () on an object.
+ * Returns: the ToString override for @obj. If @obj is a valuetype, @target is unboxed otherwise it's @obj.
*/
-MonoString *
-mono_object_to_string (MonoObject *obj, MonoObject **exc)
+static MonoMethod *
+prepare_to_string_method (MonoObject *obj, void **target)
{
MONO_REQ_GC_UNSAFE_MODE;
static MonoMethod *to_string = NULL;
- MonoError error;
MonoMethod *method;
- MonoString *s;
- void *target = obj;
-
+ g_assert (target);
g_assert (obj);
+ *target = obj;
+
if (!to_string)
to_string = mono_class_get_method_from_name_flags (mono_get_object_class (), "ToString", 0, METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_PUBLIC);
// Unbox value type if needed
if (mono_class_is_valuetype (mono_method_get_class (method))) {
- target = mono_object_unbox (obj);
+ *target = mono_object_unbox (obj);
}
+ return method;
+}
+/**
+ * mono_object_to_string:
+ * @obj: The object
+ * @exc: Any exception thrown by ToString (). May be NULL.
+ *
+ * Returns: the result of calling ToString () on an object.
+ */
+MonoString *
+mono_object_to_string (MonoObject *obj, MonoObject **exc)
+{
+ MonoError error;
+ MonoString *s = NULL;
+ void *target;
+ MonoMethod *method = prepare_to_string_method (obj, &target);
if (exc) {
s = (MonoString *) mono_runtime_try_invoke (method, target, NULL, exc, &error);
if (*exc == NULL && !mono_error_ok (&error))
mono_error_cleanup (&error);
} else {
s = (MonoString *) mono_runtime_invoke_checked (method, target, NULL, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
}
return s;
}
+/**
+ * mono_object_to_string_checked:
+ * @obj: The object
+ * @error: Set on error.
+ *
+ * Returns: the result of calling ToString () on an object. If the
+ * method cannot be invoked or if it raises an exception, sets @error
+ * and returns NULL.
+ */
+MonoString *
+mono_object_to_string_checked (MonoObject *obj, MonoError *error)
+{
+ mono_error_init (error);
+ void *target;
+ MonoMethod *method = prepare_to_string_method (obj, &target);
+ return (MonoString*) mono_runtime_invoke_checked (method, target, NULL, error);
+}
+
+/**
+ * mono_object_try_to_string:
+ * @obj: The object
+ * @exc: Any exception thrown by ToString (). Must not be NULL.
+ * @error: Set if method cannot be invoked.
+ *
+ * Returns: the result of calling ToString () on an object. If the
+ * method cannot be invoked sets @error, if it raises an exception sets @exc,
+ * and returns NULL.
+ */
+MonoString *
+mono_object_try_to_string (MonoObject *obj, MonoObject **exc, MonoError *error)
+{
+ g_assert (exc);
+ mono_error_init (error);
+ void *target;
+ MonoMethod *method = prepare_to_string_method (obj, &target);
+ return (MonoString*) mono_runtime_try_invoke (method, target, NULL, exc, error);
+}
+
+
+
/**
* mono_print_unhandled_exception:
* @exc: The exception
free_message = TRUE;
} else {
MonoObject *other_exc = NULL;
- str = mono_object_to_string (exc, &other_exc);
+ str = mono_object_try_to_string (exc, &other_exc, &error);
+ if (other_exc == NULL && !is_ok (&error))
+ other_exc = (MonoObject*)mono_error_convert_to_exception (&error);
+ else
+ mono_error_cleanup (&error);
if (other_exc) {
char *original_backtrace = mono_exception_get_managed_backtrace ((MonoException*)exc);
char *nested_backtrace = mono_exception_get_managed_backtrace ((MonoException*)other_exc);
MONO_API int
mono_object_hash (MonoObject* obj);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc);
* is_running_protected_wrapper () in threads.c and
* mono_marshal_get_remoting_invoke () in remoting.c)
*/
- mono_error_raise_exception (&error);
+ mono_error_raise_exception (&error); /* OK to throw, see note */
return NULL;
}
*/
#define EXIT_CRITICAL_REGION do { mono_atomic_store_release (&IN_CRITICAL_REGION, 0); } while (0)
+#ifndef DISABLE_CRITICAL_REGION
+/*
+ * We can only use a critical region in the managed allocator if the JIT supports OP_ATOMIC_STORE_I4.
+ *
+ * TODO: Query the JIT instead of this ifdef hack.
+ */
+#if defined (TARGET_X86) || defined (TARGET_AMD64) || (defined (TARGET_ARM) && defined (HAVE_ARMV7)) || defined (TARGET_ARM64)
+#define MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
+#endif
+#endif
+
#define SGEN_TV_DECLARE(name) gint64 name
#define SGEN_TV_GETTIME(tv) tv = mono_100ns_ticks ()
#define SGEN_TV_ELAPSED(start,end) ((gint64)(end-start))
#include "metadata/handle.h"
#include "utils/mono-memory-model.h"
#include "utils/mono-logger-internals.h"
+#include "utils/mono-threads-coop.h"
#include "sgen/sgen-thread-pool.h"
#ifdef HEAVY_STATISTICS
#ifdef HAVE_KW_THREAD
-#define EMIT_TLS_ACCESS_NEXT_ADDR(mb) do { \
+#define EMIT_TLS_ACCESS_VAR(_mb, _var) /* nothing to do */
+
+#define EMIT_TLS_ACCESS_IN_CRITICAL_REGION_ADDR(mb, _var) \
+ do { \
+ mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
+ mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
+ mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_IN_CRITICAL_REGION_ADDR); \
+ } while (0)
+
+#define EMIT_TLS_ACCESS_NEXT_ADDR(mb, _var) do { \
mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_TLAB_NEXT_ADDR); \
} while (0)
-#define EMIT_TLS_ACCESS_TEMP_END(mb) do { \
+#define EMIT_TLS_ACCESS_TEMP_END(mb, _var) do { \
mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_TLAB_TEMP_END); \
#else
#if defined(TARGET_OSX) || defined(TARGET_WIN32) || defined(TARGET_ANDROID) || defined(TARGET_IOS)
-#define EMIT_TLS_ACCESS_NEXT_ADDR(mb) do { \
- mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
- mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
- mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_THREAD_INFO); \
+
+// Cache the SgenThreadInfo pointer in a local 'var'.
+#define EMIT_TLS_ACCESS_VAR(mb, var) \
+ do { \
+ var = mono_mb_add_local ((mb), &mono_defaults.int_class->byval_arg); \
+ mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
+ mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
+ mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_THREAD_INFO); \
+ mono_mb_emit_stloc ((mb), (var)); \
+ } while (0)
+
+#define EMIT_TLS_ACCESS_IN_CRITICAL_REGION_ADDR(mb, var) \
+ do { \
+ mono_mb_emit_ldloc ((mb), (var)); \
+ mono_mb_emit_icon ((mb), MONO_STRUCT_OFFSET (SgenClientThreadInfo, in_critical_region)); \
+ mono_mb_emit_byte ((mb), CEE_ADD); \
+ } while (0)
+
+#define EMIT_TLS_ACCESS_NEXT_ADDR(mb, var) do { \
+ mono_mb_emit_ldloc ((mb), (var)); \
mono_mb_emit_icon ((mb), MONO_STRUCT_OFFSET (SgenThreadInfo, tlab_next_addr)); \
mono_mb_emit_byte ((mb), CEE_ADD); \
mono_mb_emit_byte ((mb), CEE_LDIND_I); \
} while (0)
-#define EMIT_TLS_ACCESS_TEMP_END(mb) do { \
- mono_mb_emit_byte ((mb), MONO_CUSTOM_PREFIX); \
- mono_mb_emit_byte ((mb), CEE_MONO_TLS); \
- mono_mb_emit_i4 ((mb), TLS_KEY_SGEN_THREAD_INFO); \
+#define EMIT_TLS_ACCESS_TEMP_END(mb, var) do { \
+ mono_mb_emit_ldloc ((mb), (var)); \
mono_mb_emit_icon ((mb), MONO_STRUCT_OFFSET (SgenThreadInfo, tlab_temp_end)); \
mono_mb_emit_byte ((mb), CEE_ADD); \
mono_mb_emit_byte ((mb), CEE_LDIND_I); \
} while (0)
#else
-#define EMIT_TLS_ACCESS_NEXT_ADDR(mb) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
-#define EMIT_TLS_ACCESS_TEMP_END(mb) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
+#define EMIT_TLS_ACCESS_VAR(mb, _var) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
+#define EMIT_TLS_ACCESS_NEXT_ADDR(mb, _var) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
+#define EMIT_TLS_ACCESS_TEMP_END(mb, _var) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
+#define EMIT_TLS_ACCESS_IN_CRITICAL_REGION_ADDR(mb, _var) do { g_error ("sgen is not supported when using --with-tls=pthread.\n"); } while (0)
#endif
#endif
* that they are executed atomically via the restart mechanism.
*/
static MonoMethod*
-create_allocator (int atype, gboolean slowpath)
+create_allocator (int atype, ManagedAllocatorVariant variant)
{
- int p_var, size_var;
+ int p_var, size_var, thread_var G_GNUC_UNUSED;
+ gboolean slowpath = variant == MANAGED_ALLOCATOR_SLOW_PATH;
guint32 slowpath_branch, max_size_branch;
MonoMethodBuilder *mb;
MonoMethod *res;
goto done;
}
+ EMIT_TLS_ACCESS_VAR (mb, thread_var);
+
+#ifdef MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
+ EMIT_TLS_ACCESS_IN_CRITICAL_REGION_ADDR (mb, thread_var);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_1);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_ATOMIC_STORE_I4);
+ mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_NONE);
+#endif
+
size_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
if (atype == ATYPE_SMALL) {
/* size_var = size_arg */
/* tlab_next_addr (local) = tlab_next_addr (TLS var) */
tlab_next_addr_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
- EMIT_TLS_ACCESS_NEXT_ADDR (mb);
+ EMIT_TLS_ACCESS_NEXT_ADDR (mb, thread_var);
mono_mb_emit_stloc (mb, tlab_next_addr_var);
/* p = (void**)tlab_next; */
/* if (G_LIKELY (new_next < tlab_temp_end)) */
mono_mb_emit_ldloc (mb, new_next_var);
- EMIT_TLS_ACCESS_TEMP_END (mb);
+ EMIT_TLS_ACCESS_TEMP_END (mb, thread_var);
slowpath_branch = mono_mb_emit_short_branch (mb, MONO_CEE_BLT_UN_S);
/* Slowpath */
mono_mb_emit_byte (mb, MONO_CEE_STIND_I4);
}
+#ifdef MANAGED_ALLOCATOR_CAN_USE_CRITICAL_REGION
+ EMIT_TLS_ACCESS_IN_CRITICAL_REGION_ADDR (mb, thread_var);
+ mono_mb_emit_byte (mb, CEE_LDC_I4_0);
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_ATOMIC_STORE_I4);
+#else
+ mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+ mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
+#endif
/*
We must make sure both vtable and max_length are globaly visible before returning to managed land.
*/
- mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
- mono_mb_emit_byte (mb, CEE_MONO_MEMORY_BARRIER);
mono_mb_emit_i4 (mb, MONO_MEMORY_BARRIER_REL);
/* return p */
return NULL;
if (known_instance_size && ALIGN_TO (klass->instance_size, SGEN_ALLOC_ALIGN) >= SGEN_MAX_SMALL_OBJ_SIZE)
return NULL;
- if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
+ if (mono_class_has_finalizer (klass) || mono_class_is_marshalbyref (klass))
return NULL;
if (klass->rank)
return NULL;
+ if (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS)
+ return NULL;
if (klass->byval_arg.type == MONO_TYPE_STRING)
- return mono_gc_get_managed_allocator_by_type (ATYPE_STRING, FALSE);
+ return mono_gc_get_managed_allocator_by_type (ATYPE_STRING, MANAGED_ALLOCATOR_REGULAR);
/* Generic classes have dynamic field and can go above MAX_SMALL_OBJ_SIZE. */
if (known_instance_size)
- return mono_gc_get_managed_allocator_by_type (ATYPE_SMALL, FALSE);
+ return mono_gc_get_managed_allocator_by_type (ATYPE_SMALL, MANAGED_ALLOCATOR_REGULAR);
else
- return mono_gc_get_managed_allocator_by_type (ATYPE_NORMAL, FALSE);
+ return mono_gc_get_managed_allocator_by_type (ATYPE_NORMAL, MANAGED_ALLOCATOR_REGULAR);
#else
return NULL;
#endif
return NULL;
g_assert (!mono_class_has_finalizer (klass) && !mono_class_is_marshalbyref (klass));
- return mono_gc_get_managed_allocator_by_type (ATYPE_VECTOR, FALSE);
+ return mono_gc_get_managed_allocator_by_type (ATYPE_VECTOR, MANAGED_ALLOCATOR_REGULAR);
#else
return NULL;
#endif
}
MonoMethod*
-mono_gc_get_managed_allocator_by_type (int atype, gboolean slowpath)
+mono_gc_get_managed_allocator_by_type (int atype, ManagedAllocatorVariant variant)
{
#ifdef MANAGED_ALLOCATION
MonoMethod *res;
- MonoMethod **cache = slowpath ? slowpath_alloc_method_cache : alloc_method_cache;
+ MonoMethod **cache;
if (!use_managed_allocator)
return NULL;
if (!mono_runtime_has_tls_get ())
return NULL;
+ switch (variant) {
+ case MANAGED_ALLOCATOR_REGULAR: cache = alloc_method_cache; break;
+ case MANAGED_ALLOCATOR_SLOW_PATH: cache = slowpath_alloc_method_cache; break;
+ default: g_assert_not_reached (); break;
+ }
+
res = cache [atype];
if (res)
return res;
- res = create_allocator (atype, slowpath);
+ res = create_allocator (atype, variant);
LOCK_GC;
if (cache [atype]) {
mono_free_method (res);
HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal(MonoBoolean owned, MonoString *name, MonoBoolean *created);
MonoBoolean ves_icall_System_Threading_Mutex_ReleaseMutex_internal (HANDLE handle );
HANDLE ves_icall_System_Threading_Mutex_OpenMutex_internal (MonoString *name, gint32 rights, gint32 *error);
-HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, MonoBoolean *created);
-gint32 ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, MonoBoolean *fail);
+HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error);
+MonoBoolean ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, gint32 *prevcount);
HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error);
HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, MonoBoolean *created);
gboolean ves_icall_System_Threading_Events_SetEvent_internal (HANDLE handle);
#include <mono/utils/mono-membar.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/hazard-pointer.h>
#include <mono/utils/mono-tls.h>
#include <mono/utils/atomic.h>
* This should be used at the end of embedding code which calls into managed code, and which
* can be called from pthread dtors, like dealloc: implementations in objective-c.
*/
-void
+mono_bool
mono_thread_detach_if_exiting (void)
{
if (mono_thread_info_is_exiting ()) {
if (thread) {
mono_thread_detach_internal (thread);
mono_thread_info_detach ();
+ return TRUE;
}
}
+ return FALSE;
}
void
}
-HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, MonoBoolean *created)
+HANDLE ves_icall_System_Threading_Semaphore_CreateSemaphore_internal (gint32 initialCount, gint32 maximumCount, MonoString *name, gint32 *error)
{
HANDLE sem;
- *created = TRUE;
-
if (name == NULL) {
sem = CreateSemaphore (NULL, initialCount, maximumCount, NULL);
} else {
sem = CreateSemaphore (NULL, initialCount, maximumCount,
mono_string_chars (name));
-
- if (GetLastError () == ERROR_ALREADY_EXISTS) {
- *created = FALSE;
- }
}
+ *error = GetLastError ();
return(sem);
}
-gint32 ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, MonoBoolean *fail)
+MonoBoolean ves_icall_System_Threading_Semaphore_ReleaseSemaphore_internal (HANDLE handle, gint32 releaseCount, gint32 *prevcount)
{
- gint32 prevcount;
-
- *fail = !ReleaseSemaphore (handle, releaseCount, &prevcount);
-
- return (prevcount);
+ return ReleaseSemaphore (handle, releaseCount, prevcount);
}
HANDLE ves_icall_System_Threading_Semaphore_OpenSemaphore_internal (MonoString *name, gint32 rights, gint32 *error)
{
- HANDLE ret;
-
- *error = ERROR_SUCCESS;
-
- ret = OpenSemaphore (rights, FALSE, mono_string_chars (name));
- if (ret == NULL) {
- *error = GetLastError ();
- }
-
- return(ret);
+ HANDLE sem;
+
+ sem = OpenSemaphore (rights, FALSE, mono_string_chars (name));
+ *error = GetLastError ();
+
+ return(sem);
}
HANDLE ves_icall_System_Threading_Events_CreateEvent_internal (MonoBoolean manual, MonoBoolean initial, MonoString *name, MonoBoolean *created)
This function is part of the embeding API and has no way to return the exception
to be thrown. So what we do is keep the old behavior and raise the exception.
*/
- mono_error_raise_exception (&error);
+ mono_error_raise_exception (&error); /* OK to throw, see note */
} else {
async_abort_internal (internal, TRUE);
}
}
joinable_threads_unlock ();
if (found) {
- if (thread != pthread_self ())
+ if (thread != pthread_self ()) {
+ MONO_ENTER_GC_SAFE;
/* This shouldn't block */
pthread_join (thread, NULL);
+ MONO_EXIT_GC_SAFE;
+ }
} else {
break;
}
if (!found)
return;
thread = (pthread_t)tid;
+ MONO_ENTER_GC_SAFE;
pthread_join (thread, NULL);
+ MONO_EXIT_GC_SAFE;
#endif
}
*dummy = NULL;
/* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
* return the right cookie. */
- return mono_threads_enter_gc_unsafe_region_cookie (mono_thread_info_current ());
+ return mono_threads_enter_gc_unsafe_region_cookie ();
} else {
*dummy = orig;
/* thread state (BLOCKING|RUNNING) -> RUNNING */
MONO_API mono_bool mono_thread_is_foreign (MonoThread *thread);
-extern MONO_API void mono_thread_detach_if_exiting (void);
+extern MONO_API mono_bool mono_thread_detach_if_exiting (void);
MONO_END_DECLS
arch_sources = $(amd64_sources)
arch_built=cpu-amd64.h
arch_define=__x86_64__
-ARCH_FULLAOT_EXCLUDE=--exclude DYNCALL
+ARCH_FULLAOT_EXCLUDE=
endif
if POWERPC
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-mmap.h>
#include <mono/utils/json.h>
+#include <mono/utils/mono-threads-coop.h>
#include "aot-compiler.h"
#include "seq-points.h"
/* Managed Allocators */
nallocators = mono_gc_get_managed_allocator_types ();
for (i = 0; i < nallocators; ++i) {
- m = mono_gc_get_managed_allocator_by_type (i, TRUE);
- if (m)
+ if ((m = mono_gc_get_managed_allocator_by_type (i, MANAGED_ALLOCATOR_REGULAR)))
add_method (acfg, m);
- }
- for (i = 0; i < nallocators; ++i) {
- m = mono_gc_get_managed_allocator_by_type (i, FALSE);
- if (m)
+ if ((m = mono_gc_get_managed_allocator_by_type (i, MANAGED_ALLOCATOR_SLOW_PATH)))
add_method (acfg, m);
}
}
g_hash_table_destroy (acfg->image_hash);
g_hash_table_destroy (acfg->unwind_info_offsets);
g_hash_table_destroy (acfg->method_label_hash);
- if (!acfg->typespec_classes)
+ if (acfg->typespec_classes)
g_hash_table_destroy (acfg->typespec_classes);
g_hash_table_destroy (acfg->export_names);
g_hash_table_destroy (acfg->plt_entry_debug_sym_cache);
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-digest.h>
+#include <mono/utils/mono-threads-coop.h>
#include "mini.h"
#include "seq-points.h"
#endif
case MONO_WRAPPER_ALLOC: {
int atype = decode_value (p, &p);
+ ManagedAllocatorVariant variant =
+ mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS ?
+ MANAGED_ALLOCATOR_SLOW_PATH : MANAGED_ALLOCATOR_REGULAR;
- ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
+ ref->method = mono_gc_get_managed_allocator_by_type (atype, variant);
if (!ref->method) {
mono_error_set_bad_image_name (error, module->aot_name, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
return FALSE;
gpointer res = mono_aot_get_method_checked (domain, method, &error);
/* This is external only, so its ok to raise here */
- mono_error_raise_exception (&error);
+ mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
return res;
}
vcall2_reg: src1:i len:64 clob:c
vcall2_membase: src1:b len:64 clob:c
-dyn_call: src1:i src2:i len:128 clob:c
+dyn_call: src1:i src2:i len:192 clob:c
localloc_imm: dest:i len:96
mono_loader_unlock ();
}
+/*
+ * ss_calculate_framecount:
+ *
+ * Ensure DebuggerTlsData fields are filled out.
+ */
+static void ss_calculate_framecount (DebuggerTlsData *tls, MonoContext *ctx)
+{
+ if (!tls->context.valid)
+ mono_thread_state_init_from_monoctx (&tls->context, ctx);
+ compute_frame_info (tls->thread, tls);
+}
+
/*
* ss_update:
*
return FALSE;
}
- if (req->depth == STEP_DEPTH_OVER && hit) {
- if (!tls->context.valid)
- mono_thread_state_init_from_monoctx (&tls->context, ctx);
- compute_frame_info (tls->thread, tls);
- if (req->nframes && tls->frame_count && tls->frame_count > req->nframes) {
- /* Hit the breakpoint in a recursive call */
- DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get ());
+ if ((req->depth == STEP_DEPTH_OVER || req->depth == STEP_DEPTH_OUT) && hit) {
+ gboolean is_step_out = req->depth == STEP_DEPTH_OUT;
+
+ ss_calculate_framecount (tls, ctx);
+
+ // Because functions can call themselves recursively, we need to make sure we're stopping at the right stack depth.
+ // In case of step out, the target is the frame *enclosing* the one where the request was made.
+ int target_frames = req->nframes + (is_step_out ? -1 : 0);
+ if (req->nframes > 0 && tls->frame_count > 0 && tls->frame_count > target_frames) {
+ /* Hit the breakpoint in a recursive call, don't halt */
+ DEBUG_PRINTF (1, "[%p] Breakpoint at lower frame while stepping %s, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), is_step_out ? "out" : "over");
return FALSE;
}
}
if (req->depth == STEP_DEPTH_INTO && req->size == STEP_SIZE_MIN && (sp->flags & MONO_SEQ_POINT_FLAG_NONEMPTY_STACK) && ss_req->start_method){
method = jinfo_get_method (ji);
- if (!tls->context.valid)
- mono_thread_state_init_from_monoctx (&tls->context, ctx);
- compute_frame_info (tls->thread, tls);
+ ss_calculate_framecount (tls, ctx);
if (ss_req->start_method == method && req->nframes && tls->frame_count == req->nframes) {//Check also frame count(could be recursion)
DEBUG_PRINTF (1, "[%p] Seq point at nonempty stack %x while stepping in, continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), sp->il_offset);
return FALSE;
ss_req->last_method = method;
hit = FALSE;
} else if (loc && method == ss_req->last_method && loc->row == ss_req->last_line) {
- DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), loc->row);
- hit = FALSE;
+ ss_calculate_framecount (tls, ctx);
+ if (tls->frame_count == req->nframes) { // If the frame has changed we're clearly not on the same source line.
+ DEBUG_PRINTF (1, "[%p] Same source line (%d), continuing single stepping.\n", (gpointer) (gsize) mono_native_thread_id_get (), loc->row);
+ hit = FALSE;
+ }
}
if (loc) {
}
}
+/*
+ * ss_bp_is_unique:
+ *
+ * Reject breakpoint if it is a duplicate of one already in list or hash table.
+ */
+static gboolean
+ss_bp_is_unique (GSList *bps, GHashTable *ss_req_bp_cache, MonoMethod *method, guint32 il_offset)
+{
+ if (ss_req_bp_cache) {
+ MonoBreakpoint dummy = {method, il_offset, NULL, NULL};
+ return !g_hash_table_lookup (ss_req_bp_cache, &dummy);
+ }
+ for (GSList *l = bps; l; l = l->next) {
+ MonoBreakpoint *bp = (MonoBreakpoint *)l->data;
+ if (bp->method == method && bp->il_offset == il_offset)
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*
+ * ss_bp_eq:
+ *
+ * GHashTable equality for a MonoBreakpoint (only care about method and il_offset fields)
+ */
+static gint
+ss_bp_eq (gconstpointer ka, gconstpointer kb)
+{
+ const MonoBreakpoint *s1 = (const MonoBreakpoint *)ka;
+ const MonoBreakpoint *s2 = (const MonoBreakpoint *)kb;
+ return (s1->method == s2->method && s1->il_offset == s2->il_offset) ? 1 : 0;
+}
+
+/*
+ * ss_bp_eq:
+ *
+ * GHashTable hash for a MonoBreakpoint (only care about method and il_offset fields)
+ */
+static guint
+ss_bp_hash (gconstpointer data)
+{
+ const MonoBreakpoint *s = (const MonoBreakpoint *)data;
+ guint hash = (guint) (uintptr_t) s->method;
+ hash ^= ((guint)s->il_offset) << 16; // Assume low bits are more interesting
+ hash ^= ((guint)s->il_offset) >> 16;
+ return hash;
+}
+
+#define MAX_LINEAR_SCAN_BPS 7
+
+/*
+ * ss_bp_add_one:
+ *
+ * Create a new breakpoint and add it to a step request.
+ * Will adjust the bp count and cache used by ss_start.
+ */
+static void
+ss_bp_add_one (SingleStepReq *ss_req, int *ss_req_bp_count, GHashTable **ss_req_bp_cache,
+ MonoMethod *method, guint32 il_offset)
+{
+ // This list is getting too long, switch to using the hash table
+ if (!*ss_req_bp_cache && *ss_req_bp_count > MAX_LINEAR_SCAN_BPS) {
+ *ss_req_bp_cache = g_hash_table_new (ss_bp_hash, ss_bp_eq);
+ for (GSList *l = ss_req->bps; l; l = l->next)
+ g_hash_table_insert (*ss_req_bp_cache, l->data, l->data);
+ }
+
+ if (ss_bp_is_unique (ss_req->bps, *ss_req_bp_cache, method, il_offset)) {
+ // Create and add breakpoint
+ MonoBreakpoint *bp = set_breakpoint (method, il_offset, ss_req->req, NULL);
+ ss_req->bps = g_slist_append (ss_req->bps, bp);
+ if (*ss_req_bp_cache)
+ g_hash_table_insert (*ss_req_bp_cache, bp, bp);
+ (*ss_req_bp_count)++;
+ } else {
+ DEBUG_PRINTF (1, "[dbg] Candidate breakpoint at %s:[il=0x%x] is a duplicate for this step request, will not add.\n", mono_method_full_name (method, TRUE), (int)il_offset);
+ }
+}
+
/*
* ss_start:
*
SeqPoint *next_sp, *parent_sp = NULL;
SeqPoint local_sp, local_parent_sp;
gboolean found_sp;
- MonoBreakpoint *bp;
MonoSeqPointInfo *parent_info;
MonoMethod *parent_sp_method = NULL;
gboolean enable_global = FALSE;
+ // When 8 or more entries are in bps, we build a hash table to serve as a set of breakpoints.
+ // Recreating this on each pass is a little wasteful but at least keeps behavior linear.
+ int ss_req_bp_count = g_slist_length (ss_req->bps);
+ GHashTable *ss_req_bp_cache = NULL;
+
/* Stop the previous operation */
ss_stop (ss_req);
* Implement single stepping using breakpoints if possible.
*/
if (step_to_catch) {
- bp = set_breakpoint (method, sp->il_offset, ss_req->req, NULL);
- ss_req->bps = g_slist_append (ss_req->bps, bp);
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, method, sp->il_offset);
} else {
frame_index = 1;
for (i = 0; i < sp->next_len; i++) {
next_sp = &next[i];
- bp = set_breakpoint (method, next_sp->il_offset, ss_req->req, NULL);
- ss_req->bps = g_slist_append (ss_req->bps, bp);
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, method, next_sp->il_offset);
}
g_free (next);
}
for (i = 0; i < parent_sp->next_len; i++) {
next_sp = &next[i];
- bp = set_breakpoint (parent_sp_method, next_sp->il_offset, ss_req->req, NULL);
- ss_req->bps = g_slist_append (ss_req->bps, bp);
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, parent_sp_method, next_sp->il_offset);
}
g_free (next);
}
found_sp = mono_find_next_seq_point_for_native_offset (frame->domain, frame->method, (char*)ei->handler_start - (char*)jinfo->code_start, NULL, &local_sp);
sp = (found_sp)? &local_sp : NULL;
- if (sp) {
- bp = set_breakpoint (frame->method, sp->il_offset, ss_req->req, NULL);
- ss_req->bps = g_slist_append (ss_req->bps, bp);
- }
+
+ ss_bp_add_one (ss_req, &ss_req_bp_count, &ss_req_bp_cache, frame->method, sp->il_offset);
}
}
}
} else {
ss_req->global = FALSE;
}
+
+ if (ss_req_bp_cache)
+ g_hash_table_destroy (ss_req_bp_cache);
}
/*
#include <mono/utils/mono-error-internals.h>
#include <mono/metadata/mono-basic-block.h>
#include <mono/metadata/reflection-internals.h>
+#include <mono/utils/mono-threads-coop.h>
#include "trace.h"
ip += 6;
break;
}
+ case CEE_MONO_ATOMIC_STORE_I4: {
+ g_assert (mono_arch_opcode_supported (OP_ATOMIC_STORE_I4));
+
+ CHECK_OPSIZE (6);
+ CHECK_STACK (2);
+ sp -= 2;
+
+ MONO_INST_NEW (cfg, ins, OP_ATOMIC_STORE_I4);
+ ins->dreg = sp [0]->dreg;
+ ins->sreg1 = sp [1]->dreg;
+ ins->backend.memory_barrier_kind = (int) read32 (ip + 2);
+ MONO_ADD_INS (cfg->cbb, ins);
+
+ ip += 6;
+ break;
+ }
case CEE_MONO_JIT_ATTACH: {
MonoInst *args [16], *domain_ins;
MonoInst *ad_ins, *jit_tls_ins;
case ArgInIReg:
case ArgInFloatSSEReg:
case ArgInDoubleSSEReg:
+ case ArgValuetypeAddrInIReg:
break;
case ArgValuetypeInReg: {
ArgInfo *ainfo = &cinfo->ret;
if (ainfo->pair_storage [1] != ArgNone && ainfo->pair_storage [1] != ArgInIReg)
return FALSE;
break;
+ case ArgOnStack:
+ if (!(ainfo->offset + (ainfo->arg_size / 8) <= DYN_CALL_STACK_ARGS))
+ return FALSE;
+ break;
default:
return FALSE;
}
int arg_index, greg, freg, i, pindex;
MonoMethodSignature *sig = dinfo->sig;
int buffer_offset = 0;
+ static int param_reg_to_index [16];
+ static gboolean param_reg_to_index_inited;
+
+ if (!param_reg_to_index_inited) {
+ for (i = 0; i < PARAM_REGS; ++i)
+ param_reg_to_index [param_regs [i]] = i;
+ mono_memory_barrier ();
+ param_reg_to_index_inited = 1;
+ }
g_assert (buf_len >= sizeof (DynCallArgs));
for (i = pindex; i < sig->param_count; i++) {
MonoType *t = mini_get_underlying_type (sig->params [i]);
gpointer *arg = args [arg_index ++];
+ ArgInfo *ainfo = &dinfo->cinfo->args [i + sig->hasthis];
+ int slot;
+
+ if (ainfo->storage == ArgOnStack) {
+ slot = PARAM_REGS + 1 + (ainfo->offset / sizeof (mgreg_t));
+ } else {
+ slot = param_reg_to_index [ainfo->reg];
+ }
if (t->byref) {
- p->regs [greg ++] = PTR_TO_GREG(*(arg));
+ p->regs [slot] = PTR_TO_GREG(*(arg));
+ greg ++;
continue;
}
case MONO_TYPE_I8:
case MONO_TYPE_U8:
#endif
- g_assert (dinfo->cinfo->args [i + sig->hasthis].reg == param_regs [greg]);
- p->regs [greg ++] = PTR_TO_GREG(*(arg));
+ p->regs [slot] = PTR_TO_GREG(*(arg));
break;
#if defined(__mono_ilp32__)
case MONO_TYPE_I8:
case MONO_TYPE_U8:
- g_assert (dinfo->cinfo->args [i + sig->hasthis].reg == param_regs [greg]);
- p->regs [greg ++] = *(guint64*)(arg);
+ p->regs [slot] = *(guint64*)(arg);
break;
#endif
case MONO_TYPE_U1:
- p->regs [greg ++] = *(guint8*)(arg);
+ p->regs [slot] = *(guint8*)(arg);
break;
case MONO_TYPE_I1:
- p->regs [greg ++] = *(gint8*)(arg);
+ p->regs [slot] = *(gint8*)(arg);
break;
case MONO_TYPE_I2:
- p->regs [greg ++] = *(gint16*)(arg);
+ p->regs [slot] = *(gint16*)(arg);
break;
case MONO_TYPE_U2:
- p->regs [greg ++] = *(guint16*)(arg);
+ p->regs [slot] = *(guint16*)(arg);
break;
case MONO_TYPE_I4:
- p->regs [greg ++] = *(gint32*)(arg);
+ p->regs [slot] = *(gint32*)(arg);
break;
case MONO_TYPE_U4:
- p->regs [greg ++] = *(guint32*)(arg);
+ p->regs [slot] = *(guint32*)(arg);
break;
case MONO_TYPE_R4: {
double d;
break;
case MONO_TYPE_GENERICINST:
if (MONO_TYPE_IS_REFERENCE (t)) {
- p->regs [greg ++] = PTR_TO_GREG(*(arg));
+ p->regs [slot] = PTR_TO_GREG(*(arg));
break;
} else if (t->type == MONO_TYPE_GENERICINST && mono_class_is_nullable (mono_class_from_mono_type (t))) {
MonoClass *klass = mono_class_from_mono_type (t);
/* Fall through */
}
case MONO_TYPE_VALUETYPE: {
- ArgInfo *ainfo = &dinfo->cinfo->args [i + sig->hasthis];
-
- g_assert (ainfo->storage == ArgValuetypeInReg);
- if (ainfo->pair_storage [0] != ArgNone) {
- g_assert (ainfo->pair_storage [0] == ArgInIReg);
- p->regs [greg ++] = ((mgreg_t*)(arg))[0];
- }
- if (ainfo->pair_storage [1] != ArgNone) {
- g_assert (ainfo->pair_storage [1] == ArgInIReg);
- p->regs [greg ++] = ((mgreg_t*)(arg))[1];
+ switch (ainfo->storage) {
+ case ArgValuetypeInReg:
+ if (ainfo->pair_storage [0] != ArgNone) {
+ slot = param_reg_to_index [ainfo->pair_regs [0]];
+ g_assert (ainfo->pair_storage [0] == ArgInIReg);
+ p->regs [slot] = ((mgreg_t*)(arg))[0];
+ }
+ if (ainfo->pair_storage [1] != ArgNone) {
+ slot = param_reg_to_index [ainfo->pair_regs [1]];
+ g_assert (ainfo->pair_storage [1] == ArgInIReg);
+ p->regs [slot] = ((mgreg_t*)(arg))[1];
+ }
+ break;
+ case ArgOnStack:
+ for (i = 0; i < ainfo->arg_size / 8; ++i)
+ p->regs [slot + i] = ((mgreg_t*)(arg))[i];
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
}
break;
}
g_assert_not_reached ();
}
}
-
- g_assert (greg <= PARAM_REGS);
}
/*
amd64_sse_movsd_reg_membase (code, i, AMD64_R11, MONO_STRUCT_OFFSET (DynCallArgs, fregs) + (i * sizeof (double)));
amd64_patch (label, code);
+ /* Set stack args */
+ for (i = 0; i < DYN_CALL_STACK_ARGS; ++i) {
+ amd64_mov_reg_membase (code, AMD64_RAX, AMD64_R11, MONO_STRUCT_OFFSET (DynCallArgs, regs) + ((PARAM_REGS + i) * sizeof(mgreg_t)), sizeof(mgreg_t));
+ amd64_mov_membase_reg (code, AMD64_RSP, i * sizeof (mgreg_t), AMD64_RAX, sizeof (mgreg_t));
+ }
+
/* Set argument registers */
for (i = 0; i < PARAM_REGS; ++i)
amd64_mov_reg_membase (code, param_regs [i], AMD64_R11, i * sizeof(mgreg_t), sizeof(mgreg_t));
gpointer bp_addrs [MONO_ZERO_LEN_ARRAY];
} SeqPointInfo;
+#define DYN_CALL_STACK_ARGS 6
+
typedef struct {
- mgreg_t regs [PARAM_REGS];
+ mgreg_t regs [PARAM_REGS + DYN_CALL_STACK_ARGS];
mgreg_t res;
guint8 *ret;
double fregs [8];
#define MONO_ARCH_GSHARED_SUPPORTED 1
#define MONO_ARCH_DYN_CALL_SUPPORTED 1
-#define MONO_ARCH_DYN_CALL_PARAM_AREA 0
+#define MONO_ARCH_DYN_CALL_PARAM_AREA (DYN_CALL_STACK_ARGS * 8)
#define MONO_ARCH_LLVM_SUPPORTED 1
#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-hwcap-arm.h>
#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/mono-threads-coop.h>
#include "mini-arm.h"
#include "mini-arm-tls.h"
cinfo->ret.nregs = nfields;
cinfo->ret.esize = esize;
} else {
- if (is_pinvoke && mono_class_native_size (mono_class_from_mono_type (t), &align) <= sizeof (gpointer))
- cinfo->ret.storage = RegTypeStructByVal;
- else
+ if (is_pinvoke) {
+ int native_size = mono_class_native_size (mono_class_from_mono_type (t), &align);
+ int max_size;
+
+#ifdef TARGET_WATCHOS
+ max_size = 16;
+#else
+ max_size = 4;
+#endif
+ if (native_size <= max_size) {
+ cinfo->ret.storage = RegTypeStructByVal;
+ cinfo->ret.struct_size = native_size;
+ cinfo->ret.nregs = ALIGN_TO (native_size, 4) / 4;
+ } else {
+ cinfo->ret.storage = RegTypeStructByAddr;
+ }
+ } else {
cinfo->ret.storage = RegTypeStructByAddr;
+ }
}
break;
case MONO_TYPE_VAR:
size = mini_type_stack_size_full (t, &align, FALSE);
}
DEBUG(g_print ("load %d bytes struct\n", size));
+
+#ifdef TARGET_WATCHOS
+ /* Watchos pass large structures by ref */
+ /* We only do this for pinvoke to make gsharedvt/dyncall simpler */
+ if (sig->pinvoke && size > 16) {
+ add_general (&gr, &stack_size, ainfo, TRUE);
+ switch (ainfo->storage) {
+ case RegTypeGeneral:
+ ainfo->storage = RegTypeStructByAddr;
+ break;
+ case RegTypeBase:
+ ainfo->storage = RegTypeStructByAddrOnStack;
+ break;
+ default:
+ g_assert_not_reached ();
+ break;
+ }
+ break;
+ }
+#endif
+
align_size = size;
nwords = 0;
align_size += (sizeof (gpointer) - 1);
switch (cinfo->ret.storage) {
case RegTypeStructByVal:
- cfg->ret->opcode = OP_REGOFFSET;
- cfg->ret->inst_basereg = cfg->frame_reg;
- offset += sizeof (gpointer) - 1;
- offset &= ~(sizeof (gpointer) - 1);
- cfg->ret->inst_offset = - offset;
- offset += sizeof(gpointer);
- break;
case RegTypeHFA:
/* Allocate a local to hold the result, the epilog will copy it to the correct place */
offset = ALIGN_TO (offset, 8);
cfg->ret->opcode = OP_REGOFFSET;
cfg->ret->inst_basereg = cfg->frame_reg;
cfg->ret->inst_offset = offset;
- // FIXME:
- offset += 32;
+ if (cinfo->ret.storage == RegTypeStructByVal)
+ offset += cinfo->ret.nregs * sizeof (gpointer);
+ else
+ offset += 32;
break;
case RegTypeStructByAddr:
ins = cfg->vret_addr;
linfo->ret.storage = LLVMArgVtypeRetAddr;
linfo->vret_arg_index = cinfo->vret_arg_index;
break;
+#if TARGET_WATCHOS
+ case RegTypeStructByVal:
+ /* LLVM models this by returning an int array */
+ linfo->ret.storage = LLVMArgAsIArgs;
+ linfo->ret.nslots = cinfo->ret.nregs;
+ break;
+#endif
default:
cfg->exception_message = g_strdup_printf ("unknown ret conv (%d)", cinfo->ret.storage);
cfg->disable_llvm = TRUE;
}
for (i = 0; i < n; ++i) {
+ LLVMArgInfo *lainfo = &linfo->args [i];
ainfo = cinfo->args + i;
- linfo->args [i].storage = LLVMArgNone;
+ lainfo->storage = LLVMArgNone;
switch (ainfo->storage) {
case RegTypeGeneral:
case RegTypeBase:
case RegTypeBaseGen:
case RegTypeFP:
- linfo->args [i].storage = LLVMArgNormal;
+ lainfo->storage = LLVMArgNormal;
break;
case RegTypeStructByVal:
- linfo->args [i].storage = LLVMArgAsIArgs;
- linfo->args [i].nslots = ainfo->struct_size / sizeof (gpointer);
+ lainfo->storage = LLVMArgAsIArgs;
+ lainfo->nslots = ainfo->struct_size / sizeof (gpointer);
+ break;
+ case RegTypeStructByAddr:
+ case RegTypeStructByAddrOnStack:
+ lainfo->storage = LLVMArgVtypeByRef;
break;
default:
cfg->exception_message = g_strdup_printf ("ainfo->storage (%d)", ainfo->storage);
switch (cinfo->ret.storage) {
case RegTypeStructByVal:
- /* The JIT will transform this into a normal call */
- call->vret_in_reg = TRUE;
- break;
case RegTypeHFA:
+ if (cinfo->ret.storage == RegTypeStructByVal && cinfo->ret.nregs == 1) {
+ /* The JIT will transform this into a normal call */
+ call->vret_in_reg = TRUE;
+ break;
+ }
+ if (call->inst.opcode == OP_TAILCALL)
+ break;
/*
* The vtype is returned in registers, save the return area address in a local, and save the vtype into
* the location pointed to by it after call in emit_move_return_value ().
mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE);
}
break;
- case RegTypeStructByAddr:
- NOT_IMPLEMENTED;
-#if 0
- /* FIXME: where si the data allocated? */
- arg->backend.reg3 = ainfo->reg;
- call->used_iregs |= 1 << ainfo->reg;
- g_assert_not_reached ();
-#endif
- break;
case RegTypeStructByVal:
case RegTypeGSharedVtInReg:
case RegTypeGSharedVtOnStack:
case RegTypeHFA:
+ case RegTypeStructByAddr:
+ case RegTypeStructByAddrOnStack:
MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
ins->opcode = OP_OUTARG_VT;
ins->sreg1 = in->dreg;
switch (ainfo->storage) {
case RegTypeGSharedVtInReg:
+ case RegTypeStructByAddr:
/* Pass by addr */
mono_call_inst_add_outarg_reg (cfg, call, src->dreg, ainfo->reg, FALSE);
break;
case RegTypeGSharedVtOnStack:
+ case RegTypeStructByAddrOnStack:
/* Pass by addr on stack */
MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, ARMREG_SP, ainfo->offset, src->dreg);
break;
cinfo = call->call_info;
switch (cinfo->ret.storage) {
+ case RegTypeStructByVal:
case RegTypeHFA: {
MonoInst *loc = cfg->arch.vret_addr_loc;
int i;
+ if (cinfo->ret.storage == RegTypeStructByVal && cinfo->ret.nregs == 1) {
+ /* The JIT treats this as a normal call */
+ break;
+ }
+
/* Load the destination address */
g_assert (loc && loc->opcode == OP_REGOFFSET);
code = mono_arm_emit_load_imm (code, ARMREG_LR, loc->inst_offset);
ARM_LDR_REG_REG (code, ARMREG_LR, loc->inst_basereg, ARMREG_LR);
}
- for (i = 0; i < cinfo->ret.nregs; ++i) {
- if (cinfo->ret.esize == 4)
- ARM_FSTS (code, cinfo->ret.reg + i, ARMREG_LR, i * 4);
- else
- ARM_FSTD (code, cinfo->ret.reg + (i * 2), ARMREG_LR, i * 8);
+
+ if (cinfo->ret.storage == RegTypeStructByVal) {
+ int rsize = cinfo->ret.struct_size;
+
+ for (i = 0; i < cinfo->ret.nregs; ++i) {
+ g_assert (rsize >= 0);
+ switch (rsize) {
+ case 0:
+ break;
+ case 1:
+ ARM_STRB_IMM (code, i, ARMREG_LR, i * 4);
+ break;
+ case 2:
+ ARM_STRH_IMM (code, i, ARMREG_LR, i * 4);
+ break;
+ default:
+ ARM_STR_IMM (code, i, ARMREG_LR, i * 4);
+ break;
+ }
+ rsize -= 4;
+ }
+ } else {
+ for (i = 0; i < cinfo->ret.nregs; ++i) {
+ if (cinfo->ret.esize == 4)
+ ARM_FSTS (code, cinfo->ret.reg + i, ARMREG_LR, i * 4);
+ else
+ ARM_FSTD (code, cinfo->ret.reg + (i * 2), ARMREG_LR, i * 8);
+ }
}
return code;
}
break;
}
- ARM_DMB (code, ARM_DMB_SY);
+ if (ins->backend.memory_barrier_kind != MONO_MEMORY_BARRIER_NONE)
+ ARM_DMB (code, ARM_DMB_SY);
break;
}
case OP_ATOMIC_STORE_I1:
case OP_ATOMIC_STORE_U4:
case OP_ATOMIC_STORE_R4:
case OP_ATOMIC_STORE_R8: {
- ARM_DMB (code, ARM_DMB_SY);
+ if (ins->backend.memory_barrier_kind != MONO_MEMORY_BARRIER_NONE)
+ ARM_DMB (code, ARM_DMB_SY);
code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
case RegTypeGeneral:
case RegTypeIRegPair:
case RegTypeGSharedVtInReg:
+ case RegTypeStructByAddr:
switch (ainfo->size) {
case 1:
if (arm_is_imm12 (inst->inst_offset))
break;
case RegTypeBase:
case RegTypeGSharedVtOnStack:
+ case RegTypeStructByAddrOnStack:
if (arm_is_imm12 (prev_sp_offset + ainfo->offset)) {
ARM_LDR_IMM (code, ARMREG_LR, ARMREG_SP, (prev_sp_offset + ainfo->offset));
} else {
}
break;
}
- case RegTypeStructByAddr:
- g_assert_not_reached ();
- /* FIXME: handle overrun! with struct sizes not multiple of 4 */
- code = emit_memcpy (code, ainfo->vtsize * sizeof (gpointer), inst->inst_basereg, inst->inst_offset, ainfo->reg, 0);
default:
g_assert_not_reached ();
break;
case RegTypeStructByVal: {
MonoInst *ins = cfg->ret;
- if (arm_is_imm12 (ins->inst_offset)) {
- ARM_LDR_IMM (code, ARMREG_R0, ins->inst_basereg, ins->inst_offset);
+ if (cinfo->ret.nregs == 1) {
+ if (arm_is_imm12 (ins->inst_offset)) {
+ ARM_LDR_IMM (code, ARMREG_R0, ins->inst_basereg, ins->inst_offset);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
+ ARM_LDR_REG_REG (code, ARMREG_R0, ins->inst_basereg, ARMREG_LR);
+ }
} else {
- code = mono_arm_emit_load_imm (code, ARMREG_LR, ins->inst_offset);
- ARM_LDR_REG_REG (code, ARMREG_R0, ins->inst_basereg, ARMREG_LR);
+ for (i = 0; i < cinfo->ret.nregs; ++i) {
+ int offset = ins->inst_offset + (i * 4);
+ if (arm_is_imm12 (offset)) {
+ ARM_LDR_IMM (code, i, ins->inst_basereg, offset);
+ } else {
+ code = mono_arm_emit_load_imm (code, ARMREG_LR, offset);
+ ARM_LDR_REG_REG (code, i, ins->inst_basereg, ARMREG_LR);
+ }
+ }
}
break;
}
RegTypeBaseGen,
/* FP value passed in either an ireg or a vfp reg */
RegTypeFP,
+ /* Struct passed/returned in gregs */
RegTypeStructByVal,
RegTypeStructByAddr,
+ RegTypeStructByAddrOnStack,
/* gsharedvt argument passed by addr in greg */
RegTypeGSharedVtInReg,
/* gsharedvt argument passed by addr on stack */
guint16 vtsize; /* in param area */
/* RegTypeHFA */
int esize;
- /* RegTypeHFA */
+ /* RegTypeHFA/RegTypeStructByVal */
int nregs;
guint8 reg;
ArgStorage storage;
+ /* RegTypeStructByVal */
gint32 struct_size;
guint8 size : 4; /* 1, 2, 4, 8, or regs used by RegTypeStructByVal */
} ArgInfo;
gboolean
mono_exception_walk_trace (MonoException *ex, MonoExceptionFrameWalk func, gpointer user_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoArray *ta = ex->trace_ips;
int len, i;
if (unhandled_exception_hook) {
unhandled_exception_hook (exc, unhandled_exception_hook_data);
} else {
+ MonoError inner_error;
MonoObject *other = NULL;
- MonoString *str = mono_object_to_string (exc, &other);
+ MonoString *str = mono_object_try_to_string (exc, &other, &inner_error);
char *msg = NULL;
- if (str) {
- MonoError inner_error;
+ if (str && is_ok (&inner_error)) {
msg = mono_string_to_utf8_checked (str, &inner_error);
- if (!is_ok (&inner_error)) {
- msg = g_strdup_printf ("Nested exception while formatting original exception");
- mono_error_cleanup (&inner_error);
- }
}
- else if (other) {
+ if (!is_ok (&inner_error)) {
+ msg = g_strdup_printf ("Nested exception while formatting original exception");
+ mono_error_cleanup (&inner_error);
+ } else if (other) {
char *original_backtrace = mono_exception_get_managed_backtrace ((MonoException*)exc);
char *nested_backtrace = mono_exception_get_managed_backtrace ((MonoException*)other);
static void
throw_exception (MonoObject *ex, gboolean rethrow)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
MonoException *mono_ex;
}
break;
}
+ case LLVMArgAsIArgs:
+ ret_type = LLVMArrayType (IntPtrType (), cinfo->ret.nslots);
+ break;
case LLVMArgFpStruct: {
/* Vtype returned as a fp struct */
LLVMTypeRef members [16];
addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
LLVMBuildStore (builder, lcall, addresses [call->inst.dreg]);
break;
+ case LLVMArgAsIArgs:
case LLVMArgFpStruct:
if (!addresses [call->inst.dreg])
addresses [call->inst.dreg] = build_alloca (ctx, sig->ret);
LLVMBuildRetVoid (builder);
break;
}
+ case LLVMArgAsIArgs:
case LLVMArgFpStruct: {
LLVMTypeRef ret_type = LLVMGetReturnType (LLVMGetElementType (LLVMTypeOf (method)));
LLVMValueRef retval;
void
mono_runtime_posix_install_handlers(void)
{
-
+ /* we still need to ignore SIGPIPE */
+ signal (SIGPIPE, SIG_IGN);
}
void
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-signal-handler.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/checked-build.h>
#include <mono/io-layer/io-layer.h>
MonoException *exc;
MONO_SIG_HANDLER_GET_CONTEXT;
+ MONO_ENTER_GC_UNSAFE_UNBALANCED;
+
exc = mono_get_exception_execution_engine ("SIGILL");
mono_arch_handle_exception (ctx, exc);
+
+ MONO_EXIT_GC_UNSAFE_UNBALANCED;
}
#if defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32)
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-membar.h>
#include <mono/utils/mono-compiler.h>
+#include <mono/utils/mono-threads-coop.h>
#include "mini.h"
/* Avoid loading metadata or creating a generic vtable if possible */
addr = mono_aot_get_method_from_vt_slot (mono_domain_get (), vt, slot, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!is_ok (&error))
+ goto leave;
if (addr && !vt->klass->valuetype) {
if (mono_domain_owns_vtable_slot (mono_domain_get (), vtable_slot))
*vtable_slot = addr;
}
res = common_call_trampoline (regs, code, m, vt, vtable_slot, &error);
+leave:
if (!mono_error_ok (&error)) {
mono_error_set_pending_exception (&error);
return NULL;
#include <mono/utils/mono-hwcap.h>
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/io-layer/io-layer.h>
#include "mini.h"
#include <mono/utils/mono-machine.h>
#include <mono/utils/mono-stack-unwinding.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/mono-tls.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-conc-hashtable.h>
LLVMArgGsharedvtFixedVtype,
/* Variable sized argument passed to/returned from gsharedvt method by ref */
LLVMArgGsharedvtVariable,
- /* Vtype passed as one int array argument */
+ /* Vtype passed/returned as one int array argument */
LLVMArgAsIArgs,
/* Vtype passed as a set of fp arguments */
LLVMArgAsFpArgs,
mprof_report_SOURCES = decode.c
mprof_report_LDADD = $(Z_LIBS) $(GLIB_LIBS) $(LIBICONV)
+# FIXME fix the profiler tests to work with coop.
+if ENABLE_COOP
+DISABLE_PROFILER_TESTS=1
+endif
PLOG_TESTS_SRC=test-alloc.cs test-busy.cs test-monitor.cs test-excleave.cs \
test-heapshot.cs test-traces.cs
PLOG_TESTS=$(PLOG_TESTS_SRC:.cs=.exe)
$(MCS) -out:$@ $<
testlog: $(PLOG_TESTS)
- $(with_mono_path) perl $(srcdir)/ptestrunner.pl $(top_builddir)
+ if [ "z$(DISABLE_PROFILER_TESTS)" != z1 ]; then \
+ $(with_mono_path) perl $(srcdir)/ptestrunner.pl $(top_builddir) ; \
+ else \
+ echo "Profiler tests disabled with cooperative GC" ; \
+ fi
+
if NACL_CODEGEN
check-local:
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-os-mutex.h>
+#include <mono/utils/mono-os-semaphore.h>
#include <mono/utils/mono-conc-hashtable.h>
#include <mono/utils/lock-free-alloc.h>
#include <mono/utils/lock-free-queue.h>
+#include <mono/utils/hazard-pointer.h>
+#include <mono/utils/mono-threads.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
static __thread char *tlab_real_end;
/* Used by the managed allocator/wbarrier */
static __thread char **tlab_next_addr MONO_ATTR_USED;
+#ifndef SGEN_WITHOUT_MONO
+static __thread volatile int *in_critical_region_addr MONO_ATTR_USED;
+#endif
#endif
#ifdef HAVE_KW_THREAD
#ifdef HAVE_KW_THREAD
tlab_next_addr = &tlab_next;
+#ifndef SGEN_WITHOUT_MONO
+ in_critical_region_addr = &info->client_info.in_critical_region;
+#endif
#endif
}
#if defined(HAVE_KW_THREAD) && !defined(SGEN_WITHOUT_MONO)
int tlab_next_addr_offset = -1;
int tlab_temp_end_offset = -1;
-
+ int in_critical_region_addr_offset = -1;
MONO_THREAD_VAR_OFFSET (tlab_next_addr, tlab_next_addr_offset);
MONO_THREAD_VAR_OFFSET (tlab_temp_end, tlab_temp_end_offset);
+ MONO_THREAD_VAR_OFFSET (in_critical_region_addr, in_critical_region_addr_offset);
mono_tls_key_set_offset (TLS_KEY_SGEN_TLAB_NEXT_ADDR, tlab_next_addr_offset);
mono_tls_key_set_offset (TLS_KEY_SGEN_TLAB_TEMP_END, tlab_temp_end_offset);
+ mono_tls_key_set_offset (TLS_KEY_SGEN_IN_CRITICAL_REGION_ADDR, in_critical_region_addr_offset);
#endif
#ifdef HEAVY_STATISTICS
* stay pinned, which means they can't move, therefore they can be scanned.
*/
static SgenPointerQueue pin_queue_objs;
-static MonoCoopMutex pin_queue_mutex;
+static mono_mutex_t pin_queue_mutex;
#define PIN_HASH_SIZE 1024
static void *pin_hash_filter [PIN_HASH_SIZE];
void
sgen_pinning_init (void)
{
- mono_coop_mutex_init (&pin_queue_mutex);
+ mono_os_mutex_init (&pin_queue_mutex);
}
void
sgen_init_pinning (void)
{
- mono_coop_mutex_lock (&pin_queue_mutex);
+ mono_os_mutex_lock (&pin_queue_mutex);
memset (pin_hash_filter, 0, sizeof (pin_hash_filter));
pin_queue.mem_type = INTERNAL_MEM_PIN_QUEUE;
sgen_pointer_queue_clear (&pin_queue_objs);
{
last_num_pinned = pin_queue.next_slot;
sgen_pointer_queue_clear (&pin_queue);
- mono_coop_mutex_unlock (&pin_queue_mutex);
+ mono_os_mutex_unlock (&pin_queue_mutex);
}
void
int i;
ScanObjectFunc scan_func = ctx.ops->scan_object;
- mono_coop_mutex_lock (&pin_queue_mutex);
+ mono_os_mutex_lock (&pin_queue_mutex);
for (i = 0; i < pin_queue_objs.next_slot; ++i) {
GCObject *obj = (GCObject *)pin_queue_objs.data [i];
scan_func (obj, sgen_obj_get_descriptor_safe (obj), ctx.queue);
}
- mono_coop_mutex_unlock (&pin_queue_mutex);
+ mono_os_mutex_unlock (&pin_queue_mutex);
}
void
#include <mono/utils/checked-build.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
#include <mono/utils/mono-tls.h>
#include <mono/metadata/mempool.h>
#include <mono/metadata/metadata-internals.h>
if (!mono_check_mode_enabled (MONO_CHECK_MODE_THREAD))
return;
- MonoThreadInfo *cur = mono_thread_info_current_unchecked ();
CheckState *state = get_state ();
/* We currently don't record external changes as those are hard to reason about. */
- if (cur != info)
+ if (!mono_thread_info_is_current (info))
return;
if (state->transitions->len >= MAX_TRANSITIONS)
void checked_build_thread_transition(const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta);
-void mono_fatal_with_history(const char *msg, ...);
+G_GNUC_NORETURN void mono_fatal_with_history(const char *msg, ...);
#else
#include <glib.h>
#include "mono-os-mutex.h"
-#include "mono-threads.h"
+#include "mono-threads-api.h"
G_BEGIN_DECLS
#include <glib.h>
#include "mono-os-semaphore.h"
-#include "mono-threads.h"
+#include "mono-threads-api.h"
G_BEGIN_DECLS
#ifndef __MONO_THREADS_API_H__
#define __MONO_THREADS_API_H__
+#include <glib.h>
#include <mono/utils/mono-publib.h>
+
MONO_BEGIN_DECLS
/*
This API is experimental. It will eventually be required to properly use the rest of the raw-omp embedding API.
*/
-/* Don't use those directly, use the MONO_(BEGIN|END)_EFRAME */
MONO_API gpointer
mono_threads_enter_gc_unsafe_region (gpointer* stackdata);
MONO_API void
mono_threads_exit_gc_unsafe_region (gpointer cookie, gpointer* stackdata);
+MONO_API gpointer
+mono_threads_enter_gc_unsafe_region_unbalanced (gpointer* stackdata);
+
+MONO_API void
+mono_threads_exit_gc_unsafe_region_unbalanced (gpointer cookie, gpointer* stackdata);
+
MONO_API void
mono_threads_assert_gc_unsafe_region (void);
+
+
MONO_API gpointer
mono_threads_enter_gc_safe_region (gpointer *stackdata);
MONO_API void
mono_threads_exit_gc_safe_region (gpointer cookie, gpointer *stackdata);
+MONO_API gpointer
+mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata);
+
+MONO_API void
+mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata);
+
MONO_API void
mono_threads_assert_gc_safe_region (void);
#define MONO_ENTER_GC_UNSAFE \
do { \
gpointer __gc_unsafe_dummy; \
- gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__gc_unsafe_dummy) \
+ gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region (&__gc_unsafe_dummy)
#define MONO_EXIT_GC_UNSAFE \
mono_threads_exit_gc_unsafe_region (__gc_unsafe_cookie, &__gc_unsafe_dummy); \
} while (0)
+#define MONO_ENTER_GC_UNSAFE_UNBALANCED \
+ do { \
+ gpointer __gc_unsafe_unbalanced_dummy; \
+ gpointer __gc_unsafe_unbalanced_cookie = mono_threads_enter_gc_unsafe_region_unbalanced (&__gc_unsafe_unbalanced_dummy)
+
+#define MONO_EXIT_GC_UNSAFE_UNBALANCED \
+ mono_threads_exit_gc_unsafe_region_unbalanced (__gc_unsafe_unbalanced_cookie, &__gc_unsafe_unbalanced_dummy); \
+ } while (0)
+
#define MONO_ENTER_GC_SAFE \
do { \
gpointer __gc_safe_dummy; \
- gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__gc_safe_dummy) \
+ gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region (&__gc_safe_dummy)
#define MONO_EXIT_GC_SAFE \
mono_threads_exit_gc_safe_region (__gc_safe_cookie, &__gc_safe_dummy); \
} while (0)
+#define MONO_ENTER_GC_SAFE_UNBALANCED \
+ do { \
+ gpointer __gc_safe_unbalanced_dummy; \
+ gpointer __gc_safe_unbalanced_cookie = mono_threads_enter_gc_safe_region_unbalanced (&__gc_safe_unbalanced_dummy)
+
+#define MONO_EXIT_GC_SAFE_UNBALANCED \
+ mono_threads_exit_gc_safe_region_unbalanced (__gc_safe_unbalanced_cookie, &__gc_safe_unbalanced_dummy); \
+ } while (0)
+
MONO_END_DECLS
#endif /* __MONO_LOGGER_H__ */
#endif
+static void
+check_info (MonoThreadInfo *info, const gchar *action, const gchar *state)
+{
+ if (!info)
+ g_error ("Cannot %s GC %s region if the thread is not attached", action, state);
+ if (!mono_thread_info_is_current (info))
+ g_error ("[%p] Cannot %s GC %s region on a different thread", mono_thread_info_get_tid (info), action, state);
+ if (!mono_thread_info_is_live (info))
+ g_error ("[%p] Cannot %s GC %s region if the thread is not live", mono_thread_info_get_tid (info), action, state);
+}
+
static int coop_reset_blocking_count;
static int coop_try_blocking_count;
static int coop_do_blocking_count;
static int coop_do_polling_count;
static int coop_save_count;
+static void
+mono_threads_state_poll_with_info (MonoThreadInfo *info);
+
void
mono_threads_state_poll (void)
{
- MonoThreadInfo *info;
+ mono_threads_state_poll_with_info (mono_thread_info_current_unchecked ());
+}
+static void
+mono_threads_state_poll_with_info (MonoThreadInfo *info)
+{
g_assert (mono_threads_is_coop_enabled ());
++coop_do_polling_count;
- info = mono_thread_info_current_unchecked ();
if (!info)
return;
+
THREADS_SUSPEND_DEBUG ("FINISH SELF SUSPEND OF %p\n", mono_thread_info_get_tid (info));
/* Fast check for pending suspend requests */
state->gc_stackdata_size = stackdata_size;
}
+static gpointer
+mono_threads_enter_gc_safe_region_unbalanced_with_info (MonoThreadInfo *info, gpointer *stackdata);
+
gpointer
mono_threads_enter_gc_safe_region (gpointer *stackdata)
+{
+ return mono_threads_enter_gc_safe_region_with_info (mono_thread_info_current_unchecked (), stackdata);
+}
+
+gpointer
+mono_threads_enter_gc_safe_region_with_info (MonoThreadInfo *info, gpointer *stackdata)
{
gpointer cookie;
if (!mono_threads_is_coop_enabled ())
return NULL;
- cookie = mono_threads_enter_gc_safe_region_unbalanced (stackdata);
+ cookie = mono_threads_enter_gc_safe_region_unbalanced_with_info (info, stackdata);
#ifdef ENABLE_CHECKED_BUILD_GC
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
gpointer
mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata)
{
- MonoThreadInfo *info;
+ return mono_threads_enter_gc_safe_region_unbalanced_with_info (mono_thread_info_current_unchecked (), stackdata);
+}
+static gpointer
+mono_threads_enter_gc_safe_region_unbalanced_with_info (MonoThreadInfo *info, gpointer *stackdata)
+{
if (!mono_threads_is_coop_enabled ())
return NULL;
++coop_do_blocking_count;
- info = mono_thread_info_current_unchecked ();
- /* If the thread is not attached, it doesn't make sense prepare for suspend. */
- if (!info || !mono_thread_info_is_live (info)) {
- THREADS_SUSPEND_DEBUG ("PREPARE-BLOCKING failed %p\n", info ? mono_thread_info_get_tid (info) : NULL);
- return NULL;
- }
+ check_info (info, "enter", "safe");
copy_stack_data (info, stackdata);
case DoBlockingContinue:
break;
case DoBlockingPollAndRetry:
- mono_threads_state_poll ();
+ mono_threads_state_poll_with_info (info);
goto retry;
}
void
mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata)
{
- static gboolean warned_about_bad_transition;
MonoThreadInfo *info;
if (!mono_threads_is_coop_enabled ())
return;
info = (MonoThreadInfo *)cookie;
- if (!info)
- return;
- g_assert (info == mono_thread_info_current_unchecked ());
+ check_info (info, "exit", "safe");
switch (mono_threads_transition_done_blocking (info)) {
- case DoneBlockingAborted:
- if (!warned_about_bad_transition) {
- warned_about_bad_transition = TRUE;
- g_warning ("[%p] Blocking call ended in running state for, this might lead to unbound GC pauses.", mono_thread_info_get_tid (info));
- }
- mono_threads_state_poll ();
- break;
case DoneBlockingOk:
info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE;
break;
gpointer
mono_threads_enter_gc_unsafe_region (gpointer *stackdata)
+{
+ return mono_threads_enter_gc_unsafe_region_with_info (mono_thread_info_current_unchecked (), stackdata);
+}
+
+gpointer
+mono_threads_enter_gc_unsafe_region_with_info (THREAD_INFO_TYPE *info, gpointer *stackdata)
{
gpointer cookie;
if (!mono_threads_is_coop_enabled ())
return NULL;
- cookie = mono_threads_enter_gc_unsafe_region_unbalanced (stackdata);
+ cookie = mono_threads_enter_gc_unsafe_region_unbalanced_with_info (info, stackdata);
#ifdef ENABLE_CHECKED_BUILD_GC
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
gpointer
mono_threads_enter_gc_unsafe_region_unbalanced (gpointer *stackdata)
{
- MonoThreadInfo *info;
+ return mono_threads_enter_gc_unsafe_region_unbalanced_with_info (mono_thread_info_current_unchecked (), stackdata);
+}
+gpointer
+mono_threads_enter_gc_unsafe_region_unbalanced_with_info (MonoThreadInfo *info, gpointer *stackdata)
+{
if (!mono_threads_is_coop_enabled ())
return NULL;
++coop_reset_blocking_count;
- info = mono_thread_info_current_unchecked ();
-
- /* If the thread is not attached, it doesn't make sense prepare for suspend. */
- if (!info || !mono_thread_info_is_live (info))
- return NULL;
+ check_info (info, "enter", "unsafe");
copy_stack_data (info, stackdata);
info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE;
return NULL;
case AbortBlockingIgnoreAndPoll:
- mono_threads_state_poll ();
+ mono_threads_state_poll_with_info (info);
return NULL;
case AbortBlockingOk:
info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE;
}
gpointer
-mono_threads_enter_gc_unsafe_region_cookie (MonoThreadInfo *info)
+mono_threads_enter_gc_unsafe_region_cookie (void)
{
+ MonoThreadInfo *info;
+
g_assert (mono_threads_is_coop_enabled ());
+ info = mono_thread_info_current_unchecked ();
+
+ check_info (info, "enter (cookie)", "unsafe");
+
#ifdef ENABLE_CHECKED_BUILD_GC
if (mono_check_mode_enabled (MONO_CHECK_MODE_GC))
coop_tls_push (info);
if (!cookie)
return;
-#ifdef ENABLE_CHECKED_BUILD_GC
- if (!mono_check_mode_enabled (MONO_CHECK_MODE_GC))
-#endif
- {
- g_assert (((MonoThreadInfo *)cookie) == mono_thread_info_current_unchecked ());
- }
-
mono_threads_enter_gc_safe_region_unbalanced (stackdata);
}
#include <glib.h>
#include "checked-build.h"
+#include "mono-threads.h"
#include "mono-threads-api.h"
G_BEGIN_DECLS
}
/*
- * The following are used for wrappers and trampolines as their
- * calls might be unbalanced, due to exception unwinding.
+ * The following are used when detaching a thread. We need to pass the MonoThreadInfo*
+ * as a paramater as the thread info TLS key is being destructed, meaning that
+ * mono_thread_info_current_unchecked will return NULL, which would lead to a
+ * runtime assertion error when trying to switch the state of the current thread.
*/
gpointer
-mono_threads_enter_gc_safe_region_unbalanced (gpointer *stackdata);
+mono_threads_enter_gc_safe_region_with_info (THREAD_INFO_TYPE *info, gpointer *stackdata);
-void
-mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata);
+#define MONO_ENTER_GC_SAFE_WITH_INFO(info) \
+ do { \
+ gpointer __gc_safe_dummy; \
+ gpointer __gc_safe_cookie = mono_threads_enter_gc_safe_region_with_info ((info), &__gc_safe_dummy)
-gpointer
-mono_threads_enter_gc_unsafe_region_unbalanced (gpointer *stackdata);
+#define MONO_EXIT_GC_SAFE_WITH_INFO MONO_EXIT_GC_SAFE
-void
-mono_threads_exit_gc_unsafe_region_unbalanced (gpointer cookie, gpointer *stackdata);
+gpointer
+mono_threads_enter_gc_unsafe_region_with_info (THREAD_INFO_TYPE *info, gpointer *stackdata);
-#define MONO_ENTER_GC_UNSAFE_UNBALANCED \
+#define MONO_ENTER_GC_UNSAFE_WITH_INFO(info) \
do { \
- gpointer __dummy; \
- gpointer __reset_cookie = mono_threads_enter_gc_unsafe_region_unbalanced (&__dummy)
+ gpointer __gc_unsafe_dummy; \
+ gpointer __gc_unsafe_cookie = mono_threads_enter_gc_unsafe_region_with_info ((info), &__gc_unsafe_dummy)
+
+#define MONO_EXIT_GC_UNSAFE_WITH_INFO MONO_EXIT_GC_UNSAFE
-#define MONO_EXIT_GC_UNSAFE_UNBALANCED \
- mono_threads_exit_gc_unsafe_region_unbalanced (__reset_cookie, &__dummy); \
- } while (0)
+gpointer
+mono_threads_enter_gc_unsafe_region_unbalanced_with_info (THREAD_INFO_TYPE *info, gpointer *stackdata);
G_END_DECLS
retry_state_change:
UNWRAP_THREAD_STATE (raw_state, cur_state, suspend_count, info);
switch (cur_state) {
- case STATE_RUNNING: //Blocking was aborted and not properly restored
- case STATE_ASYNC_SUSPEND_REQUESTED: //Blocking was aborted, not properly restored and now there's a pending suspend
- trace_state_change ("DONE_BLOCKING", info, raw_state, cur_state, 0);
- return DoneBlockingAborted;
-
case STATE_BLOCKING:
if (suspend_count == 0) {
if (InterlockedCompareExchange (&info->thread_state, build_thread_state (STATE_RUNNING, suspend_count), raw_state) != raw_state)
}
/*
+STATE_RUNNING: //Blocking was aborted and not properly restored
+STATE_ASYNC_SUSPEND_REQUESTED: //Blocking was aborted, not properly restored and now there's a pending suspend
STATE_ASYNC_SUSPENDED
STATE_SELF_SUSPENDED: Code should not be running while suspended.
STATE_SELF_SUSPEND_REQUESTED: A blocking operation must not be done while trying to self suspend
#include <mono/utils/mono-lazy-init.h>
#include <mono/utils/mono-coop-mutex.h>
#include <mono/utils/mono-coop-semaphore.h>
+#include <mono/utils/mono-threads-coop.h>
#include <errno.h>
The GC has to acquire this lock before starting a STW to make sure
a runtime suspend won't make it wronly see a thread in a safepoint
when it is in fact not.
+
+This has to be a naked locking primitive, and not a coop aware one, as
+it needs to be usable when destroying thread_info_key, the TLS key for
+the current MonoThreadInfo. In this case, mono_thread_info_current_unchecked,
+(which is used inside MONO_ENTER_GC_SAFE), would return NULL, leading
+to an assertion error. We then simply switch state manually in
+mono_thread_info_suspend_lock_with_info.
*/
-static MonoCoopSem global_suspend_semaphore;
+static MonoSemType global_suspend_semaphore;
static size_t thread_info_size;
static MonoThreadInfoCallbacks threads_callbacks;
return info;
}
+static void
+mono_thread_info_suspend_lock_with_info (MonoThreadInfo *info);
+
static void
unregister_thread (void *arg)
{
- MonoThreadInfo *info = (MonoThreadInfo *) arg;
- int small_id = info->small_id;
+ gpointer gc_unsafe_stackdata;
+ MonoThreadInfo *info;
+ int small_id;
+
+ info = (MonoThreadInfo *) arg;
g_assert (info);
+ small_id = info->small_id;
+
+ /* We only enter the GC unsafe region, as when exiting this function, the thread
+ * will be detached, and the current MonoThreadInfo* will be destroyed. */
+ mono_threads_enter_gc_unsafe_region_unbalanced_with_info (info, &gc_unsafe_stackdata);
+
THREADS_DEBUG ("unregistering info %p\n", info);
mono_native_tls_set_value (thread_exited_key, GUINT_TO_POINTER (1));
if (threads_callbacks.thread_detach)
threads_callbacks.thread_detach (info);
- mono_thread_info_suspend_lock ();
+ mono_thread_info_suspend_lock_with_info (info);
/*
Now perform the callback that must be done under locks.
unified_suspend_enabled = g_getenv ("MONO_ENABLE_UNIFIED_SUSPEND") != NULL || mono_threads_is_coop_enabled ();
- mono_coop_sem_init (&global_suspend_semaphore, 1);
+ mono_os_sem_init (&global_suspend_semaphore, 1);
mono_os_sem_init (&suspend_semaphore, 0);
mono_lls_init (&thread_list, NULL, HAZARD_FREE_NO_LOCK);
A GC that has safepoints must take this lock as part of its
STW to make sure no unsafe pending suspend is in progress.
*/
+
+static void
+mono_thread_info_suspend_lock_with_info (MonoThreadInfo *info)
+{
+ g_assert (info);
+
+ MONO_ENTER_GC_SAFE_WITH_INFO(info);
+
+ int res = mono_os_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
+ g_assert (res != -1);
+
+ MONO_EXIT_GC_SAFE_WITH_INFO;
+}
+
void
mono_thread_info_suspend_lock (void)
{
- int res = mono_coop_sem_wait (&global_suspend_semaphore, MONO_SEM_FLAGS_NONE);
- g_assert (res != -1);
+ mono_thread_info_suspend_lock_with_info (mono_thread_info_current_unchecked ());
}
void
mono_thread_info_suspend_unlock (void)
{
- mono_coop_sem_post (&global_suspend_semaphore);
+ mono_os_sem_post (&global_suspend_semaphore);
}
/*
else
g_string_append_printf (text, "waiting");
}
+
+gboolean
+mono_thread_info_is_current (MonoThreadInfo *info)
+{
+ return mono_thread_info_get_tid (info) == mono_native_thread_id_get ();
+}
#include <mono/utils/mono-stack-unwinding.h>
#include <mono/utils/mono-linked-list-set.h>
#include <mono/utils/mono-tls.h>
-#include <mono/utils/mono-threads-coop.h>
-#include <mono/utils/mono-threads-api.h>
#include <mono/utils/mono-coop-semaphore.h>
#include <mono/io-layer/io-layer.h>
} MonoDoBlockingResult;
typedef enum {
- DoneBlockingAborted, //blocking was aborted and not properly restored, poll the state
DoneBlockingOk, //exited blocking fine
DoneBlockingWait, //thread should end suspended
} MonoDoneBlockingResult;
MonoThreadUnwindState* mono_thread_info_get_suspend_state (THREAD_INFO_TYPE *info);
gpointer
-mono_threads_enter_gc_unsafe_region_cookie (THREAD_INFO_TYPE *info);
+mono_threads_enter_gc_unsafe_region_cookie (void);
void mono_thread_info_wait_for_resume (THREAD_INFO_TYPE *info);
void mono_threads_begin_global_suspend (void);
void mono_threads_end_global_suspend (void);
+gboolean
+mono_thread_info_is_current (THREAD_INFO_TYPE *info);
+
#endif /* __MONO_THREADS_H__ */
TLS_KEY_SGEN_TLAB_TEMP_END = 6,
TLS_KEY_BOEHM_GC_THREAD = 7,
TLS_KEY_LMF_ADDR = 8,
- TLS_KEY_NUM = 9
+ TLS_KEY_SGEN_IN_CRITICAL_REGION_ADDR = 9,
+ TLS_KEY_NUM = 10
} MonoTlsKey;
#ifdef HOST_WIN32
--- /dev/null
+cp $(ProjectDir)\System.Json\Properties\Resources.resx System.Json.Properties.Resources.resx
\ No newline at end of file
--- /dev/null
+@COPY@ $(ProjectDir)/../../../external/aspnetwebstack/src/Common/CommonWebApiResources.resx $(ProjectDir)/System.Net.Http.Properties.CommonWebApiResources.resx
+@COPY@ $(ProjectDir)/../../../external/aspnetwebstack/src/System.Net.Http.Formatting/Properties/Resources.resx $(ProjectDir)/System.Net.Http.Properties.Resources.resx
--- /dev/null
+@MONO@ $(ProjectDir)\..\lib\net_4_x\culevel.exe -o $(ProjectDir)\System.Web\UplevelHelper.cs $(ProjectDir)\UplevelHelperDefinitions.xml
--- /dev/null
+$(ProjectDir)\..\..\jay\jay.exe -ct < $(ProjectDir)\..\..\jay\skeleton.cs $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.jay > $(ProjectDir)\Monodoc.Ecma\EcmaUrlParser.cs
+
<profile>xbuild_14</profile>
<response>xbuild.exe.sources</response>
</project>
- <project dir="class/System.Json.Microsoft" library="System.Json.Microsoft-net_4_x">
- <boot>false</boot>
- <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -d:DISABLE_CAS_USE -nowarn:1699 -nostdlib -r:./../../class/lib/net_4_x/mscorlib.dll -debug -optimize /noconfig /d:ASPNETMVC -keyfile:../winfx.pub -delaysign /resource:System.Json/Properties/Resources.resources,System.Json.Properties.Resources.resources -d:FEATURE_DYNAMIC -r:./../../class/lib/net_4_x/System.dll -r:./../../class/lib/net_4_x/System.Xml.dll -r:./../../class/lib/net_4_x/System.Core.dll -r:./../../class/lib/net_4_x/System.Runtime.Serialization.dll -r:./../../class/lib/net_4_x/Microsoft.CSharp.dll</flags>
- <output>System.Json.Microsoft.dll</output>
- <built_sources></built_sources>
- <library_output>./../../class/lib/net_4_x/System.Json.Microsoft.dll</library_output>
- <fx_version>4.5</fx_version>
- <profile>net_4_x</profile>
- <response>System.Json.Microsoft.dll.sources</response>
- </project>
- <project dir="class/System.Json.Microsoft" library="System.Json.Microsoft-tests-net_4_x">
- <boot>false</boot>
- <flags>/codepage:65001 -d:NET_4_0 -d:NET_4_5 -d:NET_4_6 -d:MONO -d:DISABLE_CAS_USE -nowarn:1699 -nostdlib -r:./../../class/lib/net_4_x/mscorlib.dll -debug -optimize -r:./../../class/lib/net_4_x/System.Json.Microsoft.dll /d:ASPNETMVC -keyfile:../winfx.pub -delaysign /resource:System.Json/Properties/Resources.resources,System.Json.Properties.Resources.resources -d:FEATURE_DYNAMIC -r:./../../class/lib/net_4_x/System.dll -r:./../../class/lib/net_4_x/System.Xml.dll -r:./../../class/lib/net_4_x/System.Core.dll -r:./../../class/lib/net_4_x/System.Runtime.Serialization.dll -r:./../../class/lib/net_4_x/Microsoft.CSharp.dll</flags>
- <output>net_4_x_System.Json.Microsoft_test.dll</output>
- <built_sources></built_sources>
- <library_output>net_4_x_System.Json.Microsoft_test.dll</library_output>
- <fx_version>4.5</fx_version>
- <profile>net_4_x</profile>
- <response>./../../build/deps/net_4_x_System.Json.Microsoft_test.dll.response</response>
- </project>
</root>
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Core-net_4_x", "mcs/class/System.Core/System.Core-net_4_x.csproj", "{359142A1-D80F-401E-AA64-7167C9317649}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.CompilerServices.SymbolWriter-net_4_x", "mcs/class/Mono.CompilerServices.SymbolWriter/Mono.CompilerServices.SymbolWriter-net_4_x.csproj", "{88177C4B-894F-485D-B95A-44199C06BE9F}"
-EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Posix-net_4_x", "mcs/class/Mono.Posix/Mono.Posix-net_4_x.csproj", "{66DBB049-785B-4C2E-9EF6-C9E163F7DDD1}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.CompilerServices.SymbolWriter-net_4_x", "mcs/class/Mono.CompilerServices.SymbolWriter/Mono.CompilerServices.SymbolWriter-net_4_x.csproj", "{88177C4B-894F-485D-B95A-44199C06BE9F}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Core-plaincore-net_4_x", "mcs/class/System.Core/System.Core-plaincore-net_4_x.csproj", "{1EC0EBC0-0B35-454C-89AE-3F8F0FDD9705}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "resgen-net_4_x", "mcs/tools/resgen/resgen-net_4_x.csproj", "{647DC12E-A4EE-424A-9EC7-CE6643EE2EF7}"
{359142A1-D80F-401E-AA64-7167C9317649}.Debug|Any CPU.Build.0 = Debug|Any CPU
{359142A1-D80F-401E-AA64-7167C9317649}.Release|Any CPU.ActiveCfg = Release|Any CPU
{359142A1-D80F-401E-AA64-7167C9317649}.Release|Any CPU.Build.0 = Release|Any CPU
- {88177C4B-894F-485D-B95A-44199C06BE9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {88177C4B-894F-485D-B95A-44199C06BE9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {88177C4B-894F-485D-B95A-44199C06BE9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {88177C4B-894F-485D-B95A-44199C06BE9F}.Release|Any CPU.Build.0 = Release|Any CPU
{66DBB049-785B-4C2E-9EF6-C9E163F7DDD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{66DBB049-785B-4C2E-9EF6-C9E163F7DDD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{66DBB049-785B-4C2E-9EF6-C9E163F7DDD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{66DBB049-785B-4C2E-9EF6-C9E163F7DDD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {88177C4B-894F-485D-B95A-44199C06BE9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88177C4B-894F-485D-B95A-44199C06BE9F}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88177C4B-894F-485D-B95A-44199C06BE9F}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88177C4B-894F-485D-B95A-44199C06BE9F}.Release|Any CPU.Build.0 = Release|Any CPU
{1EC0EBC0-0B35-454C-89AE-3F8F0FDD9705}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1EC0EBC0-0B35-454C-89AE-3F8F0FDD9705}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1EC0EBC0-0B35-454C-89AE-3F8F0FDD9705}.Release|Any CPU.ActiveCfg = Release|Any CPU