-Subproject commit 0ffb5c87150819946858f452367c72ca89634ac1
+Subproject commit 8c7937a9e7cc3f61f9ceb6a9d6f19fefdf1672b0
System.Runtime.Serialization/DataContractSerializerTest_InvalidCharacters.cs
System.Runtime.Serialization/DataContractSerializerTest_ISerializable.cs
System.Runtime.Serialization/DataContractSerializerTest.cs
+System.Runtime.Serialization/Exceptions.cs
System.Runtime.Serialization/KnownTypeAttributeTest.cs
System.Runtime.Serialization/XmlObjectSerializerTest.cs
System.Runtime.Serialization/XsdDataContractExporterTest.cs
--- /dev/null
+//
+// Exceptions
+//
+// Authors:
+// Andi McClure (andi.mcclure@xamarin.com)
+//
+// Copyright 2016 Xamarin Inc. (http://www.xamarin.com)
+//
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using NUnit.Framework;
+
+namespace MonoTests.System.Runtime.Serialization
+{
+ [TestFixture]
+ public class Exceptions
+ {
+ [Serializable]
+ public class SerializableException : Exception
+ {
+ public string Data;
+
+ public SerializableException (string data) {
+ Data = data;
+
+ SerializeObjectState += HandleSerialization;
+ }
+
+ private static void HandleSerialization (object exception, SafeSerializationEventArgs eventArgs) {
+ eventArgs.AddSerializedState (new SerializableExceptionState (exception));
+ }
+
+ [Serializable]
+ private class SerializableExceptionState : ISafeSerializationData {
+ private string Data;
+
+ public SerializableExceptionState (object _exception) {
+ SerializableException exception = (SerializableException)_exception;
+
+ Data = exception.Data;
+ }
+
+ public void CompleteDeserialization (object _exception) {
+ SerializableException exception = (SerializableException)_exception;
+ exception.SerializeObjectState += HandleSerialization;
+
+ exception.Data = Data;
+ }
+ }
+ }
+
+ // Effectively tests SerializeObjectState handler support on System.Exception
+ [Test]
+ public void Exception_SerializeObjectState () {
+ SerializableException exception = new SerializableException ("success");
+ SerializableException deserializedException;
+ BinaryFormatter binaryFormatter = new BinaryFormatter ();
+
+ using (MemoryStream memoryStream = new MemoryStream ())
+ {
+ binaryFormatter.Serialize (memoryStream, exception);
+ memoryStream.Flush ();
+
+ memoryStream.Seek (0, SeekOrigin.Begin);
+
+ deserializedException = (SerializableException)binaryFormatter.Deserialize (memoryStream);
+ }
+
+ Assert.AreEqual ("success", deserializedException.Data);
+ }
+ }
+}
\ No newline at end of file
f = new FileStream (path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read,
8192, false, (FileOptions) 1);
} catch (IOException ex){
- if (ex.hresult != MonoIO.FileAlreadyExistsHResult || count ++ > 65536)
+ if (ex._HResult != MonoIO.FileAlreadyExistsHResult || count ++ > 65536)
throw;
} catch (UnauthorizedAccessException ex) {
if (count ++ > 65536)
public override IList<CustomAttributeData> GetCustomAttributesData () {
return CustomAttributeData.GetCustomAttributes (this);
}
+
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ public extern int get_core_clr_security_level ();
+
+ public override bool IsSecurityTransparent {
+ get { return get_core_clr_security_level () == 0; }
+ }
+
+ public override bool IsSecurityCritical {
+ get { return get_core_clr_security_level () > 0; }
+ }
+
+ public override bool IsSecuritySafeCritical {
+ get { return get_core_clr_security_level () == 1; }
+ }
}
}
var errorInfo = new ManagedErrorInfo(e);
SetErrorInfo (0, errorInfo);
- return e.hresult;
+ return e._HResult;
#else
return -1;
#endif
}
}
- if (info is ManagedErrorInfo && ((ManagedErrorInfo) info).Exception.hresult == errorCode) {
+ if (info is ManagedErrorInfo && ((ManagedErrorInfo) info).Exception._HResult == errorCode) {
return ((ManagedErrorInfo) info).Exception;
}
* of icalls, do not require an increment.
*/
#pragma warning disable 169
- private const int mono_corlib_version = 144;
+ private const int mono_corlib_version = 145;
#pragma warning restore 169
[ComVisible (true)]
{
}
+
+ // Copied from referencesource Environment
+ internal static String GetStackTrace(Exception e, bool needFileInfo)
+ {
+ System.Diagnostics.StackTrace st;
+ if (e == null)
+ st = new System.Diagnostics.StackTrace(needFileInfo);
+ else
+ st = new System.Diagnostics.StackTrace(e, needFileInfo);
+
+ // Do not include a trailing newline for backwards compatibility
+ return st.ToString( System.Diagnostics.StackTrace.TraceFormat.Normal );
+ }
}
}
+++ /dev/null
-//
-// System.Exception.cs
-//
-// Author:
-// Miguel de Icaza (miguel@ximian.com)
-// Patrik Torstensson
-//
-// (C) Ximian, Inc. http://www.ximian.com
-// Copyright (C) 2004-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.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Reflection;
-using System.Text;
-using System.Runtime.InteropServices;
-using System.Runtime.CompilerServices;
-using System.Runtime.Serialization;
-using System.Security.Permissions;
-
-namespace System
-{
- [Serializable]
- [ComVisible(true)]
- [ComDefaultInterface (typeof (_Exception))]
- [ClassInterface (ClassInterfaceType.None)]
- [StructLayout (LayoutKind.Sequential)]
-#if MOBILE
- public class Exception : ISerializable
-#else
- public class Exception : ISerializable, _Exception
-#endif
- {
-#pragma warning disable 169, 649
- #region Sync with object-internals.h
- /* Stores the IPs and the generic sharing infos
- (vtable/MRGCTX) of the frames. */
- IntPtr [] trace_ips;
- Exception inner_exception;
- internal string _message;
- string help_link;
- string class_name;
- string stack_trace;
- // formerly known as remote_stack_trace (see #425512):
- string _remoteStackTraceString;
- int remote_stack_index;
- internal int hresult = -2146233088;
- string source;
- IDictionary _data;
- internal StackTrace[] captured_traces;
- IntPtr[] native_trace_ips;
- object dynamic_methods;
- #endregion
-#pragma warning restore 169, 649
-
- /* Don't add fields here, the runtime depends on the layout of subclasses */
-
- public Exception ()
- {
- }
-
- public Exception (string message)
- {
- this._message = message;
- }
-
- protected Exception (SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException ("info");
-
- class_name = info.GetString ("ClassName");
- _message = info.GetString ("Message");
- help_link = info.GetString ("HelpURL");
- stack_trace = info.GetString ("StackTraceString");
- _remoteStackTraceString = info.GetString ("RemoteStackTraceString");
- remote_stack_index = info.GetInt32 ("RemoteStackIndex");
- hresult = info.GetInt32 ("HResult");
- source = info.GetString ("Source");
- inner_exception = (Exception) info.GetValue ("InnerException", typeof (Exception));
-
- try {
- _data = (IDictionary) info.GetValue ("Data", typeof (IDictionary));
- } catch (SerializationException) {
- // member did not exist in .NET 1.x
- }
- }
-
- public Exception (string message, Exception innerException)
- {
- inner_exception = innerException;
- this._message = message;
- }
-
- public Exception InnerException {
- get { return inner_exception; }
- }
-
- public virtual string HelpLink {
- get { return help_link; }
- set { help_link = value; }
- }
-
- public int HResult {
- get { return hresult; }
- protected set { hresult = value; }
- }
-
- internal void SetErrorCode(int hr)
- {
- HResult = hr;
- }
-
- internal void SetMessage (string s)
- {
- _message = s;
- }
-
- internal void SetStackTrace (string s)
- {
- stack_trace = s;
- }
-
- string ClassName {
- get {
- if (class_name == null)
- class_name = GetType ().ToString ();
- return class_name;
- }
- }
-
- public virtual string Message {
- get {
- if (_message == null)
- _message = string.Format (Locale.GetText ("Exception of type '{0}' was thrown."),
- ClassName);
-
- return _message;
- }
- }
-
- [MonoTODO]
- protected event EventHandler<SafeSerializationEventArgs> SerializeObjectState {
- add {
- }
- remove {
- }
- }
-
- public virtual string Source {
- get {
- if (source == null) {
- StackTrace st = new StackTrace (this, true);
- if (st.FrameCount > 0) {
- StackFrame sf = st.GetFrame (0);
- if (st != null) {
- MethodBase method = sf.GetMethod ();
- if (method != null) {
- source = method.DeclaringType.Assembly.UnprotectedGetName ().Name;
- }
- }
- }
- }
-
- // source can be null
- return source;
- }
-
- set {
- source = value;
- }
- }
-
- public virtual string StackTrace {
- get {
- if (stack_trace != null)
- return stack_trace;
-
- if (trace_ips == null)
- /* Not thrown yet */
- return null;
-
- StackTrace st = new StackTrace (this, 0, true);
- return stack_trace = st.ToString ();
- }
- }
-
- public MethodBase TargetSite {
- get {
- StackTrace st = new StackTrace (this, true);
- if (st.FrameCount > 0)
- return st.GetFrame (0).GetMethod ();
-
- return null;
- }
- }
-
- public virtual IDictionary Data {
- get {
- if (_data == null) {
- // default to empty dictionary
- _data = new Dictionary<object, object> ();
- }
- return _data;
- }
- }
-
- public virtual Exception GetBaseException ()
- {
- Exception inner = inner_exception;
-
- while (inner != null)
- {
- if (inner.InnerException != null)
- inner = inner.InnerException;
- else
- return inner;
- }
-
- return this;
- }
-
- [SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
- public virtual void GetObjectData (SerializationInfo info, StreamingContext context)
- {
- if (info == null)
- throw new ArgumentNullException ("info");
-
- info.AddValue ("ClassName", ClassName);
- info.AddValue ("Message", _message);
- info.AddValue ("InnerException", inner_exception, typeof (Exception));
- info.AddValue ("HelpURL", help_link);
- info.AddValue ("StackTraceString", StackTrace);
- info.AddValue ("RemoteStackTraceString", _remoteStackTraceString);
- info.AddValue ("RemoteStackIndex", remote_stack_index);
- info.AddValue ("HResult", hresult);
- info.AddValue ("Source", Source);
- info.AddValue ("ExceptionMethod", null);
- info.AddValue ("Data", _data, typeof (IDictionary));
- }
-
- public override string ToString ()
- {
- System.Text.StringBuilder result = new System.Text.StringBuilder (ClassName);
- result.Append (": ").Append (Message);
-
- if (null != _remoteStackTraceString)
- result.Append (_remoteStackTraceString);
-
- if (inner_exception != null)
- {
- result.Append (" ---> ").Append (inner_exception.ToString ());
- result.Append (Environment.NewLine);
- result.Append (Locale.GetText (" --- End of inner exception stack trace ---"));
- }
-
- if (StackTrace != null)
- result.Append (Environment.NewLine).Append (StackTrace);
- return result.ToString();
- }
-
- internal Exception FixRemotingException ()
- {
- string message = (0 == remote_stack_index) ?
- Locale.GetText ("{0}{0}Server stack trace: {0}{1}{0}{0}Exception rethrown at [{2}]: {0}") :
- Locale.GetText ("{1}{0}{0}Exception rethrown at [{2}]: {0}");
- string tmp = String.Format (message, Environment.NewLine, StackTrace, remote_stack_index);
-
- _remoteStackTraceString = tmp;
- remote_stack_index++;
-
- stack_trace = null;
-
- return this;
- }
-
- // For ExceptionDispatchInfo
- internal void RestoreExceptionDispatchInfo (System.Runtime.ExceptionServices.ExceptionDispatchInfo exceptionDispatchInfo)
- {
- captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
- trace_ips = null;
- stack_trace = null;
- }
-
- //
- // The documentation states that this is available in 1.x,
- // but it was not available (MemberRefing this would fail)
- // and it states the signature is `override sealed', but the
- // correct value is `newslot'
- //
- public new Type GetType ()
- {
- return base.GetType ();
- }
-
- internal enum ExceptionMessageKind
- {
- ThreadAbort = 1,
- ThreadInterrupted = 2,
- OutOfMemory = 3
- }
-
- internal static String GetMessageFromNativeResources (ExceptionMessageKind kind)
- {
- switch (kind) {
- case ExceptionMessageKind.ThreadAbort:
- return "";
- case ExceptionMessageKind.ThreadInterrupted:
- return "";
- case ExceptionMessageKind.OutOfMemory:
- return "Out of memory";
- }
- return "";
- }
- }
-}
public void Ctor ()
{
var cp = new CspParameters ();
- Assert.AreEqual (24, cp.ProviderType);
+ Assert.AreEqual (1, cp.ProviderType);
}
}
}
System/EmptyArray.cs
System/Environment.cs
System/EnvironmentVariableTarget.cs
-System/Exception.cs
System/GC.cs
System/GCCollectionMode.cs
System/GCNotificationStatus.cs
../../../external/referencesource/mscorlib/system/entrypointnotfoundexception.cs
../../../external/referencesource/mscorlib/system/eventargs.cs
../../../external/referencesource/mscorlib/system/eventhandler.cs
+../../../external/referencesource/mscorlib/system/exception.cs
../../../external/referencesource/mscorlib/system/executionengineexception.cs
../../../external/referencesource/mscorlib/system/fieldaccessexception.cs
../../../external/referencesource/mscorlib/system/flagsattribute.cs
/// false if candidate ain't better
/// true if candidate is better than the current best match
/// </remarks>
- static bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, AParametersCollection cparam, bool candidate_params,
+ bool BetterFunction (ResolveContext ec, Arguments args, MemberSpec candidate, AParametersCollection cparam, bool candidate_params,
MemberSpec best, AParametersCollection bparam, bool best_params)
{
AParametersCollection candidate_pd = ((IParametersMember) candidate).Parameters;
// for each argument, the conversion to 'ct' should be no worse than
// the conversion to 'bt'.
if (result == 2) {
+ //
+ // No optional parameters tie breaking rules for delegates overload resolution
+ //
+ if ((this.restrictions & Restrictions.CovariantDelegate) != 0)
+ return false;
+
better_at_least_one = false;
++j;
--- /dev/null
+using System;
+
+class Test1
+{
+ static object Foo (int arg = 1, int arg2 = 2)
+ {
+ return null;
+ }
+
+ static object Foo (object arg, object arg2)
+ {
+ return null;
+ }
+
+ public static void Main ()
+ {
+ Func<int, int, object> o = Foo;
+ }
+}
\ No newline at end of file
</method>
</type>
</test>
+ <test name="gtest-optional-37.cs">
+ <type name="Test1">
+ <method name="System.Object Foo(Int32, Int32)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="System.Object Foo(System.Object, System.Object)" attrs="145">
+ <size>10</size>
+ </method>
+ <method name="Void Main()" attrs="150">
+ <size>32</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-partial-01.cs">
<type name="B`1[U]">
<method name="Void .ctor()" attrs="6278">
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 144
+#define MONO_CORLIB_VERSION 145
typedef struct
{
ICALL_TYPE(MCMETH, "System.Reflection.MonoCMethod", MCMETH_1)
ICALL(MCMETH_1, "GetGenericMethodDefinition_impl", ves_icall_MonoMethod_GetGenericMethodDefinition)
ICALL(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke)
+ICALL(MCMETH_3, "get_core_clr_security_level", ves_icall_MonoMethod_get_core_clr_security_level)
ICALL_TYPE(MEVIN, "System.Reflection.MonoEventInfo", MEVIN_1)
ICALL(MEVIN_1, "get_event_info", ves_icall_MonoEventInfo_get_event_info)
mach_port_t host = mach_host_self();
vm_size_t page_size;
vm_statistics_data_t vmstat;
- if (KERN_SUCCESS != host_statistics(host, HOST_VM_INFO, (host_info_t)&vmstat, &count)) {
+ kern_return_t ret;
+ do {
+ ret = host_statistics(host, HOST_VM_INFO, (host_info_t)&vmstat, &count);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS) {
g_warning ("Mono was unable to retrieve memory usage!");
return 0;
}
struct _MonoException {
MonoObject object;
+ MonoString *class_name;
+ MonoString *message;
+ MonoObject *_data;
+ MonoObject *inner_ex;
+ MonoString *help_link;
/* Stores the IPs and the generic sharing infos
(vtable/MRGCTX) of the frames. */
MonoArray *trace_ips;
- MonoObject *inner_ex;
- MonoString *message;
- MonoString *help_link;
- MonoString *class_name;
MonoString *stack_trace;
MonoString *remote_stack_trace;
gint32 remote_stack_index;
+ /* Dynamic methods referenced by the stack trace */
+ MonoObject *dynamic_methods;
gint32 hresult;
MonoString *source;
- MonoObject *_data;
+ MonoObject *serialization_manager;
MonoObject *captured_traces;
MonoArray *native_trace_ips;
- /* Dynamic methods referenced by the stack trace */
- MonoObject *dynamic_methods;
};
typedef struct {
gboolean
sgen_resume_thread (SgenThreadInfo *info)
{
- return thread_resume (info->client_info.info.native_handle) == KERN_SUCCESS;
+ kern_return_t ret;
+ do {
+ ret = thread_resume (info->client_info.info.native_handle);
+ } while (ret == KERN_ABORTED);
+ return ret == KERN_SUCCESS;
}
gboolean
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
- ret = thread_suspend (info->client_info.info.native_handle);
+ do {
+ ret = thread_suspend (info->client_info.info.native_handle);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
return FALSE;
- ret = mono_mach_arch_get_thread_state (info->client_info.info.native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_state (info->client_info.info.native_handle, state, &num_state);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
return FALSE;
if (!sgen_suspend_thread (info))
continue;
} else {
- ret = thread_resume (info->client_info.info.native_handle);
+ do {
+ ret = thread_resume (info->client_info.info.native_handle);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
continue;
}
}
#if defined(MONO_ARCH_GSHAREDVT_SUPPORTED)
- acfg->opts |= MONO_OPT_GSHAREDVT;
- opts |= MONO_OPT_GSHAREDVT;
+ if (acfg->aot_opts.llvm_only || mono_aot_mode_is_full (&acfg->aot_opts)) {
+ acfg->opts |= MONO_OPT_GSHAREDVT;
+ opts |= MONO_OPT_GSHAREDVT;
+ }
#endif
if (opts & MONO_OPT_GSHAREDVT)
/* allocate two contiguous pages of memory: the first page will contain the data (like a local constant pool)
* while the second will contain the trampolines.
*/
- ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+ do {
+ ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS) {
g_error ("Cannot allocate memory for trampolines: %d", ret);
break;
#include <dlfcn.h>
#include <AvailabilityMacros.h>
-#if defined (TARGET_OSX) && (MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5)
-#define NEEDS_EXCEPTION_THREAD
-#endif
-
-#ifdef NEEDS_EXCEPTION_THREAD
-
-/*
- * This code disables the CrashReporter of MacOS X by installing
- * a dummy Mach exception handler.
- */
-
-/*
- * http://darwinsource.opendarwin.org/10.4.3/xnu-792.6.22/osfmk/man/exc_server.html
- */
-extern boolean_t exc_server (mach_msg_header_t *request_msg, mach_msg_header_t *reply_msg);
-
-/*
- * The exception message
- */
-typedef struct {
- mach_msg_base_t msg; /* common mach message header */
- char payload [1024]; /* opaque */
-} mach_exception_msg_t;
-
-/* The exception port */
-static mach_port_t mach_exception_port = VM_MAP_NULL;
-
-kern_return_t
-catch_exception_raise (
- mach_port_t exception_port,
- mach_port_t thread,
- mach_port_t task,
- exception_type_t exception,
- exception_data_t code,
- mach_msg_type_number_t code_count);
-
-/*
- * Implicitly called by exc_server. Must be public.
- *
- * http://darwinsource.opendarwin.org/10.4.3/xnu-792.6.22/osfmk/man/catch_exception_raise.html
- */
-kern_return_t
-catch_exception_raise (
- mach_port_t exception_port,
- mach_port_t thread,
- mach_port_t task,
- exception_type_t exception,
- exception_data_t code,
- mach_msg_type_number_t code_count)
-{
- /* consume the exception */
- return KERN_FAILURE;
-}
-
-/*
- * Exception thread handler.
- */
-static
-void *
-mach_exception_thread (void *arg)
-{
- for (;;) {
- mach_exception_msg_t request;
- mach_exception_msg_t reply;
- mach_msg_return_t result;
-
- /* receive from "mach_exception_port" */
- result = mach_msg (&request.msg.header,
- MACH_RCV_MSG | MACH_RCV_LARGE,
- 0,
- sizeof (request),
- mach_exception_port,
- MACH_MSG_TIMEOUT_NONE,
- MACH_PORT_NULL);
-
- g_assert (result == MACH_MSG_SUCCESS);
-
- /* dispatch to catch_exception_raise () */
- exc_server (&request.msg.header, &reply.msg.header);
-
- /* send back to sender */
- result = mach_msg (&reply.msg.header,
- MACH_SEND_MSG,
- reply.msg.header.msgh_size,
- 0,
- MACH_PORT_NULL,
- MACH_MSG_TIMEOUT_NONE,
- MACH_PORT_NULL);
-
- /*
- If we try to abort the thread while delivering an exception. The port will be gone since the kernel
- setup a send once port to deliver the resume message and thread_abort will consume it.
- */
- g_assert (result == MACH_MSG_SUCCESS || result == MACH_SEND_INVALID_DEST);
- }
- return NULL;
-}
-
-static void
-macosx_register_exception_handler (void)
-{
- mach_port_t task;
- pthread_attr_t attr;
- pthread_t thread;
-
- if (mach_exception_port != VM_MAP_NULL)
- return;
-
- task = mach_task_self ();
-
- /* create the "mach_exception_port" with send & receive rights */
- g_assert (mach_port_allocate (task, MACH_PORT_RIGHT_RECEIVE,
- &mach_exception_port) == KERN_SUCCESS);
- g_assert (mach_port_insert_right (task, mach_exception_port, mach_exception_port,
- MACH_MSG_TYPE_MAKE_SEND) == KERN_SUCCESS);
-
- /* create the exception handler thread */
- g_assert (!pthread_attr_init (&attr));
- g_assert (!pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED));
- g_assert (!pthread_create (&thread, &attr, mach_exception_thread, NULL));
- pthread_attr_destroy (&attr);
-
- /*
- * register "mach_exception_port" as a receiver for the
- * EXC_BAD_ACCESS exception
- *
- * http://darwinsource.opendarwin.org/10.4.3/xnu-792.6.22/osfmk/man/task_set_exception_ports.html
- */
- g_assert (task_set_exception_ports (task, EXC_MASK_BAD_ACCESS,
- mach_exception_port,
- EXCEPTION_DEFAULT,
- MACHINE_THREAD_STATE) == KERN_SUCCESS);
-
- mono_gc_register_mach_exception_thread (thread);
-}
-
-#endif
-
/* This is #define'd by Boehm GC to _GC_dlopen. */
#undef dlopen
void
mono_runtime_install_handlers (void)
{
-#ifdef NEEDS_EXCEPTION_THREAD
- macosx_register_exception_handler ();
-#endif
mono_runtime_posix_install_handlers ();
/* Snow Leopard has a horrible bug: http://openradar.appspot.com/7209349
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
- ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ } while (ret == KERN_ABORTED);
if (ret != KERN_SUCCESS)
return FALSE;
{
kern_return_t ret;
- if ((ret = host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, &sampling_clock_service)) != KERN_SUCCESS)
+ do {
+ ret = host_get_clock_service (mach_host_self (), SYSTEM_CLOCK, &sampling_clock_service);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
g_error ("%s: host_get_clock_service () returned %d", __func__, ret);
}
{
kern_return_t ret;
- if ((ret = mach_port_deallocate (mach_task_self (), sampling_clock_service)) != KERN_SUCCESS)
+ do {
+ ret = mach_port_deallocate (mach_task_self (), sampling_clock_service);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
g_error ("%s: mach_port_deallocate () returned %d", __func__, ret);
}
kern_return_t ret;
mach_timespec_t mach_ts;
- if ((ret = clock_get_time (sampling_clock_service, &mach_ts)) != KERN_SUCCESS)
+ do {
+ ret = clock_get_time (sampling_clock_service, &mach_ts);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
g_error ("%s: clock_get_time () returned %d", __func__, ret);
return ((guint64) mach_ts.tv_sec * 1000000000) + (guint64) mach_ts.tv_nsec;
do {
ret = clock_sleep (sampling_clock_service, TIME_ABSOLUTE, then, &remain_unused);
-
- if (ret != KERN_SUCCESS && ret != KERN_ABORTED)
- g_error ("%s: clock_sleep () returned %d", __func__, ret);
} while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
+ g_error ("%s: clock_sleep () returned %d", __func__, ret);
+
}
#else
definitely_pinned [count] = obj_to_pin;
count++;
}
+ if (concurrent_collection_in_progress)
+ sgen_pinning_register_pinned_in_nursery (obj_to_pin);
next_pin_queue_entry:
last = addr;
major_collector.scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx);
sgen_los_scan_card_table (CARDTABLE_SCAN_MOD_UNION_PRECLEAN, ctx);
+
+ sgen_scan_pin_queue_objects (ctx);
}
static void
alloc_nursery ();
+ sgen_pinning_init ();
sgen_cement_init (cement_enabled);
if ((env = g_getenv (MONO_GC_DEBUG_NAME))) {
static SgenPointerQueue pin_queue;
static size_t last_num_pinned = 0;
+/*
+ * While we hold the pin_queue_mutex, all objects in pin_queue_objs will
+ * stay pinned, which means they can't move, therefore they can be scanned.
+ */
+static SgenPointerQueue pin_queue_objs;
+static MonoCoopMutex 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);
+}
+
void
sgen_init_pinning (void)
{
+ mono_coop_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);
}
void
{
last_num_pinned = pin_queue.next_slot;
sgen_pointer_queue_clear (&pin_queue);
+ mono_coop_mutex_unlock (&pin_queue_mutex);
+}
+
+void
+sgen_pinning_register_pinned_in_nursery (GCObject *obj)
+{
+ sgen_pointer_queue_add (&pin_queue_objs, obj);
+}
+
+void
+sgen_scan_pin_queue_objects (ScanCopyContext ctx)
+{
+ int i;
+ ScanObjectFunc scan_func = ctx.ops->scan_object;
+
+ mono_coop_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);
}
void
PIN_TYPE_MAX
};
+void sgen_pinning_init (void);
void sgen_pin_stage_ptr (void *ptr);
void sgen_optimize_pin_queue (void);
void sgen_init_pinning (void);
void sgen_finish_pinning (void);
+void sgen_pinning_register_pinned_in_nursery (GCObject *obj);
+void sgen_scan_pin_queue_objects (ScanCopyContext ctx);
void sgen_pin_queue_clear_discarded_entries (GCMemSection *section, size_t max_pin_slot);
size_t sgen_get_pinned_count (void);
void sgen_pinning_setup_section (GCMemSection *section);
do {
ret = task_threads (current_task (), threads, count);
- } while (ret != KERN_SUCCESS);
+ } while (ret == KERN_ABORTED);
return ret;
}
mono_os_sem_post (MonoSemType *sem)
{
int res;
-
+retry:
res = semaphore_signal (*sem);
g_assert (res != KERN_INVALID_ARGUMENT);
+ if (res == KERN_ABORTED)
+ goto retry;
+
return res != KERN_SUCCESS ? -1 : 0;
}
mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT, th_count;
thread_array_t th_array;
size_t i;
+ kern_return_t ret;
if (pid == getpid ()) {
/* task_for_pid () doesn't work on ios, even for the current process */
task = mach_task_self ();
} else {
- if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+ do {
+ ret = task_for_pid (mach_task_self (), pid, &task);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS)
RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
}
- if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count) != KERN_SUCCESS) {
+ do {
+ ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count);
+ } while (ret == KERN_ABORTED);
+
+ if (ret != KERN_SUCCESS) {
if (pid != getpid ())
mach_port_deallocate (mach_task_self (), task);
RET_ERROR (MONO_PROCESS_ERROR_OTHER);
}
+
+ do {
+ ret = task_threads (task, &th_array, &th_count);
+ } while (ret == KERN_ABORTED);
- if (task_threads(task, &th_array, &th_count) != KERN_SUCCESS) {
+ if (ret != KERN_SUCCESS) {
if (pid != getpid ())
mach_port_deallocate (mach_task_self (), task);
RET_ERROR (MONO_PROCESS_ERROR_OTHER);
struct thread_basic_info th_info;
mach_msg_type_number_t th_info_count = THREAD_BASIC_INFO_COUNT;
- if (thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count) == KERN_SUCCESS) {
+ do {
+ ret = thread_info(th_array[i], THREAD_BASIC_INFO, (thread_info_t)&th_info, &th_info_count);
+ } while (ret == KERN_ABORTED);
+
+ if (ret == KERN_SUCCESS) {
thread_user_time = th_info.user_time.seconds + th_info.user_time.microseconds / 1e6;
thread_system_time = th_info.system_time.seconds + th_info.system_time.microseconds / 1e6;
//thread_percent = (double)th_info.cpu_usage / TH_USAGE_SCALE;
task_t task;
struct task_basic_info t_info;
mach_msg_type_number_t th_count = TASK_BASIC_INFO_COUNT;
+ kern_return_t mach_ret;
if (pid == getpid ()) {
/* task_for_pid () doesn't work on ios, even for the current process */
task = mach_task_self ();
} else {
- if (task_for_pid (mach_task_self (), pid, &task) != KERN_SUCCESS)
+ do {
+ mach_ret = task_for_pid (mach_task_self (), pid, &task);
+ } while (mach_ret == KERN_ABORTED);
+
+ if (mach_ret != KERN_SUCCESS)
RET_ERROR (MONO_PROCESS_ERROR_NOT_FOUND);
}
-
- if (task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count) != KERN_SUCCESS) {
+
+ do {
+ mach_ret = task_info (task, TASK_BASIC_INFO, (task_info_t)&t_info, &th_count);
+ } while (mach_ret == KERN_ABORTED);
+
+ if (mach_ret != KERN_SUCCESS) {
if (pid != getpid ())
mach_port_deallocate (mach_task_self (), task);
RET_ERROR (MONO_PROCESS_ERROR_OTHER);
{
kern_return_t ret;
- ret = thread_suspend (info->native_handle);
+ do {
+ ret = thread_suspend (info->native_handle);
+ } while (ret == KERN_ABORTED);
+
if (ret != KERN_SUCCESS)
return;
- ret = thread_abort_safely (info->native_handle);
+ do {
+ ret = thread_abort_safely (info->native_handle);
+ } while (ret == KERN_ABORTED);
/*
* We are doing thread_abort when thread_abort_safely returns KERN_SUCCESS because
if (ret == KERN_SUCCESS)
ret = thread_abort (info->native_handle);
- g_assert (thread_resume (info->native_handle) == KERN_SUCCESS);
+ do {
+ ret = thread_resume (info->native_handle);
+ } while (ret == KERN_ABORTED);
+
+ g_assert (ret == KERN_SUCCESS);
}
gboolean
g_assert (info);
- ret = thread_suspend (info->native_handle);
+
+ do {
+ ret = thread_suspend (info->native_handle);
+ } while (ret == KERN_ABORTED);
+
THREADS_SUSPEND_DEBUG ("SUSPEND %p -> %d\n", (void*)info->native_handle, ret);
if (ret != KERN_SUCCESS)
return FALSE;
/* We're in the middle of a self-suspend, resume and register */
if (!mono_threads_transition_finish_async_suspend (info)) {
mono_threads_add_to_pending_operation_set (info);
- g_assert (thread_resume (info->native_handle) == KERN_SUCCESS);
+ do {
+ ret = thread_resume (info->native_handle);
+ } while (ret == KERN_ABORTED);
+ g_assert (ret == KERN_SUCCESS);
THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/1 %p -> %d\n", (void*)info->native_handle, 0);
//XXX interrupt_kernel doesn't make sense in this case as the target is not in a syscall
return TRUE;
thread_abort (info->native_handle);
} else {
mono_threads_transition_async_suspend_compensation (info);
- g_assert (thread_resume (info->native_handle) == KERN_SUCCESS);
+ do {
+ ret = thread_resume (info->native_handle);
+ } while (ret == KERN_ABORTED);
+ g_assert (ret == KERN_SUCCESS);
THREADS_SUSPEND_DEBUG ("FAILSAFE RESUME/2 %p -> %d\n", (void*)info->native_handle, 0);
}
return res;
state = (thread_state_t) alloca (mono_mach_arch_get_thread_state_size ());
mctx = (mcontext_t) alloca (mono_mach_arch_get_mcontext_size ());
- ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ do {
+ ret = mono_mach_arch_get_thread_state (info->native_handle, state, &num_state);
+ } while (ret == KERN_ABORTED);
+
if (ret != KERN_SUCCESS)
return FALSE;
mono_mach_arch_mcontext_to_thread_state (mctx, state);
- ret = mono_mach_arch_set_thread_state (info->native_handle, state, num_state);
+ do {
+ ret = mono_mach_arch_set_thread_state (info->native_handle, state, num_state);
+ } while (ret == KERN_ABORTED);
+
if (ret != KERN_SUCCESS)
return FALSE;
}
- ret = thread_resume (info->native_handle);
+ do {
+ ret = thread_resume (info->native_handle);
+ } while (ret == KERN_ABORTED);
THREADS_SUSPEND_DEBUG ("RESUME %p -> %d\n", (void*)info->native_handle, ret);
return ret == KERN_SUCCESS;