# Process this file with autoconf to produce a configure script.
#AC_PREREQ([2.62])
-AC_INIT(mono, [3.0.10],
+AC_INIT(mono, [3.0.11],
[http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
AC_CONFIG_SRCDIR([README])
AC_MSG_RESULT(ok)
], [
AC_MSG_RESULT(no)
- AC_MSG_WARN(Using mono_mutex_t for recursive mutexes)
- AC_DEFINE(USE_MONO_MUTEX, 1, [Use mono_mutex_t])
+ AC_ERROR(Posix system lacks support for recursive mutexes)
])
AC_CHECK_FUNCS(pthread_attr_setstacksize)
AC_CHECK_FUNCS(pthread_attr_getstack pthread_attr_getstacksize)
# sgen_supported=true
# AOT_SUPPORTED="no"
# ;;
- s390-*-linux*)
- TARGET=S390;
- arch_target=s390;
- ACCESS_UNALIGNED="yes"
- JIT_SUPPORTED=yes
- sgen_supported=true
- # Required CFLAGS for s390[x]. USE_STRING_INLINES is automatic with gcc 4.1
- CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES"
- ;;
s390x-*-linux*)
TARGET=S390x;
arch_target=s390x;
])
fi
-if test ${TARGET} = ARM && test x$cross_compiling = xno && test x$enable_mcs_build != xno; then
+if test ${TARGET} = ARM; then
dnl ******************************************
dnl *** Check to see what FPU is available ***
dnl ******************************************
AC_MSG_CHECKING(which FPU to use)
+ #
+ # This is a bit tricky:
+ #
+ # if (__ARM_PCS_VFP) {
+ # /* mfloat-abi=hard == VFP with hard ABI */
+ # } elif (!__SOFTFP__) {
+ # /* mfloat-abi=softfp == VFP with soft ABI */
+ # } else {
+ # /* mfloat-abi=soft == no VFP */
+ # }
+ #
+ # The exception is iOS (w/ GCC) where none of the above
+ # are defined (but iOS always uses the 'softfp' ABI).
+ #
+ # No support for FPA.
+ #
+
fpu=NONE
- if gcc -v 2>&1 | grep -q -- '--with-float=hard'; then
- fpu=VFP_HARD
+
+ # iOS GCC always uses the 'softfp' ABI.
+ if test x"$GCC" = xyes && test x$platform_darwin = xyes; then
+ fpu=VFP
fi
+ # Are we using the 'hard' ABI?
if test x$fpu = xNONE; then
- ORIG_CFLAGS=$CFLAGS
- CFLAGS="$CFLAGS -mfpu=vfp -mfloat-abi=softfp"
- AC_TRY_RUN([
- int main () { __asm__ ("faddd d7, d6, d7"); return 0; }
- ], fpu=VFP, fpu=NONE)
- CFLAGS=$ORIG_CFLAGS
+ AC_TRY_COMPILE([], [
+ #ifndef __ARM_PCS_VFP
+ #error "Float ABI is not 'hard'"
+ #endif
+ return 0;
+ ], [
+ fpu=VFP_HARD
+ ], [
+ fpu=NONE
+ ])
fi
+ # No 'hard' ABI. 'soft' or 'softfp'?
if test x$fpu = xNONE; then
AC_TRY_COMPILE([], [
- __asm__ ("ldfd f0, [r0]");
- ], fpu=FPA, fpu=NONE)
+ #ifdef __SOFTFP__
+ #error "Float ABI is not 'softfp'"
+ #endif
+ return 0;
+ ], [
+ fpu=VFP
+ ], [
+ fpu=NONE
+ ])
fi
AC_MSG_RESULT($fpu)
CPPFLAGS="$CPPFLAGS -DARM_FPU_$fpu=1"
unset fpu
- AC_MSG_CHECKING(for ARMV6)
- AC_TRY_RUN([
- int main () { __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); return 0; }
- ], armv6=yes, armv6=no)
+ if test x$cross_compiling = xno; then
+ AC_MSG_CHECKING(for ARMV6)
+ AC_TRY_RUN([
+ int main () { __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" : : "r" (0) : "memory"); return 0; }
+ ], armv6=yes, armv6=no)
- AC_MSG_RESULT($armv6)
- if test ${armv6} = yes; then
- AC_DEFINE(HAVE_ARMV6, 1, "Host supports ARMV6 instructions")
- # libgc's gc_locks.h depends on this
- NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
+ AC_MSG_RESULT($armv6)
+ if test ${armv6} = yes; then
+ AC_DEFINE(HAVE_ARMV6, 1, "Host supports ARMV6 instructions")
+ # libgc's gc_locks.h depends on this
+ NESTED_LIBGC_FLAGS="$NESTED_LIBGC_FLAGS -DHAVE_ARMV6"
+ fi
fi
fi
AM_CONDITIONAL(POWERPC, test x$TARGET = xPOWERPC)
AM_CONDITIONAL(POWERPC64, test x$TARGET = xPOWERPC64)
AM_CONDITIONAL(ARM, test x$TARGET = xARM)
-AM_CONDITIONAL(S390, test x$TARGET = xS390)
AM_CONDITIONAL(S390x, test x$TARGET = xS390x)
AM_CONDITIONAL(HOST_X86, test x$HOST = xX86)
AM_CONDITIONAL(HOST_AMD64, test x$HOST = xAMD64)
mono/arch/amd64/Makefile
mono/arch/ppc/Makefile
mono/arch/sparc/Makefile
-mono/arch/s390/Makefile
mono/arch/s390x/Makefile
mono/arch/arm/Makefile
mono/arch/ia64/Makefile
.\" Copyright 2003 Ximian, Inc.
.\" Copyright 2004-2011 Novell, Inc.
.\" Copyright 2011-2012 Xamarin Inc
+.\" Copyright 2013 7digital Media Ltd.
.\" Author:
.\" Miguel de Icaza (miguel@gnu.org)
.\"
-.TH Mono "Mono 2.11"
+.TH Mono "Mono 3.0"
.SH NAME
mono \- Mono's ECMA-CLI native code generator (Just-in-Time and Ahead-of-Time)
.SH SYNOPSIS
variable in your environment before starting the application and no action will
be taken.
.TP
+\fBMONO_ASPNET_WEBCONFIG_CACHESIZE\fR
+Mono has a cache of ConfigSection objects for speeding up WebConfigurationManager
+queries. Its default size is 100 items, and when more items are needed, cache
+evictions start happening. If evictions are too frequent this could impose
+unnecessary overhead, which could be avoided by using this environment variable
+to set up a higher cache size (or to lower memory requirements by decreasing it).
+.TP
\fBMONO_CFG_DIR\fR
If set, this variable overrides the default system configuration directory
($PREFIX/etc). It's used to locate machine.config file.
Mono.Data.Sqlite \
System.Numerics \
System.Data.Services.Client \
- System.Reactive.Interfaces \
- System.Reactive.Core \
- System.Reactive.Linq \
- System.Reactive.PlatformServices \
- System.Reactive.Experimental \
- System.Reactive.Debugger \
System.IO.Compression \
System.IO.Compression.FileSystem \
System.ComponentModel.DataAnnotations \
Mono.CompilerServices.SymbolWriter \
Mono.CSharp \
Microsoft.CSharp \
- System.Net.Http \
- System.Reactive.Providers
+ System.Net.Http
monotouch_runtime_dirs := \
corlib \
run_until ("objrefs2");
// child should be gc'd now
- Assert.IsTrue (child.IsCollected);
+ // This is not deterministic
+ //Assert.IsTrue (child.IsCollected);
/*
* No longer works since Type is read eagerly
TypeMirror t = child.Type;
});
*/
-
+ /*
AssertThrows<ObjectCollectedException> (delegate () {
long addr = child.Address;
});
+ */
}
[Test]
// First, check XmlSchemaProviderAttribute and try GetSchema() to see if it returns a schema in the expected format.
var xpa = type.GetCustomAttribute<XmlSchemaProviderAttribute> (true);
if (xpa != null) {
+ if (xpa.IsAny)
+ return XmlQualifiedName.Empty;
var mi = type.GetMethod (xpa.MethodName, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static);
if (mi != null) {
try {
QName qname = GetSerializableQName (type);
- if (FindUserMap (qname, type) != null)
+ if (!QName.Empty.Equals (qname) && FindUserMap (qname, type) != null)
throw new InvalidOperationException (String.Format ("There is already a registered type for XML name {0}", qname));
XmlSerializableMap ret = new XmlSerializableMap (type, qname, this);
}
#if NET_2_0
- [MonoTODO]
[ComVisible (false)]
- public int ExitCode {
- get { throw new NotImplementedException (); }
- set { throw new NotImplementedException (); }
- }
+ public int ExitCode { get; set; }
[MonoTODO]
[EditorBrowsable (EditorBrowsableState.Advanced)]
throw new NotImplementedException ();
}
- [MonoTODO]
public void Stop ()
{
+ OnStop ();
}
#endif
using System;
using System.ComponentModel;
using System.Globalization;
-#if NET_2_0
using System.Runtime.InteropServices;
-#endif
using System.ServiceProcess.Design;
using System.Threading;
{
[Designer("System.ServiceProcess.Design.ServiceControllerDesigner, " + Consts.AssemblySystem_Design)]
[MonoTODO ("No unix implementation")]
-#if NET_2_0
[ServiceProcessDescription ("Provides the ability to connect to, query, and manipulate running or stopped Windows services.")]
-#endif
public class ServiceController : Component
{
private string _name;
[ServiceProcessDescription ("Whether this service recognizes the Pause and Continue commands.")]
public bool CanPauseAndContinue {
get {
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
return _impl.CanPauseAndContinue;
}
}
public bool CanShutdown {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
return _impl.CanShutdown;
}
}
public bool CanStop {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
return _impl.CanStop;
}
}
public ServiceController [] DependentServices {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
if (_dependentServices == null)
_dependentServices = _impl.DependentServices;
return _dependentServices;
if (_serviceName == value)
return;
-#if NET_2_0
ValidateServiceName (value);
-#endif
_serviceName = value;
public ServiceController [] ServicesDependedOn {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
if (_servicesDependedOn == null)
_servicesDependedOn = _impl.ServicesDependedOn;
return _servicesDependedOn;
}
}
-#if NET_2_0
[MonoTODO]
[Browsable (false)]
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
throw new NotImplementedException ();
}
}
-#endif
[DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
[ServiceProcessDescription ("The type of this service.")]
public ServiceType ServiceType {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
return _impl.ServiceType;
}
}
public ServiceControllerStatus Status {
get
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
return _impl.Status;
}
}
public void Continue ()
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
_impl.Continue ();
}
public void ExecuteCommand (int command)
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
_impl.ExecuteCommand (command);
}
public void Pause ()
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
_impl.Pause ();
}
public void Start (string [] args)
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
_impl.Start (args);
}
public void Stop ()
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
_impl.Stop ();
}
public void WaitForStatus (ServiceControllerStatus desiredStatus, TimeSpan timeout)
{
-#if NET_2_0
ValidateServiceName (ServiceName);
-#endif
DateTime start = DateTime.Now;
while (Status != desiredStatus) {
}
}
-#if NET_2_0
private static void ValidateServiceName (string serviceName)
{
if (serviceName.Length == 0 || serviceName.Length > 80)
"Service name {0} contains invalid characters, is empty"
+ " or is too long (max length = 80).", serviceName));
}
-#endif
private static void ValidateMachineName (string machineName)
{
+System.ServiceProcess/ServiceBaseTest.cs
System.ServiceProcess/ServiceControllerTest.cs
System.ServiceProcess/ServiceControllerPermissionAttributeTest.cs
System.ServiceProcess/ServiceControllerPermissionTest.cs
--- /dev/null
+//
+// ServiceBaseTest.cs -
+// NUnit Test Cases for ServiceBase
+//
+// Author:
+// Andres G. Aragoneses (andres@7digital.com)
+//
+// Copyright (C) 2013 7digital Media, Ltd (http://www.7digital.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.ServiceProcess;
+using NUnit.Framework;
+
+namespace Test
+{
+ [TestFixture]
+ public class ServiceBaseTest
+ {
+ const int SOME_ERROR_CODE = 1;
+
+ public partial class ServiceFoo : ServiceBase
+ {
+ public ServiceFoo ()
+ {
+ InitializeComponent ();
+ }
+
+ protected override void OnStart (string[] args)
+ {
+ }
+
+ protected override void OnStop ()
+ {
+ ExitCode = SOME_ERROR_CODE;
+ }
+
+ public void StartHook ()
+ {
+ OnStart (new string [] { });
+ }
+ }
+
+ [Test]
+ public void StopCallsOnStop ()
+ {
+ var s = new ServiceFoo ();
+ Assert.AreEqual (0, s.ExitCode);
+ s.Stop ();
+ Assert.AreEqual (SOME_ERROR_CODE, s.ExitCode);
+ }
+
+ [Test]
+ public void ExitCodeIsNotResetByBaseClassServiceBaseBetweenRuns ()
+ {
+ var s = new ServiceFoo ();
+ Assert.AreEqual (0, s.ExitCode);
+ s.Stop ();
+ Assert.AreEqual (SOME_ERROR_CODE, s.ExitCode);
+ s.StartHook ();
+ Assert.AreEqual (SOME_ERROR_CODE, s.ExitCode);
+ }
+
+ partial class ServiceFoo
+ {
+ /// <summary>
+ /// Required designer variable.
+ /// </summary>
+ private System.ComponentModel.IContainer components = null;
+
+ /// <summary>
+ /// Clean up any resources being used.
+ /// </summary>
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Component Designer generated code
+
+ /// <summary>
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ /// </summary>
+ private void InitializeComponent()
+ {
+ components = new System.ComponentModel.Container();
+ this.ServiceName = "ServiceFoo";
+ }
+
+ #endregion
+ }
+ }
+}
+
try {
bool value = sc.CanPauseAndContinue;
Assert.Fail ("#A1: " + value.ToString ());
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#A6");
Assert.IsNull (ex.InnerException, "#A7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#A2");
- Assert.IsNotNull (ex.Message, "#A3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#A4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#A5");
- Assert.IsNotNull (ex.InnerException, "#A6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#A7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#A8");
- Assert.IsNotNull (win32Error.Message, "#A9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#A10");
- Assert.IsNull (win32Error.InnerException, "#A11");
- }
-#endif
try {
bool value = sc.CanShutdown;
Assert.Fail ("#B1: " + value.ToString ());
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#B6");
Assert.IsNull (ex.InnerException, "#B7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#B2");
- Assert.IsNotNull (ex.Message, "#B3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#B4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#B5");
- Assert.IsNotNull (ex.InnerException, "#B6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#B7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#B8");
- Assert.IsNotNull (win32Error.Message, "#B9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#B10");
- Assert.IsNull (win32Error.InnerException, "#B11");
- }
-#endif
try {
bool value = sc.CanStop;
Assert.Fail ("#C1: " + value.ToString ());
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#C6");
Assert.IsNull (ex.InnerException, "#C7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#C2");
- Assert.IsNotNull (ex.Message, "#C3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#C4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#C5");
- Assert.IsNotNull (ex.InnerException, "#C6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#C7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#C8");
- Assert.IsNotNull (win32Error.Message, "#C9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#C10");
- Assert.IsNull (win32Error.InnerException, "#C11");
- }
-#endif
// closing the ServiceController does not result in exception
sc.Close ();
try {
sc.Continue ();
Assert.Fail ("#D1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#D6");
Assert.IsNull (ex.InnerException, "#D7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#D2");
- Assert.IsNotNull (ex.Message, "#D3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#D4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#D5");
- Assert.IsNotNull (ex.InnerException, "#D6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#D7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#D8");
- Assert.IsNotNull (win32Error.Message, "#D9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#D10");
- Assert.IsNull (win32Error.InnerException, "#D11");
- }
-#endif
try {
Assert.Fail ("#E1: " + sc.DependentServices.Length);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#E6");
Assert.IsNull (ex.InnerException, "#E7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#E2");
- Assert.IsNotNull (ex.Message, "#E3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#E4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#E5");
- Assert.IsNotNull (ex.InnerException, "#E6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#E7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#E8");
- Assert.IsNotNull (win32Error.Message, "#E9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#E10");
- Assert.IsNull (win32Error.InnerException, "#E11");
- }
-#endif
Assert.IsNotNull (sc.DisplayName, "#F1");
Assert.AreEqual (string.Empty, sc.DisplayName, "#F2");
try {
sc.ExecuteCommand (0);
Assert.Fail ("#G1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#G6");
Assert.IsNull (ex.InnerException, "#G7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#G2");
- Assert.IsNotNull (ex.Message, "#G3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#G4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#G5");
- Assert.IsNotNull (ex.InnerException, "#G6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#G7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#G8");
- Assert.IsNotNull (win32Error.Message, "#G9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#G10");
- Assert.IsNull (win32Error.InnerException, "#G11");
- }
-#endif
Assert.IsNotNull (sc.MachineName, "#H1");
Assert.AreEqual (".", sc.MachineName, "#H2");
try {
sc.Pause ();
Assert.Fail ("#I1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#I6");
Assert.IsNull (ex.InnerException, "#I7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#I2");
- Assert.IsNotNull (ex.Message, "#I3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#I4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#I5");
- Assert.IsNotNull (ex.InnerException, "#I6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#I7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#I8");
- Assert.IsNotNull (win32Error.Message, "#I9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#I10");
- Assert.IsNull (win32Error.InnerException, "#I11");
- }
-#endif
}
[Test]
[Test]
public void CanPauseAndContinue_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
bool canPauseAndContinue = sc.CanPauseAndContinue;
Assert.Fail ("#1: " + canPauseAndContinue);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void CanShutdown_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
bool canShutdown = sc.CanShutdown;
Assert.Fail ("#1: " + canShutdown);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void CanStop_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
bool canStop = sc.CanStop;
Assert.Fail ("#1: " + canStop);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void Continue_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
sc.Continue ();
Assert.Fail ("#1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void DependentServices_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
ServiceController [] dependenServices = sc.DependentServices;
Assert.Fail ("#1: " + dependenServices.Length);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void ExecuteCommand_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
sc.ExecuteCommand ((int) SERVICE_CONTROL_TYPE.SERVICE_CONTROL_INTERROGATE);
Assert.Fail ("#1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
Assert.IsNotNull (ex.Message, "#3");
Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4");
-#if ONLY_1_1
- Assert.IsNull (ex.InnerException, "#5");
-#else
Assert.IsNotNull (ex.InnerException, "#5");
// The RPC server is unavailable
Assert.IsNotNull (win32Error.Message, "#8");
Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9");
Assert.IsNull (win32Error.InnerException, "#10");
-#endif
}
}
Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
Assert.IsNotNull (ex.Message, "#3");
Assert.IsTrue (ex.Message.IndexOf ("'doesnotexist'") != -1, "#4");
-#if ONLY_1_1
- Assert.IsNull (ex.InnerException, "#5");
-#else
Assert.IsNotNull (ex.InnerException, "#5");
// The RPC server is unavailable
Assert.IsNotNull (win32Error.Message, "#8");
Assert.AreEqual (1722, win32Error.NativeErrorCode, "#9");
Assert.IsNull (win32Error.InnerException, "#10");
-#endif
}
}
[Test]
public void Pause_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
sc.Pause ();
Assert.Fail ("#1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
Assert.AreEqual ("Workstation", sc.DisplayName, "#B1");
Assert.AreEqual ("lanmanworkstation", sc.ServiceName, "#B2");
-#if ONLY_1_1
- sc.ServiceName = string.Empty;
-
- Assert.AreEqual (string.Empty, sc.DisplayName, "#C1");
- Assert.AreEqual (string.Empty, sc.ServiceName, "#C2");
-#else
try {
sc.ServiceName = string.Empty;
Assert.Fail ("#C1");
Assert.IsNull (ex.ParamName, "#A6");
Assert.IsNull (ex.InnerException, "#A7");
}
-#endif
}
[Test]
[Test]
public void ServicesDependedOn_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
ServiceController [] servicesDependedOn = sc.ServicesDependedOn;
Assert.Fail ("#1: " + servicesDependedOn.Length);
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
[Test]
public void Stop_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
sc.Stop ();
Assert.Fail ("#1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
} catch (TimeoutException ex) {
// Time out has expired and the operation has not been completed
Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2");
-#if NET_2_0
Assert.IsNotNull (ex.Data, "#B3");
Assert.AreEqual (0, ex.Data.Count, "#B4");
-#endif
Assert.IsNotNull (ex.Message, "#B5");
Assert.IsNull (ex.InnerException, "#B6");
}
} catch (TimeoutException ex) {
// Time out has expired and the operation has not been completed
Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2");
-#if NET_2_0
Assert.IsNotNull (ex.Data, "#B3");
Assert.AreEqual (0, ex.Data.Count, "#B4");
-#endif
Assert.IsNotNull (ex.Message, "#B5");
Assert.IsNull (ex.InnerException, "#B6");
}
[Test]
public void WaitForStatus_ServiceName_Empty ()
{
-#if ONLY_1_1
- if (RunningOnUnix)
- return;
-#endif
-
ServiceController sc = new ServiceController ();
try {
sc.WaitForStatus (ServiceControllerStatus.Stopped,
new TimeSpan (0, 0, 1));
Assert.Fail ("#1");
-#if NET_2_0
} catch (ArgumentException ex) {
// Service name contains invalid characters, is empty or is
// too long (max length = 80)
Assert.IsNull (ex.ParamName, "#6");
Assert.IsNull (ex.InnerException, "#7");
}
-#else
- } catch (InvalidOperationException ex) {
- // Cannot open service on computer '.'
- Assert.AreEqual (typeof (InvalidOperationException), ex.GetType (), "#2");
- Assert.IsNotNull (ex.Message, "#3");
- Assert.IsTrue (ex.Message.IndexOf (" ") != -1, "#4");
- Assert.IsTrue (ex.Message.IndexOf ("'.'") != -1, "#5");
- Assert.IsNotNull (ex.InnerException, "#6");
-
- // The filename, directory name, or volume label is incorrect
- Assert.AreEqual (typeof (Win32Exception), ex.InnerException.GetType (), "#7");
- Win32Exception win32Error = (Win32Exception) ex.InnerException;
- //Assert.AreEqual (-2147467259, win32Error.ErrorCode, "#8");
- Assert.IsNotNull (win32Error.Message, "#9");
- Assert.AreEqual (123, win32Error.NativeErrorCode, "#10");
- Assert.IsNull (win32Error.InnerException, "#11");
- }
-#endif
}
[Test]
} catch (TimeoutException ex) {
// Time out has expired and the operation has not been completed
Assert.AreEqual (typeof (TimeoutException), ex.GetType (), "#B2");
-#if NET_2_0
Assert.IsNotNull (ex.Data, "#B3");
Assert.AreEqual (0, ex.Data.Count, "#B4");
-#endif
Assert.IsNotNull (ex.Message, "#B5");
Assert.IsNull (ex.InnerException, "#B6");
}
<Compile Include="System.Web.Configuration_2.0\IConfigMapPathFactory.cs" />\r
<Compile Include="System.Web.Configuration_2.0\IdentitySection.cs" />\r
<Compile Include="System.Web.Configuration_2.0\IRemoteWebConfigurationHostServer.cs" />\r
+ <Compile Include="System.Web.Configuration_2.0\LruCache.cs" />\r
<Compile Include="System.Web.Configuration_2.0\LowerCaseStringConverter.cs" />\r
<Compile Include="System.Web.Configuration_2.0\MachineKeyCompatibilityMode.cs" />\r
<Compile Include="System.Web.Configuration_2.0\MachineKeyRegistryStorage.cs" />\r
--- /dev/null
+//
+// A simple LRU cache
+//
+// Authors:
+// Miguel de Icaza (miguel@gnome.org)
+// Andres G. Aragoneses (andres@7digital.com)
+//
+// Copyright 2010 Miguel de Icaza
+// Copyright 2013 7digital Media Ltd.
+//
+// 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.Collections.Generic;
+
+namespace System.Web.Configuration {
+
+ class LruCache<TKey, TValue> {
+ Dictionary<TKey, LinkedListNode <TValue>> dict;
+ Dictionary<LinkedListNode<TValue>, TKey> revdict;
+ LinkedList<TValue> list;
+ int entry_limit;
+
+ bool eviction_warning_shown;
+ int evictions;
+ bool size_overriden;
+
+ internal string EvictionWarning { set; private get; }
+
+ public LruCache (int entryLimit)
+ {
+ entry_limit = entryLimit;
+ dict = new Dictionary<TKey, LinkedListNode<TValue>> ();
+ revdict = new Dictionary<LinkedListNode<TValue>, TKey> ();
+ list = new LinkedList<TValue> ();
+ }
+
+ //for debugging: public int Count { get { return dict.Count; } }
+
+ void Evict ()
+ {
+ var last = list.Last;
+ if (last == null)
+ return;
+
+ var key = revdict [last];
+
+ dict.Remove (key);
+ revdict.Remove (last);
+ list.RemoveLast ();
+ DisposeValue (last.Value);
+ evictions++;
+
+ if (!String.IsNullOrEmpty (EvictionWarning) && !eviction_warning_shown && (evictions >= entry_limit)) {
+ Console.Error.WriteLine ("WARNING: " + EvictionWarning);
+ eviction_warning_shown = true;
+ }
+ }
+
+ public void Clear ()
+ {
+ foreach (var element in list) {
+ DisposeValue (element);
+ }
+
+ dict.Clear ();
+ revdict.Clear ();
+ list.Clear ();
+ eviction_warning_shown = false;
+ evictions = 0;
+ }
+
+ void DisposeValue (TValue value)
+ {
+ if (value is IDisposable) {
+ ((IDisposable)value).Dispose ();
+ }
+ }
+
+ public bool TryGetValue (TKey key, out TValue value)
+ {
+ LinkedListNode<TValue> node;
+
+ if (dict.TryGetValue (key, out node)){
+ list.Remove (node);
+ list.AddFirst (node);
+
+ value = node.Value;
+ return true;
+ }
+ value = default (TValue);
+ return false;
+ }
+
+ public void Add (TKey key, TValue value)
+ {
+ LinkedListNode<TValue> node;
+
+ if (dict.TryGetValue (key, out node)){
+
+ // If we already have a key, move it to the front
+ list.Remove (node);
+ list.AddFirst (node);
+
+ // Remove the old value
+ DisposeValue (node.Value);
+
+ node.Value = value;
+ return;
+ }
+
+ if (dict.Count >= entry_limit)
+ Evict ();
+
+ // Adding new node
+ node = new LinkedListNode<TValue> (value);
+ list.AddFirst (node);
+ dict [key] = node;
+ revdict [node] = key;
+ }
+
+ public override string ToString ()
+ {
+ return "LRUCache dict={0} revdict={1} list={2}";
+ }
+ }
+}
// See comment for the cacheLock field at top of System.Web.Caching/Cache.cs
static readonly ReaderWriterLockSlim sectionCacheLock;
-
+
#if !TARGET_J2EE
static IInternalConfigConfigurationFactory configFactory;
static Hashtable configurations = Hashtable.Synchronized (new Hashtable ());
- static Dictionary <int, object> sectionCache = new Dictionary <int, object> ();
static Hashtable configPaths = Hashtable.Synchronized (new Hashtable ());
static bool suppressAppReload;
#else
}
}
}
+
+ const int DEFAULT_SECTION_CACHE_SIZE = 100;
+ const string CACHE_SIZE_OVERRIDING_KEY = "MONO_ASPNET_WEBCONFIG_CACHESIZE";
+ static LruCache<int, object> sectionCache;
static WebConfigurationManager ()
{
+ var section_cache_size = DEFAULT_SECTION_CACHE_SIZE;
+ int section_cache_size_override;
+ bool size_overriden = false;
+ if (int.TryParse (Environment.GetEnvironmentVariable (CACHE_SIZE_OVERRIDING_KEY), out section_cache_size_override)) {
+ section_cache_size = section_cache_size_override;
+ size_overriden = true;
+ Console.WriteLine ("WebConfigurationManager's LRUcache Size overriden to: {0} (via {1})", section_cache_size_override, CACHE_SIZE_OVERRIDING_KEY);
+ }
+ sectionCache = new LruCache<int, object> (section_cache_size);
+ string eviction_warning = "WebConfigurationManager's LRUcache evictions count reached its max size";
+ if (!size_overriden)
+ eviction_warning += String.Format ("{0}Cache Size: {1} (overridable via {2})",
+ Environment.NewLine, section_cache_size, CACHE_SIZE_OVERRIDING_KEY);
+ sectionCache.EvictionWarning = eviction_warning;
+
configFactory = ConfigurationManager.ConfigurationFactory;
_Configuration.SaveStart += ConfigurationSaveHandler;
_Configuration.SaveEnd += ConfigurationSaveHandler;
System.Web.Configuration_2.0/IConfigMapPathFactory.cs
System.Web.Configuration_2.0/IRemoteWebConfigurationHostServer.cs
System.Web.Configuration_2.0/LowerCaseStringConverter.cs
+System.Web.Configuration_2.0/LruCache.cs
System.Web.Configuration_2.0/MachineKeyRegistryStorage.cs
System.Web.Configuration_2.0/MachineKeySection.cs
System.Web.Configuration_2.0/MachineKeyValidation.cs
// Lawrence Pit (loz@cable.a2000.nl)
// Martin Willemoes Hansen (mwh@sysrq.dk)
// Gonzalo Paniagua Javier (gonzalo@ximian.com)
+// Andres G. Aragoneses (andres@7digital.com)
//
// (C) 2003 Martin Willemoes Hansen
// Copyright (c) 2005 Novell, Inc. (http://www.novell.com
+// Copyright (c) 2013 7digital Media Ltd (http://www.7digital.com)
//
using NUnit.Framework;
}
}
+
+ #region Timeout_Bug // https://bugzilla.novell.com/show_bug.cgi?id=317553
+
+ class TimeoutTestHelper {
+
+ string url_to_test;
+ internal DateTime? Start { get; private set; }
+ internal DateTime? End { get; private set; }
+ internal Exception Exception { get; private set; }
+ internal string Body { get; private set; }
+ internal int TimeOutInMilliSeconds { get; private set; }
+
+ internal TimeoutTestHelper (string url, int timeoutInMilliseconds)
+ {
+ url_to_test = url;
+ TimeOutInMilliSeconds = timeoutInMilliseconds;
+ }
+
+ internal void LaunchWebRequest ()
+ {
+ var req = (HttpWebRequest) WebRequest.Create (url_to_test);
+ req.Timeout = TimeOutInMilliSeconds;
+
+ Start = DateTime.Now;
+ try {
+ using (var resp = (HttpWebResponse) req.GetResponse ())
+ {
+ var sr = new StreamReader (resp.GetResponseStream (), Encoding.UTF8);
+ Body = sr.ReadToEnd ();
+ }
+ } catch (Exception e) {
+ End = DateTime.Now;
+ Exception = e;
+ }
+ }
+ }
+
+ void TestTimeOut (string url)
+ {
+ var timeoutWorker = new TimeoutTestHelper (url, three_seconds_in_milliseconds);
+ var threadStart = new ThreadStart (timeoutWorker.LaunchWebRequest);
+ var thread = new Thread (threadStart);
+ thread.Start ();
+ Thread.Sleep (three_seconds_in_milliseconds * 3);
+
+ if (timeoutWorker.End == null) {
+ thread.Abort ();
+ Assert.Fail ("Thread did not finish after double the timout specified passed");
+ }
+
+ if (!String.IsNullOrEmpty (timeoutWorker.Body)) {
+ if (timeoutWorker.Body == response_of_timeout_handler) {
+ Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve proper body");
+ }
+ Assert.Fail ("Should not be reached, timeout exception was not thrown and webrequest managed to retrieve an incorrect body: " + timeoutWorker.Body);
+ }
+
+ Assert.IsNotNull (timeoutWorker.Exception,
+ "Timeout exception was not thrown");
+
+ var webEx = timeoutWorker.Exception as WebException;
+ Assert.IsNotNull (webEx, "Exception thrown should be WebException, but was: " +
+ timeoutWorker.Exception.GetType ().FullName);
+
+ Assert.AreEqual (webEx.Status, WebExceptionStatus.Timeout,
+ "WebException was thrown, but with a wrong status (should be timeout): " + webEx.Status);
+
+ Assert.IsFalse (timeoutWorker.End > (timeoutWorker.Start + TimeSpan.FromMilliseconds (three_seconds_in_milliseconds + 500)));
+ }
+
+ [Test] // 1st possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
+ public void TestTimeoutPropertyWithServerThatExistsAndRespondsButTooLate ()
+ {
+ var ep = new IPEndPoint (IPAddress.Loopback, 8123);
+ string url = "http://" + ep + "/foobar/";
+
+ using (var responder = new SocketResponder (ep, TimeOutHandler))
+ {
+ responder.Start ();
+
+ TestTimeOut (url);
+
+ responder.Stop ();
+ }
+ }
+
+ [Test] // 2nd possible case of https://bugzilla.novell.com/show_bug.cgi?id=MONO74177
+ public void TestTimeoutPropertyWithServerThatDoesntExist ()
+ {
+ string url = "http://10.128.200.100:8271/"; // some endpoint that is unlikely to exist
+
+ TestTimeOut (url);
+ }
+
+ const string response_of_timeout_handler = "RESPONSE_OF_TIMEOUT_HANDLER";
+ const int three_seconds_in_milliseconds = 3000;
+
+ private static byte[] TimeOutHandler (Socket socket)
+ {
+ socket.Receive (new byte[4096]);
+
+ Thread.Sleep (three_seconds_in_milliseconds * 2);
+
+ var sw = new StringWriter ();
+ sw.WriteLine ("HTTP/1.1 200 OK");
+ sw.WriteLine ("Content-Type: text/plain");
+ sw.WriteLine ("Content-Length: " + response_of_timeout_handler.Length);
+ sw.WriteLine ();
+ sw.Write (response_of_timeout_handler);
+ sw.Flush ();
+
+ return Encoding.UTF8.GetBytes (sw.ToString ());
+ }
+
+ #endregion
+
internal static byte [] EchoRequestHandler (Socket socket)
{
MemoryStream ms = new MemoryStream ();
return(buf_start + buf_offset);
}
set {
- if (handle == MonoIO.InvalidHandle)
- throw new ObjectDisposedException ("Stream has been closed");
-
- if(CanSeek == false) {
- throw new NotSupportedException("The stream does not support seeking");
- }
-
if(value < 0) {
throw new ArgumentOutOfRangeException("Attempt to set the position to a negative value");
}
public void OnCompleted (Action continuation)
{
- if (continuation == null)
- throw new ArgumentNullException ("continuation");
-
- if (TaskScheduler.Current == TaskScheduler.Default) {
- //
- // Pass continuation as an argument to avoid allocating
- // hoisting class
- //
- ThreadPool.QueueUserWorkItem (l => ((Action) l) (), continuation);
- } else {
- new Task (continuation).Start (TaskScheduler.Current);
- }
+ OnCompleted (continuation, false);
}
-
+
public void UnsafeOnCompleted (Action continuation)
+ {
+ OnCompleted (continuation, true);
+ }
+
+ void OnCompleted (Action continuation, bool isUnsafe)
{
if (continuation == null)
throw new ArgumentNullException ("continuation");
+ var ctx = SynchronizationContext.Current;
+ if (ctx != null) {
+ ctx.Post (l => ((Action) l) (), continuation);
+ return;
+ }
+
if (TaskScheduler.Current == TaskScheduler.Default) {
//
- // Pass the continuation as an argument to avoid allocating
+ // Pass continuation as an argument to avoid allocating
// hoisting class
//
- ThreadPool.UnsafeQueueUserWorkItem (l => ((Action) l) (), continuation);
- } else {
- new Task (continuation).Start (TaskScheduler.Current);
+ WaitCallback callBack = l => ((Action) l) ();
+ if (isUnsafe) {
+ ThreadPool.UnsafeQueueUserWorkItem (callBack, continuation);
+ } else {
+ ThreadPool.QueueUserWorkItem (callBack, continuation);
+ }
+ return;
}
+
+ new Task (continuation).Start (TaskScheduler.Current);
}
public void GetResult ()
// Constructors
public SecurityException ()
- : base (Locale.GetText ("A security error has been detected."))
+ : this (Locale.GetText ("A security error has been detected."))
{
- base.HResult = unchecked ((int)0x8013150A);
}
public SecurityException (string message)
{
base.GetObjectData (info, context);
try {
- info.AddValue ("PermissionState", PermissionState);
+ info.AddValue ("PermissionState", permissionState);
}
catch (SecurityException) {
// serialize only if permitted to do so
+//
// AggregateException.cs
//
+// Authors:
+// Marek Safar (marek.safar@gmail.com)
+//
// Copyright (c) 2008 Jérémie "Garuma" Laval
+// Copyright (C) 2013 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
namespace System
{
-
[System.SerializableAttribute]
[System.Diagnostics.DebuggerDisplay ("Count = {InnerExceptions.Count}")]
public class AggregateException : Exception
public void Handle (Func<Exception, bool> predicate)
{
+ if (predicate == null)
+ throw new ArgumentNullException ("predicate");
+
List<Exception> failed = new List<Exception> ();
foreach (var e in innerExceptions) {
- try {
- if (!predicate (e))
- failed.Add (e);
- } catch {
- throw new AggregateException (failed);
- }
+ if (!predicate (e))
+ failed.Add (e);
}
+
if (failed.Count > 0)
throw new AggregateException (failed);
}
return MemberwiseClone ();
}
- public override bool Equals (object obj)
+ internal bool Compare (Delegate d)
{
- Delegate d = obj as Delegate;
-
if (d == null)
return false;
return false;
}
+ public override bool Equals (object obj)
+ {
+ return Compare (obj as Delegate);
+ }
+
public override int GetHashCode ()
{
return method.GetHashCode () ^ (m_target != null ? m_target.GetHashCode () : 0);
MulticastDelegate d = obj as MulticastDelegate;
if (d == null)
return false;
-
- if (this.prev == null) {
- if (d.prev == null)
- return true;
- else
- return false;
- }
- return this.prev.Equals (d.prev);
+ MulticastDelegate this_prev = this.prev;
+ MulticastDelegate obj_prev = d.prev;
+
+ do {
+ if (this_prev == null)
+ return obj_prev == null;
+
+ if (!this_prev.Compare (obj_prev))
+ return false;
+
+ this_prev = this_prev.prev;
+ obj_prev = obj_prev.prev;
+ } while (true);
}
//
int[] lens = new int [3];
int index = 0;
int lastPos = 0;
- char literal = '\0';
+ bool quoted = false;
+
for (int i = 0; i < format.Length; i++) {
char c = format [i];
- if (c == literal || (literal == '\0' && (c == '\"' || c == '\''))) {
- if (literal == '\0')
- literal = c;
- else
- literal = '\0';
+ if (c == '\"' || c == '\'') {
+ if (i == 0 || format [i - 1] != '\\')
+ quoted = !quoted;
+
continue;
}
- if (literal == '\0' && format [i] == ';' && (i == 0 || format [i - 1] != '\\')) {
+ if (c == ';' && !quoted && (i == 0 || format [i - 1] != '\\')) {
lens [index++] = i - lastPos;
lastPos = i + 1;
if (index == 3)
Throws (typeof (ArgumentNullException), () => new AggregateException ((Exception[])null));
}
+ [Test]
+ [ExpectedException (typeof (ArgumentNullException))]
+ public void Handle_Invalid ()
+ {
+ e.Handle (null);
+ }
+
+ [Test]
+ public void Handle_AllHandled ()
+ {
+ e.Handle (l => true);
+ }
+
+ [Test]
+ public void Handle_Unhandled ()
+ {
+ try {
+ e.Handle (l => l is AggregateException);
+ Assert.Fail ();
+ } catch (AggregateException e) {
+ Assert.AreEqual (1, e.InnerExceptions.Count);
+ }
+ }
+
static void Throws (Type t, Action action)
{
Exception e = null;
{
Assert.AreEqual ("", 0.0.ToString ("X99", _nfi) , "#01");
}
+
+ [Test]
+ public void Test18000 ()
+ {
+ string formatString = "p 00.0000\\';n 0000.00\\';0.#\\'";
+
+ Assert.AreEqual ("p 08.3266'", 8.32663472.ToString (formatString, CultureInfo.InvariantCulture), "#1");
+ Assert.AreEqual ("n 0001.13'", (-1.1345343).ToString (formatString, CultureInfo.InvariantCulture), "#2");
+ Assert.AreEqual ("0'", 0.0.ToString (formatString, CultureInfo.InvariantCulture), "#3");
+ }
}
}
$(IMAGES)
EXTRA_DISTFILES = \
+ jay.sh \
monodoc.dll.config.in \
$(RESOURCE_FILES) \
Monodoc.Ecma/EcmaUrlParser.jay \
$(the_lib).config: Makefile monodoc.dll.config.in
sed 's,@monodoc_refdir@,$(mono_libdir)/monodoc,g' monodoc.dll.config.in > $@
-Monodoc.Ecma/EcmaUrlParser.cs: Monodoc.Ecma/EcmaUrlParser.jay $(topdir)/jay/skeleton.cs
- $(topdir)/jay/jay $(JAY_FLAGS) < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@
+Monodoc.Ecma/EcmaUrlParser.cs: Monodoc.Ecma/EcmaUrlParser.jay $(topdir)/jay/skeleton.cs jay.sh
+ $(topdir)/$(thisdir)/jay.sh $(topdir) $< $@ $(JAY_FLAGS)
parser.exe: Monodoc.Ecma/EcmaUrlParser.cs Monodoc.Ecma/EcmaUrlTokenizer.cs Monodoc.Ecma/EcmaUrlParserDriver.cs Monodoc.Ecma/EcmaDesc.cs
mcs /out:$@ /debug $^
--- /dev/null
+#!/bin/sh
+
+TOPDIR=$1
+INPUT=$2
+OUTPUT=$3
+FLAGS=$4
+
+TEMPFILE=jay-tmp-$RANDOM.out
+
+$TOPDIR/jay/jay $FLAGS < $TOPDIR/jay/skeleton.cs $INPUT > $TEMPFILE && mv $TEMPFILE $OUTPUT
--- /dev/null
+// CS1534: Overloaded binary operator `+' takes two parameters
+// Line: 6
+
+class C
+{
+ public static C operator +()
+ {
+ return null;
+ }
+}
--- /dev/null
+// CS1705: Assembly `CS1705-lib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' references `CS1705-lib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=36f3ae7e947792e3' which has a higher version number than imported assembly `CS1705-lib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=36f3ae7e947792e3'
+// Line: 0
+// Compiler options: -r:CS1705-lib.dll -r:dlls/second/CS1705-lib.dll -keyfile:key.snk
+
+class C
+{
+ public static void Main ()
+ {
+ A.Test (new B ());
+ }
+}
// no working SRE API
foreach (var entry in Importer.Assemblies) {
var a = entry as ImportedAssemblyDefinition;
- if (a == null)
+ if (a == null || a.IsMissing)
continue;
if (public_key != null && !a.HasStrongName) {
Operator.GetName (op));
}
} else {
- if (p_count > 2) {
+ if (p_count == 1) {
+ report.Error (1019, loc, "Overloadable unary operator expected");
+ } else if (p_count != 2) {
report.Error (1534, loc, "Overloaded binary operator `{0}' takes two parameters",
Operator.GetName (op));
- } else if (p_count != 2) {
- report.Error (1019, loc, "Overloadable unary operator expected");
}
}
if (ExtensionExpression == null)
return null;
+ var cand = candidates;
arguments.Insert (0, new Argument (ExtensionExpression, Argument.AType.ExtensionType));
var res = base.OverloadResolve (ec, ref arguments, ehandler ?? this, restr);
+
+ // Restore candidates in case we are running in probing mode
+ candidates = cand;
// Store resolved argument and restore original arguments
if (res == null) {
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+namespace ExtensionTest.Two
+{
+ public delegate TResult AxFunc<in T1, out TResult> (T1 first);
+
+ public static class Extensions
+ {
+ public static bool Contains<T> (this IEnumerable<T> source, T item)
+ {
+ return true;
+ }
+
+ public static bool All<T> (this IEnumerable<T> source, AxFunc<T, bool> predicate)
+ {
+ return true;
+ }
+
+ }
+}
+
+namespace ExtensionTest
+{
+ using ExtensionTest.Two;
+
+ public static class MyClass
+ {
+ public static bool IsCharacters (this string text, params char[] chars)
+ {
+ return text.All (chars.Contains);
+ }
+
+ public static bool Contains (this string text, string value, StringComparison comp)
+ {
+ return text.IndexOf (value, comp) >= 0;
+ }
+
+ public static void Main ()
+ {
+ }
+ }
+}
<?xml version="1.0" encoding="utf-8"?>
<symbols>
<files>
- <file id="1" name="test-debug-26.cs" checksum="60257ceb8e5c6406c7a8f74cbc8b9d59" />
+ <file id="1" name="test-debug-26.cs" checksum="9517379bedd3abcc97156ab28d9cb3da" />
</files>
<methods>
<method token="0x6000001">
</method>\r
</type>\r
</test>\r
+ <test name="gtest-exmethod-46.cs">\r
+ <type name="ExtensionTest.Two.AxFunc`2[T1,TResult]">\r
+ <method name="TResult Invoke(T1)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="IAsyncResult BeginInvoke(T1, System.AsyncCallback, System.Object)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="TResult EndInvoke(IAsyncResult)" attrs="454">\r
+ <size>0</size>\r
+ </method>\r
+ <method name="Void .ctor(Object, IntPtr)" attrs="6278">\r
+ <size>0</size>\r
+ </method>\r
+ </type>\r
+ <type name="ExtensionTest.Two.Extensions">\r
+ <method name="Boolean Contains[T](IEnumerable`1, T)" attrs="150">\r
+ <size>10</size>\r
+ </method>\r
+ <method name="Boolean All[T](IEnumerable`1, ExtensionTest.Two.AxFunc`2[T,System.Boolean])" attrs="150">\r
+ <size>10</size>\r
+ </method>\r
+ </type>\r
+ <type name="ExtensionTest.MyClass">\r
+ <method name="Boolean IsCharacters(System.String, System.Char[])" attrs="150">\r
+ <size>27</size>\r
+ </method>\r
+ <method name="Boolean Contains(System.String, System.String, StringComparison)" attrs="150">\r
+ <size>23</size>\r
+ </method>\r
+ <method name="Void Main()" attrs="150">\r
+ <size>2</size>\r
+ </method>\r
+ </type>\r
+ </test>\r
<test name="gtest-fixedbuffer-01.cs">\r
<type name="TestNew">\r
<method name="Void SetTest()" attrs="134">\r
Annotations.Mark (provider);
}
+ protected virtual void MarkSerializable (TypeDefinition type)
+ {
+ if (!type.HasMethods)
+ return;
+
+ MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
+ MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
+ }
+
protected virtual TypeDefinition MarkType (TypeReference reference)
{
if (reference == null)
MarkMethodCollection (type.Methods);
}
- if (IsSerializable (type) && type.HasMethods) {
- MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
- MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
- }
+ if (IsSerializable (type))
+ MarkSerializable (type);
MarkTypeSpecialCustomAttributes (type);
static bool IsDefaultConstructor (MethodDefinition method)
{
- return IsConstructor (method) && method.Parameters.Count == 0;
+ return IsConstructor (method) && !method.HasParameters;
}
static bool IsConstructor (MethodDefinition method)
using System;
using System.Diagnostics;
using System.Xml;
-using System.Collections;
+using System.Collections.Generic;
using System.Reflection;
using System.IO;
using System.IO.Compression;
using System.Text;
+#if NET_4_5
+using System.Threading.Tasks;
+#endif
+
class MakeBundle {
static string output = "a.out";
static string object_out = null;
- static ArrayList link_paths = new ArrayList ();
+ static List<string> link_paths = new List<string> ();
static bool autodeps = false;
static bool keeptemp = false;
static bool compile_only = false;
static int Main (string [] args)
{
- ArrayList sources = new ArrayList ();
+ List<string> sources = new List<string> ();
int top = args.Length;
link_paths.Add (".");
Environment.Exit (1);
}
- ArrayList assemblies = LoadAssemblies (sources);
- ArrayList files = new ArrayList ();
+ List<Assembly> assemblies = LoadAssemblies (sources);
+ List<string> files = new List<string> ();
foreach (Assembly a in assemblies)
QueueAssembly (files, a.CodeBase);
// Preallocate the strings we need.
if (chars [0] == null) {
for (int i = 0; i < chars.Length; i++)
- chars [i] = string.Format ("\t.byte {0}\n", i.ToString ());
+ chars [i] = string.Format ("{0}", i.ToString ());
}
while ((n = stream.Read (buffer, 0, buffer.Length)) != 0) {
- for (int i = 0; i < n; i++)
+ int count = 0;
+ for (int i = 0; i < n; i++) {
+ if (count % 32 == 0) {
+ ts.Write ("\n\t.byte ");
+ } else {
+ ts.Write (",");
+ }
ts.Write (chars [buffer [i]]);
+ count ++;
+ }
}
ts.WriteLine ();
}
- static void GenerateBundles (ArrayList files)
+ static void GenerateBundles (List<string> files)
{
string temp_s = "temp.s"; // Path.GetTempFileName ();
string temp_c = "temp.c";
temp_o = object_out;
try {
- ArrayList c_bundle_names = new ArrayList ();
- ArrayList config_names = new ArrayList ();
+ List<string> c_bundle_names = new List<string> ();
+ List<string[]> config_names = new List<string[]> ();
byte [] buffer = new byte [8192];
using (StreamWriter ts = new StreamWriter (File.Create (temp_s))) {
tc.WriteLine ("} CompressedAssembly;\n");
}
- foreach (string url in files){
- string fname = new Uri (url).LocalPath;
- string aname = Path.GetFileName (fname);
- string encoded = aname.Replace ("-", "_").Replace (".", "_");
+ object monitor = new object ();
- if (prog == null)
- prog = aname;
-
- Console.WriteLine (" embedding: " + fname);
-
+ var streams = new Dictionary<string, Stream> ();
+ var sizes = new Dictionary<string, long> ();
+
+ // Do the file reading and compression in parallel
+ Action<string> body = delegate (string url) {
+ string fname = new Uri (url).LocalPath;
Stream stream = File.OpenRead (fname);
- // Compression can be parallelized
long real_size = stream.Length;
int n;
if (compress) {
stream = new MemoryStream (bytes, 0, (int) ms.Length, false, false);
}
+ lock (monitor) {
+ streams [url] = stream;
+ sizes [url] = real_size;
+ }
+ };
+
+#if NET_4_5
+ Parallel.ForEach (files, body);
+#else
+ foreach (var url in files)
+ body (url);
+#endif
+
+ // The non-parallel part
+ foreach (var url in files) {
+ string fname = new Uri (url).LocalPath;
+ string aname = Path.GetFileName (fname);
+ string encoded = aname.Replace ("-", "_").Replace (".", "_");
+
+ if (prog == null)
+ prog = aname;
+
+ var stream = streams [url];
+ var real_size = sizes [url];
+
+ Console.WriteLine (" embedding: " + fname);
+
WriteSymbol (ts, "assembly_data_" + encoded, stream.Length);
WriteBuffer (ts, stream, buffer);
if (compress) {
tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
tc.WriteLine ("static CompressedAssembly assembly_bundle_{0} = {{{{\"{1}\"," +
- " assembly_data_{0}, {2}}}, {3}}};",
- encoded, aname, real_size, stream.Length);
+ " assembly_data_{0}, {2}}}, {3}}};",
+ encoded, aname, real_size, stream.Length);
double ratio = ((double) stream.Length * 100) / real_size;
Console.WriteLine (" compression ratio: {0:.00}%", ratio);
} else {
tc.WriteLine ("extern const unsigned char assembly_data_{0} [];", encoded);
tc.WriteLine ("static const MonoBundledAssembly assembly_bundle_{0} = {{\"{1}\", assembly_data_{0}, {2}}};",
- encoded, aname, real_size);
+ encoded, aname, real_size);
}
stream.Close ();
} catch (FileNotFoundException) {
/* we ignore if the config file doesn't exist */
}
-
}
+
if (config_file != null){
FileStream conf;
try {
}
}
- static ArrayList LoadAssemblies (ArrayList sources)
+ static List<Assembly> LoadAssemblies (List<string> sources)
{
- ArrayList assemblies = new ArrayList ();
+ List<Assembly> assemblies = new List<Assembly> ();
bool error = false;
foreach (string name in sources){
return assemblies;
}
- static void QueueAssembly (ArrayList files, string codebase)
+ static void QueueAssembly (List<string> files, string codebase)
{
if (files.Contains (codebase))
return;
} else {
service = services [0];
}
-
+
+ if (service.ExitCode != 0) {
+ //likely due to a previous execution, so we need to reset it to default
+ service.ExitCode = 0;
+ }
call (service, "OnStart", args);
info (logname, "Service {0} started", service.ServiceName);
term.Reset ();
info (logname, "Stopping service {0}", service.ServiceName);
call (service, "OnStop", null);
+ if (service.ExitCode != 0)
+ error (logname, "Service stopped with a non-zero ExitCode: {0}", service.ExitCode);
running = false;
}
else if (usr1.IsSet && service.CanPauseAndContinue) {
-DIST_SUBDIRS = x86 ppc sparc arm s390 s390x amd64 ia64 mips
+DIST_SUBDIRS = x86 ppc sparc arm s390x amd64 ia64 mips
AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
+++ /dev/null
-/Makefile.in
-/Makefile
-/.deps
-/.cvsignore
+++ /dev/null
-2007-04-12 Neale Ferguson <neale@sinenomine.net>
-
- * tramp.c: Add MONO_TYPE_PTR case.
-
-2005-12-13 Neale Ferguson <neale@sinenomine.net>
-
- * s390-codegen.h: Add some new instructions (conditional jumps)
-
-2004-12-15 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: Add some new instructions (CS, CDS)
-
-2004-11-15 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: Minor macro modifications
-
-2004-07-30 Neale Ferguson <Neale.Ferguson@SoftwareAG-usa.com>
-
- * s390-codegen.h: reworked macros for code generation.
+++ /dev/null
-
-AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir)
-
-noinst_LTLIBRARIES = libmonoarch-s390.la
-
-libmonoarch_s390_la_SOURCES = tramp.c s390-codegen.h
-
+++ /dev/null
-/*
- Copyright (C) 2001 Radek Doulik
-*/
-
-#ifndef S390_H
-#define S390_H
-#include <glib.h>
-#include <assert.h>
-
-#define FLOAT_REGS 2 /* No. float registers for parms */
-#define GENERAL_REGS 5 /* No. general registers for parms */
-
-#define ARG_BASE s390_r10 /* Register for addressing arguments*/
-#define STKARG \
- (i*(sizeof(stackval))) /* Displacement of ith argument */
-
-#define MINV_POS 96 /* MonoInvocation stack offset */
-#define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count)
-#define OBJ_POS 8
-#define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type))
-
-#define MIN_CACHE_LINE 256
-
-/*------------------------------------------------------------------*/
-/* Sequence to add an int/long long to parameters to stack_from_data*/
-/*------------------------------------------------------------------*/
-#define ADD_ISTACK_PARM(r, i) \
- if (reg_param < GENERAL_REGS-(r)) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param += (i); \
- } else { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param += (i); \
- }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a float/double to parameters to stack_from_data */
-/*------------------------------------------------------------------*/
-#define ADD_RSTACK_PARM(i) \
- if (fpr_param < FLOAT_REGS) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- float_pos + (fpr_param * sizeof(float) * (i))); \
- fpr_param++; \
- } else { \
- stack_param += (stack_param % (i)); \
- s390_la (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(float) * (i)); \
- stack_param += (i); \
- }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a structure ptr to parameters to stack_from_data */
-/*------------------------------------------------------------------*/
-#define ADD_TSTACK_PARM \
- if (reg_param < GENERAL_REGS) { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param++; \
- } else { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param++; \
- }
-
-#define ADD_PSTACK_PARM(r, i) \
- if (reg_param < GENERAL_REGS-(r)) { \
- s390_la (p, s390_r4, 0, STK_BASE, \
- local_start + (reg_param - this_flag) * sizeof(long)); \
- reg_param += (i); \
- } else { \
- s390_l (p, s390_r4, 0, STK_BASE, \
- sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
- stack_param++; \
- }
-typedef enum {
- s390_r0 = 0,
- s390_r1,
- s390_r2,
- s390_r3,
- s390_r4,
- s390_r5,
- s390_r6,
- s390_r7,
- s390_r8,
- s390_r9,
- s390_r10,
- s390_r11,
- s390_r12,
- s390_r13,
- s390_r14,
- s390_r15,
-} S390IntRegister;
-
-typedef enum {
- s390_f0 = 0,
- s390_f1,
- s390_f2,
- s390_f3,
- s390_f4,
- s390_f5,
- s390_f6,
- s390_f7,
- s390_f8,
- s390_f9,
- s390_f10,
- s390_f11,
- s390_f12,
- s390_f13,
- s390_f14,
- s390_f15,
-} S390FloatRegister;
-
-typedef enum {
- s390_a0 = 0,
- s390_a1,
- s390_a2,
- s390_a3,
- s390_a4,
- s390_a5,
- s390_a6,
- s390_a7,
- s390_a8,
- s390_a9,
- s390_a10,
- s390_a11,
- s390_a12,
- s390_a13,
- s390_a14,
- s390_a15,
-} S390AccRegister;
-
-typedef enum {
- s390_fpc = 256,
-} S390SpecialRegister;
-
-#define s390_is_imm16(val) ((gint)val >= (gint)-(1<<15) && \
- (gint)val <= (gint)((1<<15)-1))
-#define s390_is_uimm16(val) ((gint)val >= 0 && (gint)val <= 32767)
-#define s390_is_imm12(val) ((gint)val >= (gint)-(1<<11) && \
- (gint)val <= (gint)((1<<11)-1))
-#define s390_is_uimm12(val) ((gint)val >= 0 && (gint)val <= 4095)
-
-#define STK_BASE s390_r15
-#define S390_MINIMAL_STACK_SIZE 96
-#define S390_PARM_SAVE_OFFSET 8
-#define S390_REG_SAVE_OFFSET 24
-#define S390_RET_ADDR_OFFSET 56
-#define S390_FLOAT_SAVE_OFFSET 64
-
-#define S390_CC_ZR 8
-#define S390_CC_NE 7
-#define S390_CC_NZ 7
-#define S390_CC_LT 4
-#define S390_CC_GT 2
-#define S390_CC_GE 11
-#define S390_CC_NM 11
-#define S390_CC_LE 13
-#define S390_CC_OV 1
-#define S390_CC_NO 14
-#define S390_CC_CY 3
-#define S390_CC_NC 12
-#define S390_CC_UN 15
-
-#define s390_word(addr, value) do \
-{ \
- * (guint32 *) addr = (guint32) value; \
- addr += sizeof(guint32); \
-} while (0)
-
-#define s390_float(addr, value) do \
-{ \
- * (gfloat *) addr = (gfloat) value; \
- addr += sizeof(gfloat); \
-} while (0)
-
-#define s390_llong(addr, value) do \
-{ \
- * (guint64 *) addr = (guint64) value; \
- addr += sizeof(guint64); \
-} while (0)
-
-#define s390_double(addr, value) do \
-{ \
- * (gdouble *) addr = (gdouble) value; \
- addr += sizeof(gdouble); \
-} while (0)
-
-typedef struct {
- short op;
-} E_Format;
-
-typedef struct {
- char op;
- int im;
-} I_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r2 : 4;
-} RR_Format;
-
-typedef struct {
- short op;
- char xx;
- char r1 : 4;
- char r2 : 4;
-} RRE_Format;
-
-typedef struct {
- short op;
- char r1 : 4;
- char xx : 4;
- char r3 : 4;
- char r2 : 4;
-} RRF_Format_1;
-
-typedef struct {
- short op;
- char m3 : 4;
- char xx : 4;
- char r1 : 4;
- char r2 : 4;
-} RRF_Format_2;
-
-typedef struct {
- short op;
- char r3 : 4;
- char m4 : 4;
- char r1 : 4;
- char r2 : 4;
-} RRF_Format_3;
-
-typedef struct {
- char op;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- short d2 : 12;
-} RX_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 12;
- char xx;
- char op2;
-} RXE_Format;
-
-typedef struct {
- char op1;
- char r3 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 12;
- char r1 : 4;
- char xx : 4;
- char op2;
-} RXF_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char x2 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RXY_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_1;
-
-typedef struct {
- char op;
- char r1 : 4;
- char m3 : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_2;
-
-typedef struct {
- char op;
- char r1 : 4;
- char xx : 4;
- char b2 : 4;
- int d2 : 12;
-} RS_Format_3;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RSY_Format_1;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char m3 : 4;
- char b2 : 4;
- int d2 : 20;
- char op2;
-} RSY_Format_2;
-
-typedef struct {
- char op1;
- char l1 : 4;
- char xx : 4;
- char b1 : 4;
- int d1 : 12;
- char yy;
- char op2;
-} RSL_Format;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- short i2;
-} RSI_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char op2 : 4;
- short i2;
-} RI_Format;
-
-typedef struct {
- char op1;
- char r1 : 4;
- char r3 : 4;
- short i2;
- char xx;
- char op2;
-} RIE_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char r1 : 4;
- char op2 : 4;
- int i2;
-} RIL_Format_1;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char m1 : 4;
- char op2 : 4;
- int i2;
-} RIL_Format_2;
-
-typedef struct {
- char op;
- char i2;
- char b1 : 4;
- short d1 : 12;
-} SI_Format;
-
-typedef struct __attribute__ ((packed)) {
- char op1;
- char i2;
- char b1 : 4;
- int d1 : 20;
- char op2;
-} SIY_Format;
-
-typedef struct {
- short op;
- char b2 : 4;
- short d2 : 12;
-} S_Format;
-
-typedef struct {
- char op;
- char ll;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_1;
-
-typedef struct {
- char op;
- char l1 : 4;
- char l2 : 4;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_2;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SS_Format_3;
-
-typedef struct {
- char op;
- char r1 : 4;
- char r3 : 4;
- char b2 : 4;
- short d2 : 12;
- char b4 : 4;
- short d4 : 12;
-} SS_Format_4;
-
-typedef struct __attribute__ ((packed)) {
- short op;
- char b1 : 4;
- short d1 : 12;
- char b2 : 4;
- short d2 : 12;
-} SSE_Format;
-
-#define s390_emit16(c, x) do \
-{ \
- *((guint16 *) c) = x; \
- c += sizeof(guint16); \
-} while(0)
-
-#define s390_emit32(c, x) do \
-{ \
- *((guint32 *) c) = x; \
- c += sizeof(guint32); \
-} while(0)
-
-#define S390_E(c,opc) s390_emit16(c,opc)
-
-#define S390_I(c,opc,imm) s390_emit16(c, (opc << 8 | imm))
-
-#define S390_RR(c,opc,g1,g2) s390_emit16(c, (opc << 8 | (g1) << 4 | g2))
-
-#define S390_RRE(c,opc,g1,g2) s390_emit32(c, (opc << 16 | (g1) << 4 | g2))
-
-#define S390_RRF_1(c,opc,g1,g2,g3) s390_emit32(c, (opc << 16 | (g1) << 12 | (g3) << 4 | g2))
-
-#define S390_RRF_2(c,opc,g1,k3,g2) s390_emit32(c, (opc << 16 | (k3) << 12 | (g1) << 4 | g2))
-
-#define S390_RRF_3(c,opc,g1,g2,k4,g3) s390_emit32(c, (opc << 16 | (g3) << 12 | (k4) << 8 | (g1) << 4 | g2))
-
-#define S390_RX(c,opc,g1,n2,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (n2) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RXE(c,opc,g1,n2,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | n2)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfff) << 16) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RXY(c,opc,g1,n2,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | n2)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RS_1(c,opc,g1,g3,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (g3) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RS_2(c,opc,g1,k3,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (k3) << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RS_3(c,opc,g1,s2,p2) s390_emit32(c, (opc << 24 | (g1) << 20 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_RSY_1(c,opc,g1,g3,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSY_2(c,opc,g1,k3,s2,p2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | k3)); \
- s390_emit32(c, ((s2) << 28 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSL(c,opc,ln,s1,p1) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (ln) << 4)); \
- s390_emit32(c, ((s1) << 28 | ((s1 & 0xfff) << 16) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_RSI(c,opc,g1,g3,m2) s390_emit32(c, (opc << 24 | (g1) << 20 | (g3) << 16 | (m2 & 0xffff)))
-
-#define S390_RI(c,opc,g1,m2) s390_emit32(c, ((opc >> 4) << 24 | (g1) << 20 | (opc & 0x0f) << 16 | (m2 & 0xffff)))
-
-#define S390_RIE(c,opc,g1,g3,m2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | (g1) << 4 | g3)); \
- s390_emit32(c, ((m2) << 16 | (opc & 0xff))); \
-} while (0)
-
-#define S390_RIL_1(c,opc,g1,m2) do \
-{ \
- s390_emit16(c, ((opc >> 4) << 8 | (g1) << 4 | (opc & 0xf))); \
- s390_emit32(c, m2); \
-} while (0)
-
-#define S390_RIL_2(c,opc,k1,m2) do \
-{ \
- s390_emit16(c, ((opc >> 4) << 8 | (k1) << 4 | (opc & 0xf))); \
- s390_emit32(c, m2); \
-} while (0)
-
-#define S390_SI(c,opc,s1,p1,m2) s390_emit32(c, (opc << 24 | (m2) << 16 | (s1) << 12 | ((p1) & 0xfff)));
-
-#define S390_SIY(c,opc,s1,p1,m2) do \
-{ \
- s390_emit16(c, ((opc & 0xff00) | m2)); \
- s390_emit32(c, ((s1) << 24 | (((p2) & 0xfffff) << 8) | \
- (opc & 0xff))); \
-} while (0)
-
-#define S390_S(c,opc,s2,p2) s390_emit32(c, (opc << 16 | (s2) << 12 | ((p2) & 0xfff)))
-
-#define S390_SS_1(c,opc,ln,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | ((ln-1) & 0xff) << 16 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_2(c,opc,n1,n2,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | (n1) << 16 | (n2) << 12 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_3(c,opc,g1,g3,s1,p1,s2,p2) do \
-{ \
- s390_emit32(c, (opc << 24 | (g1) << 16 | (g3) << 12 | \
- (s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define S390_SS_4(c,opc,g1,g3,s2,p2,s4,p4) do \
-{ \
- s390_emit32(c, (opc << 24 | (g1) << 16 | (g3) << 12 | \
- (s2) << 12 | ((p2) & 0xfff))); \
- s390_emit16(c, ((s4) << 12 | ((p4) & 0xfff))); \
-} while (0)
-
-#define S390_SSE(c,opc,s1,p1,s2,p2) do \
-{ \
- s390_emit16(c, opc); \
- s390_emit16(c, ((s1) << 12 | ((p1) & 0xfff))); \
- s390_emit16(c, ((s2) << 12 | ((p2) & 0xfff))); \
-} while (0)
-
-#define s390_a(c, r, x, b, d) S390_RX(c, 0x5a, r, x, b, d)
-#define s390_adb(c, r, x, b, d) S390_RXE(c, 0xed1a, r, x, b, d)
-#define s390_adbr(c, r1, r2) S390_RRE(c, 0xb31a, r1, r2)
-#define s390_aebr(c, r1, r2) S390_RRE(c, 0xb30a, r1, r2)
-#define s390_ahi(c, r, v) S390_RI(c, 0xa7a, r, v)
-#define s390_alc(c, r, x, b, d) S390_RXY(c, 0xe398, r, x, b, d)
-#define s390_alcr(c, r1, r2) S390_RRE(c, 0xb998, r1, r2)
-#define s390_al(c, r, x, b, d) S390_RX(c, 0x5e, r, x, b, d)
-#define s390_alr(c, r1, r2) S390_RR(c, 0x1e, r1, r2)
-#define s390_ar(c, r1, r2) S390_RR(c, 0x1a, r1, r2)
-#define s390_basr(c, r1, r2) S390_RR(c, 0x0d, r1, r2)
-#define s390_bctr(c, r1, r2) S390_RR(c, 0x06, r1, r2)
-#define s390_bras(c, r, o) S390_RI(c, 0xa75, r, o)
-#define s390_brasl(c, r, o) S390_RIL_1(c, 0xc05, r, o)
-#define s390_brc(c, m, d) S390_RI(c, 0xa74, m, d)
-#define s390_br(c, r) S390_RR(c, 0x07, 0xf, r)
-#define s390_break(c) S390_RR(c, 0, 0, 0)
-#define s390_c(c, r, x, b, d) S390_RX(c, 0x59, r, x, b, d)
-#define s390_cdb(c, r, x, b, d) S390_RXE(c, 0xed19, r, x, b, d)
-#define s390_cdbr(c, r1, r2) S390_RRE(c, 0xb319, r1, r2)
-#define s390_cdfbr(c, r1, r2) S390_RRE(c, 0xb395, r1, r2)
-#define s390_cds(c, r1, r2, b, d) S390_RX(c, 0xbb, r1, r2, b, d)
-#define s390_cebr(c, r1, r2) S390_RRE(c, 0xb309, r1, r2)
-#define s390_cfdbr(c, r1, m, r2) S390_RRF_2(c, 0xb399, r1, m, r2)
-#define s390_chi(c, r, i) S390_RI(c, 0xa7e, r, i)
-#define s390_cl(c, r, x, b, d) S390_RX(c, 0x55, r, x, b, d)
-#define s390_clr(c, r1, r2) S390_RR(c, 0x15, r1, r2)
-#define s390_cr(c, r1, r2) S390_RR(c, 0x19, r1, r2)
-#define s390_cs(c, r1, r2, b, d) S390_RX(c, 0xba, r1, r2, b, d)
-#define s390_ddbr(c, r1, r2) S390_RRE(c, 0xb31d, r1, r2)
-#define s390_debr(c, r1, r2) S390_RRE(c, 0xb30d, r1, r2)
-#define s390_didbr(c, r1, r2, m, r3) S390_RRF_3(c, 0xb35b, r1, r2, m, r3)
-#define s390_dlr(c, r1, r2) S390_RRE(c, 0xb997, r1, r2)
-#define s390_dr(c, r1, r2) S390_RR(c, 0x1d, r1, r2)
-#define s390_ear(c, r1, r2) S390_RRE(c, 0xb24f, r1, r2)
-#define s390_ic(c, r, x, b, d) S390_RX(c, 0x43, r, x, b, d)
-#define s390_icm(c, r, m, b, d) S390_RX(c, 0xbf, r, m, b, d)
-#define s390_jc(c, m, d) s390_brc(c, m, d)
-#define s390_j(c,d) s390_brc(c, S390_CC_UN, d)
-#define s390_jcl(c, m, d) S390_RIL_2(c, 0xc04, m, d)
-#define s390_je(c, d) s390_brc(c, S390_CC_EQ, d)
-#define s390_jeo(c, d) s390_brc(c, S390_CC_ZR|S390_CC_OV, d)
-#define s390_jh(c, d) s390_brc(c, S390_CC_GT, d)
-#define s390_jho(c, d) s390_brc(c, S390_CC_GT|S390_CC_OV, d)
-#define s390_jl(c, d) s390_brc(c, S390_CC_LT, d)
-#define s390_jlo(c, d) s390_brc(c, S390_CC_LT|S390_CC_OV, d)
-#define s390_jm(c, d) s390_brc(c, S390_CC_LT, d)
-#define s390_jne(c, d) s390_brc(c, S390_CC_NZ, d)
-#define s390_jnh(c, d) s390_brc(c, S390_CC_LE, d)
-#define s390_jnl(c, d) s390_brc(c, S390_CC_GE, d)
-#define s390_jnz(c, d) s390_brc(c, S390_CC_NZ, d)
-#define s390_jo(c, d) s390_brc(c, S390_CC_OV, d)
-#define s390_jno(c, d) s390_brc(c, S390_CC_NO, d)
-#define s390_jp(c, d) s390_brc(c, S390_CC_GT, d)
-#define s390_jz(c, d) s390_brc(c, S390_CC_ZR, d)
-#define s390_jcy(c, d) s390_brc(c, S390_CC_CY, d)
-#define s390_jnc(c, d) s390_brc(c, S390_CC_NC, d)
-#define s390_la(c, r, x, b, d) S390_RX(c, 0x41, r, x, b, d)
-#define s390_lam(c, r1, r2, b, d) S390_RS_1(c, 0x9a, r1, r2, b, d)
-#define s390_larl(c, r, o) S390_RIL_1(c, 0xc00, r, o)
-#define s390_lcdbr(c, r1, r2) S390_RRE(c, 0xb313, r1, r2)
-#define s390_lcr(c, r1, r2) S390_RR(c, 0x13, r1, r2)
-#define s390_l(c, r, x, b, d) S390_RX(c, 0x58, r, x, b, d)
-#define s390_ld(c, f, x, b, d) S390_RX(c, 0x68, f, x, b, d)
-#define s390_ldeb(c, r, x, b, d) S390_RXE(c, 0xed04, r, x, b, d)
-#define s390_ldebr(c, r1, r2) S390_RRE(c, 0xb304, r1, r2)
-#define s390_ldr(c, r1, r2) S390_RR(c, 0x28, r1, r2)
-#define s390_le(c, f, x, b, d) S390_RX(c, 0x78, f, x, b, d)
-#define s390_ledbr(c, r1, r2) S390_RRE(c, 0xb344, r1, r2)
-#define s390_ler(c, r1, r2) S390_RR(c, 0x38, r1, r2)
-#define s390_lh(c, r, x, b, d) S390_RX(c, 0x48, r, x, b, d)
-#define s390_lhi(c, r, v) S390_RI(c, 0xa78, r, v)
-#define s390_lm(c, r1, r2, b, d) S390_RS_1(c, 0x98, r1, r2, b, d)
-#define s390_lndbr(c, r1, r2) S390_RRE(c, 0xb311, r1, r2)
-#define s390_lnr(c, r1, r2) S390_RR(c, 0x11, r1, r2)
-#define s390_lpr(c, r1, r2) S390_RR(c, 0x10, r1, r2)
-#define s390_lr(c, r1, r2) S390_RR(c, 0x18, r1, r2)
-#define s390_ltr(c, r1, r2) S390_RR(c, 0x12, r1, r2)
-#define s390_lzdr(c, r) S390_RRE(c, 0xb375, r, 0)
-#define s390_lzer(c, r) S390_RRE(c, 0xb374, r, 0)
-#define s390_m(c, r, x, b, d) S390_RX(c, 0x5c, r, x, b, d)
-#define s390_mdbr(c, r1, r2) S390_RRE(c, 0xb31c, r1, r2)
-#define s390_meebr(c, r1, r2) S390_RRE(c, 0xb317, r1, r2)
-#define s390_mlr(c, r1, r2) S390_RRE(c, 0xb996, r1, r2)
-#define s390_mr(c, r1, r2) S390_RR(c, 0x1c, r1, r2)
-#define s390_ms(c, r, x, b, d) S390_RX(c, 0x71, r, x, b, d)
-#define s390_msr(c, r1, r2) S390_RRE(c, 0xb252, r1, r2)
-#define s390_mvc(c, l, b1, d1, b2, d2) S390_SS_1(c, 0xd2, l, b1, d1, b2, d2)
-#define s390_mvcl(c, r1, r2) S390_RR(c, 0x0e, r1, r2)
-#define s390_mvcle(c, r1, r3, d2, b2) S390_RS_1(c, 0xa8, r1, r3, d2, b2)
-#define s390_n(c, r, x, b, d) S390_RX(c, 0x54, r, x, b, d)
-#define s390_nilh(c, r, v) S390_RI(c, 0xa56, r, v)
-#define s390_nill(c, r, v) S390_RI(c, 0xa57, r, v)
-#define s390_nr(c, r1, r2) S390_RR(c, 0x14, r1, r2)
-#define s390_o(c, r, x, b, d) S390_RX(c, 0x56, r, x, b, d)
-#define s390_or(c, r1, r2) S390_RR(c, 0x16, r1, r2)
-#define s390_s(c, r, x, b, d) S390_RX(c, 0x5b, r, x, b, d)
-#define s390_sdb(c, r, x, b, d) S390_RXE(c, 0xed1b, r, x, b, d)
-#define s390_sdbr(c, r1, r2) S390_RRE(c, 0xb31b, r1, r2)
-#define s390_sebr(c, r1, r2) S390_RRE(c, 0xb30b, r1, r2)
-#define s390_sla(c, r, b, d) S390_RS_3(c, 0x8b, r, b, d)
-#define s390_slb(c, r, x, b, d) S390_RXY(c, 0xe399, r, x, b, d)
-#define s390_slbr(c, r1, r2) S390_RRE(c, 0xb999, r1, r2)
-#define s390_sl(c, r, x, b, d) S390_RX(c, 0x5f, r, x, b, d)
-#define s390_slda(c, r, b, d) S390_RS_3(c, 0x8f, r, b, d)
-#define s390_sldl(c, r, b, d) S390_RS_3(c, 0x8d, r, b, d)
-#define s390_sll(c, r, b, d) S390_RS_3(c, 0x89, r, b, d)
-#define s390_slr(c, r1, r2) S390_RR(c, 0x1f, r1, r2)
-#define s390_sqdbr(c, r1, r2) S390_RRE(c, 0xb315, r1, r2)
-#define s390_sqebr(c, r1, r2) S390_RRE(c, 0xb314, r1, r2)
-#define s390_sra(c, r, b, d) S390_RS_3(c, 0x8a, r, b, d)
-#define s390_sr(c, r1, r2) S390_RR(c, 0x1b, r1, r2)
-#define s390_srda(c, r, b, d) S390_RS_3(c, 0x8e, r, b, d)
-#define s390_srdl(c, r, b, d) S390_RS_3(c, 0x8c, r, b, d)
-#define s390_srl(c, r, b, d) S390_RS_3(c, 0x88, r, b, d)
-#define s390_stam(c, r1, r2, b, d) S390_RS_1(c, 0x9b, r1, r2, b, d)
-#define s390_stc(c, r, x, b, d) S390_RX(c, 0x42, r, x, b, d)
-#define s390_stcm(c, r, m, b, d) S390_RX(c, 0xbe, r, m, b, d)
-#define s390_st(c, r, x, b, d) S390_RX(c, 0x50, r, x, b, d)
-#define s390_std(c, f, x, b, d) S390_RX(c, 0x60, f, x, b, d)
-#define s390_ste(c, f, x, b, d) S390_RX(c, 0x70, f, x, b, d)
-#define s390_stfpc(c, b, d) S390_S(c, 0xb29c, b, d)
-#define s390_sth(c, r, x, b, d) S390_RX(c, 0x40, r, x, b, d)
-#define s390_stm(c, r1, r2, b, d) S390_RS_1(c, 0x90, r1, r2, b, d)
-#define s390_tcdb(c, r, x, b, d) S390_RXE(c, 0xed11, r, x, b, d)
-#define s390_tceb(c, r, x, b, d) S390_RXE(c, 0xed10, r, x, b, d)
-#define s390_x(c, r, x, b, d) S390_RX(c, 0x57, r, x, b, d)
-#define s390_xr(c, r1, r2) S390_RR(c, 0x17, r1, r2)
-#endif
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - tramp.c */
-/* */
-/* Function - Create trampolines to invoke arbitrary functions. */
-/* */
-/* Name - Neale Ferguson. */
-/* */
-/* Date - October, 2002 */
-/* */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define PROLOG_INS 24 /* Size of emitted prolog */
-#define CALL_INS 4 /* Size of emitted call */
-#define EPILOG_INS 18 /* Size of emitted epilog */
-
-#define DEBUG(x)
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#ifdef NEED_MPROTECT
-# include <sys/mman.h>
-# include <limits.h> /* for PAGESIZE */
-# ifndef PAGESIZE
-# define PAGESIZE 4096
-# endif
-#endif
-
-#include "config.h"
-#include <stdlib.h>
-#include <string.h>
-#include "s390-codegen.h"
-#include "mono/metadata/class.h"
-#include "mono/metadata/tabledefs.h"
-#include "mono/interpreter/interp.h"
-#include "mono/metadata/appdomain.h"
-#include "mono/metadata/marshal.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* Structure used to accummulate size of stack, code, and locals */
-/*------------------------------------------------------------------*/
-typedef struct {
- guint stack_size,
- local_size,
- code_size,
- retStruct;
-} size_data;
-
-/*========================= End of Typedefs ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_general */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_general (guint *gr, size_data *sz, gboolean simple)
-{
- if (simple) {
- if (*gr >= GENERAL_REGS) {
- sz->stack_size += sizeof(long);
- sz->code_size += 12;
- } else {
- sz->code_size += 8;
- }
- } else {
- if (*gr >= GENERAL_REGS - 1) {
- sz->stack_size += 8 + (sz->stack_size % 8);
- sz->code_size += 10;
- } else {
- sz->code_size += 8;
- }
- (*gr) ++;
- }
- (*gr) ++;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - calculate_sizes */
-/* */
-/* Function - Determine the amount of space required for code */
-/* and stack. In addition determine starting points */
-/* for stack-based parameters, and area for struct- */
-/* ures being returned on the stack. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-calculate_sizes (MonoMethodSignature *sig, size_data *sz,
- gboolean string_ctor)
-{
- guint i, fr, gr, size;
- guint32 simpletype, align;
-
- fr = 0;
- gr = 2;
- sz->retStruct = 0;
- sz->stack_size = S390_MINIMAL_STACK_SIZE;
- sz->code_size = (PROLOG_INS + CALL_INS + EPILOG_INS);
- sz->local_size = 0;
-
- if (sig->hasthis) {
- add_general (&gr, sz, TRUE);
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the return code/stack in case we*/
- /* need to reserve a register to be used to address a stack */
- /* area that the callee will use. */
- /*----------------------------------------------------------*/
-
- if (sig->ret->byref || string_ctor) {
- sz->code_size += 8;
- } else {
- simpletype = sig->ret->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_STRING:
- sz->code_size += 4;
- break;
- case MONO_TYPE_I8:
- sz->code_size += 4;
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- gr++;
- if (sig->pinvoke)
- size = mono_class_native_size (sig->ret->data.klass, &align);
- else
- size = mono_class_value_size (sig->ret->data.klass, &align);
- if (align > 1)
- sz->code_size += 10;
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are returned */
- /* in (a) register(s). */
- /*----------------------------------*/
- case 1:
- case 2:
- case 4:
- case 8:
- sz->code_size += 16;
- sz->stack_size += 4;
- break;
- default:
- sz->retStruct = 1;
- sz->code_size += 32;
- }
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("tramp: cannot handle as return value 0x%x", sig->ret->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the parameter code and stack */
- /* requirements by checking the types and sizes of the */
- /* parameters. */
- /*----------------------------------------------------------*/
-
- for (i = 0; i < sig->param_count; ++i) {
- if (sig->params [i]->byref) {
- add_general (&gr, sz, TRUE);
- continue;
- }
- simpletype = sig->params [i]->type;
- enum_calc_size:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- add_general (&gr, sz, TRUE);
- break;
- case MONO_TYPE_SZARRAY:
- add_general (&gr, sz, TRUE);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simpletype = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_calc_size;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- size = mono_class_value_size (sig->params [i]->data.klass, &align);
- DEBUG(printf("%d typesize: %d (%d)\n",i,size,align));
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, TRUE);
- break;
- case 8:
- add_general(&gr, sz, FALSE);
- break;
- default:
- sz->local_size += (size + (size % align));
- sz->code_size += 40;
- }
- break;
- case MONO_TYPE_I8:
- add_general (&gr, sz, FALSE);
- break;
- case MONO_TYPE_R4:
- if (fr < FLOAT_REGS) {
- sz->code_size += 4;
- fr++;
- }
- else {
- sz->code_size += 4;
- sz->stack_size += 8;
- }
- break;
- case MONO_TYPE_R8:
- if (fr < FLOAT_REGS) {
- sz->code_size += 4;
- fr++;
- } else {
- sz->code_size += 4;
- sz->stack_size += 8 + (sz->stack_size % 8);
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
-
- /* align stack size to 8 */
- DEBUG (printf (" stack size: %d (%d)\n"
- " code size: %d\n"
- " local size: %d\n",
- (sz->stack_size + 8) & ~8, sz->stack_size,
- (sz->code_size),(sz->local_size + 8) & ~8));
- sz->stack_size = (sz->stack_size + 8) & ~8;
- sz->local_size = (sz->local_size + 8) & ~8;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_prolog */
-/* */
-/* Function - Create the instructions that implement the stand- */
-/* ard function prolog according to the S/390 ABI. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_prolog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- guint stack_size;
-
- stack_size = sz->stack_size + sz->local_size;
-
- /* function prolog */
- s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_l (p, s390_r7, 0, STK_BASE, MINV_POS);
- s390_lr (p, s390_r11, STK_BASE);
- s390_ahi (p, STK_BASE, -stack_size);
- s390_st (p, s390_r11, 0, STK_BASE, 0);
-
- /*-----------------------------------------*/
- /* Save: */
- /* - address of "callme" */
- /* - address of "retval" */
- /* - address of "arguments" */
- /*-----------------------------------------*/
- s390_lr (p, s390_r9, s390_r2);
- s390_lr (p, s390_r8, s390_r3);
- s390_lr (p, s390_r10, s390_r5);
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_save_parameters */
-/* */
-/* Function - Create the instructions that load registers with */
-/* parameters, place others on the stack according */
-/* to the S/390 ABI. */
-/* */
-/* The resulting function takes the form: */
-/* void func (void (*callme)(), void *retval, */
-/* void *this_obj, stackval *arguments); */
-/* */
-/*------------------------------------------------------------------*/
-
-inline static guint8*
-emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- guint i, fr, gr, act_strs, align,
- stack_par_pos, size, local_pos;
- guint32 simpletype;
-
- /*----------------------------------------------------------*/
- /* If a structure on stack is being returned, reserve r2 */
- /* to point to an area where it can be passed. */
- /*----------------------------------------------------------*/
- if (sz->retStruct)
- gr = 1;
- else
- gr = 0;
- fr = 0;
- act_strs = 0;
- stack_par_pos = S390_MINIMAL_STACK_SIZE;
- local_pos = sz->stack_size;
-
- if (sig->hasthis) {
- s390_lr (p, s390_r2 + gr, s390_r4);
- gr++;
- }
-
- act_strs = 0;
- for (i = 0; i < sig->param_count; ++i) {
- DEBUG(printf("par: %d type: %d ref: %d\n",i,sig->params[i]->type,sig->params[i]->byref));
- if (sig->params [i]->byref) {
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- gr ++;
- } else {
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- continue;
- }
- simpletype = sig->params [i]->type;
- enum_calc_size:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_SZARRAY:
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- gr ++;
- } else {
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simpletype = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_calc_size;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- size = mono_class_value_size (sig->params [i]->data.klass, &align);
- DEBUG(printf("parStruct - size %d pinvoke: %d\n",size,sig->pinvoke));
- switch (size) {
- case 0:
- case 1:
- case 2:
- case 4:
- if (gr < GENERAL_REGS) {
- s390_l (p, s390_r2 + gr, 0,ARG_BASE, STKARG);
- s390_l (p, s390_r2 + gr, 0, s390_r2 + gr, 0);
- gr++;
- } else {
- stack_par_pos += (stack_par_pos % align);
- s390_l (p, s390_r10, 0,ARG_BASE, STKARG);
- s390_l (p, s390_r10, 0, s390_r10, 0);
- s390_st (p, s390_r10, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- break;
- case 8:
- if (gr < GENERAL_REGS-1) {
- s390_l (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
- s390_lm (p, s390_r2 + gr, s390_r3 + gr, s390_r2 + gr, 0);
- } else {
- stack_par_pos += (stack_par_pos % align);
- s390_l (p, s390_r10, 0, ARG_BASE, STKARG);
- s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, s390_r10, 0);
- stack_par_pos += sizeof(long long);
- }
- break;
- default:
- if (size <= 256) {
- local_pos += (local_pos % align);
- s390_l (p, s390_r13, 0, ARG_BASE, STKARG);
- s390_mvc (p, size, STK_BASE, local_pos, s390_r13, 0);
- s390_la (p, s390_r13, 0, STK_BASE, local_pos);
- local_pos += size;
- } else {
- local_pos += (local_pos % align);
- s390_bras (p, s390_r13, 4);
- s390_word (p, size);
- s390_l (p, s390_r1, 0, s390_r13, 0);
- s390_l (p, s390_r0, 0, ARG_BASE, STKARG);
- s390_lr (p, s390_r14, s390_r12);
- s390_la (p, s390_r12, 0, STK_BASE, local_pos);
- s390_lr (p, s390_r13, s390_r1);
- s390_mvcl (p, s390_r12, s390_r0);
- s390_lr (p, s390_r12, s390_r14);
- s390_la (p, s390_r13, 0, STK_BASE, local_pos);
- local_pos += size;
- }
- if (gr < GENERAL_REGS) {
- s390_lr (p, s390_r2 + gr, s390_r13);
- gr++;
- } else {
- s390_st (p, s390_r13, 0, STK_BASE, stack_par_pos);
- stack_par_pos += sizeof(long);
- }
- }
- break;
- case MONO_TYPE_I8:
- if (gr < GENERAL_REGS-1) {
- s390_lm (p, s390_r2 + gr, s390_r2 + gr + 1, ARG_BASE, STKARG);
- gr += 2;
- } else {
- *(guint32 *) p += 7;
- *(guint32 *) p &= ~7;
- s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(long long) + (stack_par_pos % sizeof(long long));
- }
- break;
- case MONO_TYPE_R4:
- if (fr < FLOAT_REGS) {
- s390_le (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
- fr++;
- } else {
- s390_mvc (p, sizeof(float), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(float);
- }
- break;
- case MONO_TYPE_R8:
- if (fr < FLOAT_REGS) {
- s390_ld (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
- fr++;
- } else {
- *(guint32 *) p += 7;
- *(guint32 *) p &= ~7;
- s390_mvc (p, sizeof(double), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
- stack_par_pos += sizeof(long long) + (stack_par_pos % sizeof(long long));
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* If we're returning a structure but not in a register */
- /* then point the result area for the called routine */
- /*----------------------------------------------------------*/
- if (sz->retStruct) {
- s390_l (p, s390_r2, 0, s390_r8, 0);
- }
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - alloc_code_memory */
-/* */
-/* Function - Allocate space to place the emitted code. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-alloc_code_memory (guint code_size)
-{
- guint8 *p;
-
-#ifdef NEED_MPROTECT
- p = g_malloc (code_size + PAGESIZE - 1);
-
- /* Align to a multiple of PAGESIZE, assumed to be a power of two */
- p = (char *)(((int) p + PAGESIZE-1) & ~(PAGESIZE-1));
-#else
- p = g_malloc (code_size);
-#endif
- DEBUG (printf (" align: %p (%d)\n", p, (guint)p % 4));
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_call_and_store_retval */
-/* */
-/* Function - Emit code that will implement the call to the */
-/* desired function, and unload the result according */
-/* to the S390 ABI for the type of value returned */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig,
- size_data *sz, gboolean string_ctor)
-{
- guint32 simpletype;
- guint retSize, align;
-
- /* call "callme" */
- s390_basr (p, s390_r14, s390_r9);
-
- /* get return value */
- if (sig->ret->byref || string_ctor) {
- s390_st (p, s390_r2, 0, s390_r8, 0);
- } else {
- simpletype = sig->ret->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- s390_stc (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- s390_sth (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_STRING:
- s390_st (p, s390_r2, 0, s390_r8, 0);
- break;
- case MONO_TYPE_R4:
- s390_ste (p, s390_f0, 0, s390_r8, 0);
- break;
- case MONO_TYPE_R8:
- s390_std (p, s390_f0, 0, s390_r8, 0);
- break;
- case MONO_TYPE_I8:
- s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- if (sig->pinvoke)
- retSize = mono_class_native_size (sig->ret->data.klass, &align);
- else
- retSize = mono_class_value_size (sig->ret->data.klass, &align);
-printf("Returning %d bytes for type %d (%d)\n",retSize,simpletype,sig->pinvoke);
- switch(retSize) {
- case 0:
- break;
- case 1:
- s390_stc (p, s390_r2, 0, s390_r8, 0);
- break;
- case 2:
- s390_sth (p, s390_r2, 0, s390_r8, 0);
- break;
- case 4:
- s390_st (p, s390_r2, 0, s390_r8, 0);
- break;
- case 8:
- s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
- break;
- default: ;
- /*------------------------------------------*/
- /* The callee has already placed the result */
- /* in the required area */
- /*------------------------------------------*/
- break;
- }
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("Can't handle as return value 0x%x",
- sig->ret->type);
- }
- }
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_epilog */
-/* */
-/* Function - Create the instructions that implement the stand- */
-/* ard function epilog according to the S/390 ABI. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-emit_epilog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
-{
- /* function epilog */
- s390_l (p, STK_BASE, 0, STK_BASE, 0);
- s390_l (p, s390_r4, 0, STK_BASE, 56);
- s390_lm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_br (p, s390_r4);
-
- return p;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_trampoline. */
-/* */
-/* Function - Create the code that will allow a mono method to */
-/* invoke a system subroutine. */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoPIFunc
-mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
-{
- guint8 *p, *code_buffer;
- size_data sz;
-
- DEBUG (printf ("\nPInvoke [start emiting]\n"));
- calculate_sizes (sig, &sz, string_ctor);
-
- p = code_buffer = alloc_code_memory (sz.code_size);
- p = emit_prolog (p, sig, &sz);
- p = emit_save_parameters (p, sig, &sz);
- p = emit_call_and_store_retval (p, sig, &sz, string_ctor);
- p = emit_epilog (p, sig, &sz);
-
-#ifdef NEED_MPROTECT
- if (mprotect (code_buffer, 1024, PROT_READ | PROT_WRITE | PROT_EXEC)) {
- g_error ("Cannot mprotect trampoline\n");
- }
-#endif
-
- DEBUG (printf ("emited code size: %d\n", p - code_buffer));
-
- DEBUG (printf ("PInvoke [end emiting]\n"));
-
- return (MonoPIFunc) code_buffer;
-}
-
-/*========================= End of Function ========================*/
-\f
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_method_pointer */
-/* */
-/* Function - Returns a pointer to a native function that can */
-/* be used to call the specified method. */
-/* */
-/* The function created will receive the arguments */
-/* according to the calling convention specified in */
-/* in the method. */
-/* */
-/* This function works by creating a MonoInvocation */
-/* structure, filling the fields in and calling */
-/* ves_exec_method() on it. */
-/* */
-/* Logic: */
-/* ------ */
-/* mono_arch_create_method_pointer (MonoMethod *method) */
-/* create the unmanaged->managed wrapper */
-/* register it with mono_jit_info_table_add() */
-/* */
-/* What does the unmanaged->managed wrapper do? */
-/* allocate a MonoInvocation structure (inv) on the stack */
-/* allocate an array of stackval on the stack with length = */
-/* method->signature->param_count + 1 [call it stack_args] */
-/* set inv->ex, inv->ex_handler, inv->parent to NULL */
-/* set inv->method to method */
-/* if method is an instance method, set inv->obj to the */
-/* 'this' argument (the first argument) else set to NULL */
-/* for each argument to the method call: */
-/* stackval_from_data (sig->params[i], &stack_args[i], */
-/* arg, sig->pinvoke); */
-/* Where: */
-/* ------ */
-/* sig - is method->signature */
-/* &stack_args[i] - is the pointer to the ith element */
-/* in the stackval array */
-/* arg - is a pointer to the argument re- */
-/* ceived by the function according */
-/* to the call convention. If it */
-/* gets passed in a register, save */
-/* on the stack first. */
-/* */
-/* set inv->retval to the address of the last element of */
-/* stack_args [recall we allocated param_count+1 of them] */
-/* call ves_exec_method(inv) */
-/* copy the returned value from inv->retval where the calling */
-/* convention expects to find it on return from the wrap- */
-/* per [if it's a structure, use stackval_to_data] */
-/* */
-/*------------------------------------------------------------------*/
-
-void *
-mono_arch_create_method_pointer (MonoMethod *method)
-{
- MonoMethodSignature *sig;
- MonoJitInfo *ji;
- guint8 *p, *code_buffer;
- guint i, align = 0, simple_type, retSize, reg_save = 0,
- stackval_arg_pos, local_pos, float_pos,
- local_start, reg_param = 0, stack_param,
- this_flag, arg_pos, fpr_param, parSize;
- guint32 simpletype;
- size_data sz;
- int *vtbuf, cpos, vt_cur;
-
- sz.code_size = 1024;
- sz.stack_size = 1024;
- stack_param = 0;
- fpr_param = 0;
- arg_pos = 0;
-
- sig = method->signature;
-
- p = code_buffer = g_malloc (sz.code_size);
-
- DEBUG (printf ("\nDelegate [start emiting] %s at 0x%08x\n",
- method->name,p));
-
- /*----------------------------------------------------------*/
- /* prolog */
- /*----------------------------------------------------------*/
- s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
- s390_l (p, s390_r7, 0, STK_BASE, MINV_POS);
- s390_lr (p, s390_r0, STK_BASE);
- s390_ahi (p, STK_BASE, -(sz.stack_size+MINV_POS));
- s390_st (p, s390_r0, 0, STK_BASE, 0);
- s390_la (p, s390_r8, 0, STK_BASE, 4);
- s390_lr (p, s390_r10, s390_r8);
- s390_lhi (p, s390_r9, sz.stack_size+92);
- s390_lhi (p, s390_r11, 0);
- s390_mvcl(p, s390_r8, s390_r10);
-
- /*----------------------------------------------------------*/
- /* Let's fill MonoInvocation - first zero some fields */
- /*----------------------------------------------------------*/
- s390_lhi (p, s390_r0, 0);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)));
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)));
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)));
- s390_lhi (p, s390_r0, 1);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, invoke_trap)));
-
- /*----------------------------------------------------------*/
- /* set method pointer */
- /*----------------------------------------------------------*/
- s390_bras (p, s390_r13, 4);
- s390_word (p, method);
- s390_l (p, s390_r0, 0, s390_r13, 0);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)));
-
- local_start = local_pos = MINV_POS +
- sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof (stackval);
- this_flag = (sig->hasthis ? 1 : 0);
-
- /*----------------------------------------------------------*/
- /* if we are returning a structure, checks it's length to */
- /* see if there's a "hidden" parameter that points to the */
- /* area. If necessary save this hidden parameter for later */
- /*----------------------------------------------------------*/
- if (MONO_TYPE_ISSTRUCT(sig->ret)) {
- if (sig->pinvoke)
- retSize = mono_class_native_size (sig->ret->data.klass, &align);
- else
- retSize = mono_class_value_size (sig->ret->data.klass, &align);
- switch(retSize) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- sz.retStruct = 0;
- break;
- default:
- sz.retStruct = 1;
- s390_lr(p, s390_r8, s390_r2);
- reg_save = 1;
- }
- } else {
- reg_save = 0;
- }
-
- if (this_flag) {
- s390_st (p, s390_r2 + reg_save, 0, STK_BASE,
- (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
- reg_param++;
- } else {
- s390_st (p, s390_r2 + reg_save, 0, STK_BASE, local_pos);
- local_pos += sizeof(int);
- s390_st (p, s390_r0, 0, STK_BASE,
- (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
- }
-
- s390_stm (p, s390_r3 + reg_param, s390_r6, STK_BASE, local_pos);
- local_pos += 4 * sizeof(long);
- float_pos = local_pos;
- s390_std (p, s390_f0, 0, STK_BASE, local_pos);
- local_pos += sizeof(double);
- s390_std (p, s390_f2, 0, STK_BASE, local_pos);
- local_pos += sizeof(double);
-
- /*----------------------------------------------------------*/
- /* prepare space for valuetypes */
- /*----------------------------------------------------------*/
- vt_cur = local_pos;
- vtbuf = alloca (sizeof(int)*sig->param_count);
- cpos = 0;
- for (i = 0; i < sig->param_count; i++) {
- MonoType *type = sig->params [i];
- vtbuf [i] = -1;
- DEBUG(printf("par: %d type: %d ref: %d\n",i,type->type,type->byref));
- if (type->type == MONO_TYPE_VALUETYPE) {
- MonoClass *klass = type->data.klass;
- gint size;
-
- if (klass->enumtype)
- continue;
- size = mono_class_native_size (klass, &align);
- cpos += align - 1;
- cpos &= ~(align - 1);
- vtbuf [i] = cpos;
- cpos += size;
- }
- }
- cpos += 3;
- cpos &= ~3;
-
- local_pos += cpos;
-
- /*----------------------------------------------------------*/
- /* set MonoInvocation::stack_args */
- /*----------------------------------------------------------*/
- stackval_arg_pos = MINV_POS + sizeof (MonoInvocation);
- s390_la (p, s390_r0, 0, STK_BASE, stackval_arg_pos);
- s390_st (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)));
-
- /*----------------------------------------------------------*/
- /* add stackval arguments */
- /*----------------------------------------------------------*/
- for (i = 0; i < sig->param_count; ++i) {
- if (sig->params [i]->byref) {
- ADD_ISTACK_PARM(0, 1);
- } else {
- simple_type = sig->params [i]->type;
- enum_savechk:
- switch (simple_type) {
- case MONO_TYPE_I8:
- ADD_ISTACK_PARM(-1, 2);
- break;
- case MONO_TYPE_R4:
- ADD_RSTACK_PARM(1);
- break;
- case MONO_TYPE_R8:
- ADD_RSTACK_PARM(2);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->params [i]->data.klass->enumtype) {
- simple_type = sig->params [i]->data.klass->enum_basetype->type;
- goto enum_savechk;
- }
- if (sig->pinvoke)
- parSize = mono_class_native_size (sig->params [i]->data.klass, &align);
- else
- parSize = mono_class_value_size (sig->params [i]->data.klass, &align);
- switch(parSize) {
- case 0:
- case 1:
- case 2:
- case 4:
- ADD_PSTACK_PARM(0, 1);
- break;
- case 8:
- ADD_PSTACK_PARM(-1, 2);
- break;
- default:
- ADD_TSTACK_PARM;
- }
- break;
- default:
- ADD_ISTACK_PARM(0, 1);
- }
- }
-
- if (vtbuf [i] >= 0) {
- s390_la (p, s390_r3, 0, STK_BASE, vt_cur);
- s390_st (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- s390_la (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- vt_cur += vtbuf [i];
- } else {
- s390_la (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
- }
-
- /*--------------------------------------*/
- /* Load the parameter registers for the */
- /* call to stackval_from_data */
- /*--------------------------------------*/
- s390_bras (p, s390_r13, 8);
- s390_word (p, sig->params [i]);
- s390_word (p, sig->pinvoke);
- s390_word (p, stackval_from_data);
- s390_l (p, s390_r2, 0, s390_r13, 0);
-
- s390_l (p, s390_r5, 0, s390_r13, 4);
-
- s390_l (p, s390_r1, 0, s390_r13, 8);
- s390_basr (p, s390_r14, s390_r1);
-
- stackval_arg_pos += sizeof(stackval);
-
- /* fixme: alignment */
- DEBUG (printf ("arg_pos %d --> ", arg_pos));
- if (sig->pinvoke)
- arg_pos += mono_type_native_stack_size (sig->params [i], &align);
- else
- arg_pos += mono_type_stack_size (sig->params [i], &align);
-
- DEBUG (printf ("%d\n", stackval_arg_pos));
- }
-
- /*----------------------------------------------------------*/
- /* Set return area pointer. */
- /*----------------------------------------------------------*/
- s390_la (p, s390_r10, 0, STK_BASE, stackval_arg_pos);
- s390_st (p, s390_r10, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
- if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) {
- MonoClass *klass = sig->ret->data.klass;
- if (!klass->enumtype) {
- s390_la (p, s390_r9, 0, s390_r10, sizeof(stackval));
- s390_st (p, s390_r9, 0,STK_BASE, stackval_arg_pos);
- stackval_arg_pos += sizeof(stackval);
- }
- }
-
- /*----------------------------------------------------------*/
- /* call ves_exec_method */
- /*----------------------------------------------------------*/
- s390_bras (p, s390_r13, 4);
- s390_word (p, ves_exec_method);
- s390_l (p, s390_r1, 0, s390_r13, 0);
- s390_la (p, s390_r2, 0, STK_BASE, MINV_POS);
- s390_basr (p, s390_r14, s390_r1);
-
- /*----------------------------------------------------------*/
- /* move retval from stackval to proper place (r3/r4/...) */
- /*----------------------------------------------------------*/
- DEBUG(printf("retType: %d byRef: %d\n",sig->ret->type,sig->ret->byref));
- if (sig->ret->byref) {
- DEBUG (printf ("ret by ref\n"));
- s390_st (p, s390_r2, 0, s390_r10, 0);
- } else {
- enum_retvalue:
-DEBUG(printf("Returns: %d\n",sig->ret->type));
- switch (sig->ret->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_U1:
- s390_lhi (p, s390_r2, 0);
- s390_ic (p, s390_r2, 0, s390_r10, 0);
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- s390_lh (p, s390_r2, 0,s390_r10, 0);
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- s390_l (p, s390_r2, 0, s390_r10, 0);
- break;
- case MONO_TYPE_I8:
- s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
- break;
- case MONO_TYPE_R4:
- s390_le (p, s390_f0, 0, s390_r10, 0);
- break;
- case MONO_TYPE_R8:
- s390_ld (p, s390_f0, 0, s390_r10, 0);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simpletype = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- /*---------------------------------*/
- /* Call stackval_to_data to return */
- /* the structure */
- /*---------------------------------*/
- s390_bras (p, s390_r13, 8);
- s390_word (p, sig->ret);
- s390_word (p, sig->pinvoke);
- s390_word (p, stackval_to_data);
- s390_l (p, s390_r2, 0, s390_r13, 0);
- s390_l (p, s390_r3, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
- if (sz.retStruct) {
- /*------------------------------------------*/
- /* Get stackval_to_data to set result area */
- /*------------------------------------------*/
- s390_lr (p, s390_r4, s390_r8);
- } else {
- /*------------------------------------------*/
- /* Give stackval_to_data a temp result area */
- /*------------------------------------------*/
- s390_la (p, s390_r4, 0, STK_BASE, stackval_arg_pos);
- }
- s390_l (p, s390_r5, 0,s390_r13, 4);
- s390_l (p, s390_r1, 0, s390_r13, 8);
- s390_basr (p, s390_r14, s390_r1);
- switch (retSize) {
- case 0:
- break;
- case 1:
- s390_lhi (p, s390_r2, 0);
- s390_ic (p, s390_r2, 0, s390_r10, 0);
- break;
- case 2:
- s390_lh (p, s390_r2, 0, s390_r10, 0);
- break;
- case 4:
- s390_l (p, s390_r2, 0, s390_r10, 0);
- break;
- case 8:
- s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
- break;
- default: ;
- /*-------------------------------------------------*/
- /* stackval_to_data has placed data in result area */
- /*-------------------------------------------------*/
- break;
- }
- break;
- default:
- g_error ("Type 0x%x not handled yet in thunk creation",
- sig->ret->type);
- break;
- }
- }
-
- /*----------------------------------------------------------*/
- /* epilog */
- /*----------------------------------------------------------*/
- s390_l (p, STK_BASE, 0, STK_BASE, 0);
- s390_l (p, s390_r4, 0, STK_BASE, S390_RET_ADDR_OFFSET);
- s390_lm (p, s390_r6, STK_BASE, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (p, s390_r4);
-
- DEBUG (printf ("emited code size: %d\n", p - code_buffer));
-
- DEBUG (printf ("Delegate [end emiting]\n"));
-
- ji = g_new0 (MonoJitInfo, 1);
- ji->method = method;
- ji->code_size = p - code_buffer;
- ji->code_start = code_buffer;
-
- mono_jit_info_table_add (mono_get_root_domain (), ji);
-
- return ji->code_start;
-}
-
-/*========================= End of Function ========================*/
#define s390_basr(c, r1, r2) S390_RR(c, 0x0d, r1, r2)
#define s390_bctr(c, r1, r2) S390_RR(c, 0x06, r1, r2)
#define s390_bctrg(c, r1, r2) S390_RRE(c, 0xb946, r1, r2)
+#define s390_bnzr(c, r) S390_RR(c, 0x07, 0x07, r)
#define s390_bras(c, r, o) S390_RI(c, 0xa75, r, o)
#define s390_brasl(c, r, o) S390_RIL_1(c, 0xc05, r, o)
#define s390_brc(c, m, d) S390_RI(c, 0xa74, m, d)
+#define s390_brcl(c, m, d) S390_RIL_2(c, 0xc04, m, d)
#define s390_br(c, r) S390_RR(c, 0x07, 0xf, r)
#define s390_break(c) S390_RR(c, 0, 0, 0)
+#define s390_bzr(c, r) S390_RR(c, 0x07, 0x08, r)
#define s390_c(c, r, x, b, d) S390_RX(c, 0x59, r, x, b, d)
#define s390_cdb(c, r, x, b, d) S390_RXE(c, 0xed19, r, x, b, d)
#define s390_cdbr(c, r1, r2) S390_RRE(c, 0xb319, r1, r2)
#define s390_icy(c, r, x, b, d) S390_RXY(c, 0xe373, r, x, b, d)
#define s390_j(c,d) s390_brc(c, S390_CC_UN, d)
#define s390_jc(c, m, d) s390_brc(c, m, d)
-#define s390_jcl(c, m, d) S390_RIL_2(c, 0xc04, m, d)
+#define s390_jcl(c, m, d) s390_brcl(c, m, d)
#define s390_jcy(c, d) s390_brc(c, S390_CC_CY, d)
#define s390_je(c, d) s390_brc(c, S390_CC_EQ, d)
#define s390_jeo(c, d) s390_brc(c, S390_CC_ZR|S390_CC_OV, d)
#define s390_jno(c, d) s390_brc(c, S390_CC_NO, d)
#define s390_jp(c, d) s390_brc(c, S390_CC_GT, d)
#define s390_jz(c, d) s390_brc(c, S390_CC_ZR, d)
+#define s390_jg(c,d) s390_brcl(c, S390_CC_UN, d)
+#define s390_jgcy(c, d) s390_brcl(c, S390_CC_CY, d)
+#define s390_jge(c, d) s390_brcl(c, S390_CC_EQ, d)
+#define s390_jgeo(c, d) s390_brcl(c, S390_CC_ZR|S390_CC_OV, d)
+#define s390_jgh(c, d) s390_brcl(c, S390_CC_GT, d)
+#define s390_jgho(c, d) s390_brcl(c, S390_CC_GT|S390_CC_OV, d)
+#define s390_jgl(c, d) s390_brcl(c, S390_CC_LT, d)
+#define s390_jglo(c, d) s390_brcl(c, S390_CC_LT|S390_CC_OV, d)
+#define s390_jgm(c, d) s390_brcl(c, S390_CC_LT, d)
+#define s390_jgnc(c, d) s390_brcl(c, S390_CC_NC, d)
+#define s390_jgne(c, d) s390_brcl(c, S390_CC_NZ, d)
+#define s390_jgnh(c, d) s390_brcl(c, S390_CC_LE, d)
+#define s390_jgnl(c, d) s390_brcl(c, S390_CC_GE, d)
+#define s390_jgnz(c, d) s390_brcl(c, S390_CC_NZ, d)
+#define s390_jgo(c, d) s390_brcl(c, S390_CC_OV, d)
+#define s390_jgno(c, d) s390_brcl(c, S390_CC_NO, d)
+#define s390_jgp(c, d) s390_brcl(c, S390_CC_GT, d)
+#define s390_jgz(c, d) s390_brcl(c, S390_CC_ZR, d)
#define s390_l(c, r, x, b, d) S390_RX(c, 0x58, r, x, b, d)
#define s390_ly(c, r, x, b, d) S390_RXY(c, 0xe358, r, x, b, d)
#define s390_la(c, r, x, b, d) S390_RX(c, 0x41, r, x, b, d)
io-portability.h \
macros.h \
messages.h \
- mono-mutex.h \
mutexes.h \
processes.h \
security.h \
mutexes.c \
mutexes.h \
mutex-private.h \
- mono-mutex.c \
- mono-mutex.h \
posix.c \
processes.c \
processes.h \
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/critical-section-private.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
/* A critical section is really just like a lightweight mutex. It
* can't be waited for, and doesn't have a handle.
*/
-/* According to the MSDN docs, the Microsoft implementation spins a
- * number of times then waits for a semaphore. I could implement that
- * here but I'd need a mutex around the critical section structure
- * anyway. So I may as well just use a pthread mutex.
- */
-static mono_once_t attr_key_once=MONO_ONCE_INIT;
-static mono_mutexattr_t attr;
-
-static void attr_init(void)
-{
- int ret;
-
- ret = mono_mutexattr_init(&attr);
- g_assert (ret == 0);
-
- ret = mono_mutexattr_settype(&attr, MONO_MUTEX_RECURSIVE);
- g_assert (ret == 0);
-}
-
-void _wapi_critical_section_cleanup (void)
-{
- mono_mutexattr_destroy (&attr);
-}
-
/**
* InitializeCriticalSection:
* @section: The critical section to initialise
{
int ret;
- mono_once(&attr_key_once, attr_init);
- ret = mono_mutex_init(§ion->mutex, &attr);
+ ret = mono_mutex_init_recursive (§ion->mutex);
g_assert (ret == 0);
}
#include <glib.h>
#include <pthread.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
G_BEGIN_DECLS
#include <glib.h>
#include <pthread.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
extern struct _WapiHandleOps _wapi_event_ops;
extern struct _WapiHandleOps _wapi_namedevent_ops;
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
-
#include <mono/io-layer/event-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/shared.h>
#include <mono/io-layer/collection.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/critical-section-private.h>
+#include <mono/utils/mono-mutex.h>
#undef DEBUG_REFS
#if 0
}
-static mono_mutex_t scan_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t scan_mutex;
static void handle_cleanup (void)
{
if (_wapi_shm_enabled ())
_wapi_collection_init ();
#endif
+ _wapi_io_init ();
+ mono_mutex_init (&scan_mutex);
_wapi_global_signal_handle = _wapi_handle_new (WAPI_HANDLE_EVENT, NULL);
_wapi_global_signal_cond = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_cond;
_wapi_global_signal_mutex = &_WAPI_PRIVATE_HANDLES (GPOINTER_TO_UINT (_wapi_global_signal_handle)).signal_mutex;
+
/* Using g_atexit here instead of an explicit function call in
* a cleanup routine lets us cope when a third-party library
* calls exit (eg if an X client loses the connection to its
_wapi_has_shut_down = TRUE;
- _wapi_critical_section_cleanup ();
_wapi_error_cleanup ();
_wapi_thread_cleanup ();
}
thr_ret = pthread_cond_init (&handle->signal_cond, NULL);
g_assert (thr_ret == 0);
- thr_ret = mono_mutex_init (&handle->signal_mutex, NULL);
+ thr_ret = mono_mutex_init (&handle->signal_mutex);
g_assert (thr_ret == 0);
if (handle_specific != NULL) {
#include <utime.h>
#include <sys/stat.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/error.h>
#include <mono/io-layer/wapi_glob.h>
#include <mono/io-layer/io-portability.h>
#include <mono/utils/mono-io-portability.h>
+
+#include <mono/utils/mono-mutex.h>
+
#undef DEBUG
int _wapi_open (const char *pathname, int flags, mode_t mode)
* Return value: the handle, or %INVALID_HANDLE_VALUE on error
*/
-static mono_mutex_t stdhandle_mutex = MONO_MUTEX_INITIALIZER;
+static mono_mutex_t stdhandle_mutex;
gpointer GetStdHandle(WapiStdHandle stdhandle)
{
return status;
}
#endif
+
+
+void
+_wapi_io_init (void)
+{
+ mono_mutex_init (&stdhandle_mutex);
+}
guint32 length_high);
extern gboolean GetVolumeInformation (const gunichar2 *path, gunichar2 *volumename, int volumesize, int *outserial, int *maxcomp, int *fsflags, gunichar2 *fsbuffer, int fsbuffersize);
+
+extern void _wapi_io_init (void);
+
G_END_DECLS
#endif /* _WAPI_IO_H_ */
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/time.h>
-
-#include "mono-mutex.h"
-
-
-#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
-/* Android does not implement pthread_mutex_timedlock(), but does provide an
- * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
- */
-#ifdef PLATFORM_ANDROID
-#define CONST_NEEDED
-#else
-#define CONST_NEEDED const
-#endif
-
-int pthread_mutex_timedlock (pthread_mutex_t *mutex,
- CONST_NEEDED struct timespec *timeout);
-int
-pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
-{
- struct timeval timenow;
- struct timespec sleepytime;
- int retcode;
-
- /* This is just to avoid a completely busy wait */
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = 10000000; /* 10ms */
-
- while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
- gettimeofday (&timenow, NULL);
-
- if (timenow.tv_sec >= timeout->tv_sec &&
- (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
- return ETIMEDOUT;
- }
-
- nanosleep (&sleepytime, NULL);
- }
-
- return retcode;
-}
-#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
-
-
-int
-mono_once (mono_once_t *once, void (*once_init) (void))
-{
- int thr_ret;
-
- if (!once->complete) {
- pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
- (void *)&once->mutex);
- thr_ret = pthread_mutex_lock (&once->mutex);
- g_assert (thr_ret == 0);
-
- if (!once->complete) {
- once_init ();
- once->complete = TRUE;
- }
- thr_ret = pthread_mutex_unlock (&once->mutex);
- g_assert (thr_ret == 0);
-
- pthread_cleanup_pop (0);
- }
-
- return 0;
-}
-
-
-#ifdef USE_MONO_MUTEX
-
-int
-mono_mutexattr_init (mono_mutexattr_t *attr)
-{
- memset (attr, 0, sizeof (mono_mutexattr_t));
- return 0;
-}
-
-int
-mono_mutexattr_settype (mono_mutexattr_t *attr, int type)
-{
- attr->type = type;
- return 0;
-}
-
-int
-mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type)
-{
- *type = attr->type;
- return 0;
-}
-
-int
-mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared)
-{
- attr->shared = pshared;
- return 0;
-}
-
-int
-mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared)
-{
- *pshared = attr->shared;
- return 0;
-}
-
-int
-mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol)
-{
- attr->protocol = protocol;
- return 0;
-}
-
-int
-mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol)
-{
- *protocol = attr->protocol;
- return 0;
-}
-
-int
-mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling)
-{
- attr->priority = prioceiling;
- return 0;
-}
-
-int
-mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling)
-{
- *prioceiling = attr->priority;
- return 0;
-}
-
-int
-mono_mutexattr_destroy (mono_mutexattr_t *attr)
-{
- return 0;
-}
-
-
-int
-mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr)
-{
- int ret;
- int thr_ret;
-
- mutex->waiters = 0;
- mutex->depth = 0;
- mutex->owner = MONO_THREAD_NONE;
-
- if (!attr || attr->type == MONO_MUTEX_NORMAL) {
- mutex->type = MONO_MUTEX_NORMAL;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- } else {
- mutex->type = MONO_MUTEX_RECURSIVE;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- thr_ret = pthread_cond_init (&mutex->cond, NULL);
- g_assert (thr_ret == 0);
- }
-
- return(ret);
-}
-
-int
-mono_mutex_lock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_lock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_wait (&mutex->cond, &mutex->mutex) != 0)
- return EINVAL;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_trylock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_trylock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- if (!pthread_equal (mutex->owner, MONO_THREAD_NONE) &&
- !pthread_equal (mutex->owner, id)) {
- pthread_mutex_unlock (&mutex->mutex);
- return EBUSY;
- }
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else {
- mutex->depth++;
- break;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_timedlock (&mutex->mutex, timeout);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_timedlock (&mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_timedwait (&mutex->cond, &mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_unlock (mono_mutex_t *mutex)
-{
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_unlock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- if (pthread_equal (mutex->owner, pthread_self())) {
- /* Not owned by this thread */
- pthread_mutex_unlock (&mutex->mutex);
- return EPERM;
- }
-
- mutex->depth--;
- if (mutex->depth == 0) {
- mutex->owner = MONO_THREAD_NONE;
- if (mutex->waiters > 0) {
- thr_ret = pthread_cond_signal (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_destroy (mono_mutex_t *mutex)
-{
- int ret = 0;
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- ret = pthread_mutex_destroy (&mutex->mutex);
- break;
- case MONO_MUTEX_RECURSIVE:
- if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
- thr_ret = pthread_cond_destroy (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return ret;
-}
-
-
-int
-mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex)
-{
- return pthread_cond_wait (cond, &mutex->mutex);
-}
-
-int
-mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout)
-{
- return pthread_cond_timedwait (cond, &mutex->mutex, timeout);
-}
-
-#endif /* USE_MONO_MUTEX */
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifndef __MONO_MUTEX_H__
-#define __MONO_MUTEX_H__
-
-#include <glib.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#include <time.h>
-
-G_BEGIN_DECLS
-
-#ifndef HOST_WIN32
-
-typedef struct {
- pthread_mutex_t mutex;
- gboolean complete;
-} mono_once_t;
-
-#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
-
-int mono_once (mono_once_t *once, void (*once_init) (void));
-
-
-#ifdef USE_MONO_MUTEX
-
-#define MONO_THREAD_NONE ((pthread_t)~0)
-
-/* mutex types... */
-enum {
- MONO_MUTEX_NORMAL,
- MONO_MUTEX_RECURSIVE,
- MONO_MUTEX_ERRORCHECK = MONO_MUTEX_NORMAL,
- MONO_MUTEX_DEFAULT = MONO_MUTEX_NORMAL
-};
-
-/* mutex protocol attributes... */
-enum {
- MONO_THREAD_PRIO_NONE,
- MONO_THREAD_PRIO_INHERIT,
- MONO_THREAD_PRIO_PROTECT,
-};
-
-/* mutex process sharing attributes... */
-enum {
- MONO_THREAD_PROCESS_PRIVATE,
- MONO_THREAD_PROCESS_SHARED
-};
-
-typedef struct _mono_mutexattr_t {
- int type : 1;
- int shared : 1;
- int protocol : 2;
- int priority : 28;
-} mono_mutexattr_t;
-
-typedef struct _mono_mutex_t {
- int type;
- pthread_t owner;
- short waiters;
- short depth;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} mono_mutex_t;
-
-/* static initializers */
-#define MONO_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, 0 }
-#define MONO_RECURSIVE_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
-
-int mono_mutexattr_init (mono_mutexattr_t *attr);
-int mono_mutexattr_settype (mono_mutexattr_t *attr, int type);
-int mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type);
-int mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared);
-int mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared);
-int mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol);
-int mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol);
-int mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling);
-int mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling);
-int mono_mutexattr_destroy (mono_mutexattr_t *attr);
-
-
-int mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr);
-int mono_mutex_lock (mono_mutex_t *mutex);
-int mono_mutex_trylock (mono_mutex_t *mutex);
-int mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout);
-int mono_mutex_unlock (mono_mutex_t *mutex);
-int mono_mutex_destroy (mono_mutex_t *mutex);
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond, attr)
-int mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex);
-int mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout);
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#else /* system is equipped with a fully-functional pthread mutex library */
-
-#define MONO_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
-#define MONO_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
-
-#define MONO_THREAD_PRIO_NONE PTHREAD_PRIO_NONE
-#define MONO_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT
-#define MONO_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT
-
-#define MONO_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
-#define MONO_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
-
-typedef pthread_mutex_t mono_mutex_t;
-typedef pthread_mutexattr_t mono_mutexattr_t;
-typedef pthread_cond_t mono_cond_t;
-
-#define MONO_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#define MONO_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-#define MONO_COND_INITIALIZER PTHREAD_COND_INITIALIZER
-
-#define mono_mutexattr_init(attr) pthread_mutexattr_init (attr)
-#define mono_mutexattr_settype(attr,type) pthread_mutexattr_settype (attr, type)
-#define mono_mutexattr_gettype(attr,type) pthread_mutexattr_gettype (attr, type)
-#define mono_mutexattr_setpshared(attr,pshared) pthread_mutexattr_setpshared (attr, pshared)
-#define mono_mutexattr_getpshared(attr,pshared) pthread_mutexattr_getpshared (attr, pshared)
-#define mono_mutexattr_setprotocol(attr,protocol) pthread_mutexattr_setprotocol (attr, protocol)
-#define mono_mutexattr_getprotocol(attr,protocol) pthread_mutexattr_getprotocol (attr, protocol)
-#define mono_mutexattr_setprioceiling(attr,prioceiling) pthread_mutexattr_setprioceiling (attr, prioceiling)
-#define mono_mutexattr_getprioceiling(attr,prioceiling) pthread_mutexattr_getprioceiling (attr, prioceiling)
-#define mono_mutexattr_destroy(attr) pthread_mutexattr_destroy (attr)
-
-#define mono_mutex_init(mutex,attr) pthread_mutex_init (mutex, attr)
-#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
-#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
-#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
-#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
-#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
-#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
-#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#endif /* USE_MONO_MUTEX */
-
-/* This is a function so it can be passed to pthread_cleanup_push -
- * that is a macro and giving it a macro as a parameter breaks.
- */
-G_GNUC_UNUSED
-static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
-{
- return(mono_mutex_unlock (mutex));
-}
-
-#else
-
-typedef CRITICAL_SECTION mono_mutex_t;
-typedef HANDLE mono_cond_t;
-
-#define mono_mutex_init(mutex,attr) InitializeCriticalSection((mutex))
-#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
-#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
-#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
-#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
-
-
-#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
-#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
-#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
-#define mono_cond_signal(cond) SetEvent(*(cond))
-#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
-#define mono_cond_destroy(cond) CloseHandle(*(cond))
-
-#define MONO_COND_INITIALIZER NULL
-#endif
-
-G_END_DECLS
-
-#endif /* __MONO_MUTEX_H__ */
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/mutex-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/utils/strenc.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-membar.h>
+#include <mono/utils/mono-mutex.h>
/* The process' environment strings */
#if defined(__APPLE__) && !defined (__arm__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/semaphore-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
static void
noshm_semaphores_init (void)
{
- int i;
+ int i;
- for (i = 0; i < _WAPI_SHARED_SEM_COUNT; i++)
- mono_mutex_init (&noshm_sems [i], NULL);
+ for (i = 0; i < _WAPI_SHARED_SEM_COUNT; i++)
+ mono_mutex_init (&noshm_sems [i]);
}
static int
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/gc_wrapper.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
handle_enum:
switch (t->type) {
+ /* Can't share these as the argument needs to be loaded using sign/zero extension */
+ /*
case MONO_TYPE_U1:
return &mono_defaults.sbyte_class->byval_arg;
case MONO_TYPE_U2:
return &mono_defaults.int16_class->byval_arg;
case MONO_TYPE_U4:
return &mono_defaults.int32_class->byval_arg;
+ */
case MONO_TYPE_U8:
return &mono_defaults.int64_class->byval_arg;
case MONO_TYPE_BOOLEAN:
- return &mono_defaults.sbyte_class->byval_arg;
+ return &mono_defaults.byte_class->byval_arg;
case MONO_TYPE_CHAR:
- return &mono_defaults.int16_class->byval_arg;
+ return &mono_defaults.uint16_class->byval_arg;
case MONO_TYPE_U:
case MONO_TYPE_PTR:
return &mono_defaults.int_class->byval_arg;
*
* Returns: the 1-based index into the TypeDef table of the type
* where the type described by @index is nested.
- * Retruns 0 if @index describes a non-nested type.
+ * Returns 0 if @index describes a non-nested type.
*/
guint32
mono_metadata_nested_in_typedef (MonoImage *meta, guint32 index)
dyn_array_int_init (&merge_array);
current_time = 0;
+ /*
+ First we insert all bridges into the hash table and then we do dfs1.
+
+ It must be done in 2 steps since the bridge arrays doesn't come in reverse topological order,
+ which means that we can have entry N pointing to entry N + 1.
+
+ If we dfs1 entry N before N + 1 is registered we'll not consider N + 1 for this bridge
+ pass and not create the required xref between the two.
+ */
+ for (i = 0; i < registered_bridges.size; ++i)
+ register_bridge_object (DYN_ARRAY_PTR_REF (®istered_bridges, i));
+
for (i = 0; i < registered_bridges.size; ++i)
- dfs1 (register_bridge_object (DYN_ARRAY_PTR_REF (®istered_bridges, i)), NULL);
+ dfs1 (get_hash_entry (DYN_ARRAY_PTR_REF (®istered_bridges, i), NULL), NULL);
SGEN_TV_GETTIME (atv);
step_2 = SGEN_TV_ELAPSED (btv, atv);
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/atomic.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/sgen-conf.h>
#define LOCK_DECLARE(name) mono_mutex_t name
/* if changing LOCK_INIT to something that isn't idempotent, look at
its use in mono_gc_base_init in sgen-gc.c */
-#define LOCK_INIT(name) mono_mutex_init (&(name), NULL)
+#define LOCK_INIT(name) mono_mutex_init (&(name))
#define LOCK_GC do { \
mono_mutex_lock (&gc_mutex); \
MONO_GC_LOCKED (); \
queue->locked = locked;
if (locked) {
-#ifdef HOST_WIN32
- /*
- * mono_mutex_t is a critical section on Win32, which
- * is recursive by default. mono_mutexattr_t is not
- * defined there.
- */
- mono_mutex_init (&queue->lock, NULL);
-#else
- mono_mutexattr_t attr;
- mono_mutexattr_init (&attr);
- mono_mutexattr_settype (&attr, MONO_MUTEX_RECURSIVE);
- mono_mutex_init (&queue->lock, &attr);
-#endif
+ mono_mutex_init_recursive (&queue->lock);
}
#ifdef SGEN_CHECK_GRAY_OBJECT_ENQUEUE
for (i = 0; i < workers_num; ++i) {
/* private gray queue is inited by the thread itself */
- mono_mutex_init (&workers_data [i].stealable_stack_mutex, NULL);
+ mono_mutex_init (&workers_data [i].stealable_stack_mutex);
workers_data [i].stealable_stack_fill = 0;
if (sgen_get_major_collector ()->alloc_worker_data)
static GPtrArray *wsqs;
CRITICAL_SECTION wsqs_lock;
+static gboolean suspended;
/* Hooks */
static MonoThreadPoolFunc tp_start_func;
if (mono_runtime_is_shutting_down ())
break;
+ if (suspended)
+ continue;
+
for (i = 0; i < 2; i++) {
ThreadPool *tp;
tp = pools [i];
mono_thread_internal_reset_abort (mono_thread_internal_current ());
}
}
+
+/*
+ * Suspend creation of new threads.
+ */
+void
+mono_thread_pool_suspend (void)
+{
+ suspended = TRUE;
+}
+
+/*
+ * Resume creation of new threads.
+ */
+void
+mono_thread_pool_resume (void)
+{
+ suspended = FALSE;
+}
gboolean mono_thread_pool_remove_domain_jobs (MonoDomain *domain, int timeout) MONO_INTERNAL;
+void mono_thread_pool_suspend (void) MONO_INTERNAL;
+void mono_thread_pool_resume (void) MONO_INTERNAL;
+
void
ves_icall_System_Threading_ThreadPool_GetAvailableThreads (int *workerThreads,
int *completionPortThreads) MONO_INTERNAL;
/* if the thread is not in the hash it has been removed already */
if (!handle_remove (thread)) {
+ if (thread == mono_thread_internal_current ()) {
+ mono_domain_unset ();
+ mono_memory_barrier ();
+ }
/* This needs to be called even if handle_remove () fails */
if (mono_thread_cleanup_fn)
mono_thread_cleanup_fn (thread);
mono_thread_create_internal (domain, func, arg, FALSE, FALSE, 0);
}
-#if defined(HOST_WIN32) && defined(__GNUC__) && defined(TARGET_X86)
+#if defined(HOST_WIN32) && defined(__GNUC__)
static __inline__ __attribute__((always_inline))
/* This is not defined by gcc */
unsigned long long
return;
/* FIXME: simplify the mess below */
#elif defined(HOST_WIN32)
-#ifdef TARGET_X86
/* http://en.wikipedia.org/wiki/Win32_Thread_Information_Block */
void* tib = (void*)__readfsdword(0x18);
guint8 *stackTop = (guint8*)*(int*)((char*)tib + 4);
*staddr = stackBottom;
*stsize = stackTop - stackBottom;
-#else
- *staddr = NULL;
- *stsize = (size_t)-1;
-#endif
return;
#else
pthread_attr_t attr;
MonoThread *
mono_thread_attach (MonoDomain *domain)
{
+ MonoThreadInfo *info;
MonoInternalThread *thread;
MonoThread *current_thread;
HANDLE thread_handle;
THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
+ info = mono_thread_info_current ();
+ g_assert (info);
+ thread->thread_info = info;
+
current_thread = new_thread_with_internal (domain, thread);
if (!handle_store (current_thread)) {
g_return_if_fail (thread != NULL);
THREAD_DEBUG (g_message ("%s: mono_thread_detach for %p (%"G_GSIZE_FORMAT")", __func__, thread, (gsize)thread->internal_thread->tid));
-
- mono_profiler_thread_end (thread->internal_thread->tid);
thread_cleanup (thread->internal_thread);
LeaveCriticalSection (thread->synch_cs);
return TRUE;
}
+
+
+/*
+ * mono_thread_is_foreign:
+ * @thread: the thread to query
+ *
+ * This function allows one to determine if a thread was created by the mono runtime and has
+ * a well defined lifecycle or it's a foreigh one, created by the native environment.
+ *
+ * Returns: true if @thread was not created by the runtime.
+ */
+mono_bool
+mono_thread_is_foreign (MonoThread *thread)
+{
+ MonoThreadInfo *info = thread->internal_thread->thread_info;
+ return info->runtime_thread == FALSE;
+}
void mono_threads_request_thread_dump (void);
+mono_bool mono_thread_is_foreign (MonoThread *thread);
+
MONO_END_DECLS
#endif /* _MONO_METADATA_THREADS_H_ */
exceptions-sparc.c \
tramp-sparc.c
-s390_sources = \
- mini-s390.c \
- mini-s390.h \
- exceptions-s390.c \
- tramp-s390.c
-
s390x_sources = \
mini-s390x.c \
mini-s390x.h \
arch_define=__sparc__
endif
-if S390
-arch_sources = $(s390_sources)
-arch_built=cpu-s390.h
-arch_define=__s390__
-endif
-
if S390x
arch_sources = $(s390x_sources)
arch_built=cpu-s390x.h
cpu-sparc.h: cpu-sparc.md genmdesc$(EXEEXT)
$(GENMDESC_PRG) cpu-sparc.h sparc_desc $(srcdir)/cpu-sparc.md
-cpu-s390.h: cpu-s390.md genmdesc$(EXEEXT)
- $(GENMDESC_PRG) cpu-s390.h s390_cpu_desc $(srcdir)/cpu-s390.md
-
cpu-s390x.h: cpu-s390x.md genmdesc$(EXEEXT)
$(GENMDESC_PRG) cpu-s390x.h s390x_cpu_desc $(srcdir)/cpu-s390x.md
$(arm_sources) cpu-arm.md \
$(mips_sources) cpu-mips.md \
$(sparc_sources) cpu-sparc.md \
- $(s390_sources) cpu-s390.md \
$(s390x_sources) cpu-s390x.md \
$(ia64_sources) cpu-ia64.md \
$(windows_sources) \
+++ /dev/null
-# S/390 64-bit cpu description file
-# this file is read by genmdesc to pruduce a table with all the relevant information
-# about the cpu instructions that may be used by the regsiter allocator, the scheduler
-# and other parts of the arch-dependent part of mini.
-#
-# An opcode name is followed by a colon and optional specifiers.
-# A specifier has a name, a colon and a value. Specifiers are separated by white space.
-# Here is a description of the specifiers valid for this file and their possible values.
-#
-# dest:register describes the destination register of an instruction
-# src1:register describes the first source register of an instruction
-# src2:register describes the second source register of an instruction
-#
-# register may have the following values:
-# i integer register
-# a r3 register (output from calls)
-# b base register (used in address references)
-# f floating point register
-#
-# len:number describe the maximun length in bytes of the instruction
-# number is a positive integer
-#
-# cost:number describe how many cycles are needed to complete the instruction (unused)
-#
-# clob:spec describe if the instruction clobbers registers or has special needs
-#
-# spec can be one of the following characters:
-# c clobbers caller-save registers
-# r 'reserves' the destination register until a later instruction unreserves it
-# used mostly to set output registers in function calls
-#
-# flags:spec describe if the instruction uses or sets the flags (unused)
-#
-# spec can be one of the following chars:
-# s sets the flags
-# u uses the flags
-# m uses and modifies the flags
-#
-# res:spec describe what units are used in the processor (unused)
-#
-# delay: describe delay slots (unused)
-#
-# the required specifiers are: len, clob (if registers are clobbered), the registers
-# specifiers if the registers are actually used, flags (when scheduling is implemented).
-#
-# See the code in mini-x86.c for more details on how the specifiers are used.
-#
-
-nop: len:4
-relaxed_nop: len:4
-
-adc: dest:i src1:i src2:i len:6
-add_ovf_carry: dest:i src1:1 src2:i len:28
-add_ovf_un_carry: dest:i src1:1 src2:i len:28
-addcc: dest:i src1:i src2:i len:6
-aot_const: dest:i len:8
-atomic_add_i4: src1:b src2:i dest:i len:20
-atomic_exchange_i4: src1:b src2:i dest:i len:20
-atomic_add_new_i4: src1:b src2:i dest:i len:24
-br: len:6
-br_reg: src1:i len:8
-break: len:6
-call: dest:o len:6 clob:c
-call_handler: len:12 clob:c
-call_membase: dest:o src1:b len:12 clob:c
-call_reg: dest:o src1:i len:8 clob:c
-ceq: dest:i len:12
-cgt.un: dest:i len:12
-cgt: dest:i len:12
-checkthis: src1:b len:4
-ckfinite: dest:f src1:f len:22
-clt.un: dest:i len:12
-clt: dest:i len:12
-compare: src1:i src2:i len:4
-compare_imm: src1:i len:14
-cond_exc_c: len:8
-cond_exc_eq: len:8
-cond_exc_ge: len:8
-cond_exc_ge_un: len:8
-cond_exc_gt: len:8
-cond_exc_gt_un: len:8
-cond_exc_le: len:8
-cond_exc_le_un: len:8
-cond_exc_lt: len:8
-cond_exc_lt_un: len:8
-cond_exc_nc: len:8
-cond_exc_ne_un: len:8
-cond_exc_no: len:8
-cond_exc_ov: len:8
-endfinally: len: 20
-fcall: dest:g len:10 clob:c
-fcall_membase: dest:g src1:b len:14 clob:c
-fcall_reg: dest:g src1:i len:10 clob:c
-fcompare: src1:f src2:f len:14
-float_add: dest:f src1:f src2:f len:6
-float_beq: len:10
-float_bge: len:10
-float_bge_un: len:8
-float_bgt: len:10
-float_ble: len:10
-float_ble_un: len:8
-float_blt: len:10
-float_blt_un: len:8
-float_bne_un: len:8
-float_bgt_un: len:8
-float_ceq: dest:i src1:f src2:f len:16
-float_cgt: dest:i src1:f src2:f len:16
-float_cgt_un: dest:i src1:f src2:f len:16
-float_clt: dest:i src1:f src2:f len:16
-float_clt_un: dest:i src1:f src2:f len:16
-float_conv_to_i1: dest:i src1:f len:50
-float_conv_to_i2: dest:i src1:f len:50
-float_conv_to_i4: dest:i src1:f len:50
-float_conv_to_i8: dest:l src1:f len:50
-float_conv_to_i: dest:i src1:f len:52
-float_conv_to_r4: dest:f src1:f len:4
-float_conv_to_u1: dest:i src1:f len:62
-float_conv_to_u2: dest:i src1:f len:62
-float_conv_to_u4: dest:i src1:f len:62
-float_conv_to_u8: dest:l src1:f len:62
-float_conv_to_u: dest:i src1:f len:36
-float_div: dest:f src1:f src2:f len:6
-float_div_un: dest:f src1:f src2:f len:6
-float_mul: dest:f src1:f src2:f len:6
-float_neg: dest:f src1:f len:6
-float_not: dest:f src1:f len:6
-float_rem: dest:f src1:f src2:f len:16
-float_rem_un: dest:f src1:f src2:f len:16
-float_sub: dest:f src1:f src2:f len:6
-fmove: dest:f src1:f len:4
-iconst: dest:i len:16
-jmp: len:56
-label: len:0
-lcall: dest:L len:8 clob:c
-lcall_membase: dest:L src1:b len:12 clob:c
-lcall_reg: dest:L src1:i len:8 clob:c
-load_membase: dest:i src1:b len:18
-loadi1_membase: dest:i src1:b len:40
-loadi2_membase: dest:i src1:b len:24
-loadi4_membase: dest:i src1:b len:18
-loadi8_membase: dest:i src1:b
-loadr4_membase: dest:f src1:b len:20
-loadr8_membase: dest:f src1:b len:18
-loadu1_membase: dest:i src1:b len:26
-loadu2_membase: dest:i src1:b len:26
-loadu4_mem: dest:i len:8
-loadu4_membase: dest:i src1:b len:18
-localloc: dest:i src1:i len:72
-long_add: len: 18 dest:l src1:l src2:i clob:1
-long_add_ovf_un: len:22 dest:l src1:l src2:i clob:1
-long_add_ovf: len:28 dest:l src1:l src2:i clob:1
-long_conv_to_ovf_i: dest:i src1:i src2:i len:44
-long_conv_to_r_un: dest:f src1:i src2:i len:37
-long_conv_to_r4: dest:f src1:i len:4
-long_conv_to_r8: dest:f src1:i len:4
-long_mul_ovf: len: 18
-long_mul_ovf_un: len: 18
-long_sub: len: 18 dest:l src1:l src2:i clob:1
-long_sub_ovf_un: len:22 dest:l src1:l src2:i clob:1
-long_sub_ovf: len:36 dest:l src1:l src2:i clob:1
-memory_barrier: len: 10
-move: dest:i src1:i len:4
-bigmul: len:2 dest:l src1:a src2:i
-bigmul_un: len:2 dest:l src1:a src2:i
-endfilter: src1:i len:12
-rethrow: src1:i len:8
-oparglist: src1:i len:20
-r4const: dest:f len:22
-r8const: dest:f len:18
-s390_bkchain: len:16 dest:i src1:i
-s390_move: len:48 dest:b src1:b
-s390_setf4ret: dest:f src1:f len:4
-tls_get: dest:i len:44
-sbb: dest:i src1:i src2:i len:8
-setlret: src1:i src2:i len:12
-sqrt: dest:f src1:f len:4
-start_handler: len:18
-store_membase_imm: dest:b len:32
-store_membase_reg: dest:b src1:i len:18
-storei1_membase_imm: dest:b len:32
-storei1_membase_reg: dest:b src1:i len:18
-storei2_membase_imm: dest:b len:32
-storei2_membase_reg: dest:b src1:i len:18
-storei4_membase_imm: dest:b len:32
-storei4_membase_reg: dest:b src1:i len:18
-storei8_membase_imm: dest:b
-storei8_membase_reg: dest:b src1:i
-storer4_membase_reg: dest:b src1:f len:22
-storer8_membase_reg: dest:b src1:f len:22
-sub_ovf_carry: dest:i src1:1 src2:i len:28
-sub_ovf_un_carry: dest:i src1:1 src2:i len:28
-subcc: dest:i src1:i src2:i len:6
-throw: src1:i len:8
-vcall: len:8 clob:c
-vcall_membase: src1:b len:12 clob:c
-vcall_reg: src1:i len:8 clob:c
-voidcall: len:8 clob:c
-voidcall_membase: src1:b len:12 clob:c
-voidcall_reg: src1:i len:8 clob:c
-
-# 32 bit opcodes
-int_add: dest:i src1:i src2:i len:6
-int_sub: dest:i src1:i src2:i len:6
-int_mul: dest:i src1:i src2:i len:6
-int_div: dest:a src1:i src2:i len:10
-int_div_un: dest:a src1:i src2:i len:12
-int_and: dest:i src1:i src2:i len:6
-int_or: dest:i src1:i src2:i len:4
-int_xor: dest:i src1:i src2:i len:4
-int_rem: dest:d src1:i src2:i len:10
-int_rem_un: dest:d src1:i src2:i len:12
-int_shl: dest:i src1:i src2:i clob:s len:8
-int_shr: dest:i src1:i src2:i clob:s len:8
-int_shr_un: dest:i src1:i src2:i clob:s len:8
-int_add_ovf: len: 24 dest:i src1:i src2:i
-int_add_ovf_un: len: 10 dest:i src1:i src2:i
-int_sub_ovf: len:24 dest:i src1:i src2:i
-int_sub_ovf_un: len:10 dest:i src1:i src2:i
-int_mul_ovf: dest:i src1:i src2:i len:42
-int_mul_ovf_un: dest:i src1:i src2:i len:20
-
-int_neg: dest:i src1:i len:4
-int_not: dest:i src1:i len:8
-int_conv_to_i1: dest:i src1:i len:16
-int_conv_to_i2: dest:i src1:i len:16
-int_conv_to_i4: dest:i src1:i len:2
-int_conv_to_r4: dest:f src1:i len:4
-int_conv_to_r8: dest:f src1:i len:4
-int_conv_to_u1: dest:i src1:i len:8
-int_conv_to_u2: dest:i src1:i len:16
-int_conv_to_u4: dest:i src1:i
-
-int_conv_to_r_un: dest:f src1:i len:30
-
-int_beq: len:8
-int_bge_un: len:8
-int_bge: len:8
-int_bgt_un: len:8
-int_bgt: len:8
-int_ble_un: len:8
-int_ble: len:8
-int_blt_un: len:8
-int_blt: len:8
-int_bne_un: len:8
-
-mul_imm: dest:i src1:i len:20
-adc_imm: dest:i src1:i len:18
-add_imm: dest:i src1:i len:18
-addcc_imm: dest:i src1:i len:18
-and_imm: dest:i src1:i len:16
-div_imm: dest:i src1:i len:24
-div_un_imm: dest:i src1:i len:24
-or_imm: dest:i src1:i len:16
-rem_imm: dest:i src1:i len:24
-rem_un_imm: dest:i src1:i len:24
-sbb_imm: dest:i src1:i len:18
-shl_imm: dest:i src1:i len:8
-shr_imm: dest:i src1:i len:8
-shr_un_imm: dest:i src1:i len:8
-sub_imm: dest:i src1:i len:18
-subcc_imm: dest:i src1:i len:18
-xor_imm: dest:i src1:i len:16
-
-# Linear IR opcodes
-dummy_use: src1:i len:0
-dummy_store: len:0
-not_reached: len:0
-not_null: src1:i len:0
-
-jump_table: dest:i len:16
-
-icompare: src1:i src2:i len:4
-icompare_imm: src1:i len:14
-
-int_ceq: dest:i len:12
-int_cgt_un: dest:i len:12
-int_cgt: dest:i len:12
-int_clt_un: dest:i len:12
-int_clt: dest:i len:12
-
-cond_exc_ic: len:8
-cond_exc_ieq: len:8
-cond_exc_ige: len:8
-cond_exc_ige_un: len:8
-cond_exc_igt: len:8
-cond_exc_igt_un: len:8
-cond_exc_ile: len:8
-cond_exc_ile_un: len:8
-cond_exc_ilt: len:8
-cond_exc_ilt_un: len:8
-cond_exc_inc: len:8
-cond_exc_ine_un: len:8
-cond_exc_ino: len:8
-cond_exc_iov: len:8
-
-int_add_imm: dest:i src1:i len:18
-int_sub_imm: dest:i src1:i len:18
-int_mul_imm: dest:i src1:i len:20
-int_div_imm: dest:i src1:i len:24
-int_div_un_imm: dest:i src1:i len:24
-int_rem_imm: dest:i src1:i len:24
-int_rem_un_imm: dest:i src1:i len:24
-int_and_imm: dest:i src1:i len:16
-int_or_imm: dest:i src1:i len:16
-int_xor_imm: dest:i src1:i len:16
-int_adc_imm: dest:i src1:i len:18
-int_sbb_imm: dest:i src1:i len:18
-int_shl_imm: dest:i src1:i len:8
-int_shr_imm: dest:i src1:i len:8
-int_shr_un_imm: dest:i src1:i len:8
-
-int_adc: dest:i src1:i src2:i len:6
-int_sbb: dest:i src1:i src2:i len:8
-int_addcc: dest:i src1:i src2:i len:6
-int_subcc: dest:i src1:i src2:i len:6
-
-long_conv_to_ovf_i4_2: dest:i src1:i src2:i len:44
-
-vcall2: len:8 clob:c
-vcall2_membase: src1:b len:12 clob:c
-vcall2_reg: src1:i len:8 clob:c
-
-s390_long_add: dest:l src1:i src2:i len:18
-s390_long_add_ovf: dest:l src1:i src2:i len:32
-s390_long_add_ovf_un: dest:l src1:i src2:i len:32
-s390_long_sub: dest:l src1:i src2:i len:18
-s390_long_sub_ovf: dest:l src1:i src2:i len:32
-s390_long_sub_ovf_un: dest:l src1:i src2:i len:32
-s390_long_neg: dest:l src1:i src2:i len:18
-
-s390_int_add_ovf: len:24 dest:i src1:i src2:i
-s390_int_add_ovf_un: len:10 dest:i src1:i src2:i
-s390_int_sub_ovf: len:24 dest:i src1:i src2:i
-s390_int_sub_ovf_un: len:10 dest:i src1:i src2:i
ceq: dest:i len:12
cgt.un: dest:i len:12
cgt: dest:i len:12
-checkthis: src1:b len:10
+checkthis: src1:b len:16
ckfinite: dest:f src1:f len:22
clt.un: dest:i len:12
clt: dest:i len:12
#include <mono/metadata/socket-io.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/runtime.h>
+#include <mono/metadata/threadpool.h>
#include <mono/utils/mono-semaphore.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-stack-unwinding.h>
#ifndef DISABLE_DEBUGGER_AGENT
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
/* Definitions to make backporting to 2.6 easier */
//#define MonoInternalThread MonoThread
event_requests = g_ptr_array_new ();
- mono_mutex_init (&debugger_thread_exited_mutex, NULL);
+ mono_mutex_init (&debugger_thread_exited_mutex);
mono_cond_init (&debugger_thread_exited_cond, NULL);
mono_profiler_install ((MonoProfiler*)&debugger_profiler, runtime_shutdown);
static void
suspend_init (void)
{
- mono_mutex_init (&suspend_mutex, NULL);
+ mono_mutex_init (&suspend_mutex);
mono_cond_init (&suspend_cond, NULL);
MONO_SEM_INIT (&suspend_sem, 0);
}
mono_mutex_unlock (&suspend_mutex);
+ if (suspend_count == 1)
+ /*
+ * Suspend creation of new threadpool threads, since they cannot run
+ */
+ mono_thread_pool_suspend ();
+
mono_loader_unlock ();
}
mono_mutex_unlock (&suspend_mutex);
//g_assert (err == 0);
+ if (suspend_count == 0)
+ mono_thread_pool_resume ();
+
mono_loader_unlock ();
}
case CMD_VM_EXIT: {
MonoInternalThread *thread;
DebuggerTlsData *tls;
+#ifdef TRY_MANAGED_SYSTEM_ENVIRONMENT_EXIT
MonoClass *env_class;
+#endif
MonoMethod *exit_method = NULL;
gpointer *args;
int exit_code;
if (coree_module_handle)
FreeLibrary (coree_module_handle);
break;
- case DLL_THREAD_ATTACH:
- mono_thread_info_attach (&dummy);
- break;
case DLL_THREAD_DETACH:
mono_thread_info_dettach ();
break;
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - exceptions-s390.c */
-/* */
-/* Function - Exception support for S/390. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From exceptions-x86 & exceptions-ppc */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/* Copyright - 2001 Ximian, Inc. */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define S390_CALLFILTER_INTREGS S390_MINIMAL_STACK_SIZE
-#define S390_CALLFILTER_FLTREGS S390_CALLFILTER_INTREGS+(16*sizeof(gulong))
-#define S390_CALLFILTER_ACCREGS S390_CALLFILTER_FLTREGS+(16*sizeof(gdouble))
-#define S390_CALLFILTER_SIZE (S390_CALLFILTER_ACCREGS+(16*sizeof(gulong)))
-
-#define S390_THROWSTACK_ACCPRM S390_MINIMAL_STACK_SIZE
-#define S390_THROWSTACK_FPCPRM S390_THROWSTACK_ACCPRM+sizeof(gpointer)
-#define S390_THROWSTACK_RETHROW S390_THROWSTACK_FPCPRM+sizeof(gulong)
-#define S390_THROWSTACK_INTREGS S390_THROWSTACK_RETHROW+sizeof(gboolean)
-#define S390_THROWSTACK_FLTREGS S390_THROWSTACK_INTREGS+(16*sizeof(gulong))
-#define S390_THROWSTACK_ACCREGS S390_THROWSTACK_FLTREGS+(16*sizeof(gdouble))
-#define S390_THROWSTACK_SIZE (S390_THROWSTACK_ACCREGS+(16*sizeof(gulong)))
-
-#define SZ_THROW 384
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include <config.h>
-#include <glib.h>
-#include <signal.h>
-#include <string.h>
-#include <ucontext.h>
-
-#include <mono/arch/s390/s390-codegen.h>
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/metadata/threads.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/exception.h>
-#include <mono/metadata/mono-debug.h>
-
-#include "mini.h"
-#include "mini-s390.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-gboolean mono_arch_handle_exception (void *ctx,
- gpointer obj);
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_call_filter */
-/* */
-/* Function - Return a pointer to a method which calls an */
-/* exception filter. We also use this function to */
-/* call finally handlers (we pass NULL as @exc */
-/* object in this case). */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
- guint8 *code;
- int alloc_size, pos, i;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
-
- inited = 1;
- /* call_filter (MonoContext *ctx, unsigned long eip, gpointer exc) */
- code = start = mono_global_codeman_reserve (512);
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_lr (code, s390_r14, STK_BASE);
- alloc_size = S390_ALIGN(S390_CALLFILTER_SIZE, S390_STACK_ALIGNMENT);
- s390_ahi (code, STK_BASE, -alloc_size);
- s390_st (code, s390_r14, 0, STK_BASE, 0);
-
- /*------------------------------------------------------*/
- /* save general registers on stack */
- /*------------------------------------------------------*/
- s390_stm (code, s390_r0, s390_r13, STK_BASE, S390_CALLFILTER_INTREGS);
-
- /*------------------------------------------------------*/
- /* save floating point registers on stack */
- /*------------------------------------------------------*/
-// pos = S390_CALLFILTER_FLTREGS;
-// for (i = 0; i < 16; ++i) {
-// s390_std (code, i, 0, STK_BASE, pos);
-// pos += sizeof (gdouble);
-// }
-
- /*------------------------------------------------------*/
- /* save access registers on stack */
- /*------------------------------------------------------*/
-// s390_stam (code, s390_a0, s390_a15, STK_BASE, S390_CALLFILTER_ACCREGS);
-
- /*------------------------------------------------------*/
- /* Get A(Context) */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r13, s390_r2);
-
- /*------------------------------------------------------*/
- /* Get A(Handler Entry Point) */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r0, s390_r3);
-
- /*------------------------------------------------------*/
- /* Set parameter register with Exception */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r2, s390_r4);
-
- /*------------------------------------------------------*/
- /* Load all registers with values from the context */
- /*------------------------------------------------------*/
- s390_lm (code, s390_r3, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoContext, uc_mcontext.gregs[3]));
- pos = G_STRUCT_OFFSET(MonoContext, uc_mcontext.fpregs.fprs[0]);
- for (i = 0; i < 16; ++i) {
- s390_ld (code, i, 0, s390_r13, pos);
- pos += sizeof(gdouble);
- }
-
- /*------------------------------------------------------*/
- /* Point at the copied stack frame and call the filter */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r1, s390_r0);
- s390_basr (code, s390_r14, s390_r1);
-
- /*------------------------------------------------------*/
- /* Save return value */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r14, s390_r2);
-
- /*------------------------------------------------------*/
- /* Restore all the regs from the stack */
- /*------------------------------------------------------*/
- s390_lm (code, s390_r0, s390_r13, STK_BASE, S390_CALLFILTER_INTREGS);
-// pos = S390_CALLFILTER_FLTREGS;
-// for (i = 0; i < 16; ++i) {
-// s390_ld (code, i, 0, STK_BASE, pos);
-// pos += sizeof (gdouble);
-// }
-
- s390_lr (code, s390_r2, s390_r14);
-// s390_lam (code, s390_a0, s390_a15, STK_BASE, S390_CALLFILTER_ACCREGS);
- s390_ahi (code, s390_r15, alloc_size);
- s390_lm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (code, s390_r14);
-
- g_assert ((code - start) < SZ_THROW);
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - throw_exception. */
-/* */
-/* Function - Raise an exception based on the parameters passed.*/
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-throw_exception (MonoObject *exc, unsigned long ip, unsigned long sp,
- gulong *int_regs, gdouble *fp_regs, gulong *acc_regs,
- guint fpc, gboolean rethrow)
-{
- MonoContext ctx;
- int iReg;
-
- memset(&ctx, 0, sizeof(ctx));
-
- getcontext(&ctx);
-
- /* adjust eip so that it point into the call instruction */
- ip -= 6;
-
- for (iReg = 0; iReg < 16; iReg++) {
- ctx.uc_mcontext.gregs[iReg] = int_regs[iReg];
- ctx.uc_mcontext.fpregs.fprs[iReg].d = fp_regs[iReg];
- ctx.uc_mcontext.aregs[iReg] = acc_regs[iReg];
- }
-
- ctx.uc_mcontext.fpregs.fpc = fpc;
-
- MONO_CONTEXT_SET_BP (&ctx, sp);
- MONO_CONTEXT_SET_IP (&ctx, ip);
-
- if (mono_object_isinst (exc, mono_defaults.exception_class)) {
- MonoException *mono_ex = (MonoException*)exc;
- if (!rethrow)
- mono_ex->stack_trace = NULL;
- }
- mono_arch_handle_exception (&ctx, exc);
- setcontext(&ctx);
-
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - get_throw_exception_generic */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); or, */
-/* void (*func) (char *exc_name); */
-/* */
-/*------------------------------------------------------------------*/
-
-static gpointer
-get_throw_exception_generic (guint8 *start, int size,
- int by_name, gboolean rethrow)
-{
- guint8 *code;
- int alloc_size, pos, i, offset;
-
- code = start;
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- alloc_size = S390_ALIGN(S390_THROWSTACK_SIZE, S390_STACK_ALIGNMENT);
- s390_lr (code, s390_r14, STK_BASE);
- s390_ahi (code, STK_BASE, -alloc_size);
- s390_st (code, s390_r14, 0, STK_BASE, 0);
- if (by_name) {
- s390_lr (code, s390_r4, s390_r2);
- s390_bras (code, s390_r13, 6);
- s390_word (code, mono_defaults.corlib);
- s390_word (code, "System");
- s390_l (code, s390_r2, 0, s390_r13, 0);
- s390_l (code, s390_r3, 0, s390_r13, 4);
- offset = (guint32) S390_RELATIVE(mono_exception_from_name, code);
- s390_brasl(code, s390_r14, offset);
- }
- /*------------------------------------------------------*/
- /* save the general registers on the stack */
- /*------------------------------------------------------*/
- s390_stm (code, s390_r0, s390_r13, STK_BASE, S390_THROWSTACK_INTREGS);
-
- s390_lr (code, s390_r1, STK_BASE);
- s390_ahi (code, s390_r1, alloc_size);
- /*------------------------------------------------------*/
- /* save the return address in the parameter register */
- /*------------------------------------------------------*/
- s390_l (code, s390_r3, 0, s390_r1, S390_RET_ADDR_OFFSET);
-
- /*------------------------------------------------------*/
- /* save the floating point registers */
- /*------------------------------------------------------*/
- pos = S390_THROWSTACK_FLTREGS;
- for (i = 0; i < 16; ++i) {
- s390_std (code, i, 0,STK_BASE, pos);
- pos += sizeof (gdouble);
- }
- /*------------------------------------------------------*/
- /* save the access registers */
- /*------------------------------------------------------*/
- s390_stam (code, s390_r0, s390_r15, STK_BASE, S390_THROWSTACK_ACCREGS);
-
- /*------------------------------------------------------*/
- /* call throw_exception (exc, ip, sp, gr, fr, ar) */
- /* exc is already in place in r2 */
- /*------------------------------------------------------*/
- s390_lr (code, s390_r4, s390_r1); /* caller sp */
- /*------------------------------------------------------*/
- /* pointer to the saved int regs */
- /*------------------------------------------------------*/
- s390_la (code, s390_r5, 0, STK_BASE, S390_THROWSTACK_INTREGS);
- s390_la (code, s390_r6, 0, STK_BASE, S390_THROWSTACK_FLTREGS);
- s390_la (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCREGS);
- s390_st (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_ACCPRM);
- s390_stfpc(code, STK_BASE, S390_THROWSTACK_FPCPRM);
- s390_lhi (code, s390_r7, rethrow);
- s390_st (code, s390_r7, 0, STK_BASE, S390_THROWSTACK_RETHROW);
- offset = (guint32) S390_RELATIVE(throw_exception, code);
- s390_brasl(code, s390_r14, offset);
- /* we should never reach this breakpoint */
- s390_break (code);
- g_assert ((code - start) < size);
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_throw_exception */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, FALSE, FALSE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_rethrow_exception */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise exceptions. The returned function has the */
-/* following signature: */
-/* void (*func) (MonoException *exc); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_rethrow_exception (MonoTrampInfo **info, gboolean aot)
-{
- static guint8 *start;
- static int inited = 0;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, FALSE, TRUE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_throw_exception_by_name */
-/* */
-/* Function - Return a function pointer which can be used to */
-/* raise corlib exceptions. The return function has */
-/* the following signature: */
-/* void (*func) (char *exc_name); */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_throw_exception_by_name (void)
-{
- static guint8 *start;
- static int inited = 0;
-
- if (inited)
- return start;
- start = mono_global_codeman_reserve (SZ_THROW);
- get_throw_exception_generic (start, SZ_THROW, TRUE, FALSE);
- inited = 1;
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_find_jit_info */
-/* */
-/* Function - See exceptions-amd64.c for docs. */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
- MonoJitInfo *ji, MonoContext *ctx,
- MonoContext *new_ctx, MonoLMF **lmf,
- mgreg_t **save_locations,
- StackFrameInfo *frame)
-{
- gpointer ip = MONO_CONTEXT_GET_IP (ctx);
- MonoS390StackFrame *sframe;
-
- memset (frame, 0, sizeof (StackFrameInfo));
- frame->ji = ji;
-
- *new_ctx = *ctx;
-
- if (ji != NULL) {
- gint32 address;
-
- frame->type = FRAME_TYPE_MANAGED;
-
- if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->ebp)) {
- /* remove any unused lmf */
- *lmf = (*lmf)->previous_lmf;
- }
-
- address = (char *)ip - (char *)ji->code_start;
-
- sframe = (MonoS390StackFrame *) MONO_CONTEXT_GET_SP (ctx);
- MONO_CONTEXT_SET_BP (new_ctx, sframe->prev);
- sframe = (MonoS390StackFrame *) sframe->prev;
- MONO_CONTEXT_SET_IP (new_ctx, (guint8*)sframe->return_address - 2);
- memcpy (&new_ctx->uc_mcontext.gregs[6], sframe->regs, (8*sizeof(gint32)));
- return TRUE;
- } else if (*lmf) {
- if (!(*lmf)->method)
- return FALSE;
-
- ji = mini_jit_info_table_find (domain, (gpointer)(*lmf)->eip, NULL);
- if (!ji) {
- // FIXME: This can happen with multiple appdomains (bug #444383)
- return FALSE;
- }
-
- frame->ji = ji;
- frame->type = FRAME_TYPE_MANAGED_TO_NATIVE;
-
- memcpy(new_ctx->uc_mcontext.gregs, (*lmf)->gregs, sizeof((*lmf)->gregs));
- memcpy(new_ctx->uc_mcontext.fpregs.fprs, (*lmf)->fregs, sizeof((*lmf)->fregs));
-
- MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp);
- MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip - 2);
- *lmf = (*lmf)->previous_lmf;
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_handle_exception */
-/* */
-/* Function - Handle an exception raised by the JIT code. */
-/* */
-/* Parameters - ctx - Saved processor state */
-/* obj - The exception object */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_handle_exception (void *uc, gpointer obj)
-{
- return mono_handle_exception (uc, obj);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_ip_from_context */
-/* */
-/* Function - Return the instruction pointer from the context. */
-/* */
-/* Parameters - sigctx - Saved processor state */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_ip_from_context (void *sigctx)
-{
- return context_get_ip (sigctx);
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_restore_context */
-/* */
-/* Function - Return the address of the routine that will rest- */
-/* ore the context. */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
-{
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- return setcontext;
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_is_int_overflow */
-/* */
-/* Function - Inspect the code that raised the SIGFPE signal */
-/* to see if the DivideByZero or Arithmetic exception*/
-/* should be raised. */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_is_int_overflow (void *uc, void *info)
-{
- MonoContext *ctx;
- guint8 *code;
- guint32 *operand;
- gboolean arithExc = TRUE;
- gint regNo,
- offset;
-
- ctx = (MonoContext *) uc;
- code = (guint8 *) ((siginfo_t *)info)->si_addr;
- /*----------------------------------------------------------*/
- /* Divide operations are the only ones that will give the */
- /* divide by zero exception so just check for these ops. */
- /*----------------------------------------------------------*/
- switch (code[0]) {
- case 0x1d : /* Divide Register */
- regNo = code[1] & 0x0f;
- if (ctx->uc_mcontext.gregs[regNo] == 0)
- arithExc = FALSE;
- break;
- case 0x5d : /* Divide */
- regNo = (code[2] & 0xf0 >> 8);
- offset = *((guint16 *) code+2) & 0x0fff;
- operand = (guint32*)(ctx->uc_mcontext.gregs[regNo] + offset);
- if (*operand == 0)
- arithExc = FALSE;
- break;
- case 0xb9 : /* Divide logical Register? */
- if (code[1] == 0x97) {
- regNo = (code[2] & 0xf0 >> 8);
- if (ctx->uc_mcontext.gregs[regNo] == 0)
- arithExc = FALSE;
- }
- break;
- case 0xe3 : /* Divide logical? */
- if (code[1] == 0x97) {
- regNo = (code[2] & 0xf0 >> 8);
- offset = *((guint32 *) code+1) & 0x000fffff;
- operand = (guint32*)(ctx->uc_mcontext.gregs[regNo] + offset);
- if (*operand == 0)
- arithExc = FALSE;
- }
- break;
- default:
- arithExc = TRUE;
- }
- ctx->uc_mcontext.psw.addr = (guint32)code;
- return (arithExc);
-}
-
-/*========================= End of Function ========================*/
return 0;
}
+ public class TAbstractTableItem<TC> {
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void SetProperty<TV> () { }
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void Test () {
+ SetProperty<bool> ();
+ }
+ }
+
+ public static int test_0_gsharedvt_method_on_shared_class () {
+ TAbstractTableItem<object>.Test ();
+ return 0;
+ }
}
# if defined(__s390x__)
# include "mini-s390x.h"
# else
-# include "mini-s390.h"
+#error "s390 is no longer supported."
# endif
#elif defined(__ia64__)
#include "mini-ia64.h"
sa.ss_sp = tls->signal_stack;
sa.ss_size = MONO_ARCH_SIGNAL_STACK_SIZE;
-#if __APPLE__
sa.ss_flags = 0;
-#else
- sa.ss_flags = SS_ONSTACK;
-#endif
g_assert (sigaltstack (&sa, NULL) == 0);
mono_gc_register_altstack ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size, (char*)staddr + stsize - ((char*)tls->stack_ovf_guard_base + tls->stack_ovf_guard_size), tls->signal_stack, tls->signal_stack_size);
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mini-s390.c */
-/* */
-/* Function - S/390 backend for the Mono code generator. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From mini-x86 & mini-ppc by - */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define EMIT_COND_BRANCH(ins,cond) \
-{ \
-if (ins->inst_true_bb->native_offset) { \
- int displace; \
- displace = ((cfg->native_code + \
- ins->inst_true_bb->native_offset) - code) / 2; \
- if (s390_is_imm16(displace)) { \
- s390_brc (code, cond, displace); \
- } else { \
- s390_jcl (code, cond, displace); \
- } \
-} else { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_BB, ins->inst_true_bb); \
- s390_jcl (code, cond, 0); \
-} \
-}
-
-#define EMIT_UNCOND_BRANCH(ins) \
-{ \
-if (ins->inst_target_bb->native_offset) { \
- int displace; \
- displace = ((cfg->native_code + \
- ins->inst_target_bb->native_offset) - code) / 2; \
- if (s390_is_imm16(displace)) { \
- s390_brc (code, S390_CC_UN, displace); \
- } else { \
- s390_jcl (code, S390_CC_UN, displace); \
- } \
-} else { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_BB, ins->inst_target_bb); \
- s390_jcl (code, S390_CC_UN, 0); \
-} \
-}
-
-#define EMIT_COND_SYSTEM_EXCEPTION(cond,exc_name) \
- do { \
- mono_add_patch_info (cfg, code - cfg->native_code, \
- MONO_PATCH_INFO_EXC, exc_name); \
- s390_jcl (code, cond, 0); \
- } while (0);
-
-#define CHECK_SRCDST_COM \
- if (ins->dreg == ins->sreg2) { \
- src2 = ins->sreg1; \
- } else { \
- src2 = ins->sreg2; \
- if (ins->dreg != ins->sreg1) { \
- s390_lr (code, ins->dreg, ins->sreg1); \
- } \
- }
-
-#define CHECK_SRCDST_NCOM \
- if (ins->dreg == ins->sreg2) { \
- src2 = s390_r13; \
- s390_lr (code, s390_r13, ins->sreg2); \
- } else { \
- src2 = ins->sreg2; \
- } \
- if (ins->dreg != ins->sreg1) { \
- s390_lr (code, ins->dreg, ins->sreg1); \
- }
-
-#define CHECK_SRCDST_COM_F \
- if (ins->dreg == ins->sreg2) { \
- src2 = ins->sreg1; \
- } else { \
- src2 = ins->sreg2; \
- if (ins->dreg != ins->sreg1) { \
- s390_ldr (code, ins->dreg, ins->sreg1); \
- } \
- }
-
-#define CHECK_SRCDST_NCOM_F \
- if (ins->dreg == ins->sreg2) { \
- src2 = s390_f15; \
- s390_ldr (code, s390_r13, ins->sreg2); \
- } else { \
- src2 = ins->sreg2; \
- } \
- if (ins->dreg != ins->sreg1) { \
- s390_ldr (code, ins->dreg, ins->sreg1); \
- }
-
-#define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do { \
- MonoInst *inst; \
- int tmpr = 0; \
- int sReg, dReg; \
- MONO_INST_NEW (cfg, inst, OP_NOP); \
- if (size > 256) { \
- inst->dreg = dest; \
- inst->inst_offset = offset; \
- inst->sreg1 = src; \
- inst->inst_imm = imm; \
- } else { \
- if (s390_is_uimm12(offset)) { \
- inst->dreg = dest; \
- inst->inst_offset = offset; \
- } else { \
- dReg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
- dReg, dest, offset); \
- inst->dreg = dReg; \
- inst->inst_offset = 0; \
- } \
- if (s390_is_uimm12(imm)) { \
- inst->sreg1 = src; \
- inst->inst_imm = imm; \
- } else { \
- sReg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM, \
- sReg, src, imm); \
- inst->sreg1 = sReg; \
- inst->inst_imm = 0; \
- } \
- } \
- inst->opcode = OP_S390_MOVE; \
- inst->backend.size = size; \
- MONO_ADD_INS (cfg->cbb, inst); \
- } while (0)
-
-#define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do { \
- int reg = mono_alloc_preg (cfg); \
- switch (size) { \
- case 0: \
- MONO_EMIT_NEW_ICONST(cfg, reg, 0); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 1: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 2: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 4: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- break; \
- case 8: \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr, FALSE); \
- reg = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE, \
- reg, sr, so + sizeof (guint32)); \
- mono_call_inst_add_outarg_reg(cfg, call, reg, dr + 1, FALSE); \
- break; \
- } \
-} while (0)
-
-#define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do { \
- int tmpr; \
- switch (size) { \
- case 0: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_ICONST(cfg, tmpr, 0); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 1: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE, \
- tmpr, sr, so); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 2: \
- tmpr = mono_alloc_preg (cfg); \
- MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE, \
- tmpr, sr, so); \
- MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG, \
- dr, dx, tmpr); \
- break; \
- case 4: \
- case 8: \
- MONO_EMIT_NEW_MOVE (cfg, dr, dx, sr, so, size); \
- break; \
- } \
-} while (0)
-
-#undef DEBUG
-#define DEBUG(a) if (cfg->verbose_level > 1) a
-
-#define MAX_EXC 16
-
-#define S390_TRACE_STACK_SIZE (5*sizeof(gint32)+3*sizeof(gdouble))
-
-#define MAX (a, b) ((a) > (b) ? (a) : (b))
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include "mini.h"
-#include <string.h>
-
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/profiler-private.h>
-#include <mono/utils/mono-math.h>
-
-#include "mini-s390.h"
-#include "cpu-s390.h"
-#include "jit-icalls.h"
-#include "ir-emit.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-typedef struct {
- guint stack_size,
- local_size,
- code_size,
- parm_size,
- offset,
- offStruct,
- retStruct;
-} size_data;
-
-/*------------------------------------------------------------------*/
-/* Used by the instrument_emit_epilog */
-/*------------------------------------------------------------------*/
-
-enum {
- SAVE_NONE,
- SAVE_STRUCT,
- SAVE_ONE,
- SAVE_TWO,
- SAVE_R4,
- SAVE_R8
-};
-
-typedef struct InstList InstList;
-
-struct InstList {
- InstList *prev;
- InstList *next;
- MonoInst *data;
-};
-
-typedef enum {
- RegTypeGeneral,
- RegTypeBase,
- RegTypeFP,
- RegTypeFPR4,
- RegTypeStructByVal,
- RegTypeStructByValInFP,
- RegTypeStructByAddr
-} ArgStorage;
-
-typedef struct {
- gint32 offset; /* offset from caller's stack */
- gint32 offparm; /* offset from callee's stack */
- guint16 vtsize; /* in param area */
- guint8 reg;
- ArgStorage regtype; /* See RegType* */
- guint32 size; /* Size of structure used by RegTypeStructByVal */
-} ArgInfo;
-
-typedef struct {
- int nargs;
- int lastgr;
- guint32 stack_usage;
- guint32 struct_ret;
- ArgInfo ret;
- ArgInfo sigCookie;
- size_data sz;
- ArgInfo args [1];
-} CallInfo;
-
-typedef struct {
- gint32 gr[5]; /* R2-R6 */
- gdouble fp[3]; /* F0-F2 */
-} __attribute__ ((packed)) RegParm;
-
-/*========================= End of Typedefs ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-static void indent (int);
-static guint8 * backUpStackPtr(MonoCompile *, guint8 *, gint);
-static void decodeParm (MonoType *, void *, int);
-static void enter_method (MonoMethod *, RegParm *, char *);
-static void leave_method (MonoMethod *, ...);
-static gboolean is_regsize_var (MonoType *);
-static inline void add_general (guint *, size_data *, ArgInfo *, gboolean);
-static inline void add_stackParm (guint *, size_data *, ArgInfo *, gint);
-static inline void add_float (guint *, size_data *, ArgInfo *);
-static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *, gboolean);
-static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
-gpointer mono_arch_get_lmf_addr (void);
-static guint8 * emit_load_volatile_registers(guint8 *, MonoCompile *);
-static void emit_sig_cookie (MonoCompile *, MonoCallInst *, CallInfo *);
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-int mono_exc_esp_offset = 0;
-
-static int indent_level = 0;
-
-static int appdomain_tls_offset = -1,
- thread_tls_offset = -1;
-
-pthread_key_t lmf_addr_key;
-
-gboolean lmf_addr_key_inited = FALSE;
-
-#if 0
-
-extern __thread MonoDomain *tls_appdomain;
-extern __thread MonoThread *tls_current_object;
-extern __thread gpointer mono_lmf_addr;
-
-#endif
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_regname */
-/* */
-/* Function - Returns the name of the register specified by */
-/* the input parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-const char*
-mono_arch_regname (int reg) {
- static const char * rnames[] = {
- "s390_r0", "s390_sp", "s390_r2", "s390_r3", "s390_r4",
- "s390_r5", "s390_r6", "s390_r7", "s390_r8", "s390_r9",
- "s390_r10", "s390_r11", "s390_r12", "s390_r13", "s390_r14",
- "s390_r15"
- };
-
- if (reg >= 0 && reg < 16)
- return rnames [reg];
- else
- return "unknown";
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_fregname */
-/* */
-/* Function - Returns the name of the register specified by */
-/* the input parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-const char*
-mono_arch_fregname (int reg) {
- static const char * rnames[] = {
- "s390_f0", "s390_f1", "s390_f2", "s390_f3", "s390_f4",
- "s390_f5", "s390_f6", "s390_f7", "s390_f8", "s390_f9",
- "s390_f10", "s390_f11", "s390_f12", "s390_f13", "s390_f14",
- "s390_f15"
- };
-
- if (reg >= 0 && reg < 16)
- return rnames [reg];
- else
- return "unknown";
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - arch_get_argument_info */
-/* */
-/* Function - Gathers information on parameters such as size, */
-/* alignment, and padding. arg_info should be large */
-/* enough to hold param_count + 1 entries. */
-/* */
-/* Parameters - @csig - Method signature */
-/* @param_count - No. of parameters to consider */
-/* @arg_info - An array to store the result info */
-/* */
-/* Returns - Size of the activation frame */
-/* */
-/*------------------------------------------------------------------*/
-
-int
-mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *csig,
- int param_count,
- MonoJitArgumentInfo *arg_info)
-{
- int k, frame_size = 0;
- int size, align, pad;
- int offset = 8;
-
- if (MONO_TYPE_ISSTRUCT (csig->ret)) {
- frame_size += sizeof (gpointer);
- offset += 4;
- }
-
- arg_info [0].offset = offset;
-
- if (csig->hasthis) {
- frame_size += sizeof (gpointer);
- offset += 4;
- }
-
- arg_info [0].size = frame_size;
-
- for (k = 0; k < param_count; k++) {
-
- if (csig->pinvoke)
- size = mono_type_native_stack_size (csig->params [k], &align);
- else
- size = mini_type_stack_size (NULL, csig->params [k], &align);
-
- frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
- arg_info [k].pad = pad;
- frame_size += size;
- arg_info [k + 1].pad = 0;
- arg_info [k + 1].size = size;
- offset += pad;
- arg_info [k + 1].offset = offset;
- offset += size;
- }
-
- align = MONO_ARCH_FRAME_ALIGNMENT;
- frame_size += pad = (align - (frame_size & (align - 1))) & (align - 1);
- arg_info [k].pad = pad;
-
- return frame_size;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - retFitsInReg. */
-/* */
-/* Function - Determines if a value can be returned in one or */
-/* two registers. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline gboolean
-retFitsInReg(guint32 size)
-{
- switch (size) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- return (TRUE);
- break;
- default:
- return (FALSE);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - backStackPtr. */
-/* */
-/* Function - Restore Stack Pointer to previous frame. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline guint8 *
-backUpStackPtr(MonoCompile *cfg, guint8 *code, gint framePtr)
-{
- int stackSize = cfg->stack_usage;
-
- if (s390_is_uimm16 (cfg->stack_usage)) {
- s390_ahi (code, framePtr, cfg->stack_usage);
- } else {
- while (stackSize > 32767) {
- s390_ahi (code, framePtr, 32767);
- stackSize -= 32767;
- }
- s390_ahi (code, framePtr, stackSize);
- }
- return (code);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - indent */
-/* */
-/* Function - Perform nice indenting to current level */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-indent (int diff) {
- int v;
- if (diff < 0)
- indent_level += diff;
- v = indent_level;
- printf("[%3d] ",v);
- while (v-- > 0) {
- printf (". ");
- }
- if (diff > 0)
- indent_level += diff;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - decodeParm */
-/* */
-/* Function - Decode a parameter for the trace. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-decodeParm(MonoType *type, void *curParm, int size)
-{
- guint32 simpleType;
-
- if (type->byref) {
- printf("[BYREF:%p], ", *((char **) curParm));
- } else {
- simpleType = mono_type_get_underlying_type(type)->type;
-enum_parmtype:
- switch (simpleType) {
- case MONO_TYPE_I :
- printf ("[INTPTR:%p], ", *((int **) curParm));
- break;
- case MONO_TYPE_U :
- printf ("[UINTPTR:%p], ", *((int **) curParm));
- break;
- case MONO_TYPE_BOOLEAN :
- printf ("[BOOL:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_CHAR :
- printf ("[CHAR:%c], ", *((int *) curParm));
- break;
- case MONO_TYPE_I1 :
- printf ("[INT1:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_I2 :
- printf ("[INT2:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_I4 :
- printf ("[INT4:%d], ", *((int *) curParm));
- break;
- case MONO_TYPE_U1 :
- printf ("[UINT1:%u], ", *((unsigned int *) curParm));
- break;
- case MONO_TYPE_U2 :
- printf ("[UINT2:%u], ", *((guint16 *) curParm));
- break;
- case MONO_TYPE_U4 :
- printf ("[UINT4:%u], ", *((guint32 *) curParm));
- break;
- case MONO_TYPE_U8 :
- printf ("[UINT8:%llu], ", *((guint64 *) curParm));
- break;
- case MONO_TYPE_STRING : {
- MonoString *s = *((MonoString **) curParm);
- if (s) {
- g_assert (((MonoObject *) s)->vtable->klass == mono_defaults.string_class);
- printf("[STRING:%p:%s], ", s, mono_string_to_utf8(s));
- } else {
- printf("[STRING:null], ");
- }
- break;
- }
- case MONO_TYPE_CLASS :
- case MONO_TYPE_OBJECT : {
- MonoObject *obj = *((MonoObject **) curParm);
- MonoClass *class;
- if ((obj) && (obj->vtable)) {
- printf("[CLASS/OBJ:");
- class = obj->vtable->klass;
- printf("%p [%p] ",obj,curParm);
-// if (class == mono_defaults.string_class) {
-// printf("[STRING:%p:%s]",
-// *obj, mono_string_to_utf8 (obj));
-// } else if (class == mono_defaults.int32_class) {
-// printf("[INT32:%p:%d]",
-// obj, *(gint32 *)((char *)obj + sizeof (MonoObject)));
-// } else
-// printf("[%s.%s:%p]",
-// class->name_space, class->name, obj);
- printf("], ");
- } else {
- printf("[OBJECT:null], ");
- }
- break;
- }
- case MONO_TYPE_PTR :
- printf("[PTR:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_FNPTR :
- printf("[FNPTR:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_ARRAY :
- printf("[ARRAY:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_SZARRAY :
- printf("[SZARRAY:%p], ", *((gpointer **) (curParm)));
- break;
- case MONO_TYPE_I8 :
- printf("[INT8:%lld], ", *((gint64 *) (curParm)));
- break;
- case MONO_TYPE_R4 :
- printf("[FLOAT4:%g], ", *((double *) (curParm)));
- break;
- case MONO_TYPE_R8 :
- printf("[FLOAT8:%g], ", *((double *) (curParm)));
- break;
- case MONO_TYPE_VALUETYPE : {
- int i;
- MonoMarshalType *info;
-
- if (type->data.klass->enumtype) {
- simpleType = mono_class_enum_basetype (type->data.klass)->type;
- printf("{VALUETYPE} - ");
- goto enum_parmtype;
- }
-
- info = mono_marshal_load_type_info (type->data.klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- printf("[FLOAT4:%f], ", *((float *) (curParm)));
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- printf("[FLOAT8:%g], ", *((double *) (curParm)));
- break;
- }
-
- printf("[VALUETYPE:");
- for (i = 0; i < size; i++)
- printf("%02x,", *((guint8 *)curParm+i));
- printf("]");
- break;
- }
- case MONO_TYPE_TYPEDBYREF: {
- int i;
- printf("[TYPEDBYREF:");
- for (i = 0; i < size; i++)
- printf("%02x,", *((guint8 *)curParm+i));
- printf("]");
- break;
- }
- default :
- printf("[?? - %d], ",simpleType);
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-//static int lc = 0;
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - enter_method */
-/* */
-/* Function - Perform tracing of the entry to the current */
-/* method. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-enter_method (MonoMethod *method, RegParm *rParm, char *sp)
-{
- int i, oParm = 0, iParm = 0;
- MonoObject *obj;
- MonoMethodSignature *sig;
- char *fname;
- guint32 ip;
- CallInfo *cinfo;
- ArgInfo *ainfo;
- void *curParm;
-
- fname = mono_method_full_name (method, TRUE);
- indent (1);
- printf ("ENTER: %s(", fname);
- g_free (fname);
-
- ip = (*(guint32 *) (sp+S390_RET_ADDR_OFFSET)) & 0x7fffffff;
- printf (") ip: %p sp: %p - ", (gpointer) ip, sp);
-
- if (rParm == NULL)
- return;
-
- sig = mono_method_signature (method);
-
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- printf ("[STRUCTRET:%p], ", (gpointer) rParm->gr[0]);
- iParm = 1;
- }
-
- if (sig->hasthis) {
- gpointer *this = (gpointer *) rParm->gr[iParm];
- obj = (MonoObject *) this;
- if (method->klass->valuetype) {
- if (obj) {
- printf("this:[value:%p:%08x], ",
- this, *((guint32 *)(this+sizeof(MonoObject))));
- } else
- printf ("this:[NULL], ");
- } else {
- if (obj) {
-// class = obj->vtable->klass;
-// if (class == mono_defaults.string_class) {
-// printf ("this:[STRING:%p:%s], ",
-// obj, mono_string_to_utf8 ((MonoString *)obj));
-// } else {
-// printf ("this:%p[%s.%s], ",
-// obj, class->name_space, class->name);
-// }
-printf("this:%p, ",obj);
- } else
- printf ("this:NULL, ");
- }
- oParm++;
- }
-
- for (i = 0; i < sig->param_count; ++i) {
- ainfo = &cinfo->args[i + oParm];
- switch (ainfo->regtype) {
- case RegTypeGeneral :
- decodeParm(sig->params[i], &(rParm->gr[ainfo->reg-2]), ainfo->size);
- break;
- case RegTypeFP :
- decodeParm(sig->params[i], &(rParm->fp[ainfo->reg]), ainfo->size);
- break;
- case RegTypeBase :
- decodeParm(sig->params[i], sp+ainfo->offset, ainfo->size);
- break;
- case RegTypeStructByVal :
- if (ainfo->reg != STK_BASE)
- curParm = &(rParm->gr[ainfo->reg-2]);
- else
- curParm = sp+ainfo->offset;
-
- if (retFitsInReg (ainfo->vtsize))
- decodeParm(sig->params[i],
- curParm,
- ainfo->size);
- else
- decodeParm(sig->params[i],
- *((char **) curParm),
- ainfo->vtsize);
- break;
- case RegTypeStructByAddr :
- if (ainfo->reg != STK_BASE)
- curParm = &(rParm->gr[ainfo->reg-2]);
- else
- curParm = sp+ainfo->offset;
-
- decodeParm(sig->params[i],
- *((char **) curParm),
- ainfo->vtsize);
- break;
-
- default :
- printf("???, ");
- }
- }
- printf("\n");
- g_free(cinfo);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - leave_method */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-static void
-leave_method (MonoMethod *method, ...)
-{
- MonoType *type;
- char *fname;
- guint32 ip;
- va_list ap;
-
- va_start(ap, method);
-
- fname = mono_method_full_name (method, TRUE);
- indent (-1);
- printf ("LEAVE: %s", fname);
- g_free (fname);
-
- type = mono_method_signature (method)->ret;
-
-handle_enum:
- switch (type->type) {
- case MONO_TYPE_VOID:
- break;
- case MONO_TYPE_BOOLEAN: {
- int val = va_arg (ap, int);
- if (val)
- printf ("[TRUE:%d]", val);
- else
- printf ("[FALSE]");
-
- break;
- }
- case MONO_TYPE_CHAR: {
- int val = va_arg (ap, int);
- printf ("[CHAR:%d]", val);
- break;
- }
- case MONO_TYPE_I1: {
- int val = va_arg (ap, int);
- printf ("[INT1:%d]", val);
- break;
- }
- case MONO_TYPE_U1: {
- int val = va_arg (ap, int);
- printf ("[UINT1:%d]", val);
- break;
- }
- case MONO_TYPE_I2: {
- int val = va_arg (ap, int);
- printf ("[INT2:%d]", val);
- break;
- }
- case MONO_TYPE_U2: {
- int val = va_arg (ap, int);
- printf ("[UINT2:%d]", val);
- break;
- }
- case MONO_TYPE_I4: {
- int val = va_arg (ap, int);
- printf ("[INT4:%d]", val);
- break;
- }
- case MONO_TYPE_U4: {
- int val = va_arg (ap, int);
- printf ("[UINT4:%d]", val);
- break;
- }
- case MONO_TYPE_I: {
- int val = va_arg (ap, int);
- printf ("[INT:%d]", val);
- printf("]");
- break;
- }
- case MONO_TYPE_U: {
- int val = va_arg (ap, int);
- printf ("[UINT:%d]", val);
- printf("]");
- break;
- }
- case MONO_TYPE_STRING: {
- MonoString *s = va_arg (ap, MonoString *);
-;
- if (s) {
- g_assert (((MonoObject *)s)->vtable->klass == mono_defaults.string_class);
- printf ("[STRING:%p:%s]", s, mono_string_to_utf8 (s));
- } else
- printf ("[STRING:null], ");
- break;
- }
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT: {
- MonoObject *o = va_arg (ap, MonoObject *);
-
-// if ((o) && (o->vtable)) {
-// if (o->vtable->klass == mono_defaults.boolean_class) {
-// printf ("[BOOLEAN:%p:%d]", o, *((guint8 *)o + sizeof (MonoObject)));
-// } else if (o->vtable->klass == mono_defaults.int32_class) {
-// printf ("[INT32:%p:%d]", o, *((gint32 *)((char *)o + sizeof (MonoObject))));
-// } else if (o->vtable->klass == mono_defaults.int64_class) {
-// printf ("[INT64:%p:%lld]", o, *((gint64 *)((char *)o + sizeof (MonoObject))));
-// } else
-// printf ("[%s.%s:%p]", o->vtable->klass->name_space, o->vtable->klass->name, o);
-// } else
- printf ("[OBJECT:%p]", o);
-
- break;
- }
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY: {
- gpointer p = va_arg (ap, gpointer);
- printf ("[result=%p]", p);
- break;
- }
- case MONO_TYPE_I8: {
- gint64 l = va_arg (ap, gint64);
- printf ("[LONG:%lld]", l);
- break;
- }
- case MONO_TYPE_U8: {
- guint64 l = va_arg (ap, guint64);
- printf ("[ULONG:%llu]", l);
- break;
- }
- case MONO_TYPE_R4: {
- double f;
- f = va_arg (ap, double);
- printf ("[FLOAT4:%g]\n", f);
- break;
- }
- case MONO_TYPE_R8: {
- double f = va_arg (ap, double);
- printf ("[FLOAT8:%g]\n", f);
- break;
- }
- case MONO_TYPE_VALUETYPE: {
- MonoMarshalType *info;
- if (type->data.klass->enumtype) {
- type = mono_class_enum_basetype (type->data.klass);
- goto handle_enum;
- } else {
- guint8 *p = va_arg (ap, gpointer);
- int j, size, align;
-
- info = mono_marshal_load_type_info (type->data.klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- double f = va_arg (ap, double);
- printf("[FLOAT4:%g]\n", (double) f);
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- double f = va_arg (ap, double);
- printf("[FLOAT8:%g]\n", f);
- break;
- }
-
- size = mono_type_size (type, &align);
- switch (size) {
- case 1:
- case 2:
- case 4:
- case 8:
- printf ("[");
- for (j = 0; p && j < size; j++)
- printf ("%02x,", p [j]);
- printf ("]\n");
- break;
- default:
- printf ("[VALUERET]\n");
- }
- }
- break;
- }
- case MONO_TYPE_TYPEDBYREF: {
- guint8 *p = va_arg (ap, gpointer);
- int j, size, align;
- size = mono_type_size (type, &align);
- switch (size) {
- case 1:
- case 2:
- case 4:
- case 8:
- printf ("[");
- for (j = 0; p && j < size; j++)
- printf ("%02x,", p [j]);
- printf ("]\n");
- break;
- default:
- printf ("[TYPEDBYREF]\n");
- }
- }
- break;
- default:
- printf ("(unknown return type %x)",
- mono_method_signature (method)->ret->type);
- }
-
- ip = ((gint32) __builtin_return_address (0)) & 0x7fffffff;
- printf (" ip: %p\n", (gpointer) ip);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_init */
-/* */
-/* Function - Perform CPU specific initialization to execute */
-/* managed code. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_cpu_init (void)
-{
- guint mode = 1;
-
- /*--------------------------------------*/
- /* Set default rounding mode for FP */
- /*--------------------------------------*/
- __asm__ ("SRNM\t%0\n\t"
- : : "m" (mode));
-}
-
-/*========================= End of Function ========================*/
-
-
-/*
- * Initialize architecture specific code.
- */
-void
-mono_arch_init (void)
-{
-}
-
-/*
- * Cleanup architecture specific code.
- */
-void
-mono_arch_cleanup (void)
-{
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_optimizations */
-/* */
-/* Function - Returns the optimizations supported on this CPU */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_cpu_optimizations (guint32 *exclude_mask)
-{
- guint32 opts = 0;
-
- /*----------------------------------------------------------*/
- /* no s390-specific optimizations yet */
- /*----------------------------------------------------------*/
- *exclude_mask = MONO_OPT_INLINE|MONO_OPT_LINEARS;
-// *exclude_mask = MONO_OPT_INLINE;
- return opts;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_cpu_enumerate_simd_versions */
-/* */
-/* Function - Returns the SIMD instruction sets on this CPU */
-/* */
-/*------------------------------------------------------------------*/
-guint32
-mono_arch_cpu_enumerate_simd_versions (void)
-{
- /* SIMD is currently unimplemented */
- return 0;
-}
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-static gboolean
-is_regsize_var (MonoType *t) {
- if (t->byref)
- return TRUE;
- switch (mono_type_get_underlying_type (t)->type) {
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- return TRUE;
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- return FALSE;
- case MONO_TYPE_VALUETYPE:
- if (t->data.klass->enumtype)
- return is_regsize_var (mono_class_enum_basetype (t->data.klass));
- return FALSE;
- }
- return FALSE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_allocatable_int_vars */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-GList *
-mono_arch_get_allocatable_int_vars (MonoCompile *cfg)
-{
- GList *vars = NULL;
- int i;
-
- for (i = 0; i < cfg->num_varinfo; i++) {
- MonoInst *ins = cfg->varinfo [i];
- MonoMethodVar *vmv = MONO_VARINFO (cfg, i);
-
- /* unused vars */
- if (vmv->range.first_use.abs_pos >= vmv->range.last_use.abs_pos)
- continue;
-
- if (ins->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT) ||
- (ins->opcode != OP_LOCAL && ins->opcode != OP_ARG))
- continue;
-
- /* we can only allocate 32 bit values */
- if (is_regsize_var (ins->inst_vtype)) {
- g_assert (MONO_VARINFO (cfg, i)->reg == -1);
- g_assert (i == vmv->idx);
- vars = mono_varlist_insert_sorted (cfg, vars, vmv, FALSE);
- }
- }
-
- return vars;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_global_int_regs */
-/* */
-/* Function - Return a list of usable integer registers. */
-/* */
-/*------------------------------------------------------------------*/
-
-GList *
-mono_arch_get_global_int_regs (MonoCompile *cfg)
-{
- GList *regs = NULL;
- MonoMethodHeader *header;
- int i, top = 13;
-
- header = cfg->header;
- if ((cfg->flags & MONO_CFG_HAS_ALLOCA) || header->num_clauses)
- cfg->frame_reg = s390_r11;
-
- /* FIXME: s390_r12 is reserved for bkchain_reg. Only reserve it if needed */
- top = 12;
- for (i = 8; i < top; ++i) {
- if (cfg->frame_reg != i)
- regs = g_list_prepend (regs, GUINT_TO_POINTER (i));
- }
-
- return regs;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_flush_icache */
-/* */
-/* Function - Flush the CPU icache. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_flush_icache (guint8 *code, gint size)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_is_inst_imm */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_is_inst_imm (gint64 imm)
-{
- /* The lowering pass will take care of it */
- return TRUE;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_general */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_general (guint *gr, size_data *sz, ArgInfo *ainfo, gboolean simple)
-{
- int disp;
-
- if (simple) {
- if (*gr > S390_LAST_ARG_REG) {
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->stack_size += sizeof(int);
- sz->local_size += sizeof(int);
- sz->offStruct += sizeof(int);
- sz->code_size += 12;
- } else {
- ainfo->reg = *gr;
- sz->code_size += 8;
- }
- } else {
- if (*gr > S390_LAST_ARG_REG - 1) {
- disp = sz->stack_size;
- sz->stack_size = S390_ALIGN(sz->stack_size, S390_STACK_ALIGNMENT);
- disp = sz->stack_size - disp;
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->stack_size += sizeof(long long);
- sz->local_size += (sizeof(long long) + disp);
- sz->offStruct += (sizeof(long long) + disp);
- sz->code_size += 10;
- } else {
- ainfo->reg = *gr;
- sz->code_size += 8;
- }
- (*gr) ++;
- }
- (*gr) ++;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_stackParm */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_stackParm (guint *gr, size_data *sz, ArgInfo *ainfo, gint size)
-{
- if (*gr > S390_LAST_ARG_REG) {
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
- ainfo->reg = STK_BASE;
- ainfo->offset = sz->stack_size;
- sz->stack_size += sizeof (gpointer);
- sz->parm_size += sizeof(gpointer);
- sz->offStruct += sizeof(gpointer);
- } else {
- ainfo->reg = *gr;
- ainfo->offset = sz->stack_size;
- }
- (*gr) ++;
- ainfo->offparm = sz->offset;
- sz->offset = S390_ALIGN(sz->offset+size, sizeof(long));
- ainfo->size = size;
- ainfo->regtype = RegTypeStructByAddr;
- ainfo->vtsize = size;
- sz->parm_size += size;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - add_float */
-/* */
-/* Function - Determine code and stack size incremements for a */
-/* float parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-add_float (guint *fr, size_data *sz, ArgInfo *ainfo)
-{
- if ((*fr) <= S390_LAST_FPARG_REG) {
- ainfo->regtype = RegTypeFP;
- ainfo->reg = *fr;
- sz->code_size += 4;
- (*fr) += 2;
- }
- else {
- ainfo->offset = sz->stack_size;
- ainfo->reg = STK_BASE;
- ainfo->regtype = RegTypeBase;
- sz->code_size += 4;
- sz->stack_size += ainfo->size;
- sz->local_size += ainfo->size;
- sz->offStruct += ainfo->size;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - get_call_info */
-/* */
-/* Function - Determine the amount of space required for code */
-/* and stack. In addition determine starting points */
-/* for stack-based parameters, and area for struct- */
-/* ures being returned on the stack. */
-/* */
-/*------------------------------------------------------------------*/
-
-static CallInfo *
-get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
-{
- guint i, fr, gr, size;
- int nParm = sig->hasthis + sig->param_count;
- MonoType *ret_type;
- guint32 simpletype, align;
- CallInfo *cinfo;
- size_data *sz;
- MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
-
- if (mp)
- cinfo = mono_mempool_alloc0 (mp, sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
- else
- cinfo = g_malloc0 (sizeof (CallInfo) + sizeof (ArgInfo) * nParm);
-
- fr = 0;
- gr = s390_r2;
- nParm = 0;
- cinfo->struct_ret = 0;
- sz = &cinfo->sz;
- sz->offset = 0;
- sz->offStruct = S390_MINIMAL_STACK_SIZE;
- sz->retStruct = 0;
- sz->stack_size = S390_MINIMAL_STACK_SIZE;
- sz->code_size = 0;
- sz->parm_size = 0;
- sz->local_size = 0;
-
- /*----------------------------------------------------------*/
- /* We determine the size of the return code/stack in case we*/
- /* need to reserve a register to be used to address a stack */
- /* area that the callee will use. */
- /*----------------------------------------------------------*/
-
- ret_type = mono_type_get_underlying_type (sig->ret);
- ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
- simpletype = ret_type->type;
-enum_retvalue:
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_STRING:
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- case MONO_TYPE_R4:
- case MONO_TYPE_R8:
- cinfo->ret.reg = s390_f0;
- sz->code_size += 4;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (ret_type)) {
- cinfo->ret.reg = s390_r2;
- sz->code_size += 4;
- break;
- }
- /* Fall through */
- case MONO_TYPE_VALUETYPE: {
- MonoClass *klass = mono_class_from_mono_type (sig->ret);
- if (klass->enumtype) {
- simpletype = mono_class_enum_basetype (klass)->type;
- goto enum_retvalue;
- }
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- cinfo->ret.reg = s390_r2;
- cinfo->struct_ret = 1;
- cinfo->ret.size = size;
- cinfo->ret.vtsize = size;
- gr++;
- break;
- }
- case MONO_TYPE_TYPEDBYREF:
- size = sizeof (MonoTypedRef);
- cinfo->ret.reg = s390_r2;
- cinfo->struct_ret = 1;
- cinfo->ret.size = size;
- cinfo->ret.vtsize = size;
- gr++;
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- g_error ("mini-s390: cannot handle as return value 0x%x (0x%x)", sig->ret->type,simpletype);
- }
-
- if (sig->hasthis) {
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = sizeof(gpointer);
- nParm++;
- }
-
- /*----------------------------------------------------------*/
- /* We determine the size of the parameter code and stack */
- /* requirements by checking the types and sizes of the */
- /* parameters. */
- /*----------------------------------------------------------*/
-
- for (i = 0; i < sig->param_count; ++i) {
- MonoType *ptype;
-
- /*--------------------------------------------------*/
- /* Handle vararg type calls. All args are put on */
- /* the stack. */
- /*--------------------------------------------------*/
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- gr = S390_LAST_ARG_REG + 1;
- add_general (&gr, sz, &cinfo->sigCookie, TRUE);
- }
-
- if (sig->params [i]->byref) {
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = sizeof(gpointer);
- nParm++;
- continue;
- }
-
- ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (gsctx, ptype);
- simpletype = ptype->type;
- switch (simpletype) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- cinfo->args[nParm].size = sizeof(char);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- case MONO_TYPE_CHAR:
- cinfo->args[nParm].size = sizeof(short);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- cinfo->args[nParm].size = sizeof(int);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_PTR:
- case MONO_TYPE_FNPTR:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_ARRAY:
- cinfo->args[nParm].size = sizeof(gpointer);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- cinfo->args[nParm].size = sizeof(long long);
- add_general (&gr, sz, cinfo->args+nParm, FALSE);
- nParm++;
- break;
- case MONO_TYPE_R4:
- cinfo->args[nParm].size = sizeof(float);
- add_float (&fr, sz, cinfo->args+nParm);
- nParm++;
- break;
- case MONO_TYPE_R8:
- cinfo->args[nParm].size = sizeof(double);
- add_float (&fr, sz, cinfo->args+nParm);
- nParm++;
- break;
- case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (ptype)) {
- cinfo->args[nParm].size = sizeof(gpointer);
- add_general (&gr, sz, cinfo->args+nParm, TRUE);
- nParm++;
- break;
- }
- /* Fall through */
- case MONO_TYPE_VALUETYPE: {
- MonoMarshalType *info;
- MonoClass *klass = mono_class_from_mono_type (sig->params [i]);
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- info = mono_marshal_load_type_info (klass);
-
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- cinfo->args[nParm].size = sizeof(float);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
-
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- cinfo->args[nParm].size = sizeof(double);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
-
- cinfo->args[nParm].vtsize = 0;
- cinfo->args[nParm].size = 0;
-
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = size;
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long);
- break;
- case 8:
- add_general(&gr, sz, cinfo->args+nParm, FALSE);
- cinfo->args[nParm].size = sizeof(long long);
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long long);
- break;
- default:
- add_stackParm(&gr, sz, cinfo->args+nParm, size);
- nParm++;
- }
- }
- break;
- case MONO_TYPE_TYPEDBYREF: {
- int size = sizeof (MonoTypedRef);
-
- cinfo->args[nParm].vtsize = 0;
- cinfo->args[nParm].size = 0;
-
- switch (size) {
- /*----------------------------------*/
- /* On S/390, structures of size 1, */
- /* 2, 4, and 8 bytes are passed in */
- /* (a) register(s). */
- /*----------------------------------*/
- case 0:
- case 1:
- case 2:
- case 4:
- add_general(&gr, sz, cinfo->args+nParm, TRUE);
- cinfo->args[nParm].size = size;
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long);
- break;
- case 8:
- add_general(&gr, sz, cinfo->args+nParm, FALSE);
- cinfo->args[nParm].size = sizeof(long long);
- cinfo->args[nParm].regtype = RegTypeStructByVal;
- nParm++;
- sz->local_size += sizeof(long long);
- break;
- default:
- add_stackParm(&gr, sz, cinfo->args+nParm, size);
- nParm++;
- }
- }
- break;
- default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
- }
- }
-
- /*----------------------------------------------------------*/
- /* If we are passing a structure back then if it won't be */
- /* in a register(s) then we make room at the end of the */
- /* parameters that may have been placed on the stack */
- /*----------------------------------------------------------*/
- if (cinfo->struct_ret) {
- cinfo->ret.offset = sz->stack_size;
- switch (cinfo->ret.size) {
- case 0:
- case 1:
- case 2:
- case 4:
- case 8:
- break;
- default:
- sz->stack_size += S390_ALIGN(cinfo->ret.size, align);
- }
- }
-
- /*----------------------------------------------------------*/
- /* Handle the case where there are no implicit arguments */
- /*----------------------------------------------------------*/
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (sig->param_count == sig->sentinelpos)) {
- gr = S390_LAST_ARG_REG + 1;
- add_general (&gr, sz, &cinfo->sigCookie, TRUE);
- }
-
- cinfo->lastgr = gr;
- sz->stack_size = sz->stack_size + sz->local_size + sz->parm_size +
- sz->offset;
- sz->stack_size = S390_ALIGN(sz->stack_size, sizeof(long));
-
- return (cinfo);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_allocate_vars */
-/* */
-/* Function - Set var information according to the calling */
-/* convention for S/390. The local var stuff should */
-/* most likely be split in another method. */
-/* */
-/* Parameter - @m - Compile unit. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_allocate_vars (MonoCompile *cfg)
-{
- MonoMethodSignature *sig;
- MonoMethodHeader *header;
- MonoInst *inst;
- CallInfo *cinfo;
- int iParm, iVar, offset, size, align, curinst;
- int frame_reg = STK_BASE;
- int sArg, eArg;
-
- header = cfg->header;
-
- cfg->flags |= MONO_CFG_HAS_SPILLUP;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- /*---------------------------------------------------------*/
- /* We use the frame register also for any method that has */
- /* filter clauses. This way, when the handlers are called, */
- /* the code will reference local variables using the frame */
- /* reg instead of the stack pointer: if we had to restore */
- /* the stack pointer, we'd corrupt the method frames that */
- /* are already on the stack (since filters get called */
- /* before stack unwinding happens) when the filter code */
- /* would call any method. */
- /*---------------------------------------------------------*/
- if ((cfg->flags & MONO_CFG_HAS_ALLOCA) || header->num_clauses)
- frame_reg = s390_r11;
-
- cfg->frame_reg = frame_reg;
-
- cfg->arch.bkchain_reg = -1;
-
- if (frame_reg != STK_BASE)
- cfg->used_int_regs |= 1 << frame_reg;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (!cinfo->struct_ret) {
- switch (mono_type_get_underlying_type (sig->ret)->type) {
- case MONO_TYPE_VOID:
- break;
- default:
- cfg->ret->opcode = OP_REGVAR;
- cfg->ret->dreg = s390_r2;
- break;
- }
- }
-
- /*--------------------------------------------------------------*/
- /* local vars are at a positive offset from the stack pointer */
- /* also note that if the function uses alloca, we use s390_r11 */
- /* to point at the local variables. */
- /* add parameter area size for called functions */
- /*--------------------------------------------------------------*/
- offset = (cfg->param_area + S390_MINIMAL_STACK_SIZE);
- cfg->sig_cookie = 0;
-
- if (cinfo->struct_ret) {
- inst = cfg->vret_addr;
- offset = S390_ALIGN(offset, sizeof(gpointer));
- inst->inst_offset = offset;
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset += sizeof(gpointer);
- if (G_UNLIKELY (cfg->verbose_level > 1)) {
- printf ("vret_addr =");
- mono_print_ins (cfg->vret_addr);
- }
- }
-
- if (sig->hasthis) {
- inst = cfg->args [0];
- if (inst->opcode != OP_REGVAR) {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset = S390_ALIGN(offset, sizeof(gpointer));
- inst->inst_offset = offset;
- offset += sizeof (gpointer);
- }
- curinst = sArg = 1;
- } else {
- curinst = sArg = 0;
- }
-
- eArg = sig->param_count + sArg;
-
- if (sig->call_convention == MONO_CALL_VARARG)
- cfg->sig_cookie += S390_MINIMAL_STACK_SIZE;
-
- for (iParm = sArg; iParm < eArg; ++iParm) {
- inst = cfg->args [curinst];
- if (inst->opcode != OP_REGVAR) {
- switch (cinfo->args[iParm].regtype) {
- case RegTypeStructByAddr : {
- MonoInst *indir;
-
- size = sizeof (gpointer);
-
- if (cinfo->args [iParm].reg == STK_BASE) {
- cfg->arch.bkchain_reg = s390_r12;
- cfg->used_int_regs |= 1 << cfg->arch.bkchain_reg;
-
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = cfg->arch.bkchain_reg;
- inst->inst_offset = cinfo->args [iParm].offset;
- } else {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- inst->inst_offset = S390_ALIGN(offset, sizeof (gpointer));
- }
-
- /* Add a level of indirection */
- MONO_INST_NEW (cfg, indir, 0);
- *indir = *inst;
- inst->opcode = OP_VTARG_ADDR;
- inst->inst_left = indir;
- }
- break;
- case RegTypeStructByVal :
- size = cinfo->args[iParm].size;
- offset = S390_ALIGN(offset, size);
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- inst->inst_offset = S390_ALIGN (offset, size);
- break;
- default :
- if (cinfo->args [iParm].reg == STK_BASE) {
- /*
- * These arguments are in the previous frame, so we can't
- * compute their offset from the current frame pointer right
- * now, since cfg->stack_offset is not yet known, so dedicate a
- * register holding the previous frame pointer.
- */
- cfg->arch.bkchain_reg = s390_r12;
- cfg->used_int_regs |= 1 << cfg->arch.bkchain_reg;
-
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = cfg->arch.bkchain_reg;
- size = (cinfo->args[iParm].size < 4
- ? 4 - cinfo->args[iParm].size
- : 0);
- inst->inst_offset = cinfo->args [iParm].offset + size;
- size = sizeof (long);
- } else {
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- size = (cinfo->args[iParm].size < 8
- ? sizeof(long)
- : sizeof(long long));
- offset = S390_ALIGN(offset, size);
- inst->inst_offset = offset;
- }
- }
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (cinfo->args[iParm].regtype != RegTypeGeneral) &&
- (iParm < sig->sentinelpos))
- cfg->sig_cookie += size;
-
- offset += size;
- }
- curinst++;
- }
-
- curinst = cfg->locals_start;
- for (iVar = curinst; iVar < cfg->num_varinfo; ++iVar) {
- inst = cfg->varinfo [iVar];
- if ((inst->flags & MONO_INST_IS_DEAD) ||
- (inst->opcode == OP_REGVAR))
- continue;
-
- /*--------------------------------------------------*/
- /* inst->backend.is_pinvoke indicates native sized value types, */
- /* this is used by the pinvoke wrappers when they */
- /* call functions returning structure */
- /*--------------------------------------------------*/
- if (inst->backend.is_pinvoke && MONO_TYPE_ISSTRUCT (inst->inst_vtype))
- size = mono_class_native_size (mono_class_from_mono_type(inst->inst_vtype), &align);
- else
- size = mono_type_size (inst->inst_vtype, &align);
-
- offset = S390_ALIGN(offset, align);
- inst->inst_offset = offset;
- inst->opcode = OP_REGOFFSET;
- inst->inst_basereg = frame_reg;
- offset += size;
- DEBUG (g_print("allocating local %d to %ld\n", iVar, inst->inst_offset));
- }
-
- /*------------------------------------------------------*/
- /* Allow space for the trace method stack area if needed*/
- /*------------------------------------------------------*/
- if (mono_jit_trace_calls != NULL && mono_trace_eval (cfg->method)) {
- offset += S390_TRACE_STACK_SIZE;
- }
-
- /*------------------------------------------------------*/
- /* Reserve space to save LMF and caller saved registers */
- /*------------------------------------------------------*/
- if (cfg->method->save_lmf)
- offset += sizeof (MonoLMF);
-
- /*------------------------------------------------------*/
- /* align the offset */
- /*------------------------------------------------------*/
- cfg->stack_offset = S390_ALIGN(offset, S390_STACK_ALIGNMENT);
-
- /* Fix up offsets for arguments whose value is in the parent frame */
- for (iParm = sArg; iParm < eArg; ++iParm) {
- inst = cfg->args [iParm];
-
- if (inst->opcode == OP_S390_STKARG) {
- inst->opcode = OP_REGOFFSET;
- inst->inst_offset += cfg->stack_offset;
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_vars */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_create_vars (MonoCompile *cfg)
-{
- MonoMethodSignature *sig;
- CallInfo *cinfo;
-
- sig = mono_method_signature (cfg->method);
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
- if (G_UNLIKELY (cfg->verbose_level > 1)) {
- printf ("vret_addr = ");
- mono_print_ins (cfg->vret_addr);
- }
- }
-}
-
-/*========================= End of Function ========================*/
-
-static void
-add_outarg_reg2 (MonoCompile *cfg, MonoCallInst *call, ArgStorage storage, int reg, MonoInst *tree)
-{
- MonoInst *ins;
-
- switch (storage) {
- case RegTypeGeneral:
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, FALSE);
- break;
- case RegTypeFP:
- MONO_INST_NEW (cfg, ins, OP_FMOVE);
- ins->dreg = mono_alloc_freg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE);
- break;
- case RegTypeFPR4:
- MONO_INST_NEW (cfg, ins, OP_S390_SETF4RET);
- ins->dreg = mono_alloc_freg (cfg);
- ins->sreg1 = tree->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, reg, TRUE);
- break;
- default:
- g_assert_not_reached ();
- }
-}
-
-static void
-emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo)
-{
- MonoMethodSignature *tmpSig;
- MonoInst *sig_arg;
-
- cfg->disable_aot = TRUE;
-
- /*----------------------------------------------------------*/
- /* mono_ArgIterator_Setup assumes the signature cookie is */
- /* passed first and all the arguments which were before it */
- /* passed on the stack after the signature. So compensate */
- /* by passing a different signature. */
- /*----------------------------------------------------------*/
- tmpSig = mono_metadata_signature_dup (call->signature);
- tmpSig->param_count -= call->signature->sentinelpos;
- tmpSig->sentinelpos = 0;
- if (tmpSig->param_count > 0)
- memcpy (tmpSig->params,
- call->signature->params + call->signature->sentinelpos,
- tmpSig->param_count * sizeof(MonoType *));
-
- MONO_INST_NEW (cfg, sig_arg, OP_ICONST);
- sig_arg->dreg = mono_alloc_ireg (cfg);
- sig_arg->inst_p0 = tmpSig;
- MONO_ADD_INS (cfg->cbb, sig_arg);
-
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, STK_BASE,
- cinfo->sigCookie.offset, sig_arg->dreg);
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_call */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
-{
- MonoInst *in;
- MonoMethodSignature *sig;
- MonoInst *ins;
- int i, n, lParamArea;
- CallInfo *cinfo;
- ArgInfo *ainfo = NULL;
- int stackSize;
-
- sig = call->signature;
- n = sig->param_count + sig->hasthis;
- DEBUG (g_print ("Call requires: %d parameters\n",n));
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- stackSize = cinfo->sz.stack_size + cinfo->sz.local_size + cinfo->sz.parm_size + cinfo->sz.offset;
- call->stack_usage = MAX(stackSize, call->stack_usage);
- lParamArea = MAX((call->stack_usage-S390_MINIMAL_STACK_SIZE-cinfo->sz.parm_size), 0);
- cfg->param_area = MAX(((signed) cfg->param_area), lParamArea);
- cfg->flags |= MONO_CFG_HAS_CALLS;
-
- if (cinfo->struct_ret) {
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->sreg1 = call->vret_var->dreg;
- ins->dreg = mono_alloc_preg (cfg);
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, cinfo->ret.reg, FALSE);
- }
-
- for (i = 0; i < n; ++i) {
- ainfo = cinfo->args + i;
- MonoType *t;
-
- if (i >= sig->hasthis)
- t = sig->params [i - sig->hasthis];
- else
- t = &mono_defaults.int_class->byval_arg;
- t = mono_type_get_underlying_type (t);
-
- in = call->args [i];
-
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- emit_sig_cookie (cfg, call, cinfo);
- }
-
- switch (ainfo->regtype) {
- case RegTypeGeneral:
- if (!t->byref && (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8)) {
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = in->dreg + 2;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, FALSE);
- MONO_INST_NEW (cfg, ins, OP_MOVE);
- ins->dreg = mono_alloc_ireg (cfg);
- ins->sreg1 = in->dreg + 1;
- MONO_ADD_INS (cfg->cbb, ins);
- mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg + 1, FALSE);
- } else {
- add_outarg_reg2 (cfg, call, ainfo->regtype, ainfo->reg, in);
- }
- break;
- case RegTypeFP:
- if (MONO_TYPE_ISSTRUCT (t)) {
- /* Valuetype passed in one fp register */
- ainfo->regtype = RegTypeStructByValInFP;
- /* Fall through */
- } else {
- if (ainfo->size == 4)
- ainfo->regtype = RegTypeFPR4;
- add_outarg_reg2 (cfg, call, ainfo->regtype, ainfo->reg, in);
- break;
- }
- case RegTypeStructByVal:
- case RegTypeStructByAddr: {
- guint32 align;
- guint32 size;
-
- if (sig->params [i - sig->hasthis]->type == MONO_TYPE_TYPEDBYREF) {
- size = sizeof (MonoTypedRef);
- align = sizeof (gpointer);
- }
- else
- if (sig->pinvoke)
- size = mono_type_native_stack_size (&in->klass->byval_arg, &align);
- else {
- /*
- * Other backends use mono_type_stack_size (), but that
- * aligns the size to 8, which is larger than the size of
- * the source, leading to reads of invalid memory if the
- * source is at the end of address space.
- */
- size = mono_class_value_size (in->klass, &align);
- }
-
- g_assert (in->klass);
-
- ainfo->offparm += cinfo->sz.offStruct;
-
- MONO_INST_NEW (cfg, ins, OP_OUTARG_VT);
- ins->sreg1 = in->dreg;
- ins->klass = in->klass;
- ins->backend.size = ainfo->size;
- ins->inst_p0 = call;
- ins->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
- memcpy (ins->inst_p1, ainfo, sizeof (ArgInfo));
-
- MONO_ADD_INS (cfg->cbb, ins);
-
- if (ainfo->regtype == RegTypeStructByAddr) {
- /*
- * We use OP_OUTARG_VT to copy the valuetype to a stack location, then
- * use the normal OUTARG opcodes to pass the address of the location to
- * the callee.
- */
- int treg = mono_alloc_preg (cfg);
- MONO_EMIT_NEW_BIALU_IMM (cfg, OP_ADD_IMM, treg,
- STK_BASE, ainfo->offparm);
- if (ainfo->reg == STK_BASE) {
- /* The address is passed on the stack */
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset;
- ins->sreg1 = treg;
- MONO_ADD_INS (cfg->cbb, ins);
- } else {
- mono_call_inst_add_outarg_reg (cfg, call, treg, ainfo->reg, FALSE);
- }
- }
- break;
- }
- case RegTypeBase:
- if (!t->byref && t->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER4_MEMBASE_REG,
- STK_BASE, ainfo->offset,
- in->dreg);
- } else if (!t->byref && (t->type == MONO_TYPE_R8)) {
- MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORER8_MEMBASE_REG,
- STK_BASE, ainfo->offset,
- in->dreg);
- } else if (!t->byref && (t->type == MONO_TYPE_I8 || t->type == MONO_TYPE_U8)) {
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset + MINI_LS_WORD_OFFSET;
- ins->sreg1 = in->dreg + 1;
- MONO_ADD_INS (cfg->cbb, ins);
-
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset + MINI_MS_WORD_OFFSET;
- ins->sreg1 = in->dreg + 2;
- MONO_ADD_INS (cfg->cbb, ins);
- } else {
- MONO_INST_NEW (cfg, ins, OP_STORE_MEMBASE_REG);
- ins->inst_destbasereg = STK_BASE;
- ins->inst_offset = ainfo->offset;
- ins->sreg1 = in->dreg;
- MONO_ADD_INS (cfg->cbb, ins);
- }
- break;
- default:
- g_assert_not_reached ();
- break;
- }
- }
-
- /*
- * Handle the case where there are no implicit arguments
- */
- if ((sig->call_convention == MONO_CALL_VARARG) &&
- (i == sig->sentinelpos)) {
- emit_sig_cookie (cfg, call, cinfo);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_outarg_vt */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
-{
- MonoCallInst *call = (MonoCallInst*)ins->inst_p0;
- ArgInfo *ainfo = (ArgInfo*)ins->inst_p1;
- int size = ins->backend.size;
-
- if (ainfo->regtype == RegTypeStructByVal) {
- /*
- arg->ins.sreg1 = ainfo->reg;
- arg->ins.opcode = OP_OUTARG_VT;
- arg->size = ainfo->size;
- arg->offset = ainfo->offset;
- arg->offPrm = ainfo->offparm + cinfo->sz.offStruct;
- */
- if (ainfo->reg != STK_BASE) {
- MONO_OUTPUT_VTR (cfg, size, ainfo->reg, src->dreg, 0);
- } else {
- MONO_OUTPUT_VTS (cfg, size, ainfo->reg, ainfo->offset,
- src->dreg, 0);
- }
- } else if (ainfo->regtype == RegTypeStructByValInFP) {
- int dreg = mono_alloc_freg (cfg);
-
- if (ainfo->size == 4) {
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR4_MEMBASE, dreg, src->dreg, 0);
- MONO_EMIT_NEW_UNALU (cfg, OP_S390_SETF4RET, dreg, dreg);
- } else {
- g_assert (ainfo->size == 8);
-
- MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADR8_MEMBASE, dreg, src->dreg, 0);
- }
-
- mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, TRUE);
- } else {
- MONO_EMIT_NEW_MOVE (cfg, STK_BASE, ainfo->offparm,
- src->dreg, 0, size);
- }
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_setret */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
-{
- MonoType *ret = mono_type_get_underlying_type (mono_method_signature (method)->ret);
-
- if (!ret->byref) {
- if (ret->type == MONO_TYPE_R4) {
- MONO_EMIT_NEW_UNALU (cfg, OP_S390_SETF4RET, s390_f0, val->dreg);
- return;
- } else if (ret->type == MONO_TYPE_R8) {
- MONO_EMIT_NEW_UNALU (cfg, OP_FMOVE, s390_f0, val->dreg);
- return;
- } else if (ret->type == MONO_TYPE_I8 || ret->type == MONO_TYPE_U8) {
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r3, val->dreg + 1);
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r2, val->dreg + 2);
- return;
- }
- }
-
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, cfg->ret->dreg, val->dreg);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_mem_needs */
-/* */
-/* Function - Allow tracing to work with this interface (with */
-/* an optional argument). */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_instrument_mem_needs (MonoMethod *method, int *stack, int *code)
-{
- /* no stack room needed now (may be needed for FASTCALL-trace support) */
- *stack = 0;
- /* split prolog-epilog requirements? */
- *code = 50; /* max bytes needed: check this number */
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_prolog */
-/* */
-/* Function - Create an "instrumented" prolog. */
-/* */
-/*------------------------------------------------------------------*/
-
-void*
-mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
- gboolean enable_arguments)
-{
- guchar *code = p;
- int parmOffset,
- fpOffset,
- baseReg;
-
- parmOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
- if (cfg->method->save_lmf)
- parmOffset -= sizeof(MonoLMF);
- fpOffset = parmOffset + (5*sizeof(gint32));
- if (fpOffset > 4096) {
- s390_lr (code, s390_r12, STK_BASE);
- baseReg = s390_r12;
- while (fpOffset > 4096) {
- s390_ahi (code, baseReg, 4096);
- fpOffset -= 4096;
- parmOffset -= 4096;
- }
- } else {
- baseReg = STK_BASE;
- }
-
- s390_stm (code, s390_r2, s390_r6, baseReg, parmOffset);
- s390_std (code, s390_f0, 0, baseReg, fpOffset);
- s390_std (code, s390_f1, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_std (code, s390_f2, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->method);
- s390_word (code, func);
- s390_l (code, s390_r2, 0, s390_r13, 4);
- s390_la (code, s390_r3, 0, baseReg, parmOffset);
- s390_lr (code, s390_r4, STK_BASE);
- s390_ahi (code, s390_r4, cfg->stack_usage);
- s390_l (code, s390_r1, 0, s390_r13, 8);
- s390_basr (code, s390_r14, s390_r1);
- s390_ld (code, s390_f2, 0, baseReg, fpOffset+2*sizeof(gdouble));
- s390_ld (code, s390_f1, 0, baseReg, fpOffset+sizeof(gdouble));
- s390_ld (code, s390_f0, 0, baseReg, fpOffset);
- s390_lm (code, s390_r2, s390_r6, baseReg, parmOffset);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_instrument_epilog */
-/* */
-/* Function - Create an epilog that will handle the returned */
-/* values used in instrumentation. */
-/* */
-/*------------------------------------------------------------------*/
-
-void*
-mono_arch_instrument_epilog_full (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments, gboolean preserve_argument_registers)
-{
- guchar *code = p;
- int save_mode = SAVE_NONE,
- saveOffset;
- MonoMethod *method = cfg->method;
- int rtype = mono_type_get_underlying_type (mono_method_signature (method)->ret)->type;
-
- saveOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
- if (method->save_lmf)
- saveOffset -= sizeof(MonoLMF);
-
-handle_enum:
- switch (rtype) {
- case MONO_TYPE_VOID:
- /* special case string .ctor icall */
- if (strcmp (".ctor", method->name) && method->klass == mono_defaults.string_class)
- save_mode = SAVE_ONE;
- else
- save_mode = SAVE_NONE;
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- save_mode = SAVE_TWO;
- break;
- case MONO_TYPE_R4:
- save_mode = SAVE_R4;
- break;
- case MONO_TYPE_R8:
- save_mode = SAVE_R8;
- break;
- case MONO_TYPE_VALUETYPE:
- if (mono_method_signature (method)->ret->data.klass->enumtype) {
- rtype = mono_class_enum_basetype (mono_method_signature (method)->ret->data.klass)->type;
- goto handle_enum;
- }
- save_mode = SAVE_STRUCT;
- break;
- default:
- save_mode = SAVE_ONE;
- break;
- }
-
- switch (save_mode) {
- case SAVE_TWO:
- s390_stm (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_lr (code, s390_r4, s390_r3);
- s390_lr (code, s390_r3, s390_r2);
- }
- break;
- case SAVE_ONE:
- s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_lr (code, s390_r3, s390_r2);
- }
- break;
- case SAVE_R4:
- s390_std (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case SAVE_R8:
- s390_std (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_STRUCT:
- s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- if (enable_arguments) {
- s390_l (code, s390_r3, 0, cfg->frame_reg,
- S390_MINIMAL_STACK_SIZE+cfg->param_area);
- }
- break;
- case SAVE_NONE:
- default:
- break;
- }
-
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->method);
- s390_word (code, func);
- s390_l (code, s390_r2, 0, s390_r13, 4);
- s390_l (code, s390_r1, 0, s390_r13, 8);
- s390_basr (code, s390_r14, s390_r1);
-
- switch (save_mode) {
- case SAVE_TWO:
- s390_lm (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
- break;
- case SAVE_ONE:
- s390_l (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_R4:
- case SAVE_R8:
- s390_ld (code, s390_f0, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_STRUCT:
- s390_l (code, s390_r2, 0, cfg->frame_reg, saveOffset);
- break;
- case SAVE_NONE:
- default:
- break;
- }
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_peephole_pass_1 (MonoCompile *cfg, MonoBasicBlock *bb)
-{
-}
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_peephole_pass */
-/* */
-/* Function - Form a peephole pass at the code looking for */
-/* simple optimizations. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_peephole_pass_2 (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins, *n;
-
- MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
- mono_peephole_ins (bb, ins);
- }
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins, *next;
-
- MONO_BB_FOR_EACH_INS_SAFE (bb, next, ins) {
- switch (ins->opcode) {
- case OP_DIV_IMM:
- case OP_REM_IMM:
- case OP_IDIV_IMM:
- case OP_IREM_IMM:
- case OP_IDIV_UN_IMM:
- case OP_IREM_UN_IMM:
- case OP_LOCALLOC_IMM:
- mono_decompose_op_imm (cfg, bb, ins);
- break;
- default:
- break;
- }
- }
-
- bb->max_vreg = cfg->next_vreg;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_float_to_int */
-/* */
-/* Function - Create instructions which will convert a floating */
-/* point value to integer. */
-/* */
-/*------------------------------------------------------------------*/
-
-static guchar*
-emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size, gboolean is_signed)
-{
- /* sreg is a float, dreg is an integer reg. */
- if (is_signed) {
- s390_cfdbr (code, dreg, 5, sreg);
- switch (size) {
- case 1:
- s390_lhi (code, s390_r0, 0);
- s390_lhi (code, s390_r13, 0xff);
- s390_ltr (code, dreg, dreg);
- s390_jnl (code, 4);
- s390_lhi (code, s390_r0, 0x80);
- s390_nr (code, dreg, s390_r13);
- s390_or (code, dreg, s390_r0);
- break;
- }
- } else {
- short *o[1];
- s390_basr (code, s390_r13, 0);
- s390_j (code, 10);
- s390_llong (code, 0x41e0000000000000LL);
- s390_llong (code, 0x41f0000000000000LL);
- s390_ldr (code, s390_f15, sreg);
- s390_cdb (code, s390_f15, 0, s390_r13, 4);
- s390_jl (code, 0); CODEPTR(code, o[0]);
- s390_sdb (code, s390_f15, 0, s390_r13, 12);
- s390_cfdbr (code, dreg, 7, s390_f15);
- s390_j (code, 4);
- PTRSLOT(code, o[0]);
- s390_cfdbr (code, dreg, 5, sreg);
- switch (size) {
- case 1:
- s390_lhi (code, s390_r0, 0xff);
- s390_nr (code, dreg, s390_r0);
- break;
- case 2:
- s390_lhi (code, s390_r0, -1);
- s390_srl (code, s390_r0, 0, 16);
- s390_nr (code, dreg, s390_r0);
- break;
- }
- }
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_output_basic_block */
-/* */
-/* Function - Perform the "real" work of emitting instructions */
-/* that will do the work of in the basic block. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
-{
- MonoInst *ins;
- MonoCallInst *call;
- guint offset;
- guint8 *code = cfg->native_code + cfg->code_len;
- MonoInst *last_ins = NULL;
- guint last_offset = 0;
- int max_len, cpos, src2;
-
- /* we don't align basic blocks of loops on s390 */
-
- if (cfg->verbose_level > 2)
- g_print ("Basic block %d starting at offset 0x%x\n", bb->block_num, bb->native_offset);
-
- cpos = bb->max_offset;
-
- if (cfg->prof_options & MONO_PROFILE_COVERAGE) {
- //MonoCoverageInfo *cov = mono_get_coverage_info (cfg->method);
- //g_assert (!mono_compile_aot);
- //cpos += 6;
- //if (bb->cil_code)
- // cov->data [bb->dfn].iloffset = bb->cil_code - cfg->cil_code;
- /* this is not thread save, but good enough */
- /* fixme: howto handle overflows? */
- //x86_inc_mem (code, &cov->data [bb->dfn].count);
- }
-
- MONO_BB_FOR_EACH_INS (bb, ins) {
- offset = code - cfg->native_code;
-
- max_len = ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
-
- if (offset > (cfg->code_size - max_len - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- code = cfg->native_code + offset;
- }
-
- mono_debug_record_line_number (cfg, ins, offset);
-
- switch (ins->opcode) {
- case OP_STOREI1_MEMBASE_IMM: {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm12(ins->inst_offset))
- s390_stc (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI2_MEMBASE_IMM: {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_sth (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STORE_MEMBASE_IMM:
- case OP_STOREI4_MEMBASE_IMM: {
- if (s390_is_imm16(ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_l (code, s390_r0, 0, s390_r13, 4);
- }
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_st (code, s390_r0, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, s390_r0, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI1_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_stc (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_stc (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STOREI2_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_sth (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_sth (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_STORE_MEMBASE_REG:
- case OP_STOREI4_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_st (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADU4_MEM:
- g_assert_not_reached ();
- break;
- case OP_LOAD_MEMBASE:
- case OP_LOADI4_MEMBASE:
- case OP_LOADU4_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset))
- s390_l (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- else {
- if (s390_is_imm16(ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- s390_l (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- }
- break;
- case OP_LOADU1_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_ic (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ic (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADI1_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_ic (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ic (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lhi (code, s390_r13, 0x80);
- s390_nr (code, s390_r13, s390_r0);
- s390_jz (code, 5);
- s390_lhi (code, s390_r13, 0xff00);
- s390_or (code, s390_r0, s390_r13);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADU2_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_icm (code, s390_r0, 3, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ar (code, s390_r13, ins->inst_basereg);
- s390_icm (code, s390_r0, 3, s390_r13, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_LOADI2_MEMBASE: {
- s390_lhi (code, s390_r0, 0);
- if (s390_is_uimm12(ins->inst_offset))
- s390_lh (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_lh (code, s390_r0, s390_r13, ins->inst_basereg, 0);
- }
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
-
- case OP_ICONV_TO_I1: {
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 24);
- s390_sra (code, ins->dreg, 0, 24);
- }
- break;
- case OP_ICONV_TO_I2: {
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_sll (code, ins->dreg, 0, 16);
- s390_sra (code, ins->dreg, 0, 16);
- }
- break;
- case OP_ICONV_TO_U1: {
- s390_lhi (code, s390_r0, 0xff);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_ICONV_TO_U2: {
- s390_lhi (code, s390_r0, -1);
- s390_sll (code, s390_r0, 0, 16);
- s390_srl (code, s390_r0, 0, 16);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_COMPARE:
- case OP_ICOMPARE: {
- gboolean un = FALSE;
- MonoInst *next = ins->next;
-
- if ((next) &&
- (((next->opcode >= OP_IBNE_UN) &&
- (next->opcode <= OP_IBLT_UN)) ||
- ((next->opcode >= OP_COND_EXC_NE_UN) &&
- (next->opcode <= OP_COND_EXC_LT_UN)) ||
- ((next->opcode >= OP_COND_EXC_INE_UN) &&
- (next->opcode <= OP_COND_EXC_ILT_UN)) ||
- ((next->opcode == OP_CLT_UN) ||
- (next->opcode == OP_CGT_UN)) ||
- ((next->opcode == OP_ICLT_UN) ||
- (next->opcode == OP_ICGT_UN))))
- un = TRUE;
-
- if (un)
- s390_clr (code, ins->sreg1, ins->sreg2);
- else
- s390_cr (code, ins->sreg1, ins->sreg2);
- }
- break;
- case OP_COMPARE_IMM:
- case OP_ICOMPARE_IMM: {
- gboolean un = FALSE;
- MonoInst *next = ins->next;
-
- if ((next) &&
- (((next->opcode >= OP_IBNE_UN) &&
- (next->opcode <= OP_IBLT_UN)) ||
- ((next->opcode >= OP_COND_EXC_NE_UN) &&
- (next->opcode <= OP_COND_EXC_LT_UN)) ||
- ((next->opcode >= OP_COND_EXC_INE_UN) &&
- (next->opcode <= OP_COND_EXC_ILT_UN)) ||
- ((next->opcode == OP_CLT_UN) ||
- (next->opcode == OP_CGT_UN)) ||
- ((next->opcode == OP_ICLT_UN) ||
- (next->opcode == OP_ICGT_UN))))
- un = TRUE;
-
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (un)
- s390_clr (code, ins->sreg1, s390_r0);
- else
- s390_cr (code, ins->sreg1, s390_r0);
- }
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (un)
- s390_cl (code, ins->sreg1, 0, s390_r13, 4);
- else
- s390_c (code, ins->sreg1, 0, s390_r13, 4);
- }
- }
- break;
- case OP_BREAK: {
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, mono_break);
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_ADDCC:
- case OP_IADDCC: {
- CHECK_SRCDST_COM;
- s390_alr (code, ins->dreg, src2);
- }
- break;
- case OP_IADD: {
- CHECK_SRCDST_COM;
- s390_ar (code, ins->dreg, src2);
- }
- break;
- case OP_ADC:
- case OP_IADC: {
- CHECK_SRCDST_COM;
- s390_alcr (code, ins->dreg, src2);
- }
- break;
- case OP_ADD_IMM:
- case OP_IADD_IMM: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- if ((ins->next) &&
- (ins->next->opcode == OP_ADC_IMM)) {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- } else {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_ahi (code, ins->dreg, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- }
- break;
- case OP_ADDCC_IMM: {
- if ((ins->next) &&
- (ins->next->opcode == OP_ADC_IMM)) {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_al (code, ins->dreg, 0, s390_r13, 4);
- } else {
- if (s390_is_imm16 (ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_alcr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_al (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- }
- break;
- case OP_ADC_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_alcr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_alcr (code, ins->dreg, s390_r13);
- }
- }
- break;
- case OP_IADD_OVF:
- case OP_S390_IADD_OVF: {
- CHECK_SRCDST_COM;
- s390_ar (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_IADD_OVF_UN:
- case OP_S390_IADD_OVF_UN: {
- CHECK_SRCDST_COM;
- s390_alr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- }
- break;
- case OP_LADD:
- case OP_S390_LADD: {
- s390_alr (code, s390_r0, ins->sreg1);
- s390_jnc (code, 4);
- s390_ahi (code, s390_r1, 1);
- s390_ar (code, s390_r1, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LADD_OVF:
- case OP_S390_LADD_OVF: {
- short int *o[1];
- s390_alr (code, s390_r0, ins->sreg1);
- s390_jnc (code, 0); CODEPTR(code, o[0]);
- s390_ahi (code, s390_r1, 1);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- PTRSLOT (code, o[0]);
- s390_ar (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LADD_OVF_UN:
- case OP_S390_LADD_OVF_UN: {
- s390_alr (code, s390_r0, ins->sreg1);
- s390_alcr (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_ADD_OVF_CARRY: {
- CHECK_SRCDST_COM;
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, s390_r0);
- s390_alcr (code, s390_r0, s390_r1);
- s390_ar (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_ar (code, ins->dreg, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_ADD_OVF_UN_CARRY: {
- CHECK_SRCDST_COM;
- s390_alcr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, "OverflowException");
- }
- break;
- case OP_SUBCC:
- case OP_ISUBCC: {
- CHECK_SRCDST_NCOM;
- s390_slr (code, ins->dreg, src2);
- }
- break;
- case OP_ISUB: {
- CHECK_SRCDST_NCOM;
- s390_sr (code, ins->dreg, src2);
- }
- break;
- case OP_SBB:
- case OP_ISBB: {
- CHECK_SRCDST_NCOM;
- s390_slbr (code, ins->dreg, src2);
- }
- break;
- case OP_SUBCC_IMM: {
- if (s390_is_imm16 (-ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_slr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sl (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_SUB_IMM:
- case OP_ISUB_IMM: {
- if (s390_is_imm16 (-ins->inst_imm)) {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_ahi (code, ins->dreg, -ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_s (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_SBB_IMM: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- if (s390_is_imm16 (-ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- s390_slbr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- s390_slb (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_ISUB_OVF:
- case OP_S390_ISUB_OVF: {
- CHECK_SRCDST_NCOM;
- s390_sr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_ISUB_OVF_UN:
- case OP_S390_ISUB_OVF_UN: {
- CHECK_SRCDST_NCOM;
- s390_slr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, "OverflowException");
- }
- break;
- case OP_LSUB:
- case OP_S390_LSUB: {
- s390_lr (code, s390_r14, ins->sreg2);
- s390_slr (code, s390_r0, ins->sreg1);
- s390_jnl (code, 4);
- s390_ahi (code, s390_r14, 1);
- s390_sr (code, s390_r1, s390_r14);
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LSUB_OVF:
- case OP_S390_LSUB_OVF: {
- short int *o[1];
- s390_lr (code, s390_r14, ins->sreg2);
- s390_slr (code, s390_r0, ins->sreg1);
- s390_jnl (code, 0); CODEPTR(code, o[0]);
- s390_ahi (code, s390_r14, 1);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- PTRSLOT (code, o[0]);
- s390_sr (code, s390_r1, s390_r14);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_LSUB_OVF_UN:
- case OP_S390_LSUB_OVF_UN: {
- s390_slr (code, s390_r0, ins->sreg1);
- s390_slbr (code, s390_r1, ins->sreg2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, "OverflowException");
- s390_lr (code, ins->dreg, s390_r0);
- s390_lr (code, ins->dreg+1, s390_r1);
- }
- break;
- case OP_SUB_OVF_CARRY: {
- CHECK_SRCDST_NCOM;
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, s390_r0);
- s390_slbr (code, s390_r0, s390_r1);
- s390_sr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- s390_ar (code, ins->dreg, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, "OverflowException");
- }
- break;
- case OP_SUB_OVF_UN_CARRY: {
- CHECK_SRCDST_NCOM;
- s390_slbr (code, ins->dreg, src2);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, "OverflowException");
- }
- break;
- case OP_IAND: {
- if (ins->sreg1 == ins->dreg) {
- s390_nr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_nr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_nr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_AND_IMM:
- case OP_IAND_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_nr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_n (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_IDIV: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srda (code, s390_r0, 0, 32);
- s390_dr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IDIV_UN: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srdl (code, s390_r0, 0, 32);
- s390_dlr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IREM: {
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srda (code, s390_r0, 0, 32);
- s390_dr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- break;
- case OP_IREM_UN:
- s390_lr (code, s390_r0, ins->sreg1);
- s390_srdl (code, s390_r0, 0, 32);
- s390_dlr (code, s390_r0, ins->sreg2);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_IOR: {
- if (ins->sreg1 == ins->dreg) {
- s390_or (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_or (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_or (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_OR_IMM:
- case OP_IOR_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_or (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_o (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_IXOR: {
- if (ins->sreg1 == ins->dreg) {
- s390_xr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_xr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_xr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_XOR_IMM:
- case OP_IXOR_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r0, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_xr (code, ins->dreg, s390_r0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_x (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_ISHL: {
- CHECK_SRCDST_NCOM;
- s390_sll (code, ins->dreg, src2, 0);
- }
- break;
- case OP_SHL_IMM:
- case OP_ISHL_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sll (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_ISHR: {
- CHECK_SRCDST_NCOM;
- s390_sra (code, ins->dreg, src2, 0);
- }
- break;
- case OP_SHR_IMM:
- case OP_ISHR_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_sra (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_SHR_UN_IMM:
- case OP_ISHR_UN_IMM: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_srl (code, ins->dreg, 0, (ins->inst_imm & 0x1f));
- }
- break;
- case OP_ISHR_UN: {
- CHECK_SRCDST_NCOM;
- s390_srl (code, ins->dreg, src2, 0);
- }
- break;
- case OP_INOT: {
- if (ins->sreg1 != ins->dreg) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_lhi (code, s390_r0, -1);
- s390_xr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_INEG: {
- s390_lcr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_S390_LNEG: {
- /* From gcc code */
- g_assert (ins->dreg + 1 != ins->sreg1);
- s390_lcr (code, ins->dreg + 1, ins->sreg2);
- s390_lcr (code, ins->dreg, ins->sreg1);
- s390_je (code, 3);
- s390_bctr (code, ins->dreg + 1, 0);
- }
- break;
- case OP_IMUL: {
- if (ins->sreg1 == ins->dreg) {
- s390_msr (code, ins->dreg, ins->sreg2);
- }
- else {
- if (ins->sreg2 == ins->dreg) {
- s390_msr (code, ins->dreg, ins->sreg1);
- }
- else {
- s390_lr (code, ins->dreg, ins->sreg1);
- s390_msr (code, ins->dreg, ins->sreg2);
- }
- }
- }
- break;
- case OP_MUL_IMM:
- case OP_IMUL_IMM: {
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_lhi (code, s390_r13, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_imm);
-// if (ins->dreg != ins->sreg1) {
-// s390_lr (code, ins->dreg, ins->sreg1);
-// }
- s390_l (code, s390_r13, 0, s390_r13, 4);
- }
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- s390_msr (code, ins->dreg, s390_r13);
- }
- break;
- case OP_IMUL_OVF: {
- short int *o[2];
- s390_ltr (code, s390_r1, ins->sreg1);
- s390_jz (code, 0); CODEPTR(code, o[0]);
- s390_ltr (code, s390_r0, ins->sreg2);
- s390_jnz (code, 6);
- s390_lhi (code, s390_r1, 0);
- s390_j (code, 0); CODEPTR(code, o[1]);
- s390_xr (code, s390_r0, s390_r1);
- s390_msr (code, s390_r1, ins->sreg2);
- s390_xr (code, s390_r0, s390_r1);
- s390_srl (code, s390_r0, 0, 31);
- s390_ltr (code, s390_r0, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
- PTRSLOT (code, o[0]);
- PTRSLOT (code, o[1]);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_IMUL_OVF_UN: {
- s390_lhi (code, s390_r0, 0);
- s390_lr (code, s390_r1, ins->sreg1);
- s390_mlr (code, s390_r0, ins->sreg2);
- s390_ltr (code, s390_r0, s390_r0);
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NZ, "OverflowException");
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_LMUL: {
- s390_l (code, s390_r0, 0, ins->sreg1, 4);
- s390_srda (code, s390_r0, 0, 32);
- s390_m (code, s390_r0, 0, ins->sreg2, 4);
- s390_l (code, s390_r0, 0, ins->sreg1, 4);
- s390_srl (code, s390_r0, 0, 31);
- s390_a (code, s390_r0, 0, ins->sreg1, 0);
- s390_l (code, s390_r13, 0, ins->sreg2, 0);
- s390_srl (code, s390_r13, 0, 31);
- s390_ms (code, s390_r13, 0, ins->sreg1, 4);
- s390_ar (code, s390_r0, s390_r13);
- s390_st (code, s390_r0, 0, ins->dreg, 0);
- s390_st (code, s390_r1, 0, ins->dreg, 4);
- }
- break;
- case OP_ICONST: {
- if (s390_is_imm16(ins->inst_c0)) {
- s390_lhi (code, ins->dreg, ins->inst_c0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_c0);
- s390_l (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- break;
- case OP_AOTCONST: {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- mono_add_patch_info (cfg, code - cfg->native_code,
- (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_word (code, 0);
- s390_l (code,ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_JUMP_TABLE: {
- mono_add_patch_info (cfg, code - cfg->native_code,
- (MonoJumpInfoType)ins->inst_i1, ins->inst_p0);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, 0);
- s390_l (code, ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_ICONV_TO_I4:
- case OP_ICONV_TO_U4:
- case OP_MOVE: {
- if (ins->dreg != ins->sreg1) {
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- }
- break;
- case OP_SETLRET: {
- int saved = ins->sreg1;
- if (ins->sreg1 == s390_r2) {
- s390_lr (code, s390_r0, ins->sreg1);
- saved = s390_r0;
- }
- if (ins->sreg2 != s390_r2)
- s390_lr (code, s390_r2, ins->sreg2);
- if (saved != s390_r3)
- s390_lr (code, s390_r3, saved);
- break;
- }
- case OP_FMOVE: {
- if (ins->dreg != ins->sreg1) {
- s390_ldr (code, ins->dreg, ins->sreg1);
- }
- }
- break;
- case OP_S390_SETF4RET: {
- s390_ledbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_TLS_GET: {
- if (s390_is_imm16 (ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- } else {
- s390_bras (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- }
- s390_ear (code, s390_r1, 0);
- s390_l (code, ins->dreg, s390_r13, s390_r1, 0);
- }
- break;
- case OP_FCONV_TO_R4: {
- // FIXME:
- if (ins->dreg != ins->sreg1) {
- s390_ldr (code, ins->dreg, ins->sreg1);
- }
- /*
- NOT_IMPLEMENTED;
- if ((ins->next) &&
- (ins->next->opcode != OP_FMOVE) &&
- (ins->next->opcode != OP_STORER4_MEMBASE_REG))
- s390_ledbr (code, ins->dreg, ins->sreg1);
- */
- }
- break;
- case OP_JMP: {
- if (cfg->method->save_lmf)
- restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
-
- if (cfg->flags & MONO_CFG_HAS_TAIL) {
- code = emit_load_volatile_registers(code, cfg);
- }
-
- code = backUpStackPtr(cfg, code, STK_BASE);
- s390_l (code, s390_r14, 0, STK_BASE, S390_RET_ADDR_OFFSET);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_METHOD_JUMP,
- ins->inst_p0);
- s390_jcl (code, S390_CC_UN, 0);
- }
- break;
- case OP_CHECK_THIS: {
- /* ensure ins->sreg1 is not NULL */
- s390_icm (code, s390_r0, 15, ins->sreg1, 0);
- }
- break;
- case OP_ARGLIST: {
- int offset = cfg->sig_cookie + cfg->stack_usage;
-
- if (s390_is_imm16 (offset))
- s390_lhi (code, s390_r0, offset);
- else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, offset);
- s390_l (code, s390_r0, 0, s390_r13, 0);
- }
- s390_ar (code, s390_r0, cfg->frame_reg);
- s390_st (code, s390_r0, 0, ins->sreg1, 0);
- }
- break;
- case OP_FCALL: {
- call = (MonoCallInst*)ins;
- if (ins->flags & MONO_INST_HAS_METHOD)
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD,
- call->method);
- else
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS,
- call->fptr);
- s390_brasl (code, s390_r14, 0);
- if (call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LCALL:
- case OP_VCALL:
- case OP_VCALL2:
- case OP_VOIDCALL:
- case OP_CALL: {
- call = (MonoCallInst*)ins;
- if (ins->flags & MONO_INST_HAS_METHOD)
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD, call->method);
- else
- mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_ABS, call->fptr);
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_FCALL_REG: {
- call = (MonoCallInst*)ins;
- s390_lr (code, s390_r1, ins->sreg1);
- s390_basr (code, s390_r14, s390_r1);
- if (call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LCALL_REG:
- case OP_VCALL_REG:
- case OP_VCALL2_REG:
- case OP_VOIDCALL_REG:
- case OP_CALL_REG: {
- s390_lr (code, s390_r1, ins->sreg1);
- s390_basr (code, s390_r14, s390_r1);
- }
- break;
- case OP_LCALL_MEMBASE:
- case OP_VCALL_MEMBASE:
- case OP_VCALL2_MEMBASE:
- case OP_VOIDCALL_MEMBASE:
- case OP_FCALL_MEMBASE:
- case OP_CALL_MEMBASE: {
- call = (MonoCallInst*)ins;
- if (s390_is_uimm12(ins->inst_offset))
- s390_l (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- else {
- if (s390_is_imm16(ins->inst_offset)) {
- s390_lhi (code, s390_r13, ins->inst_offset);
- s390_l (code, s390_r1, s390_r13, ins->inst_basereg, 0);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r1, s390_r13, ins->inst_basereg, 0);
- }
- }
- s390_basr (code, s390_r14, s390_r1);
- if (ins->opcode == OP_FCALL_MEMBASE && call->signature->ret->type == MONO_TYPE_R4)
- s390_ldebr (code, s390_f0, s390_f0);
- }
- break;
- case OP_LOCALLOC: {
- /*------------------------------------------*/
- /* To allocate space on the stack we have */
- /* to allow room for parameters passed in */
- /* calls, the backchain pointer and round */
- /* it to our stack alignment requirements */
- /*------------------------------------------*/
- int alloca_skip = S390_MINIMAL_STACK_SIZE + cfg->param_area;
- int area_offset = S390_ALIGN(alloca_skip, S390_STACK_ALIGNMENT);
- s390_lr (code, s390_r1, ins->sreg1);
- if (ins->flags & MONO_INST_INIT)
- s390_lr (code, s390_r0, ins->sreg1);
- s390_ahi (code, s390_r1, 14);
- s390_srl (code, s390_r1, 0, 3);
- s390_sll (code, s390_r1, 0, 3);
- if (cfg->method->save_lmf) {
- /*----------------------------------*/
- /* we have to adjust lmf ebp value */
- /*----------------------------------*/
- int lmfOffset = cfg->stack_usage - sizeof(MonoLMF);
-
- s390_lr (code, s390_r13, cfg->frame_reg);
- if (s390_is_uimm16(lmfOffset))
- s390_ahi (code, s390_r13, lmfOffset);
- else {
- s390_basr (code, s390_r14, 0);
- s390_j (code, 4);
- s390_word (code, lmfOffset);
- s390_a (code, s390_r13, 0, s390_r14, 4);
- }
- s390_lr (code, s390_r14, STK_BASE);
- s390_sr (code, s390_r14, s390_r1);
- s390_st (code, s390_r14, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, ebp));
- }
- s390_l (code, s390_r13, 0, STK_BASE, 0);
- s390_sr (code, STK_BASE, s390_r1);
- s390_st (code, s390_r13, 0, STK_BASE, 0);
- s390_la (code, ins->dreg, 0, STK_BASE, area_offset);
- s390_srl (code, ins->dreg, 0, 3);
- s390_sll (code, ins->dreg, 0, 3);
- if (ins->flags & MONO_INST_INIT) {
- s390_lr (code, s390_r1, s390_r0);
- s390_lr (code, s390_r0, ins->dreg);
- s390_lr (code, s390_r14, s390_r12);
- s390_lhi (code, s390_r13, 0);
- s390_mvcle(code, s390_r0, s390_r12, 0, 0);
- s390_jo (code, -2);
- s390_lr (code, s390_r12, s390_r14);
- }
- }
- break;
- case OP_THROW: {
- s390_lr (code, s390_r2, ins->sreg1);
- mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_arch_throw_exception");
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_RETHROW: {
- s390_lr (code, s390_r2, ins->sreg1);
- mono_add_patch_info (cfg, code-cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_arch_rethrow_exception");
- s390_brasl (code, s390_r14, 0);
- }
- break;
- case OP_START_HANDLER: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_st (code, s390_r14, 0,
- spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_st (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- }
- break;
- case OP_ENDFILTER: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (ins->sreg1 != s390_r2)
- s390_lr (code, s390_r2, ins->sreg1);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_l (code, s390_r14, 0, spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- s390_br (code, s390_r14);
- }
- break;
- case OP_ENDFINALLY: {
- MonoInst *spvar = mono_find_spvar_for_region (cfg, bb->region);
- if (s390_is_uimm12 (spvar->inst_offset)) {
- s390_l (code, s390_r14, 0, spvar->inst_basereg,
- spvar->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, spvar->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_l (code, s390_r14, s390_r13,
- spvar->inst_basereg, 0);
- }
- s390_br (code, s390_r14);
- }
- break;
- case OP_CALL_HANDLER: {
- mono_add_patch_info (cfg, code-cfg->native_code,
- MONO_PATCH_INFO_BB, ins->inst_target_bb);
- s390_brasl (code, s390_r14, 0);
- mono_cfg_add_try_hole (cfg, ins->inst_eh_block, code, bb);
- }
- break;
- case OP_LABEL: {
- ins->inst_c0 = code - cfg->native_code;
- }
- break;
- case OP_RELAXED_NOP:
- case OP_NOP:
- case OP_DUMMY_USE:
- case OP_DUMMY_STORE:
- case OP_NOT_REACHED:
- case OP_NOT_NULL: {
- }
- break;
- case OP_BR:
- EMIT_UNCOND_BRANCH(ins);
- break;
- case OP_BR_REG: {
- s390_br (code, ins->sreg1);
- }
- break;
- case OP_CEQ:
- case OP_ICEQ: {
- s390_lhi (code, ins->dreg, 1);
- s390_jz (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CLT:
- case OP_ICLT: {
- s390_lhi (code, ins->dreg, 1);
- s390_jl (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CLT_UN:
- case OP_ICLT_UN: {
- s390_lhi (code, ins->dreg, 1);
- s390_jlo (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CGT:
- case OP_ICGT: {
- s390_lhi (code, ins->dreg, 1);
- s390_jh (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_CGT_UN:
- case OP_ICGT_UN: {
- s390_lhi (code, ins->dreg, 1);
- s390_jho (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_COND_EXC_EQ:
- case OP_COND_EXC_IEQ:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_EQ, ins->inst_p1);
- break;
- case OP_COND_EXC_NE_UN:
- case OP_COND_EXC_INE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NE, ins->inst_p1);
- break;
- case OP_COND_EXC_LT:
- case OP_COND_EXC_ILT:
- case OP_COND_EXC_LT_UN:
- case OP_COND_EXC_ILT_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LT, ins->inst_p1);
- break;
- case OP_COND_EXC_GT:
- case OP_COND_EXC_IGT:
- case OP_COND_EXC_GT_UN:
- case OP_COND_EXC_IGT_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GT, ins->inst_p1);
- break;
- case OP_COND_EXC_GE:
- case OP_COND_EXC_IGE:
- case OP_COND_EXC_GE_UN:
- case OP_COND_EXC_IGE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_GE, ins->inst_p1);
- break;
- case OP_COND_EXC_LE:
- case OP_COND_EXC_ILE:
- case OP_COND_EXC_LE_UN:
- case OP_COND_EXC_ILE_UN:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_LE, ins->inst_p1);
- break;
- case OP_COND_EXC_OV:
- case OP_COND_EXC_IOV:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_OV, ins->inst_p1);
- break;
- case OP_COND_EXC_NO:
- case OP_COND_EXC_INO:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NO, ins->inst_p1);
- break;
- case OP_COND_EXC_C:
- case OP_COND_EXC_IC:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_CY, ins->inst_p1);
- break;
- case OP_COND_EXC_NC:
- case OP_COND_EXC_INC:
- EMIT_COND_SYSTEM_EXCEPTION (S390_CC_NC, ins->inst_p1);
- break;
- case OP_IBEQ:
- EMIT_COND_BRANCH (ins, S390_CC_EQ);
- break;
- case OP_IBNE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_NE);
- break;
- case OP_IBLT:
- case OP_IBLT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LT);
- break;
- case OP_IBGT:
- case OP_IBGT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GT);
- break;
- case OP_IBGE:
- case OP_IBGE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GE);
- break;
- case OP_IBLE:
- case OP_IBLE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LE);
- break;
-
- /* floating point opcodes */
- case OP_R8CONST: {
- if (*((float *) ins->inst_p0) == 0) {
- s390_lzdr (code, ins->dreg);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_p0);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ld (code, ins->dreg, 0, s390_r13, 0);
- }
- }
- break;
- case OP_R4CONST: {
- if (*((float *) ins->inst_p0) == 0) {
- s390_lzdr (code, ins->dreg);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_p0);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ldeb (code, ins->dreg, 0, s390_r13, 0);
- }
- }
- break;
- case OP_STORER8_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_std (code, ins->sreg1, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_std (code, ins->sreg1, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADR8_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ld (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ld (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- break;
- case OP_STORER4_MEMBASE_REG: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_ste (code, s390_f15, 0, ins->inst_destbasereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ledbr(code, s390_f15, ins->sreg1);
- s390_ste (code, s390_f15, s390_r13, ins->inst_destbasereg, 0);
- }
- }
- break;
- case OP_LOADR4_MEMBASE: {
- if (s390_is_uimm12(ins->inst_offset)) {
- s390_ldeb (code, ins->dreg, 0, ins->inst_basereg, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, ins->inst_offset);
- s390_l (code, s390_r13, 0, s390_r13, 4);
- s390_ldeb (code, ins->dreg, s390_r13, ins->inst_basereg, 0);
- }
- }
- break;
- case OP_ICONV_TO_R_UN: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- s390_ltr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 12);
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, 0x41f00000);
- s390_word (code, 0);
- s390_adb (code, ins->dreg, 0, s390_r13, 4);
- }
- break;
- case OP_ICONV_TO_R4: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_ICONV_TO_R8: {
- s390_cdfbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FCONV_TO_I1:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
- break;
- case OP_FCONV_TO_U1:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, FALSE);
- break;
- case OP_FCONV_TO_I2:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, TRUE);
- break;
- case OP_FCONV_TO_U2:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 2, FALSE);
- break;
- case OP_FCONV_TO_I4:
- case OP_FCONV_TO_I:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, TRUE);
- break;
- case OP_FCONV_TO_U4:
- case OP_FCONV_TO_U:
- code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 4, FALSE);
- break;
- case OP_FCONV_TO_I8:
- case OP_FCONV_TO_U8:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_R_UN:
- g_assert_not_reached ();
- /* Implemented as helper calls */
- break;
- case OP_LCONV_TO_OVF_I:
- case OP_LCONV_TO_OVF_I4_2: {
- /* Valid ints: 0xffffffff:8000000 to 00000000:0x7f000000 */
- short int *o[5];
- s390_ltr (code, ins->sreg1, ins->sreg1);
- s390_jnl (code, 0); CODEPTR(code, o[0]);
- s390_ltr (code, ins->sreg2, ins->sreg2);
- s390_jnl (code, 0); CODEPTR(code, o[1]);
- s390_lhi (code, s390_r13, -1);
- s390_cr (code, ins->sreg2, s390_r13);
- s390_jnz (code, 0); CODEPTR(code, o[2]);
- s390_j (code, 0); CODEPTR(code, o[3]);
- PTRSLOT(code, o[0]);
- s390_ltr (code, ins->sreg2, ins->sreg2);
- s390_jz (code, 0); CODEPTR(code, o[4]);
- PTRSLOT(code, o[1]);
- PTRSLOT(code, o[2]);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_EXC, "OverflowException");
- s390_brasl (code, s390_r14, 0);
- PTRSLOT(code, o[3]);
- PTRSLOT(code, o[4]);
- if (ins->dreg != ins->sreg1)
- s390_lr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_SQRT: {
- s390_sqdbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FADD: {
- CHECK_SRCDST_COM_F;
- s390_adbr (code, ins->dreg, src2);
- }
- break;
- case OP_FSUB: {
- CHECK_SRCDST_NCOM_F;
- s390_sdbr (code, ins->dreg, src2);
- }
- break;
- case OP_FMUL: {
- CHECK_SRCDST_COM_F;
- s390_mdbr (code, ins->dreg, src2);
- }
- break;
- case OP_FDIV: {
- CHECK_SRCDST_NCOM_F;
- s390_ddbr (code, ins->dreg, src2);
- }
- break;
- case OP_FNEG: {
- s390_lcdbr (code, ins->dreg, ins->sreg1);
- }
- break;
- case OP_FREM: {
- CHECK_SRCDST_NCOM_F;
- s390_didbr (code, ins->dreg, src2, 5, s390_f15);
- }
- break;
- case OP_FCOMPARE: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- }
- break;
- case OP_FCEQ: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_je (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCLT: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jl (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCLT_UN: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jlo (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCGT: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jh (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FCGT_UN: {
- s390_cdbr (code, ins->sreg1, ins->sreg2);
- s390_lhi (code, ins->dreg, 1);
- s390_jho (code, 4);
- s390_lhi (code, ins->dreg, 0);
- }
- break;
- case OP_FBEQ: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_EQ);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBNE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_NE|S390_CC_OV);
- break;
- case OP_FBLT: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_LT);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBLT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LT|S390_CC_OV);
- break;
- case OP_FBGT: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_GT);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBGT_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GT|S390_CC_OV);
- break;
- case OP_FBGE: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_GE);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBGE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_GE|S390_CC_OV);
- break;
- case OP_FBLE: {
- short *o;
- s390_jo (code, 0); CODEPTR(code, o);
- EMIT_COND_BRANCH (ins, S390_CC_LE);
- PTRSLOT(code, o);
- }
- break;
- case OP_FBLE_UN:
- EMIT_COND_BRANCH (ins, S390_CC_LE|S390_CC_OV);
- break;
- case OP_CKFINITE: {
- short *o;
- s390_lhi (code, s390_r13, 0x7f);
- s390_tcdb (code, ins->sreg1, 0, s390_r13, 0);
- s390_jz (code, 0); CODEPTR(code, o);
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_EXC, "ArithmeticException");
- s390_brasl (code, s390_r14,0);
- PTRSLOT(code, o);
- }
- break;
- case OP_S390_MOVE: {
- if (ins->backend.size > 0) {
- if (ins->backend.size <= 256) {
- s390_mvc (code, ins->backend.size, ins->dreg,
- ins->inst_offset, ins->sreg1, ins->inst_imm);
- } else {
- s390_lr (code, s390_r0, ins->dreg);
- if (s390_is_imm16 (ins->inst_offset)) {
- s390_ahi (code, s390_r0, ins->inst_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->inst_offset);
- s390_a (code, s390_r0, 0, s390_r13, 4);
- }
- s390_lr (code, s390_r12, ins->sreg1);
- if (s390_is_imm16 (ins->inst_imm)) {
- s390_ahi (code, s390_r12, ins->inst_imm);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->inst_imm);
- s390_a (code, s390_r12, 0, s390_r13, 4);
- }
- if (s390_is_imm16 (ins->backend.size)) {
- s390x_lhi (code, s390_r1, ins->backend.size);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_long (code, ins->backend.size);
- s390_l (code, s390_r1, 0, s390_r13, 4);
- }
- s390_lr (code, s390_r1, ins->backend.size);
- s390_lr (code, s390_r13, s390_r1);
- s390_mvcle(code, s390_r0, s390_r12, 0, 0);
- s390_jo (code, -2);
- }
- }
- }
- case OP_ATOMIC_ADD_I4: {
- s390_lr (code, s390_r1, ins->sreg2);
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_a (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -7);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_ATOMIC_ADD_NEW_I4: {
- s390_lr (code, s390_r1, ins->sreg2);
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_a (code, s390_r1, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, s390_r1, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -7);
- s390_lr (code, ins->dreg, s390_r1);
- }
- break;
- case OP_ATOMIC_EXCHANGE_I4: {
- s390_l (code, s390_r0, 0, ins->inst_basereg, ins->inst_offset);
- s390_cs (code, s390_r0, ins->sreg2, ins->inst_basereg, ins->inst_offset);
- s390_jnz (code, -4);
- s390_lr (code, ins->dreg, s390_r0);
- }
- break;
- case OP_S390_BKCHAIN: {
- s390_lr (code, ins->dreg, ins->sreg1);
- if (s390_is_imm16 (cfg->stack_offset)) {
- s390_ahi (code, ins->dreg, cfg->stack_offset);
- } else {
- s390_basr (code, s390_r13, 0);
- s390_j (code, 6);
- s390_word (code, cfg->stack_offset);
- s390_a (code, ins->dreg, 0, s390_r13, 4);
- }
- }
- case OP_MEMORY_BARRIER: {
- }
- break;
- default:
- g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
- g_assert_not_reached ();
- }
-
- if ((cfg->opt & MONO_OPT_BRANCH) && ((code - cfg->native_code - offset) > max_len)) {
- g_warning ("wrong maximal instruction length of instruction %s (expected %d, got %d)",
- mono_inst_name (ins->opcode), max_len, code - cfg->native_code - offset);
- g_assert_not_reached ();
- }
-
- cpos += max_len;
-
- last_ins = ins;
- last_offset = offset;
- }
-
- cfg->code_len = code - cfg->native_code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_register_lowlevel_calls */
-/* */
-/* Function - Register routines to help with --trace operation. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_register_lowlevel_calls (void)
-{
- mono_register_jit_icall (mono_arch_get_lmf_addr, "mono_arch_get_lmf_addr", NULL, TRUE);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_patch_code */
-/* */
-/* Function - Process the patch data created during the */
-/* instruction build process. This resolves jumps, */
-/* calls, variables etc. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_patch_code (MonoMethod *method, MonoDomain *domain,
- guint8 *code, MonoJumpInfo *ji, MonoCodeManager *dyn_code_mp, gboolean run_cctors)
-{
- MonoJumpInfo *patch_info;
-
- for (patch_info = ji; patch_info; patch_info = patch_info->next) {
- unsigned char *ip = patch_info->ip.i + code;
- gconstpointer target = NULL;
-
- target = mono_resolve_patch_target (method, domain, code,
- patch_info, run_cctors);
-
- switch (patch_info->type) {
- case MONO_PATCH_INFO_IP:
- case MONO_PATCH_INFO_EXC_NAME:
- case MONO_PATCH_INFO_LDSTR:
- case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
- case MONO_PATCH_INFO_LDTOKEN:
- case MONO_PATCH_INFO_EXC:
- continue;
- case MONO_PATCH_INFO_SWITCH:
- /*----------------------------------*/
- /* ip points at the basr r13,0/j +4 */
- /* instruction the vtable value */
- /* follows this (i.e. ip+6) */
- /*----------------------------------*/
- *((gconstpointer *)(ip+6)) = target;
- target = NULL;
- continue;
- case MONO_PATCH_INFO_METHODCONST:
- case MONO_PATCH_INFO_CLASS:
- case MONO_PATCH_INFO_IMAGE:
- case MONO_PATCH_INFO_FIELD:
- case MONO_PATCH_INFO_IID:
- target = S390_RELATIVE(target, ip);
- continue;
- case MONO_PATCH_INFO_R4:
- case MONO_PATCH_INFO_R8:
- case MONO_PATCH_INFO_METHOD_REL:
- g_assert_not_reached ();
- continue;
- default:
- target = S390_RELATIVE(target, ip);
- ip += 2;
- }
- s390_patch (ip, (guint32) target);
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - emit_load_volatile_registers */
-/* */
-/* Function - Create the instruction sequence for loading the */
-/* parameter registers for use with the 'tail' op. */
-/* */
-/* The register loading operations performed here */
-/* are the mirror of the store operations performed */
-/* in mono_arch_emit_prolog and need to be kept in */
-/* synchronization with it. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint8 *
-emit_load_volatile_registers (guint8 * code, MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- MonoMethodSignature *sig;
- MonoInst *inst;
- int pos, i;
- CallInfo *cinfo;
-
- sig = mono_method_signature (method);
- pos = 0;
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- ArgInfo *ainfo = &cinfo->ret;
- inst = cfg->vret_addr;
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
-
- for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
- ArgInfo *ainfo = cinfo->args + i;
- inst = cfg->args [pos];
-
- if (inst->opcode == OP_REGVAR) {
- if (ainfo->regtype == RegTypeGeneral)
- s390_lr (code, ainfo->reg, inst->dreg);
- else if (ainfo->regtype == RegTypeFP) {
- if (inst->dreg != ainfo->reg) {
- if (ainfo->size == 4) {
- s390_ldebr (code, ainfo->reg, inst->dreg);
- } else {
- s390_ldr (code, ainfo->reg, inst->dreg);
- }
- }
- }
- else if (ainfo->regtype == RegTypeBase) {
- } else
- g_assert_not_reached ();
- } else {
- if (ainfo->regtype == RegTypeGeneral) {
- if (!((ainfo->reg >= 2) && (ainfo->reg <= 6)))
- g_assert_not_reached();
- switch (ainfo->size) {
- case 1:
- s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_lm (code, ainfo->reg, ainfo->reg + 1,
- inst->inst_basereg, inst->inst_offset);
- break;
- default:
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else if (ainfo->regtype == RegTypeBase) {
- } else if (ainfo->regtype == RegTypeFP) {
- if (ainfo->size == 8)
- s390_ld (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else if (ainfo->size == 4)
- s390_le (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else
- g_assert_not_reached ();
- } else if (ainfo->regtype == RegTypeStructByVal) {
- if (ainfo->reg != STK_BASE) {
- switch (ainfo->size) {
- case 1:
- s390_ic (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_lh (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 4:
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_lm (code, ainfo->reg, ainfo->reg+1, inst->inst_basereg, inst->inst_offset);
- break;
- }
- }
- } else if (ainfo->regtype == RegTypeStructByAddr) {
- if (ainfo->reg != STK_BASE) {
- s390_l (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else
- g_assert_not_reached ();
- }
- pos++;
- }
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_prolog */
-/* */
-/* Function - Create the instruction sequence for a function */
-/* prolog. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint8 *
-mono_arch_emit_prolog (MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- MonoBasicBlock *bb;
- MonoMethodSignature *sig;
- MonoInst *inst;
- int alloc_size, pos, max_offset, i;
- guint8 *code;
- CallInfo *cinfo;
- int tracing = 0;
- int lmfOffset; \
-
- if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
- tracing = 1;
-
- cfg->code_size = 1024;
- cfg->native_code = code = g_malloc (cfg->code_size);
-
- s390_stm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
-
- if (cfg->arch.bkchain_reg != -1)
- s390_lr (code, cfg->arch.bkchain_reg, STK_BASE);
-
- if (cfg->flags & MONO_CFG_HAS_ALLOCA) {
- cfg->used_int_regs |= 1 << 11;
- }
-
- alloc_size = cfg->stack_offset;
-
- cfg->stack_usage = alloc_size;
- s390_lr (code, s390_r11, STK_BASE);
- if (s390_is_uimm16 (alloc_size)) {
- s390_ahi (code, STK_BASE, -alloc_size);
- } else {
- int stackSize = alloc_size;
- while (stackSize > 32767) {
- s390_ahi (code, STK_BASE, -32767);
- stackSize -= 32767;
- }
- s390_ahi (code, STK_BASE, -stackSize);
- }
- s390_st (code, s390_r11, 0, STK_BASE, 0);
-
- if (cfg->frame_reg != STK_BASE)
- s390_lr (code, s390_r11, STK_BASE);
-
- /* compute max_offset in order to use short forward jumps
- * we always do it on s390 because the immediate displacement
- * for jumps is too small
- */
- max_offset = 0;
- for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
- MonoInst *ins = bb->code;
- bb->max_offset = max_offset;
-
- if (cfg->prof_options & MONO_PROFILE_COVERAGE)
- max_offset += 6;
-
- MONO_BB_FOR_EACH_INS (bb, ins)
- max_offset += ((guint8 *)ins_get_spec (ins->opcode))[MONO_INST_LEN];
- }
-
- /* load arguments allocated to register from the stack */
- sig = mono_method_signature (method);
- pos = 0;
-
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
-
- if (cinfo->struct_ret) {
- ArgInfo *ainfo = &cinfo->ret;
- inst = cfg->vret_addr;
- inst->backend.size = ainfo->vtsize;
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
-
- for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
- ArgInfo *ainfo = cinfo->args + i;
- inst = cfg->args [pos];
-
- if (inst->opcode == OP_VTARG_ADDR)
- inst = inst->inst_left;
-
- if (inst->opcode == OP_REGVAR) {
- if (ainfo->regtype == RegTypeGeneral)
- s390_lr (code, inst->dreg, ainfo->reg);
- else if (ainfo->regtype == RegTypeFP) {
- if (inst->dreg != ainfo->reg) {
- if (ainfo->size == 4) {
- s390_ledbr (code, inst->dreg, ainfo->reg);
- } else {
- s390_ldr (code, inst->dreg, ainfo->reg);
- }
- }
- }
- else if (ainfo->regtype == RegTypeBase) {
- s390_lr (code, s390_r13, STK_BASE);
- s390_ahi (code, s390_r13, alloc_size);
- s390_l (code, inst->dreg, 0, s390_r13, ainfo->offset);
- } else
- g_assert_not_reached ();
-
- if (cfg->verbose_level > 2)
- g_print ("Argument %d assigned to register %s\n",
- pos, mono_arch_regname (inst->dreg));
- } else {
- if (ainfo->regtype == RegTypeGeneral) {
- if (!((ainfo->reg >= 2) && (ainfo->reg <= 6)))
- g_assert_not_reached();
- switch (ainfo->size) {
- case 1:
- s390_stc (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 2:
- s390_sth (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- break;
- case 8:
- s390_stm (code, ainfo->reg, ainfo->reg + 1,
- inst->inst_basereg, inst->inst_offset);
- break;
- default:
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- }
- } else if (ainfo->regtype == RegTypeBase) {
- } else if (ainfo->regtype == RegTypeFP) {
- if (ainfo->size == 8)
- s390_std (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else if (ainfo->size == 4)
- s390_ste (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- else
- g_assert_not_reached ();
- } else if (ainfo->regtype == RegTypeStructByVal) {
- int doffset = inst->inst_offset;
- int reg;
- if (ainfo->reg != STK_BASE)
- reg = ainfo->reg;
- else {
- reg = s390_r0;
- s390_lr (code, s390_r13, STK_BASE);
- s390_ahi (code, s390_r13, alloc_size);
- }
- switch (ainfo->size) {
- case 1:
- if (ainfo->reg == STK_BASE)
- s390_ic (code, reg, 0, s390_r13, ainfo->offset+3);
- s390_stc (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 2:
- if (ainfo->reg == STK_BASE)
- s390_lh (code, reg, 0, s390_r13, ainfo->offset+2);
- s390_sth (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 4:
- if (ainfo->reg == STK_BASE)
- s390_l (code, reg, 0, s390_r13, ainfo->offset);
- s390_st (code, reg, 0, inst->inst_basereg, doffset);
- break;
- case 8:
- if (ainfo->reg == STK_BASE)
- s390_lm (code, s390_r0, s390_r1, s390_r13, ainfo->offset);
- s390_stm (code, reg, reg+1, inst->inst_basereg, doffset);
- break;
- }
- } else if (ainfo->regtype == RegTypeStructByAddr) {
- if (ainfo->reg != STK_BASE)
- s390_st (code, ainfo->reg, 0, inst->inst_basereg, inst->inst_offset);
- } else
- g_assert_not_reached ();
- }
- pos++;
- }
-
- if (method->save_lmf) {
- /*---------------------------------------------------------------*/
- /* we build the MonoLMF structure on the stack - see mini-s390.h */
- /*---------------------------------------------------------------*/
- lmfOffset = alloc_size - sizeof(MonoLMF);
-
- s390_lr (code, s390_r13, cfg->frame_reg);
- if (s390_is_uimm16(lmfOffset))
- s390_ahi (code, s390_r13, lmfOffset);
- else {
- s390_basr (code, s390_r14, 0);
- s390_j (code, 4);
- s390_word (code, lmfOffset);
- s390_a (code, s390_r13, 0, s390_r14, 4);
- }
-
- /*---------------------------------------------------------------*/
- /* Preserve the parameter registers while we fix up the lmf */
- /*---------------------------------------------------------------*/
- s390_stm (code, s390_r2, s390_r6, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, pregs[0]));
-
- /*---------------------------------------------------------------*/
- /* On return from this call r2 have the address of the &lmf */
- /*---------------------------------------------------------------*/
- mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_INTERNAL_METHOD,
- (gpointer)"mono_get_lmf_addr");
- s390_brasl (code, s390_r14, 0);
-
- /*---------------------------------------------------------------*/
- /* Set lmf.lmf_addr = jit_tls->lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r2, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, lmf_addr));
-
- /*---------------------------------------------------------------*/
- /* Get current lmf */
- /*---------------------------------------------------------------*/
- s390_l (code, s390_r0, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Set our lmf as the current lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r13, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Have our lmf.previous_lmf point to the last lmf */
- /*---------------------------------------------------------------*/
- s390_st (code, s390_r0, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, previous_lmf));
-
- /*---------------------------------------------------------------*/
- /* save method info */
- /*---------------------------------------------------------------*/
- s390_basr (code, s390_r1, 0);
- s390_j (code, 4);
- s390_word (code, method);
- s390_l (code, s390_r1, 0, s390_r1, 4);
- s390_st (code, s390_r1, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, method));
-
- /*---------------------------------------------------------------*/
- /* save the current IP */
- /*---------------------------------------------------------------*/
- s390_st (code, STK_BASE, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
- s390_basr (code, s390_r1, 0);
- s390_la (code, s390_r1, 0, s390_r1, 0);
- s390_st (code, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
-
- /*---------------------------------------------------------------*/
- /* Save general and floating point registers */
- /*---------------------------------------------------------------*/
- s390_stm (code, s390_r2, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, gregs[2]));
- for (i = 0; i < 16; i++) {
- s390_std (code, i, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, fregs[i]));
- }
-
- /*---------------------------------------------------------------*/
- /* Restore the parameter registers now that we've set up the lmf */
- /*---------------------------------------------------------------*/
- s390_lm (code, s390_r2, s390_r6, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, pregs[0]));
- }
-
- if (tracing)
- code = mono_arch_instrument_prolog(cfg, enter_method, code, TRUE);
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_epilog */
-/* */
-/* Function - Emit the instructions for a function epilog. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_epilog (MonoCompile *cfg)
-{
- MonoMethod *method = cfg->method;
- int tracing = 0;
- guint8 *code;
- int max_epilog_size = 96;
-
- if (cfg->method->save_lmf)
- max_epilog_size += 128;
-
- if (mono_jit_trace_calls != NULL)
- max_epilog_size += 128;
-
- if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
- max_epilog_size += 128;
-
- while ((cfg->code_len + max_epilog_size) > (cfg->code_size - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- cfg->stat_code_reallocs++;
- }
-
- code = cfg->native_code + cfg->code_len;
-
- if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) {
- code = mono_arch_instrument_epilog (cfg, leave_method, code, TRUE);
- tracing = 1;
- }
-
- if (method->save_lmf)
- restoreLMF(code, cfg->frame_reg, cfg->stack_usage);
-
- if (cfg->flags & MONO_CFG_HAS_ALLOCA)
- s390_l (code, STK_BASE, 0, STK_BASE, 0);
- else
- code = backUpStackPtr(cfg, code, STK_BASE);
-
- s390_lm (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_br (code, s390_r14);
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_exceptions */
-/* */
-/* Function - Emit the blocks to handle exception conditions. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_emit_exceptions (MonoCompile *cfg)
-{
- MonoJumpInfo *patch_info;
- guint8 *code;
- int nThrows = 0,
- exc_count = 0,
- iExc;
- guint32 code_size;
- MonoClass *exc_classes [MAX_EXC];
- guint8 *exc_throw_start [MAX_EXC];
-
- for (patch_info = cfg->patch_info;
- patch_info;
- patch_info = patch_info->next) {
- if (patch_info->type == MONO_PATCH_INFO_EXC)
- exc_count++;
- }
-
- code_size = exc_count * 26;
-
- while ((cfg->code_len + code_size) > (cfg->code_size - 16)) {
- cfg->code_size *= 2;
- cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
- cfg->stat_code_reallocs++;
- }
-
- code = cfg->native_code + cfg->code_len;
-
- /*---------------------------------------------------------------------*/
- /* Add code to raise exceptions */
- /*---------------------------------------------------------------------*/
- for (patch_info = cfg->patch_info; patch_info; patch_info = patch_info->next) {
- switch (patch_info->type) {
- case MONO_PATCH_INFO_EXC: {
- guint8 *ip = patch_info->ip.i + cfg->native_code;
- MonoClass *exc_class;
- guint32 throw_ip;
-
- /*-----------------------------------------------------*/
- /* Patch the branch in epilog to come here */
- /*-----------------------------------------------------*/
- s390_patch (ip + 2, (guint32) (S390_RELATIVE(code,ip)));
-
- exc_class = mono_class_from_name (mono_defaults.corlib,
- "System",
- patch_info->data.name);
- g_assert (exc_class);
- throw_ip = patch_info->ip.i;
-
- for (iExc = 0; iExc < nThrows; ++iExc)
- if (exc_classes [iExc] == exc_class)
- break;
-
- if (iExc < nThrows) {
- s390_jcl (code, S390_CC_UN, (guint32) exc_throw_start [iExc]);
- patch_info->type = MONO_PATCH_INFO_NONE;
- } else {
-
- if (nThrows < MAX_EXC) {
- exc_classes [nThrows] = exc_class;
- exc_throw_start [nThrows] = code;
- }
-
- /*---------------------------------------------*/
- /* Patch the parameter passed to the handler */
- /*---------------------------------------------*/
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, patch_info->data.target);
- /*---------------------------------------------*/
- /* Load return address & parameter register */
- /*---------------------------------------------*/
- s390_larl (code, s390_r14, (gsize)S390_RELATIVE((patch_info->ip.i +
- cfg->native_code + 8), code));
- s390_l (code, s390_r2, 0, s390_r13, 4);
- /*---------------------------------------------*/
- /* Reuse the current patch to set the jump */
- /*---------------------------------------------*/
- patch_info->type = MONO_PATCH_INFO_INTERNAL_METHOD;
- patch_info->data.name = "mono_arch_throw_exception_by_name";
- patch_info->ip.i = code - cfg->native_code;
- s390_jcl (code, S390_CC_UN, 0);
- }
- break;
- }
- default:
- /* do nothing */
- break;
- }
- }
-
- cfg->code_len = code - cfg->native_code;
-
- g_assert (cfg->code_len < cfg->code_size);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_finish_init */
-/* */
-/* Function - Setup the JIT's Thread Level Specific Data. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_finish_init (void)
-{
-#if HAVE_KW_THREAD
-# if 0
- __asm__ ("\tear\t%r1,0\n"
- "\tlr\t%0,%3\n"
- "\tsr\t%0,%r1\n"
- "\tlr\t%1,%4\n"
- "\tsr\t%1,%r1\n"
- "\tlr\t%2,%5\n"
- "\tsr\t%2,%r1\n"
- : "=r" (appdomain_tls_offset),
- "=r" (thread_tls_offset),
- "=r" (lmf_tls_offset)
- : "r" (&tls_appdomain),
- "r" (&tls_current_object),
- "r" (&mono_lmf_addr)
- : "1", "cc");
-# endif
-#endif
-
- if (!lmf_addr_key_inited) {
- lmf_addr_key_inited = TRUE;
- pthread_key_create (&lmf_addr_key, NULL);
- }
- pthread_setspecific (lmf_addr_key, &tls->lmf);
-
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_free_jit_tls_data */
-/* */
-/* Function - Free tls data. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_emit_inst_for_method */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoInst*
-mono_arch_emit_inst_for_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **args)
-{
- return NULL;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_decompose_opts */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins)
-{
- switch (ins->opcode) {
- case OP_ISUB_OVF:
- ins->opcode = OP_S390_ISUB_OVF;
- break;
- case OP_ISUB_OVF_UN:
- ins->opcode = OP_S390_ISUB_OVF_UN;
- break;
- case OP_IADD_OVF:
- ins->opcode = OP_S390_IADD_OVF;
- break;
- case OP_IADD_OVF_UN:
- ins->opcode = OP_S390_IADD_OVF_UN;
- break;
- default:
- break;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_decompose_long_opts */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_decompose_long_opts (MonoCompile *cfg, MonoInst *ins)
-{
- // The generic code seems to work for OP_LSUB fine on s390, why is a different
- // implementation needed ? gcc also seems to use the different implementation.
- // FIXME: What about the other OP_L opcodes below ?
-
- switch (ins->opcode) {
- case OP_LADD_OVF:
- case OP_LADD_OVF_UN:
- case OP_LSUB_OVF:
- case OP_LSUB_OVF_UN: {
- int opcode = 0;
-
- switch (ins->opcode) {
- case OP_LADD:
- opcode = OP_S390_LADD;
- break;
- case OP_LADD_OVF:
- opcode = OP_S390_LADD_OVF;
- break;
- case OP_LADD_OVF_UN:
- opcode = OP_S390_LADD_OVF_UN;
- break;
- case OP_LSUB:
- opcode = OP_S390_LSUB;
- break;
- case OP_LSUB_OVF:
- opcode = OP_S390_LSUB_OVF;
- break;
- case OP_LSUB_OVF_UN:
- opcode = OP_S390_LSUB_OVF_UN;
- break;
- default:
- g_assert_not_reached ();
- }
-
- /* These hard regs make ssa crazy */
- cfg->disable_ssa = TRUE;
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r0, ins->sreg1 + 1);
- MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, s390_r1, ins->sreg1 + 2);
- MONO_EMIT_NEW_BIALU (cfg, opcode, ins->dreg, ins->sreg2 + 1, ins->sreg2 + 2);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LADD_IMM: {
- int dreg = mono_alloc_dreg (cfg, STACK_I8);
- MONO_EMIT_NEW_I8CONST (cfg, dreg, ins->inst_l);
- MONO_EMIT_NEW_BIALU (cfg, OP_LADD, ins->dreg, ins->sreg1, dreg);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LSUB_IMM: {
- int dreg = mono_alloc_dreg (cfg, STACK_I8);
- MONO_EMIT_NEW_I8CONST (cfg, dreg, ins->inst_l);
- MONO_EMIT_NEW_BIALU (cfg, OP_LSUB, ins->dreg, ins->sreg1, dreg);
- NULLIFY_INS (ins);
- break;
- }
- case OP_LNEG: {
- MONO_EMIT_NEW_BIALU (cfg, OP_S390_LNEG, ins->dreg, ins->sreg1 + 1, ins->sreg1 + 2);
- NULLIFY_INS (ins);
- break;
- }
- case OP_ISUB_OVF:
- ins->opcode = OP_S390_ISUB_OVF;
- break;
- case OP_ISUB_OVF_UN:
- ins->opcode = OP_S390_ISUB_OVF_UN;
- break;
- default:
- break;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_print_tree */
-/* */
-/* Function - Print platform-specific opcode details. */
-/* */
-/* Returns - 1 - opcode details have been printed */
-/* 0 - opcode details have not been printed */
-/* */
-/*------------------------------------------------------------------*/
-
-gboolean
-mono_arch_print_tree (MonoInst *tree, int arity)
-{
- gboolean done;
-
- switch (tree->opcode) {
- case OP_S390_LOADARG:
- case OP_S390_ARGREG:
- case OP_S390_ARGPTR:
- printf ("[0x%lx(%s)]", tree->inst_offset,
- mono_arch_regname (tree->inst_basereg));
- done = 1;
- break;
- case OP_S390_STKARG:
- printf ("[0x%lx(previous_frame)]",
- tree->inst_offset);
- done = 1;
- break;
- case OP_S390_MOVE:
- printf ("[0x%lx(%d,%s),0x%lx(%s)]",
- tree->inst_offset, tree->backend.size,
- mono_arch_regname(tree->dreg), tree->inst_imm,
- mono_arch_regname(tree->sreg1));
- done = 1;
- break;
- case OP_S390_SETF4RET:
- printf ("[%s,%s]",
- mono_arch_fregname (tree->dreg),
- mono_arch_fregname (tree->sreg1));
- done = 1;
- break;
- case OP_TLS_GET:
- printf ("[0x%lx(0x%lx,%s)]", tree->inst_offset,
- tree->inst_imm,
- mono_arch_regname (tree->sreg1));
- done = 1;
- break;
- case OP_S390_BKCHAIN:
- printf ("[previous_frame(%s)]",
- mono_arch_regname (tree->sreg1));
- done = 1;
- break;
- default:
- done = 0;
- }
- return (done);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_regalloc_cost */
-/* */
-/* Function - Determine the cost, in the number of memory */
-/* references, of the action of allocating the var- */
-/* iable VMV into a register during global register */
-/* allocation. */
-/* */
-/* Returns - Cost */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
-{
- /* FIXME: */
- return 2;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_domain_intrinsic */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-MonoInst *
-mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
- MonoInst *ins;
-
- if (appdomain_tls_offset == -1)
- return NULL;
-
- MONO_INST_NEW (cfg, ins, OP_TLS_GET);
- ins->inst_offset = appdomain_tls_offset;
- return (ins);
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_flush_register_windows */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_flush_register_windows (void)
-{
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_lmf_addr */
-/* */
-/* Function - */
-/* */
-/* Returns - */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_lmf_addr (void)
-{
- return pthread_getspecific (lmf_addr_key);
-}
-
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_patch_offset */
-/* */
-/* Function - Dummy entry point until s390x supports aot. */
-/* */
-/* Returns - Offset for patch. */
-/* */
-/*------------------------------------------------------------------*/
-
-guint32
-mono_arch_get_patch_offset (guint8 *code)
-{
- return 0;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_context_get_int_reg. */
-/* */
-/* Function - Dummy entry point until s390x supports aot. */
-/* */
-/* Returns - Pointer to intreg. */
-/* */
-/*------------------------------------------------------------------*/
-
-mgreg_t
-mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
-{
- /* FIXME: implement */
- g_assert_not_reached ();
- return NULL;
-}
-
-/*========================= End of Function ========================*/
+++ /dev/null
-#ifndef __MONO_MINI_S390_H__
-#define __MONO_MINI_S390_H__
-
-#include <mono/arch/s390/s390-codegen.h>
-#include <signal.h>
-
-#define MONO_ARCH_CPU_SPEC s390_cpu_desc
-
-#define MONO_MAX_IREGS 16
-#define MONO_MAX_FREGS 16
-
-/*-------------------------------------------*/
-/* Parameters used by the register allocator */
-/*-------------------------------------------*/
-
-struct MonoLMF {
- gpointer previous_lmf;
- gpointer lmf_addr;
- MonoMethod *method;
- gulong ebp;
- gulong eip;
- gulong pregs[6];
- gulong gregs[16];
- gdouble fregs[16];
-};
-
-typedef struct ucontext MonoContext;
-
-typedef struct MonoCompileArch {
- int bkchain_reg;
-} MonoCompileArch;
-
-typedef struct
-{
- void *prev;
- void *unused[5];
- void *regs[8];
- void *return_address;
-} MonoS390StackFrame;
-
-typedef struct
-{
- gint32 size;
- gint32 offset;
- gint32 offPrm;
-} MonoS390ArgParm;
-
-#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R4 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
-#define MONO_ARCH_EMULATE_LMUL 1
-#define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
-#define MONO_ARCH_NEED_DIV_CHECK 1
-#define MONO_ARCH_HAVE_ATOMIC_ADD 1
-#define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1
-#define MONO_ARCH_HAVE_DECOMPOSE_OPTS 1
-#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
-// #define MONO_ARCH_SIGSEGV_ON_ALTSTACK 1
-// #define MONO_ARCH_SIGNAL_STACK_SIZE 65536
-
-#define MONO_ARCH_USE_SIGACTION 1
-
-#define S390_STACK_ALIGNMENT 8
-#define S390_FIRST_ARG_REG s390_r2
-#define S390_LAST_ARG_REG s390_r6
-#define S390_FIRST_FPARG_REG s390_f0
-#define S390_LAST_FPARG_REG s390_f2
-#define S390_PASS_STRUCTS_BY_VALUE 1
-#define S390_SMALL_RET_STRUCT_IN_REG 1
-
-#define S390_NUM_REG_ARGS (S390_LAST_ARG_REG-S390_FIRST_ARG_REG+1)
-#define S390_NUM_REG_FPARGS (S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG)
-
-/*===============================================*/
-/* Definitions used by mini-codegen.c */
-/*===============================================*/
-
-/*-----------------------------------------------------*/
-/* use s390_r2-s390_r6 as parm registers */
-/* s390_r0, s390_r1, s390_r12, s390_r13 used internally*/
-/* s390_r8..s390_r11 are used for global regalloc */
-/* s390_r15 is the stack pointer */
-/*-----------------------------------------------------*/
-#define MONO_ARCH_CALLEE_REGS (0xfc)
-
-#define MONO_ARCH_CALLEE_SAVED_REGS 0xff80
-
-/*----------------------------------------*/
-/* use s390_f1/s390_f3-s390_f15 as temps */
-/*----------------------------------------*/
-
-#define MONO_ARCH_CALLEE_FREGS (0xfffe)
-
-#define MONO_ARCH_CALLEE_SAVED_FREGS 0
-
-#define MONO_ARCH_USE_FPSTACK FALSE
-#define MONO_ARCH_FPSTACK_SIZE 0
-
-#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? s390_r2 : \
- ((desc == 'L') ? s390_r3 : \
- ((desc == 'g') ? s390_f0 : - 1)))
-
-#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
-
-#define MONO_ARCH_INST_SREG2_MASK(ins) (0)
-
-#define MONO_ARCH_INST_IS_REGPAIR(desc) ((desc == 'l') || (desc == 'L'))
-//#define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
-#define MONO_ARCH_INST_REGPAIR_REG2(desc,hr) ((desc == 'l') ? (hr + 1) : \
- ((desc == 'L') ? s390_r2 : -1))
-
-#define MONO_ARCH_IS_GLOBAL_IREG(reg) 0
-
-#define MONO_ARCH_FRAME_ALIGNMENT 4
-#define MONO_ARCH_CODE_ALIGNMENT 32
-
-#define MONO_ARCH_RETREG1 s390_r2
-
-/*-----------------------------------------------*/
-/* Macros used to generate instructions */
-/*-----------------------------------------------*/
-#define S390_OFFSET(b, t) (guchar *) ((gint32) (b) - (gint32) (t))
-#define S390_RELATIVE(b, t) (guchar *) ((((gint32) (b) - (gint32) (t))) / 2)
-
-#define CODEPTR(c, o) (o) = (short *) ((guint32) c - 2)
-#define PTRSLOT(c, o) *(o) = (short) ((guint32) c - (guint32) (o) + 2)/2
-
-#define S390_CC_EQ 8
-#define S390_ALIGN(v, a) (((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v)))
-
-#define MONO_CONTEXT_SET_IP(ctx,ip) \
- do { \
- (ctx)->uc_mcontext.gregs[14] = (unsigned long)ip; \
- (ctx)->uc_mcontext.psw.addr = (unsigned long)ip; \
- } while (0);
-
-#define MONO_CONTEXT_SET_SP(ctx,bp) MONO_CONTEXT_SET_BP((ctx),(bp))
-#define MONO_CONTEXT_SET_BP(ctx,bp) \
- do { \
- (ctx)->uc_mcontext.gregs[15] = (unsigned long)bp; \
- (ctx)->uc_stack.ss_sp = (void*)bp; \
- } while (0);
-
-#define MONO_CONTEXT_GET_IP(ctx) context_get_ip ((ctx))
-#define MONO_CONTEXT_GET_BP(ctx) MONO_CONTEXT_GET_SP((ctx))
-#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.gregs[15]))
-
-#define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \
- MonoS390StackFrame *sframe; \
- __asm__ volatile("lr %0,15" : "=r" (sframe)); \
- MONO_CONTEXT_SET_BP ((ctx), sframe->prev); \
- MONO_CONTEXT_SET_SP ((ctx), sframe->prev); \
- sframe = (MonoS390StackFrame*)sframe->prev; \
- MONO_CONTEXT_SET_IP ((ctx), sframe->return_address); \
- } while (0)
-
-#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - context_get_ip */
-/* */
-/* Function - Extract the current instruction address from the */
-/* context. */
-/* */
-/*------------------------------------------------------------------*/
-
-static inline gpointer
-context_get_ip (MonoContext *ctx)
-{
- gpointer ip;
-
- ip = (gpointer) ((gint32) (ctx->uc_mcontext.psw.addr) & 0x7fffffff);
- return ip;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - s390_patch */
-/* */
-/* Function - Patch the code with a given value. */
-/* */
-/*------------------------------------------------------------------*/
-
-static void inline
-s390_patch (guchar *code, gint32 target)
-{
- gint32 *offset = (gint32 *) code;
-
- if (target != 00) {
- *offset = target;
- }
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - restoreLMF */
-/* */
-/* Function - Restore the LMF state prior to exiting a method. */
-/* */
-/*------------------------------------------------------------------*/
-
-#define restoreLMF(code, frame_reg, stack_usage) do \
-{ \
- int lmfOffset = 0; \
- \
- s390_lr (code, s390_r13, frame_reg); \
- \
- lmfOffset = stack_usage - sizeof(MonoLMF); \
- \
- /*-------------------------------------------------*/ \
- /* r13 = my lmf */ \
- /*-------------------------------------------------*/ \
- s390_ahi (code, s390_r13, lmfOffset); \
- \
- /*-------------------------------------------------*/ \
- /* r6 = &jit_tls->lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r6, 0, s390_r13, \
- G_STRUCT_OFFSET(MonoLMF, lmf_addr)); \
- \
- /*-------------------------------------------------*/ \
- /* r0 = lmf.previous_lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r0, 0, s390_r13, \
- G_STRUCT_OFFSET(MonoLMF, previous_lmf)); \
- \
- /*-------------------------------------------------*/ \
- /* jit_tls->lmf = previous_lmf */ \
- /*-------------------------------------------------*/ \
- s390_l (code, s390_r13, 0, s390_r6, 0); \
- s390_st (code, s390_r0, 0, s390_r6, 0); \
-} while (0)
-
-/*========================= End of Function ========================*/
-
-#endif /* __MONO_MINI_S390_H__ */
#define JUMP_SIZE 6
#define ENABLE_WRONG_METHOD_CHECK 0
+#define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
+#define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
+
/*========================= End of Defines =========================*/
/*------------------------------------------------------------------*/
static inline void add_general (guint *, size_data *, ArgInfo *);
static inline void add_stackParm (guint *, size_data *, ArgInfo *, gint);
static inline void add_float (guint *, size_data *, ArgInfo *);
-static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *, gboolean);
+static CallInfo * get_call_info (MonoCompile *, MonoMemPool *, MonoMethodSignature *);
static guchar * emit_float_to_int (MonoCompile *, guchar *, int, int, int, gboolean);
static guint8 * emit_load_volatile_arguments (guint8 *, MonoCompile *);
static void catch_SIGILL(int, siginfo_t *, void *);
breakpoint_t breakpointCode;
+/*
+ * This mutex protects architecture specific caches
+ */
+static CRITICAL_SECTION mini_arch_mutex;
+
/*====================== End of Global Variables ===================*/
/*------------------------------------------------------------------*/
sig = mono_method_signature (method);
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
+ cinfo = get_call_info (NULL, NULL, sig);
if (cinfo->struct_ret) {
printf ("[STRUCTRET:%p], ", (gpointer) rParm->gr[0]);
/*------------------------------------------------------------------*/
static CallInfo *
-get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig, gboolean is_pinvoke)
+get_call_info (MonoCompile *cfg, MonoMemPool *mp, MonoMethodSignature *sig)
{
guint i, fr, gr, size, pstart;
int nParm = sig->hasthis + sig->param_count;
MonoType *ret_type;
- guint32 simpletype, align;
+ guint32 simpleType, align;
+ gboolean is_pinvoke = sig->pinvoke;
CallInfo *cinfo;
size_data *sz;
MonoGenericSharingContext *gsctx = cfg ? cfg->generic_sharing_context : NULL;
/* area that the callee will use. */
/*----------------------------------------------------------*/
- ret_type = mono_type_get_underlying_type (sig->ret);
+ ret_type = mini_type_get_underlying_type (gsctx, sig->ret);
ret_type = mini_get_basic_type_from_generic (gsctx, ret_type);
- simpletype = ret_type->type;
+ simpleType = ret_type->type;
enum_retvalue:
- switch (simpletype) {
+ switch (simpleType) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
case MONO_TYPE_VALUETYPE: {
MonoClass *klass = mono_class_from_mono_type (sig->ret);
if (klass->enumtype) {
- simpletype = mono_class_enum_basetype (klass)->type;
+ simpleType = mono_class_enum_basetype (klass)->type;
goto enum_retvalue;
}
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
+ size = mini_type_stack_size_full (gsctx, &klass->byval_arg, NULL, sig->pinvoke);
cinfo->struct_ret = 1;
cinfo->ret.size = size;
continue;
}
- ptype = mono_type_get_underlying_type (sig->params [i]);
- ptype = mini_get_basic_type_from_generic (gsctx, ptype);
- simpletype = ptype->type;
- cinfo->args[nParm].type = simpletype;
- switch (simpletype) {
+ ptype = mini_type_get_underlying_type (gsctx, sig->params [i]);
+// ptype = mini_get_basic_type_from_generic (gsctx, ptype);
+ simpleType = ptype->type;
+ cinfo->args[nParm].type = simpleType;
+ switch (simpleType) {
case MONO_TYPE_BOOLEAN:
case MONO_TYPE_I1:
case MONO_TYPE_U1:
nParm++;
break;
case MONO_TYPE_GENERICINST:
- if (!mono_type_generic_inst_is_valuetype (sig->params [i])) {
+ if (!mono_type_generic_inst_is_valuetype (ptype)) {
cinfo->args[nParm].size = sizeof(gpointer);
add_general (&gr, sz, cinfo->args+nParm);
nParm++;
/* Fall through */
case MONO_TYPE_VALUETYPE: {
MonoMarshalType *info;
- MonoClass *klass = mono_class_from_mono_type (sig->params [i]);
- if (sig->pinvoke)
- size = mono_class_native_size (klass, &align);
- else
- size = mono_class_value_size (klass, &align);
-
- info = mono_marshal_load_type_info (klass);
+ MonoClass *klass = mono_class_from_mono_type (ptype);
- if ((info->native_size == sizeof(float)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R4)) {
- cinfo->args[nParm].size = sizeof(float);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
- }
+ size = mini_type_stack_size_full(gsctx, &klass->byval_arg, NULL, sig->pinvoke);
+ if (simpleType != MONO_TYPE_GENERICINST) {
+ info = mono_marshal_load_type_info(klass);
- if ((info->native_size == sizeof(double)) &&
- (info->num_fields == 1) &&
- (info->fields[0].field->type->type == MONO_TYPE_R8)) {
- cinfo->args[nParm].size = sizeof(double);
- add_float(&fr, sz, cinfo->args+nParm);
- nParm ++;
- break;
+ if ((info->native_size == sizeof(float)) &&
+ (info->num_fields == 1) &&
+ (info->fields[0].field->type->type == MONO_TYPE_R4)) {
+ cinfo->args[nParm].size = sizeof(float);
+ add_float(&fr, sz, cinfo->args+nParm);
+ nParm ++;
+ break;
+ }
+
+ if ((info->native_size == sizeof(double)) &&
+ (info->num_fields == 1) &&
+ (info->fields[0].field->type->type == MONO_TYPE_R8)) {
+ cinfo->args[nParm].size = sizeof(double);
+ add_float(&fr, sz, cinfo->args+nParm);
+ nParm ++;
+ break;
+ }
}
cinfo->args[nParm].vtsize = 0;
}
break;
default:
- g_error ("Can't trampoline 0x%x", sig->params [i]->type);
+ g_error ("Can't trampoline 0x%x", ptype);
}
}
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (!cinfo->struct_ret) {
switch (mono_type_get_underlying_type (sig->ret)->type) {
sig = mono_method_signature (cfg->method);
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (cinfo->struct_ret) {
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
n = sig->param_count + sig->hasthis;
DEBUG (g_print ("Call requires: %d parameters\n",n));
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
stackSize = cinfo->sz.stack_size + cinfo->sz.local_size +
cinfo->sz.parm_size + cinfo->sz.offset;
/* ensure ins->sreg1 is not NULL */
s390_lg (code, s390_r0, 0, ins->sreg1, 0);
s390_ltgr (code, s390_r0, s390_r0);
+ EMIT_COND_SYSTEM_EXCEPTION (S390_CC_ZR, "NullReferenceException");
}
break;
case OP_ARGLIST: {
case MONO_PATCH_INFO_EXC:
case MONO_PATCH_INFO_ABS:
case MONO_PATCH_INFO_METHOD:
+ case MONO_PATCH_INFO_RGCTX_FETCH:
case MONO_PATCH_INFO_INTERNAL_METHOD:
case MONO_PATCH_INFO_CLASS_INIT:
+ case MONO_PATCH_INFO_JIT_ICALL_ADDR:
+ case MONO_PATCH_INFO_GENERIC_CLASS_INIT:
s390_patch_addr (ip, (guint64) target);
continue;
case MONO_PATCH_INFO_SWITCH:
int pos = 0, i;
CallInfo *cinfo;
- cinfo = get_call_info (NULL, NULL, sig, sig->pinvoke);
+ cinfo = get_call_info (NULL, NULL, sig);
if (cinfo->struct_ret) {
ArgInfo *ainfo = &cinfo->ret;
mono_emit_unwind_op_def_cfa_reg (cfg, code, cfg->frame_reg);
+ /* store runtime generic context */
+ if (cfg->rgctx_var) {
+ g_assert (cfg->rgctx_var->opcode == OP_REGOFFSET);
+
+ s390_stg (code, MONO_ARCH_RGCTX_REG, 0,
+ cfg->rgctx_var->inst_basereg,
+ cfg->rgctx_var->inst_offset);
+ }
+
/* compute max_offset in order to use short forward jumps
* we always do it on s390 because the immediate displacement
* for jumps is too small
sig = mono_method_signature (method);
pos = 0;
- cinfo = get_call_info (cfg, cfg->mempool, sig, sig->pinvoke);
+ cinfo = get_call_info (cfg, cfg->mempool, sig);
if (cinfo->struct_ret) {
ArgInfo *ainfo = &cinfo->ret;
/*========================= End of Function ========================*/
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_find_static_call_vtable */
+/* */
+/* Function - Find the static call vtable. */
+/* */
+/*------------------------------------------------------------------*/
+
+MonoVTable*
+mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
+{
+ mgreg_t *r = (mgreg_t*)regs;
+
+ return (MonoVTable*)(gsize) r [MONO_ARCH_RGCTX_REG];
+}
+
+/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_get_cie_program */
+/* */
+/* Function - Find the static call vtable. */
+/* */
+/*------------------------------------------------------------------*/
+
+GSList*
+mono_arch_get_cie_program (void)
+{
+ GSList *l = NULL;
+
+ mono_add_unwind_op_def_cfa (l, NULL, NULL, STK_BASE, 0);
+
+ return(l);
+}
+
+/*========================= End of Function ========================*/
+
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
/*------------------------------------------------------------------*/
#define MONO_ARCH_HAVE_TLS_GET 1
#define MONO_ARCH_ENABLE_MONO_LMF_VAR 1
#define MONO_ARCH_IMT_REG s390_r9
+#define MONO_ARCH_VTABLE_REG MONO_ARCH_IMT_REG
+#define MONO_ARCH_RGCTX_REG MONO_ARCH_IMT_REG
#define MONO_ARCH_THIS_AS_FIRST_ARG 1
#define MONO_ARCH_HAVE_XP_UNWIND 1
#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
#define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
#define MONO_ARCH_USE_SIGACTION 1
#define MONO_ARCH_GC_MAPS_SUPPORTED 1
+#define MONO_ARCH_GSHARED_SUPPORTED 1
+#define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT 1
#define S390_STACK_ALIGNMENT 8
#define S390_FIRST_ARG_REG s390_r2
#endif
void
-mono_arch_finish_init (void)
+mono_arch_tls_init (void)
{
+ MonoJitTlsData *jit_tls;
+
if (!lmf_addr_key_inited) {
int res;
}
+ jit_tls = pthread_getspecific (mono_get_jit_tls_key ());
+
#ifdef MONO_SPARC_THR_TLS
- thr_setspecific (lmf_addr_key, &tls->lmf);
+ thr_setspecific (lmf_addr_key, &jit_tls->lmf);
#else
- pthread_setspecific (lmf_addr_key, &tls->lmf);
+ pthread_setspecific (lmf_addr_key, &jit_tls->lmf);
#endif
}
+void
+mono_arch_finish_init (void)
+{
+}
+
void
mono_arch_free_jit_tls_data (MonoJitTlsData *tls)
{
#define MONO_ARCH_HAVE_IMT 1
#define MONO_ARCH_IMT_REG sparc_g1
#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
+#define MONO_ARCH_HAVE_TLS_INIT 1
+
+void mono_arch_tls_init (void);
#ifdef SPARCV9
#define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
jit_tls->lmf = lmf;
#endif
+#ifdef MONO_ARCH_HAVE_TLS_INIT
+ mono_arch_tls_init ();
+#endif
+
mono_setup_altstack (jit_tls);
return jit_tls;
gboolean gsharedvt = FALSE;
MonoGenericContainer *class_container, *method_container = NULL;
- if (method->is_generic || method->klass->generic_container) {
+ if (method->is_generic || (method->klass->generic_container && !method->is_inflated)) {
declaring_method = method;
} else {
declaring_method = mono_method_get_declaring_generic_method (method);
if (getenv ("MONO_DEBUG") != NULL)
mini_parse_debug_options ();
-
+
+ mono_code_manager_init ();
+
mono_arch_cpu_init ();
mono_arch_init ();
mono_install_imt_thunk_builder (mono_arch_build_imt_thunk);
}
#endif
+
/*Init arch tls information only after the metadata side is inited to make sure we see dynamic appdomain tls keys*/
mono_arch_finish_init ();
-
/* This must come after mono_init () in the aot-only case */
mono_exceptions_init ();
DeleteCriticalSection (&mono_delegate_section);
+ mono_code_manager_cleanup ();
+
#ifdef USE_JUMP_TABLES
mono_jumptable_cleanup ();
#endif
+++ /dev/null
-/*------------------------------------------------------------------*/
-/* */
-/* Name - tramp-s390.c */
-/* */
-/* Function - JIT trampoline code for S/390. */
-/* */
-/* Name - Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com) */
-/* */
-/* Date - January, 2004 */
-/* */
-/* Derivation - From exceptions-x86 & exceptions-ppc */
-/* Paolo Molaro (lupus@ximian.com) */
-/* Dietmar Maurer (dietmar@ximian.com) */
-/* */
-/* Copyright - 2001 Ximian, Inc. */
-/* */
-/*------------------------------------------------------------------*/
-
-/*------------------------------------------------------------------*/
-/* D e f i n e s */
-/*------------------------------------------------------------------*/
-
-#define GR_SAVE_SIZE 4*sizeof(long)
-#define FP_SAVE_SIZE 16*sizeof(double)
-#define METHOD_SAVE_OFFSET S390_MINIMAL_STACK_SIZE
-#define CREATE_GR_OFFSET METHOD_SAVE_OFFSET+sizeof(gpointer)
-#define CREATE_FP_OFFSET CREATE_GR_OFFSET+GR_SAVE_SIZE
-#define CREATE_LMF_OFFSET CREATE_FP_OFFSET+FP_SAVE_SIZE
-#define CREATE_STACK_SIZE (CREATE_LMF_OFFSET+2*sizeof(long)+sizeof(MonoLMF))
-
-/*------------------------------------------------------------------*/
-/* Specific trampoline code fragment sizes */
-/*------------------------------------------------------------------*/
-#define SPECIFIC_TRAMPOLINE_SIZE 64
-
-/*========================= End of Defines =========================*/
-
-/*------------------------------------------------------------------*/
-/* I n c l u d e s */
-/*------------------------------------------------------------------*/
-
-#include <config.h>
-#include <glib.h>
-#include <string.h>
-
-#include <mono/metadata/appdomain.h>
-#include <mono/metadata/marshal.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/arch/s390/s390-codegen.h>
-
-#include "mini.h"
-#include "mini-s390.h"
-
-/*========================= End of Includes ========================*/
-
-/*------------------------------------------------------------------*/
-/* T y p e d e f s */
-/*------------------------------------------------------------------*/
-
-/*========================= End of Typedefs ========================*/
-
-/*------------------------------------------------------------------*/
-/* P r o t o t y p e s */
-/*------------------------------------------------------------------*/
-
-/*========================= End of Prototypes ======================*/
-
-/*------------------------------------------------------------------*/
-/* G l o b a l V a r i a b l e s */
-/*------------------------------------------------------------------*/
-
-
-/*====================== End of Global Variables ===================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_unbox_trampoline */
-/* */
-/* Function - Return a pointer to a trampoline which does the */
-/* unboxing before calling the method. */
-/* */
-/* When value type methods are called through the */
-/* vtable we need to unbox the 'this' argument. */
-/* */
-/* Parameters - method - Methd pointer */
-/* addr - Pointer to native code for method */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_unbox_trampoline (MonoMethod *method, gpointer addr)
-{
- guint8 *code, *start;
- int this_pos = s390_r2;
- MonoDomain *domain = mono_domain_get ();
-
- start = addr;
- if (MONO_TYPE_ISSTRUCT (mono_method_signature (method)->ret))
- this_pos = s390_r3;
-
- start = code = mono_domain_code_reserve (domain, 28);
-
- s390_basr (code, s390_r13, 0);
- s390_j (code, 4);
- s390_word (code, addr);
- s390_l (code, s390_r1, 0, s390_r13, 4);
- s390_ahi (code, this_pos, sizeof(MonoObject));
- s390_br (code, s390_r1);
-
- g_assert ((code - start) <= 28);
-
- mono_arch_flush_icache (start, code - start);
-
- return start;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_patch_callsite */
-/* */
-/* Function - Patch a non-virtual callsite so it calls @addr. */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_patch_callsite (guint8 *method_start, guint8 *orig_code, guint8 *addr)
-{
- gint32 displace;
- unsigned short opcode;
-
- opcode = *((unsigned short *) (orig_code - 6));
- /* This should be a 'brasl' instruction */
- g_assert (opcode == 0xc0e5);
- orig_code -= 4;
- displace = ((gint32) addr - (gint32) (orig_code - 2)) / 2;
- s390_patch (orig_code, displace);
- mono_arch_flush_icache (orig_code, 4);
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_patch_plt_entry (guint8 *code, gpointer *got, mgreg_t *regs, guint8 *addr)
-{
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_nullify_class_init_trampoline */
-/* */
-/* Function - Nullify a call which calls a class init trampoline */
-/* */
-/*------------------------------------------------------------------*/
-
-void
-mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
-{
- char patch[6] = {0x47, 0x00, 0x00, 0x00, 0x07, 0x00};
-
- code = code - 6;
-
- memcpy(code, patch, sizeof(patch));
-}
-
-/*========================= End of Function ========================*/
-
-void
-mono_arch_nullify_plt_entry (guint8 *code, mgreg_t *regs)
-{
- g_assert_not_reached ();
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_get_vcall_slot */
-/* */
-/* Function - This method is called by the arch independent */
-/* trampoline code to determine the vtable slot used by */
-/* the call which invoked the trampoline. */
-/* The calls */
-/* generated by mono for S/390 will look like either:*/
-/* 1. l %r1,xxx(%rx) */
-/* bras %r14,%r1 */
-/* 2. brasl %r14,xxxxxx */
-/* */
-/* Parameters - code - Pointer into caller code */
-/* regs - Register state at the point of the call */
-/* displacement - Out parameter which will receive */
-/* the displacement of the vtable slot */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_get_vcall_slot (guint8 *code, mgreg_t *regs, int *displacement)
-{
- int reg;
- guchar* base;
- unsigned short opcode;
- char *sp;
-
- // We are passed sp instead of the register array
- sp = (char*)regs;
-
- *displacement = 0;
-
- opcode = *((unsigned short *) (code - 6));
- switch (opcode) {
- case 0x5810 :
- /* This is a bras r14,r1 instruction */
- code -= 4;
- reg = *code >> 4;
- *displacement = *((short *)code) & 0x0fff;
- if (reg > 5)
- base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(reg-6)));
- else
- base = *((guchar **) ((sp - CREATE_STACK_SIZE) +
- CREATE_GR_OFFSET +
- sizeof(int)*(reg-2)));
- return base;
- case 0x581d :
- /* l %r1,OFFSET(%r13,%r7) */
- code -= 4;
- reg = *code >> 4;
- *displacement = *((short *)code) & 0x0fff;
- if (reg > 5)
- base = *((guchar **) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(reg-6)));
- else
- base = *((guchar **) ((sp - CREATE_STACK_SIZE) +
- CREATE_GR_OFFSET +
- sizeof(int)*(reg-2)));
- base += *((guint32*) (sp + S390_REG_SAVE_OFFSET+
- sizeof(int)*(s390_r13-6)));
- return base;
- case 0xc0e5 :
- /* This is the 'brasl' instruction */
- return NULL;
- default :
- g_error("Unable to patch instruction prior to %p",code);
- }
-
- return NULL;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_trampoline_code */
-/* */
-/* Function - Create the designated type of trampoline according*/
-/* to the 'tramp_type' parameter. */
-/* */
-/*------------------------------------------------------------------*/
-
-guchar*
-mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInfo **info, gboolean aot)
-{
- guint8 *buf, *tramp, *code;
- int i, offset, lmfOffset;
-
- g_assert (!aot);
- if (info)
- *info = NULL;
-
- /* Now we'll create in 'buf' the S/390 trampoline code. This
- is the trampoline code common to all methods */
-
- code = buf = mono_global_codeman_reserve (512);
-
- /*-----------------------------------------------------------
- STEP 0: First create a non-standard function prologue with a
- stack size big enough to save our registers.
- -----------------------------------------------------------*/
-
- s390_stm (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- s390_lr (buf, s390_r11, s390_r15);
- s390_ahi (buf, STK_BASE, -CREATE_STACK_SIZE);
- s390_st (buf, s390_r11, 0, STK_BASE, 0);
- s390_st (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
- s390_stm (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
-
- /* Save the FP registers */
- offset = CREATE_FP_OFFSET;
- for (i = s390_f0; i <= s390_f15; ++i) {
- s390_std (buf, i, 0, STK_BASE, offset);
- offset += 8;
- }
-
- /*----------------------------------------------------------
- STEP 1: call 'mono_get_lmf_addr()' to get the address of our
- LMF. We'll need to restore it after the call to
- 's390_magic_trampoline' and before the call to the native
- method.
- ----------------------------------------------------------*/
-
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- s390_word (buf, mono_get_lmf_addr);
- s390_l (buf, s390_r1, 0, s390_r13, 4);
- s390_basr (buf, s390_r14, s390_r1);
-
- /*---------------------------------------------------------------*/
- /* we build the MonoLMF structure on the stack - see mini-s390.h */
- /* Keep in sync with the code in mono_arch_emit_prolog */
- /*---------------------------------------------------------------*/
- lmfOffset = CREATE_STACK_SIZE - sizeof(MonoLMF);
-
- s390_lr (buf, s390_r13, STK_BASE);
- s390_ahi (buf, s390_r13, lmfOffset);
-
- /*---------------------------------------------------------------*/
- /* Set lmf.lmf_addr = jit_tls->lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r2, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, lmf_addr));
-
- /*---------------------------------------------------------------*/
- /* Get current lmf */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r0, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Set our lmf as the current lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r13, 0, s390_r2, 0);
-
- /*---------------------------------------------------------------*/
- /* Have our lmf.previous_lmf point to the last lmf */
- /*---------------------------------------------------------------*/
- s390_st (buf, s390_r0, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, previous_lmf));
-
- /*---------------------------------------------------------------*/
- /* save method info */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r1, 0, STK_BASE, METHOD_SAVE_OFFSET);
- s390_st (buf, s390_r1, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, method));
-
- /*---------------------------------------------------------------*/
- /* save the current SP */
- /*---------------------------------------------------------------*/
- s390_l (buf, s390_r1, 0, STK_BASE, 0);
- s390_st (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
-
- /*---------------------------------------------------------------*/
- /* save the current IP */
- /*---------------------------------------------------------------*/
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lhi (buf, s390_r1, 0);
- } else {
- s390_l (buf, s390_r1, 0, s390_r1, S390_RET_ADDR_OFFSET);
- s390_la (buf, s390_r1, 0, s390_r1, 0);
- }
- s390_st (buf, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
-
- /*---------------------------------------------------------------*/
- /* Save general and floating point registers */
- /*---------------------------------------------------------------*/
- s390_stm (buf, s390_r2, s390_r12, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, gregs[2]));
- for (i = 0; i < 16; i++) {
- s390_std (buf, i, 0, s390_r13,
- G_STRUCT_OFFSET(MonoLMF, fregs[i]));
- }
-
- /*---------------------------------------------------------------*/
- /* STEP 2: call the C trampoline function */
- /*---------------------------------------------------------------*/
-
- /* Set arguments */
-
- /* Arg 1: mgreg_t *regs. We pass sp instead */
- s390_lr (buf, s390_r2, STK_BASE);
- s390_ahi (buf, s390_r2, CREATE_STACK_SIZE);
-
- /* Arg 2: code (next address to the instruction that called us) */
- if (tramp_type == MONO_TRAMPOLINE_JUMP) {
- s390_lhi (buf, s390_r3, 0);
- } else {
- s390_l (buf, s390_r3, 0, s390_r11, S390_RET_ADDR_OFFSET);
-
- /* Mask out bit 31 */
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- s390_word (buf, (~(1 << 31)));
- s390_n (buf, s390_r3, 0, s390_r13, 4);
- }
-
- /* Arg 3: MonoMethod *method. It was put in r1 by the
- method-specific trampoline code, and then saved before the call
- to mono_get_lmf_addr()'. */
- s390_l (buf, s390_r4, 0, STK_BASE, METHOD_SAVE_OFFSET);
-
- /* Arg 4: trampoline address. Ignore for now */
-
- /* Calculate call address and call the C trampoline. Return value will be in r2 */
- s390_basr (buf, s390_r13, 0);
- s390_j (buf, 4);
- tramp = (guint8*)mono_get_trampoline_func (tramp_type);
- s390_word (buf, tramp);
- s390_l (buf, s390_r1, 0, s390_r13, 4);
- s390_basr (buf, s390_r14, s390_r1);
-
- /* OK, code address is now on r2. Move it to r1, so that we
- can restore r2 and use it from r1 later */
- s390_lr (buf, s390_r1, s390_r2);
-
- /*----------------------------------------------------------
- STEP 3: Restore the LMF
- ----------------------------------------------------------*/
- restoreLMF(buf, STK_BASE, CREATE_STACK_SIZE);
-
- /*----------------------------------------------------------
- STEP 4: call the compiled method
- ----------------------------------------------------------*/
-
- /* Restore registers */
-
- s390_lm (buf, s390_r2, s390_r5, STK_BASE, CREATE_GR_OFFSET);
-
- /* Restore the FP registers */
- offset = CREATE_FP_OFFSET;
- for (i = s390_f0; i <= s390_f15; ++i) {
- s390_ld (buf, i, 0, STK_BASE, offset);
- offset += 8;
- }
-
- /* Restore stack pointer and jump to the code -
- R14 contains the return address to our caller */
- s390_lr (buf, STK_BASE, s390_r11);
- s390_lm (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
-
- if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT || tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
- s390_br (buf, s390_r14);
- else
- s390_br (buf, s390_r1);
-
- /* Flush instruction cache, since we've generated code */
- mono_arch_flush_icache (code, buf - code);
-
- /* Sanity check */
- g_assert ((buf - code) <= 512);
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_specific_trampoline */
-/* */
-/* Function - Creates the given kind of specific trampoline */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_specific_trampoline (gpointer arg1, MonoTrampolineType tramp_type, MonoDomain *domain, guint32 *code_len)
-{
- guint8 *code, *buf, *tramp;
- gint32 displace;
-
- tramp = mono_get_trampoline_code (tramp_type);
-
- /*----------------------------------------------------------*/
- /* This is the method-specific part of the trampoline. Its */
- /* purpose is to provide the generic part with the */
- /* MonoMethod *method pointer. We'll use r1 to keep it. */
- /*----------------------------------------------------------*/
- code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
-
- s390_basr (buf, s390_r1, 0);
- s390_j (buf, 4);
- s390_word (buf, arg1);
- s390_l (buf, s390_r1, 0, s390_r1, 4);
- displace = (tramp - buf) / 2;
- s390_jcl (buf, S390_CC_UN, displace);
-
- /* Flush instruction cache, since we've generated code */
- mono_arch_flush_icache (code, buf - code);
-
- /* Sanity check */
- g_assert ((buf - code) <= SPECIFIC_TRAMPOLINE_SIZE);
-
- if (code_len)
- *code_len = buf - code;
-
- return code;
-}
-
-/*========================= End of Function ========================*/
-
-gpointer
-mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
-{
- /* FIXME: implement! */
- g_assert_not_reached ();
- return NULL;
-}
#define CREATE_FP_OFFSET CREATE_GR_OFFSET+GR_SAVE_SIZE
#define CREATE_LMF_OFFSET CREATE_FP_OFFSET+FP_SAVE_SIZE
#define CREATE_STACK_SIZE (CREATE_LMF_OFFSET+2*sizeof(long)+sizeof(MonoLMF))
+#define GENERIC_REG_OFFSET CREATE_STACK_SIZE + \
+ S390_REG_SAVE_OFFSET + \
+ 3*sizeof(long)
/*------------------------------------------------------------------*/
/* Method-specific trampoline code fragment sizes */
s390_lg (buf, s390_r3, 0, s390_r11, S390_RET_ADDR_OFFSET);
}
- /* Arg 3: MonoMethod *method. It was put in r1 by the
- method-specific trampoline code, and then saved before the call
- to mono_get_lmf_addr()'. */
- s390_lg (buf, s390_r4, 0, STK_BASE, METHOD_SAVE_OFFSET);
+ /* Arg 3: Trampoline argument */
+ if (tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
+ s390_lg (buf, s390_r4, 0, STK_BASE, GENERIC_REG_OFFSET);
+ else
+ s390_lg (buf, s390_r4, 0, STK_BASE, METHOD_SAVE_OFFSET);
/* Arg 4: trampoline address. Ignore for now */
s390_lgr (buf, STK_BASE, s390_r11);
s390_lmg (buf, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
- if (tramp_type == MONO_TRAMPOLINE_CLASS_INIT || tramp_type == MONO_TRAMPOLINE_GENERIC_CLASS_INIT)
- s390_br (buf, s390_r14);
- else
- s390_br (buf, s390_r1);
+ if (MONO_TRAMPOLINE_TYPE_MUST_RETURN(tramp_type)) {
+ s390_lgr (buf, s390_r2, s390_r1);
+ s390_br (buf, s390_r14);
+ } else {
+ s390_br (buf, s390_r1);
+ }
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (code, buf - code);
s390_llong(buf, arg1);
s390_lg (buf, s390_r1, 0, s390_r1, 4);
displace = (tramp - buf) / 2;
- s390_jcl (buf, S390_CC_UN, displace);
+ s390_jg (buf, displace);
/* Flush instruction cache, since we've generated code */
mono_arch_flush_icache (code, buf - code);
gpointer
mono_arch_create_rgctx_lazy_fetch_trampoline (guint32 slot, MonoTrampInfo **info, gboolean aot)
{
- /* FIXME: implement! */
+#ifdef MONO_ARCH_VTABLE_REG
+ guint8 *tramp;
+ guint8 *code, *buf;
+ guint8 **rgctx_null_jumps;
+ gint32 displace;
+ int tramp_size,
+ depth,
+ index,
+ iPatch = 0,
+ i;
+ gboolean mrgctx;
+ MonoJumpInfo *ji = NULL;
+ GSList *unwind_ops = NULL;
+
+ mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
+ index = MONO_RGCTX_SLOT_INDEX (slot);
+ if (mrgctx)
+ index += MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT / sizeof (gpointer);
+ for (depth = 0; ; ++depth) {
+ int size = mono_class_rgctx_get_array_size (depth, mrgctx);
+
+ if (index < size - 1)
+ break;
+ index -= size - 1;
+ }
+
+ tramp_size = 48 + 16 * depth;
+ if (mrgctx)
+ tramp_size += 4;
+ else
+ tramp_size += 12;
+
+ code = buf = mono_global_codeman_reserve (tramp_size);
+
+ unwind_ops = mono_arch_get_cie_program ();
+
+ rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
+
+ if (mrgctx) {
+ /* get mrgctx ptr */
+ s390_lgr (code, s390_r1, s390_r2);
+ } else {
+ /* load rgctx ptr from vtable */
+ s390_lg (code, s390_r1, 0, s390_r2, G_STRUCT_OFFSET(MonoVTable, runtime_generic_context));
+ /* is the rgctx ptr null? */
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if yes, jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ }
+
+ for (i = 0; i < depth; ++i) {
+ /* load ptr to next array */
+ if (mrgctx && i == 0)
+ s390_lg (code, s390_r1, 0, s390_r1, MONO_SIZEOF_METHOD_RUNTIME_GENERIC_CONTEXT);
+ else
+ s390_lg (code, s390_r1, 0, s390_r1, 0);
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if the ptr is null then jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ }
+
+ /* fetch slot */
+ s390_lg (code, s390_r1, 0, s390_r1, (sizeof (gpointer) * (index + 1)));
+ /* is the slot null? */
+ s390_ltgr (code, s390_r1, s390_r1);
+ /* if yes, jump to actual trampoline */
+ rgctx_null_jumps [iPatch++] = code;
+ s390_jge (code, 0);
+ /* otherwise return r1 */
+ s390_lgr (code, s390_r2, s390_r1);
+ s390_br (code, s390_r14);
+
+ for (i = 0; i < iPatch; i++) {
+ displace = ((uintptr_t) code - (uintptr_t) rgctx_null_jumps[i]) / 2;
+ s390_patch_rel ((rgctx_null_jumps [i] + 2), displace);
+ }
+
+ g_free (rgctx_null_jumps);
+
+ /* move the rgctx pointer to the VTABLE register */
+ s390_lgr (code, MONO_ARCH_VTABLE_REG, s390_r2);
+
+ tramp = mono_arch_create_specific_trampoline (GUINT_TO_POINTER (slot),
+ MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
+
+ /* jump to the actual trampoline */
+ displace = (tramp - code) / 2;
+ s390_jg (code, displace);
+
+ mono_arch_flush_icache (buf, code - buf);
+
+ g_assert (code - buf <= tramp_size);
+
+ if (info)
+ *info = mono_tramp_info_create (mono_get_rgctx_fetch_trampoline_name (slot), buf, code - buf, ji, unwind_ops);
+
+ return(buf);
+#else
g_assert_not_reached ();
- return NULL;
+#endif
+ return(NULL);
+}
+
+/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_get_static_rgctx_trampoline */
+/* */
+/* Function - Create a trampoline which sets RGCTX_REG to MRGCTX*/
+/* then jumps to ADDR. */
+/* */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_get_static_rgctx_trampoline (MonoMethod *m,
+ MonoMethodRuntimeGenericContext *mrgctx,
+ gpointer addr)
+{
+ guint8 *code, *start;
+ gint32 displace;
+ int buf_len;
+
+ MonoDomain *domain = mono_domain_get ();
+
+ buf_len = 32;
+
+ start = code = mono_domain_code_reserve (domain, buf_len);
+
+ s390_basr (code, s390_r1, 0);
+ s390_j (code, 6);
+ s390_llong(code, mrgctx);
+ s390_lg (code, MONO_ARCH_RGCTX_REG, 0, s390_r1, 4);
+ displace = ((uintptr_t) addr - (uintptr_t) code) / 2;
+ s390_jg (code, displace);
+ g_assert ((code - start) < buf_len);
+
+ mono_arch_flush_icache (start, code - start);
+
+ return(start);
}
/*========================= End of Function ========================*/
+
+/*------------------------------------------------------------------*/
+/* */
+/* Name - mono_arch_create_generic_class_init_trampoline */
+/* */
+/* Function - */
+/* */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_create_generic_class_init_trampoline (MonoTrampInfo **info, gboolean aot)
+{
+ guint8 *tramp;
+ guint8 *code, *buf;
+ static int byte_offset = -1;
+ static guint8 bitmask;
+ guint8 *jump;
+ gint32 displace;
+ int tramp_size;
+ GSList *unwind_ops = NULL;
+ MonoJumpInfo *ji = NULL;
+
+ tramp_size = 48;
+
+ code = buf = mono_global_codeman_reserve (tramp_size);
+
+ unwind_ops = mono_arch_get_cie_program ();
+
+ if (byte_offset < 0)
+ mono_marshal_find_bitfield_offset (MonoVTable, initialized, &byte_offset, &bitmask);
+
+ s390_llgc(code, s390_r0, 0, MONO_ARCH_VTABLE_REG, byte_offset);
+ s390_nill(code, s390_r0, bitmask);
+ s390_bnzr(code, s390_r14);
+
+ tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_GENERIC_CLASS_INIT,
+ mono_get_root_domain (), NULL);
+
+ /* jump to the actual trampoline */
+ displace = (tramp - code) / 2;
+ s390_jg (code, displace);
+
+ mono_arch_flush_icache (buf, code - buf);
+
+ g_assert (code - buf <= tramp_size);
+
+ if (info)
+ *info = mono_tramp_info_create (g_strdup_printf ("generic_class_init_trampoline"), buf, code - buf, ji, unwind_ops);
+
+ return(buf);
+}
+
+/*========================= End of Function ========================*/
#include <mono/metadata/threads.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/loader.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#define LOCATION_INDENT " "
#define BACKTRACE_SIZE 64
{
MonoProfiler *prof = g_new0 (MonoProfiler, 1);
- mono_mutex_init (&mismatched_files_section, NULL);
+ mono_mutex_init (&mismatched_files_section);
prof->mismatched_files_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
prof->saved_strings_hash = g_hash_table_new (NULL, NULL);
prof->string_locations_hash = g_hash_table_new (mismatched_files_guint32_hash, mismatched_files_guint32_equal);
logbuffer = ensure_logbuf (20 + count * 8);
emit_byte (logbuffer, TYPE_SAMPLE | TYPE_SAMPLE_HIT);
emit_value (logbuffer, type);
- emit_uvalue (logbuffer, (prof->startup_time + sample [2]) * 10000);
+ emit_uvalue (logbuffer, prof->startup_time + (uint64_t)sample [2] * (uint64_t)10000);
emit_value (logbuffer, count);
for (i = 0; i < count; ++i) {
emit_ptr (logbuffer, (void*)sample [i + 3]);
$(MCS) -Warn:0 descriptor-tests.cs
descriptor-tests.cs : descriptor-tests-driver.cs descriptor-tests-prefix.cs gen-descriptor-tests.py
- ./gen-descriptor-tests.py >descriptor-tests.cs
+ -cp $^ .
+ $(srcdir)/gen-descriptor-tests.py >descriptor-tests.cs
EXTRA_DIST = descriptor-tests-driver.cs descriptor-tests-prefix.cs gen-descriptor-tests.py
//Console.WriteLine (new IntPtr (val));
return val;
}
+
+ public static bool pack_u2 (ushort us) {
+ return true;
+ }
+
+ public static bool pack_i2 (short value) {
+ int c = 0;
+ // Force 'value' to be register allocated
+ for (int i = 0; i < value; ++i)
+ c += value;
+ return value < 0x80;
+ }
+
+ // #11750
+ public static int test_0_i2_u2 () {
+ typeof (Tests).GetMethod ("pack_u2").Invoke (null, new object [] { (ushort)0 });
+ var res = typeof (Tests).GetMethod ("pack_i2").Invoke (null, new object [] { (short)-1 });
+ return (bool)res ? 0 : 1;
+ }
+
+ public static bool pack_bool (bool b) {
+ return true;
+ }
+
+ public static bool pack_i1 (sbyte value) {
+ int c = 0;
+ // Force 'value' to be register allocated
+ for (int i = 0; i < value; ++i)
+ c += value;
+ return value < -1;
+ }
+
+ public static int test_0_i1_bool () {
+ typeof (Tests).GetMethod ("pack_bool").Invoke (null, new object [] { true });
+ var res = typeof (Tests).GetMethod ("pack_i1").Invoke (null, new object [] { (sbyte)-0x40 });
+ return (bool)res ? 0 : 1;
+ }
}
mono-math.c \
mono-mmap.c \
mono-mmap.h \
+ mono-mutex.c \
+ mono-mutex.h \
mono-networkinterfaces.c \
mono-networkinterfaces.h \
mono-proclib.c \
return ret;
}
-#elif __s390__
+#elif __s390x__
static inline gint32
InterlockedCompareExchange(volatile gint32 *dest,
return(old);
}
-#ifndef __s390x__
-static inline gpointer
-InterlockedCompareExchangePointer(volatile gpointer *dest,
- gpointer exch, gpointer comp)
-{
- gpointer old;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "\tLR\t%1,%3\n"
- "\tCS\t%1,%2,0(1)\n"
- : "+m" (*dest), "=&r" (old)
- : "r" (exch), "r" (comp)
- : "1", "cc");
- return(old);
-}
-# else
static inline gpointer
InterlockedCompareExchangePointer(volatile gpointer *dest,
gpointer exch,
return(old);
}
-# endif
-
-# ifndef __s390x__
-static inline gint32
-InterlockedIncrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAHI\t1,1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
- return(tmp);
-}
-# else
static inline gint32
InterlockedIncrement(volatile gint32 *val)
{
return(tmp);
}
-# endif
-# ifndef __s390x__
-static inline gint32
-InterlockedDecrement(volatile gint32 *val)
-{
- gint32 tmp;
-
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAHI\t1,-1\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b\n"
- "\tLR\t%0,1"
- : "=r" (tmp), "+m" (*val)
- : : "1", "2", "cc");
-
- return(tmp);
-}
-# else
static inline gint32
InterlockedDecrement(volatile gint32 *val)
{
return(tmp);
}
-# endif
static inline gint32
InterlockedExchange(volatile gint32 *val, gint32 new_val)
return(ret);
}
-# ifndef __s390x__
-static inline gpointer
-InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
-{
- gpointer ret;
-
- __asm__ __volatile__ ("\tLA\t1,%0\n"
- "0:\tL\t%1,%0\n"
- "\tCS\t%1,%2,0(1)\n"
- "\tJNZ\t0b"
- : "+m" (*val), "=&r" (ret)
- : "r" (new_val)
- : "1", "cc");
-
- return(ret);
-}
-# else
static inline gpointer
InterlockedExchangePointer(volatile gpointer *val, gpointer new_val)
{
return(ret);
}
-# endif
-
-# ifndef __s390x__
-static inline gint32
-InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
-{
- gint32 ret;
- __asm__ __volatile__ ("\tLA\t2,%1\n"
- "0:\tL\t%0,%1\n"
- "\tLR\t1,%0\n"
- "\tAR\t1,%2\n"
- "\tCS\t%0,1,0(2)\n"
- "\tJNZ\t0b"
- : "=&r" (ret), "+m" (*val)
- : "r" (add)
- : "1", "2", "cc");
-
- return(ret);
-}
-# else
static inline gint32
InterlockedExchangeAdd(volatile gint32 *val, gint32 add)
{
return(ret);
}
-# endif
#elif defined(__mono_ppc__)
#endif /* __native_client_codegen && __native_client__ */
+#define VALLOC_FREELIST_SIZE 16
+
+static CRITICAL_SECTION valloc_mutex;
+static GHashTable *valloc_freelists;
+
+static void*
+codechunk_valloc (guint32 size)
+{
+ void *ptr;
+ GSList *freelist;
+
+ if (!valloc_freelists) {
+ InitializeCriticalSection (&valloc_mutex);
+ valloc_freelists = g_hash_table_new (NULL, NULL);
+ }
+
+ /*
+ * Keep a small freelist of memory blocks to decrease pressure on the kernel memory subsystem to avoid #3321.
+ */
+ EnterCriticalSection (&valloc_mutex);
+ freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+ if (freelist) {
+ ptr = freelist->data;
+ memset (ptr, 0, size);
+ freelist = g_slist_remove_link (freelist, freelist);
+ g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
+ } else {
+ ptr = mono_valloc (NULL, size + MIN_ALIGN - 1, MONO_PROT_RWX | ARCH_MAP_FLAGS);
+ }
+ LeaveCriticalSection (&valloc_mutex);
+ return ptr;
+}
+
+static void
+codechunk_vfree (void *ptr, guint32 size)
+{
+ GSList *freelist;
+
+ EnterCriticalSection (&valloc_mutex);
+ freelist = g_hash_table_lookup (valloc_freelists, GUINT_TO_POINTER (size));
+ if (!freelist || g_slist_length (freelist) < VALLOC_FREELIST_SIZE) {
+ freelist = g_slist_prepend (freelist, ptr);
+ g_hash_table_insert (valloc_freelists, GUINT_TO_POINTER (size), freelist);
+ } else {
+ mono_vfree (ptr, size);
+ }
+ LeaveCriticalSection (&valloc_mutex);
+}
+
+static void
+codechunk_cleanup (void)
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ if (!valloc_freelists)
+ return;
+ g_hash_table_iter_init (&iter, valloc_freelists);
+ while (g_hash_table_iter_next (&iter, &key, &value)) {
+ GSList *freelist = value;
+ GSList *l;
+
+ for (l = freelist; l; l = l->next) {
+ mono_vfree (l->data, GPOINTER_TO_UINT (key));
+ }
+ g_slist_free (freelist);
+ }
+ g_hash_table_destroy (valloc_freelists);
+}
+
+void
+mono_code_manager_init (void)
+{
+}
+
+void
+mono_code_manager_cleanup (void)
+{
+ codechunk_cleanup ();
+}
+
/**
* mono_code_manager_new:
*
mono_profiler_code_chunk_destroy ((gpointer) dead->data);
chunk = chunk->next;
if (dead->flags == CODE_FLAG_MMAP) {
- mono_vfree (dead->data, dead->size);
+ codechunk_vfree (dead->data, dead->size);
/* valgrind_unregister(dead->data); */
} else if (dead->flags == CODE_FLAG_MALLOC) {
dlfree (dead->data);
/* Allocate MIN_ALIGN-1 more than we need so we can still */
/* guarantee MIN_ALIGN alignment for individual allocs */
/* from mono_code_manager_reserve_align. */
- ptr = mono_valloc (NULL, chunk_size + MIN_ALIGN - 1, MONO_PROT_RWX | ARCH_MAP_FLAGS);
+ ptr = codechunk_valloc (chunk_size);
if (!ptr)
return NULL;
}
void* mono_code_manager_reserve (MonoCodeManager *cman, int size);
void mono_code_manager_commit (MonoCodeManager *cman, void *data, int size, int newsize);
int mono_code_manager_size (MonoCodeManager *cman, int *used_size);
+void mono_code_manager_init (void);
+void mono_code_manager_cleanup (void);
/* find the extra block allocated to resolve branches close to code */
typedef int (*MonoCodeManagerFunc) (void *data, int csize, int size, void *user_data);
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include "mono-mutex.h"
+
+#ifndef HOST_WIN32
+
+#if defined(__APPLE__)
+#define _DARWIN_C_SOURCE
+// #include <pthread_spis.h>
+#endif
+
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+/* Android does not implement pthread_mutex_timedlock(), but does provide an
+ * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
+ */
+#ifdef PLATFORM_ANDROID
+#define CONST_NEEDED
+#else
+#define CONST_NEEDED const
+#endif
+
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+ CONST_NEEDED struct timespec *timeout);
+int
+pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
+{
+ struct timeval timenow;
+ struct timespec sleepytime;
+ int retcode;
+
+ /* This is just to avoid a completely busy wait */
+ sleepytime.tv_sec = 0;
+ sleepytime.tv_nsec = 10000000; /* 10ms */
+
+ while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
+ gettimeofday (&timenow, NULL);
+
+ if (timenow.tv_sec >= timeout->tv_sec &&
+ (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
+ return ETIMEDOUT;
+ }
+
+ nanosleep (&sleepytime, NULL);
+ }
+
+ return retcode;
+}
+#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
+
+
+int
+mono_once (mono_once_t *once, void (*once_init) (void))
+{
+ int thr_ret;
+
+ if (!once->complete) {
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&once->mutex);
+ thr_ret = pthread_mutex_lock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ if (!once->complete) {
+ once_init ();
+ once->complete = TRUE;
+ }
+ thr_ret = pthread_mutex_unlock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+ }
+
+ return 0;
+}
+
+#endif
+
+/*
+Returns a recursive mutex that is safe under suspension.
+
+A suspension safe mutex means one that can handle this scenario:
+
+mutex M
+
+thread 1:
+1)lock M
+2)suspend thread 2
+3)unlock M
+4)lock M
+
+thread 2:
+5)lock M
+
+Say (1) happens before (5) and (5) happens before (2).
+This means that thread 2 was suspended by the kernel because
+it's waiting on mutext M.
+
+Thread 1 then proceed to suspend thread 2 and unlock/lock the
+mutex.
+
+If the kernel implements mutexes with FIFO wait lists, this means
+that thread 1 will be blocked waiting for thread 2 acquire the lock.
+Since thread 2 is suspended, we have a deadlock.
+
+A suspend safe mutex is an unfair lock but will schedule any runable
+thread that is waiting for a the lock.
+
+This problem was witnessed on OSX in mono/tests/thread-exit.cs.
+
+*/
+int
+mono_mutex_init_suspend_safe (mono_mutex_t *mutex)
+{
+#if defined(__APPLE__)
+ int res;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ // pthread_mutexattr_setpolicy_np (&attr, _PTHREAD_MUTEX_POLICY_FIRSTFIT);
+ res = pthread_mutex_init (mutex, &attr);
+ pthread_mutexattr_destroy (&attr);
+
+ return res;
+#else
+ return mono_mutex_init (mutex);
+#endif
+}
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifndef __MONO_MUTEX_H__
+#define __MONO_MUTEX_H__
+
+#include <glib.h>
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <time.h>
+
+#ifdef HOST_WIN32
+#include <windows.h>
+#endif
+
+G_BEGIN_DECLS
+
+#ifndef HOST_WIN32
+
+typedef struct {
+ pthread_mutex_t mutex;
+ gboolean complete;
+} mono_once_t;
+
+#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
+
+int mono_once (mono_once_t *once, void (*once_init) (void));
+
+typedef pthread_mutex_t mono_mutex_t;
+typedef pthread_cond_t mono_cond_t;
+
+#define mono_mutex_init(mutex) pthread_mutex_init (mutex, NULL)
+#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
+#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
+#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
+#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
+#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
+
+#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
+#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
+#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
+#define mono_cond_signal(cond) pthread_cond_signal (cond)
+#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
+
+/* This is a function so it can be passed to pthread_cleanup_push -
+ * that is a macro and giving it a macro as a parameter breaks.
+ */
+G_GNUC_UNUSED
+static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
+{
+ return(mono_mutex_unlock (mutex));
+}
+
+/* Returns zero on success. */
+static inline int
+mono_mutex_init_recursive (mono_mutex_t *mutex)
+{
+ int res;
+ pthread_mutexattr_t attr;
+
+ pthread_mutexattr_init (&attr);
+ pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ res = pthread_mutex_init (mutex, &attr);
+ pthread_mutexattr_destroy (&attr);
+
+ return res;
+}
+
+#else
+
+typedef CRITICAL_SECTION mono_mutex_t;
+typedef HANDLE mono_cond_t;
+
+#define mono_mutex_init(mutex) (InitializeCriticalSection((mutex)), 0)
+#define mono_mutex_init_recursive(mutex) (InitializeCriticalSection((mutex)), 0)
+#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
+#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
+#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
+#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
+
+
+#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
+#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
+#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
+#define mono_cond_signal(cond) SetEvent(*(cond))
+#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
+#define mono_cond_destroy(cond) CloseHandle(*(cond))
+
+#endif
+
+int mono_mutex_init_suspend_safe (mono_mutex_t *mutex);
+
+G_END_DECLS
+
+#endif /* __MONO_MUTEX_H__ */
void *(*start_func)(void*) = start_info->start_routine;
void *result;
- mono_thread_info_attach (&result);
+ mono_thread_info_attach (&result)->runtime_thread = TRUE;
post_result = MONO_SEM_POST (&(start_info->registered));
g_assert (!post_result);
result = start_func (t_arg);
g_assert (!mono_domain_get ());
+ mono_thread_info_dettach ();
return result;
}
gboolean suspend = start_info->suspend;
HANDLE suspend_event = start_info->suspend_event;
- mono_thread_info_attach (&result);
+ mono_thread_info_attach (&result)->runtime_thread = TRUE;
post_result = MONO_SEM_POST (&(start_info->registered));
g_assert (!post_result);
g_assert (!mono_domain_get ());
+ mono_thread_info_dettach ();
+
return result;
}
a runtime suspend won't make it wronly see a thread in a safepoint
when it is in fact not.
*/
-static CRITICAL_SECTION global_suspend_lock;
+static mono_mutex_t global_suspend_lock;
static int thread_info_size;
{
MonoThreadInfo *info = mem;
- DeleteCriticalSection (&info->suspend_lock);
+ mono_mutex_destroy (&info->suspend_lock);
MONO_SEM_DESTROY (&info->resume_semaphore);
MONO_SEM_DESTROY (&info->finish_resume_semaphore);
mono_threads_platform_free (info);
mono_thread_info_set_tid (info, mono_native_thread_id_get ());
info->small_id = small_id;
- InitializeCriticalSection (&info->suspend_lock);
+ mono_mutex_init_suspend_safe (&info->suspend_lock);
MONO_SEM_INIT (&info->resume_semaphore, 0);
MONO_SEM_INIT (&info->finish_resume_semaphore, 0);
if (info) {
THREADS_DEBUG ("detaching %p\n", info);
unregister_thread (info);
+ mono_native_tls_set_value (thread_info_key, NULL);
}
}
res = mono_native_tls_alloc (&small_id_key, NULL);
g_assert (res);
- InitializeCriticalSection (&global_suspend_lock);
+ mono_mutex_init_suspend_safe (&global_suspend_lock);
mono_lls_init (&thread_list, NULL);
mono_thread_smr_init ();
if (!info)
return NULL;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
/*thread is on the process of detaching*/
if (mono_thread_info_run_state (info) > STATE_RUNNING) {
if (info->suspend_count) {
++info->suspend_count;
mono_hazard_pointer_clear (hp, 1);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
return info;
}
if (!mono_threads_core_suspend (info)) {
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return NULL;
}
++info->suspend_count;
info->thread_state |= STATE_SUSPENDED;
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return info;
if (!info)
return;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
THREADS_DEBUG ("self suspend IN COUNT %d\n", info->suspend_count);
ret = mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->suspend_state, NULL);
g_assert (ret);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
while (MONO_SEM_WAIT (&info->resume_semaphore) != 0) {
/*if (EINTR != errno) ABORT("sem_wait failed"); */
if (!info)
return FALSE;
- EnterCriticalSection (&info->suspend_lock);
+ mono_mutex_lock (&info->suspend_lock);
THREADS_DEBUG ("resume %x IN COUNT %d\n",tid, info->suspend_count);
if (info->suspend_count <= 0) {
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return FALSE;
}
if (--info->suspend_count == 0)
result = mono_thread_info_resume_internal (info);
- LeaveCriticalSection (&info->suspend_lock);
+ mono_mutex_unlock (&info->suspend_lock);
mono_hazard_pointer_clear (hp, 1);
return result;
void
mono_thread_info_suspend_lock (void)
{
- EnterCriticalSection (&global_suspend_lock);
+ mono_mutex_lock (&global_suspend_lock);
}
void
mono_thread_info_suspend_unlock (void)
{
- LeaveCriticalSection (&global_suspend_lock);
+ mono_mutex_unlock (&global_suspend_lock);
}
void
#include <mono/utils/mono-semaphore.h>
#include <mono/utils/mono-stack-unwinding.h>
#include <mono/utils/mono-linked-list-set.h>
-
-/* FIXME used for CRITICAL_SECTION replace with mono-mutex */
-#include <mono/io-layer/io-layer.h>
+#include <mono/utils/mono-mutex.h>
#include <glib.h>
MonoNativeThreadHandle native_handle; /* Valid on mach and android */
int thread_state;
+ /*Tells if this thread was created by the runtime or not.*/
+ gboolean runtime_thread;
+
/* suspend machinery, fields protected by the suspend_lock */
- CRITICAL_SECTION suspend_lock;
+ mono_mutex_t suspend_lock;
int suspend_count;
MonoSemType finish_resume_semaphore;
<ClCompile Include="..\mono\metadata\sgen-os-mach.c" />\r
<ClCompile Include="..\mono\metadata\sgen-os-posix.c" />\r
<ClCompile Include="..\mono\metadata\sgen-os-win32.c" />\r
- <ClCompile Include="..\mono\metadata\sgen-pinned-allocator.c" />\r
<ClCompile Include="..\mono\metadata\sgen-pinning-stats.c" />\r
<ClCompile Include="..\mono\metadata\sgen-pinning.c" />\r
<ClCompile Include="..\mono\metadata\sgen-protocol.c" />\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<ImportGroup Label="ExtensionTargets">\r
</ImportGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
@$(MAKE) dist2
# This is a separate target because 'update-po' must be executed before.
dist2: stamp-po $(DISTFILES)
+ mkdir -p $(distdir)
dists="$(DISTFILES)"; \
if test "$(PACKAGE)" = "gettext-tools"; then \
dists="$$dists Makevars.template"; \
} while ((r = getpwuid_r (uid, &_pwbuf, buf, buflen, (struct passwd**) pwbufp)) &&
recheck_range (r));
+ if (r == 0 && !(*pwbufp))
+ /* On solaris, this function returns 0 even if the entry was not found */
+ r = errno = ENOENT;
+
if (r == 0 && copy_passwd (pwbuf, &_pwbuf) == -1)
r = errno = ENOMEM;
free (buf);