[runtime] Fix test_op_il_seq_point in amd64.
parallel_mark=yes
ikvm_native=yes
-case "$host" in
- powerpc*-*-linux*)
- # https://bugzilla.novell.com/show_bug.cgi?id=504411
- disable_munmap=yes
- ;;
-esac
-
host_win32=no
target_win32=no
platform_android=no
-platform_darwin=no
+host_darwin=no
case "$host" in
*-mingw*|*-*-cygwin*)
AC_DEFINE(DISABLE_PORTABILITY,1,[Disable the io-portability layer])
libgc_configure_args="$libgc_configure_args --enable-win32-dllmain=yes"
;;
*-*-*netbsd*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -D_REENTRANT -DGC_NETBSD_THREADS -D_GNU_SOURCE"
libmono_cflags="-D_REENTRANT"
LDFLAGS="$LDFLAGS -pthread"
use_sigposix=yes
;;
*-*-kfreebsd*-gnu)
- host_win32=no
CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP -DUSE_MUNMAP -DTHREAD_LOCAL_ALLOC -pthread"
libmono_cflags="-D_REENTRANT -DTHREAD_LOCAL_ALLOC -pthread"
libmono_ldflags="-lpthread -pthread"
use_sigposix=yes
;;
*-*-*freebsd*)
- host_win32=no
if test "x$PTHREAD_CFLAGS" = "x"; then
CPPFLAGS="$CPPFLAGS -DGC_FREEBSD_THREADS"
libmono_cflags=
has_dtrace=yes
;;
*-*-*openbsd*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_OPENBSD_THREADS -DPLATFORM_BSD -D_REENTRANT -DUSE_MMAP"
if test "x$disable_munmap" != "xyes"; then
CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
use_sigposix=yes
;;
*-*-linux-android*)
- host_win32=no
platform_android=yes
AC_DEFINE(PLATFORM_ANDROID,1,[Targeting the Android platform])
AC_DEFINE(TARGET_ANDROID,1,[Targeting the Android platform])
mono_cv_clang=no
;;
*-*-linux*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
if test "x$disable_munmap" != "xyes"; then
CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
support_boehm=no
with_gc=sgen
;;
+ powerpc*-*-linux*)
+ # https://bugzilla.novell.com/show_bug.cgi?id=504411
+ disable_munmap=yes
+ ;;
esac
;;
*-*-nacl*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -DGC_LINUX_THREADS -D_GNU_SOURCE -D_REENTRANT -DUSE_MMAP"
if test "x$disable_munmap" != "xyes"; then
CPPFLAGS="$CPPFLAGS -DUSE_MUNMAP"
AC_DEFINE(DISABLE_ATTACH, 1, [Disable agent attach support])
;;
*-*-hpux*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -DGC_HPUX_THREADS -D_HPUX_SOURCE -D_XOPEN_SOURCE_EXTENDED -D_REENTRANT"
# +ESdbgasm only valid on bundled cc on RISC
# silently ignored for ia64
use_sigposix=yes
;;
*-*-solaris*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -DGC_SOLARIS_THREADS -DGC_SOLARIS_PTHREADS -D_REENTRANT -D_POSIX_PTHREAD_SEMANTICS -DUSE_MMAP -DUSE_MUNMAP -DPLATFORM_SOLARIS"
need_link_unlink=yes
libmono_cflags="-D_REENTRANT"
;;
*-*-darwin*)
parallel_mark="Disabled_Currently_Hangs_On_MacOSX"
- host_win32=no
- platform_darwin=yes
+ host_darwin=yes
target_mach=yes
CPPFLAGS="$CPPFLAGS -D_THREAD_SAFE -DGC_MACOSX_THREADS -DPLATFORM_MACOSX -DUSE_MMAP -DUSE_MUNMAP"
libmono_cflags="-D_THREAD_SAFE"
esac
;;
*-*-haiku*)
- host_win32=no
CPPFLAGS="$CPPFLAGS -D_REENTRANT -D_THREAD_SAFE"
libmono_cflags="-D_REENTRANT -D_THREAD_SAFE"
libdl=
;;
*)
AC_MSG_WARN([*** Please add $host to configure.ac checks!])
- host_win32=no
libdl="-ldl"
;;
esac
AC_SUBST(extra_runtime_ldflags)
AM_CONDITIONAL(HOST_WIN32, test x$host_win32 = xyes)
AM_CONDITIONAL(TARGET_WIN32, test x$target_win32 = xyes)
-AM_CONDITIONAL(PLATFORM_GNU, echo x$target_os | grep -q -- -gnu)
AM_CONDITIONAL(PLATFORM_LINUX, echo x$target_os | grep -q linux)
-AM_CONDITIONAL(PLATFORM_DARWIN, test x$platform_darwin = xyes)
+AM_CONDITIONAL(PLATFORM_DARWIN, test x$host_darwin = xyes)
AM_CONDITIONAL(PLATFORM_SIGPOSIX, test x$use_sigposix = xyes)
AM_CONDITIONAL(PLATFORM_ANDROID, test x$platform_android = xyes)
GLIB_CFLAGS='-I$(top_srcdir)/eglib/src -I$(top_builddir)/eglib/src'
GLIB_LIBS='-L$(top_builddir)/eglib/src -leglib -lm'
-BUILD_GLIB_CFLAGS="$GLIB_CFLAGS"
-BUILD_GLIB_LIBS="$GLIB_LIBS"
-GMODULE_CFLAGS="$GLIB_CFLAGS"
-GMODULE_LIBS="$GLIB_LIBS"
AC_SUBST(GLIB_CFLAGS)
AC_SUBST(GLIB_LIBS)
-AC_SUBST(GMODULE_CFLAGS)
-AC_SUBST(GMODULE_LIBS)
-AC_SUBST(BUILD_GLIB_CFLAGS)
-AC_SUBST(BUILD_GLIB_LIBS)
# Enable support for fast thread-local storage
# Some systems have broken support, so we allow to disable it.
AC_MSG_NOTICE([Enabling mono extension module.])
fi
-AC_ARG_ENABLE(gsharing, [ --enable-gsharing Enable gsharing], enable_gsharing=$enableval, enable_gsharing=no)
-if test x$enable_gsharing = xyes; then
- AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharing])
-fi
-
-# A synonym
AC_ARG_ENABLE(gsharedvt, [ --enable-gsharedvt Enable generic valuetype sharing], enable_gsharedvt=$enableval, enable_gsharedvt=no)
if test x$enable_gsharedvt = xyes; then
AC_DEFINE(ENABLE_GSHAREDVT,1,[Gsharedvt])
dnl * back
dnl **************************************
if test "x$havekqueue" = "xyes" -a "x$ac_cv_header_sys_event_h" = "xyes"; then
- if test "x$platform_darwin" = "xno"; then
+ if test "x$host_darwin" = "xno"; then
AC_DEFINE(USE_KQUEUE_FOR_THREADPOOL, 1, [Use kqueue for the threadpool])
fi
fi
AC_CHECK_FUNCS(readv writev preadv pwritev)
AC_CHECK_FUNCS(setpgid)
AC_CHECK_FUNCS(system)
+ AC_CHECK_FUNCS(fork execv execve)
AC_CHECK_SIZEOF(size_t)
AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], ,
[#include <sys/types.h>
#include <fcntl.h>])
AC_CHECK_TYPES([struct iovec], [AC_DEFINE(HAVE_STRUCT_IOVEC)], ,
[#include <sys/uio.h>])
+ AC_CHECK_TYPES([struct linger], [AC_DEFINE(HAVE_STRUCT_LINGER)], ,
+ [#include <sys/socket.h>])
AC_CHECK_TYPES([struct pollfd], [AC_DEFINE(HAVE_STRUCT_POLLFD)], ,
[#include <sys/poll.h>])
AC_CHECK_TYPES([struct stat], [AC_DEFINE(HAVE_STRUCT_STAT)], ,
#endif
])
AC_CHECK_HEADERS([termios.h])
-
- dnl * This is provided in io-layer, but on windows it's only available
- dnl * on xp+
- AC_DEFINE(HAVE_GETPROCESSID, 1, [Define if GetProcessId is available])
else
dnl *********************************
dnl *** Checks for Windows compilation ***
AC_CHECK_DECLS(InterlockedAdd, [], [], [[#include <windows.h>]])
AC_CHECK_DECLS(InterlockedAdd64, [], [], [[#include <windows.h>]])
AC_CHECK_DECLS(__readfsdword, [], [], [[#include <windows.h>]])
-
- AC_MSG_CHECKING(for GetProcessId)
- AC_TRY_COMPILE([#include <windows.h>], [
- GetProcessId (0);
- ], [
- AC_MSG_RESULT(yes)
- AC_DEFINE(HAVE_GETPROCESSID)
- ], [
- AC_MSG_RESULT(no)
- ])
fi
dnl socklen_t check
AC_CHECK_LIB(sunmath, aintl, [ AC_DEFINE(HAVE_AINTL, 1, [Has the 'aintl' function]) LIBS="$LIBS -lsunmath"])
fi
-AC_CHECK_FUNCS(round)
-AC_CHECK_FUNCS(rint)
AC_CHECK_FUNCS(execvp)
dnl ****************************
sizeof_register="SIZEOF_VOID_P"
jit_wanted=true
-sgen_supported=false
boehm_supported=true
case "$host" in
mips*)
TARGET=MIPS;
arch_target=mips;
- sgen_supported=true
ACCESS_UNALIGNED="no"
AC_MSG_CHECKING(for mips n32)
# foo.c:6: warning: visibility attribute not supported in this configuration; ignored
# ld: fatal: relocation error: R_386_GOTOFF: file /var/tmp//ccxYR96k.o: symbol astruct: relocation must bind locally
have_visibility_hidden=no
- sgen_supported=true
;;
mingw*|cygwin*)
- sgen_supported=true
have_visibility_hidden=no
;;
haiku*)
LIBC=libroot.so
;;
linux*)
- sgen_supported=true
AOT_SUPPORTED="yes"
;;
darwin*)
- sgen_supported=true
AOT_SUPPORTED="yes"
;;
openbsd*|freebsd*|kfreebsd-gnu*)
- sgen_supported=true
;;
esac
;;
fi
case $host_os in
linux*)
- sgen_supported=true
AOT_SUPPORTED="yes"
;;
darwin*)
- sgen_supported=true
AOT_SUPPORTED="yes"
;;
openbsd*|freebsd*|kfreebsd-gnu*)
- sgen_supported=true
;;
mingw*)
- sgen_supported=true
;;
esac
case "$host" in
if test x"$AR" = xfalse; then
AC_MSG_ERROR([The required utility 'ar' is not found in your PATH. Usually it can be found in /usr/ccs/bin.])
fi
- sgen_supported=true
;;
*-mingw*|*-*-cygwin*)
# When this is enabled, it leads to very strange crashes at runtime (gcc-3.4.4)
arch_target=ppc;
case $host_os in
linux*|darwin*)
- sgen_supported=true
;;
esac
;;
+ armv7k-*-darwin*)
+ TARGET=ARM;
+ TARGET_SYS=WATCHOS
+ arch_target=arm;
+ ACCESS_UNALIGNED="no"
+ CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
+ ;;
+
arm*-darwin*)
TARGET=ARM;
arch_target=arm;
ACCESS_UNALIGNED="no"
CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
- sgen_supported=true
;;
arm*-linux*)
TARGET=ARM;
arch_target=arm;
ACCESS_UNALIGNED="no"
- sgen_supported=true
AOT_SUPPORTED="yes"
CPPFLAGS="$CPPFLAGS -D__ARM_EABI__"
;;
# TARGET=ARM;
# arch_target=arm;
# ACCESS_UNALIGNED="no"
-# sgen_supported=true
# AOT_SUPPORTED="no"
# ;;
aarch64-*)
# https://lkml.org/lkml/2012/7/15/133
TARGET=ARM64
arch_target=arm64
- sgen_supported=true
boehm_supported=false
;;
s390x-*-linux*)
TARGET=S390X;
arch_target=s390x;
ACCESS_UNALIGNED="yes"
- sgen_supported=true
CFLAGS="$CFLAGS -mbackchain -D__USE_STRING_INLINES"
;;
esac
# Can't use tls, since it depends on the runtime detection of tls offsets
# in mono-compiler.h
with_tls=pthread
+ case "$target" in
+ armv7k-*)
+ AC_DEFINE(TARGET_WATCHOS, 1, [...])
+ ;;
+ esac
;;
powerpc64-ps3-linux-gnu)
TARGET=POWERPC64
AC_DEFINE(TARGET_X86, 1, [...])
AC_DEFINE(TARGET_ANDROID, 1, [...])
CPPFLAGS="$CPPFLAGS"
- sgen_supported=true
# Can't use tls, since it depends on the runtime detection of tls offsets
# in mono-compiler.h
with_tls=pthread
AC_DEFINE(TARGET_AMD64, 1, [...])
AC_DEFINE(TARGET_ANDROID, 1, [...])
CPPFLAGS="$CPPFLAGS"
- sgen_supported=true
# Can't use tls, since it depends on the runtime detection of tls offsets
# in mono-compiler.h
with_tls=pthread
AC_DEFINE(TARGET_AMD64, 1, [...])
AC_DEFINE(TARGET_PS4, 1, [...])
CPPFLAGS="$CPPFLAGS"
- sgen_supported=true
# Can't use tls, since it depends on the runtime detection of tls offsets
# in mono-compiler.h
with_tls=pthread
fi
if test "x$target_mach" = "xyes"; then
- if test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64"; then
+
+ if test "x$TARGET_SYS" = "xWATCHOS"; then
+ AC_DEFINE(TARGET_WATCHOS,1,[The JIT/AOT targets WatchOS])
+ CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
+ CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_WATCHOS"
+ elif test "x$TARGET" = "xARM" -o "x$TARGET" = "xARM64"; then
AC_DEFINE(TARGET_IOS,1,[The JIT/AOT targets iOS])
CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DTARGET_IOS"
CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC -DTARGET_IOS"
dnl
dnl Simple Generational checks (sgen)
dnl
-if $sgen_supported; then
- build_sgen_default=yes
-else
- build_sgen_default=no
-fi
SGEN_DEFINES=
-AC_ARG_WITH(sgen, [ --with-sgen=yes,no Extra Generational GC, default=yes],[buildsgen=$with_sgen],[buildsgen=$build_sgen_default])
+AC_ARG_WITH(sgen, [ --with-sgen=yes,no Extra Generational GC, default=yes],[buildsgen=$with_sgen],[buildsgen=yes])
if test x$buildsgen = xyes; then
- if $sgen_supported; then
- SGEN_DEFINES="-DHAVE_SGEN_GC -DHAVE_MOVING_COLLECTOR"
- gc_msg="sgen and $gc_msg"
- else
- buildsgen=no
- AC_MSG_WARN("Sgen is not supported on this platform")
- fi
+ SGEN_DEFINES="-DHAVE_SGEN_GC -DHAVE_MOVING_COLLECTOR"
+ gc_msg="sgen and $gc_msg"
fi
AC_SUBST(SGEN_DEFINES)
AM_CONDITIONAL(SUPPORT_SGEN, test x$buildsgen = xyes)
fpu=NONE
# iOS GCC always uses the 'softfp' ABI.
- if test x"$GCC" = xyes && test x$platform_darwin = xyes; then
+ if test x"$GCC" = xyes && test x$host_darwin = xyes; then
fpu=VFP
fi
;;
esac
-AC_ARG_WITH(profile4_x,[ --with-profile4=yes,no If you want to install the 4.6 FX (defaults to yes)], [], [with_profile4_x=yes])
-AC_ARG_WITH(monodroid, [ --with-monodroid=yes,no If you want to build the MonoDroid assemblies (defaults to no)], [], [with_monodroid=no])
-AC_ARG_WITH(monotouch, [ --with-monotouch=yes,no If you want to build the Xamarin.iOS assemblies (defaults to no)], [], [with_monotouch=no])
-AC_ARG_WITH(xammac, [ --with-xammac=yes,no If you want to build the Xamarin.Mac assemblies (defaults to no)], [], [with_xammac=no])
+AC_ARG_WITH(profile4_x, [ --with-profile4=yes,no If you want to install the 4.6 FX (defaults to yes)], [], [with_profile4_x=yes])
+AC_ARG_WITH(monodroid, [ --with-monodroid=yes,no If you want to build the MonoDroid assemblies (defaults to no)], [], [with_monodroid=no])
+AC_ARG_WITH(monotouch, [ --with-monotouch=yes,no If you want to build the Xamarin.iOS assemblies (defaults to no)], [], [with_monotouch=no])
+AC_ARG_WITH(monotouch_watch, [ --with-monotouch_watch=yes,no If you want to build the Xamarin.WatchOS assemblies (defaults to no)],[], [with_monotouch_watch=no])
+AC_ARG_WITH(xammac, [ --with-xammac=yes,no If you want to build the Xamarin.Mac assemblies (defaults to no)], [], [with_xammac=no])
OPROFILE=no
AC_ARG_WITH(oprofile,[ --with-oprofile=no,<oprofile install dir> Enable oprofile support (defaults to no)],[
fi
], [with_cooperative_gc=no])
+AC_ARG_WITH(checked_build, [ --with-checked-build=yes|no Enable checked build (expensive asserts)) (defaults to no)],[
+ if test x$with_checked_build != xno ; then
+ AC_DEFINE(CHECKED_BUILD,1,[Enable checked build.])
+ fi
+], [with_checked_build=no])
+
+
AC_CHECK_HEADER([malloc.h],
[AC_DEFINE([HAVE_USR_INCLUDE_MALLOC_H], [1],
[Define to 1 if you have /usr/include/malloc.h.])],,)
with_profile4_x=no
with_monodroid=no
with_monotouch=no
+ with_monotouch_watch=no
with_xammac=no
fi
AM_CONDITIONAL(INSTALL_4_x, [test "x$with_profile4_x" = xyes])
AM_CONDITIONAL(INSTALL_MONODROID, [test "x$with_monodroid" != "xno"])
AM_CONDITIONAL(INSTALL_MONOTOUCH, [test "x$with_monotouch" != "xno"])
+AM_CONDITIONAL(INSTALL_MONOTOUCH_WATCH, [test "x$with_monotouch_watch" != "xno"])
AM_CONDITIONAL(INSTALL_XAMMAC, [test "x$with_xammac" != "xno"])
AM_CONDITIONAL(MIPS_GCC, test ${TARGET}${ac_cv_prog_gcc} = MIPSyes)
sed -e "s,-mno-cygwin,,g" libtool > libtool.new; mv libtool.new libtool; chmod 755 libtool
fi
-if test x$platform_darwin = xyes; then
+if test x$host_darwin = xyes; then
# This doesn't seem to be required and it slows down parallel builds
sed -e 's,lock_old_archive_extraction=yes,lock_old_archive_extraction=no,g' < libtool > libtool.new && mv libtool.new libtool && chmod +x libtool
fi
echo "MONO_VERSION = $myver" >> $mcs_topdir/build/config.make
- if test x$platform_darwin = xyes; then
+ if test x$host_darwin = xyes; then
echo "PLATFORM = darwin" >> $mcs_topdir/build/config.make
fi
LLVM Back End: $enable_llvm (dynamically loaded: $enable_loadedllvm)
Libraries:
- .NET 4.6: $with_profile4_x
- MonoDroid: $with_monodroid
- MonoTouch: $with_monotouch
- Xamarin.Mac: $with_xammac
- JNI support: $jdk_headers_found
- libgdiplus: $libgdiplus_msg
- zlib: $zlib_msg
+ .NET 4.6: $with_profile4_x
+ MonoDroid: $with_monodroid
+ Xamarin.iOS: $with_monotouch
+ Xamarin.WatchOS: $with_monotouch_watch
+ Xamarin.Mac: $with_xammac
+ JNI support: $jdk_headers_found
+ libgdiplus: $libgdiplus_msg
+ zlib: $zlib_msg
$disabled
"
if test x$with_static_mono = xno -a "x$host_win32" != "xyes"; then
AC_CHECK_SIZEOF(long long)
AC_CHECK_FUNCS(strlcpy stpcpy strtok_r rewinddir vasprintf)
AC_CHECK_FUNCS(getrlimit)
+AC_CHECK_FUNCS(fork execv execve)
#
# Mono currently supports 10.6, but strndup is not available prior to 10.7; avoiding
AC_CHECK_FUNCS(strndup getpwuid_r)
fi
-AM_CONDITIONAL(NEED_VASPRINTF, test x$have_vasprintf = x )
+AM_CONDITIONAL(NEED_VASPRINTF, test x$ac_cv_func_vasprintf = x )
AM_ICONV()
AC_SEARCH_LIBS(sqrtf, m)
-noinst_LTLIBRARIES = libeglib.la libeglib-static.la
+noinst_LTLIBRARIES = libeglib.la
AM_CFLAGS = $(WERROR_CFLAGS)
$(vasprintf_files)
libeglib_la_CFLAGS = -g -Wall -D_FORTIFY_SOURCE=2
-libeglib_static_la_SOURCES=$(libeglib_la_SOURCES)
-libeglib_static_la_CFLAGS = $(libeglib_la_CFLAGS)
AM_CPPFLAGS = -I$(srcdir)
endif
endif
-libeglib_static_la_LIBADD = $(libeglib_la_LIBADD) $(LIBICONV)
-libeglib_static_la_LDFLAGS = -static
-
MAINTAINERCLEANFILES = Makefile.in
EXTRA_DIST = eglib-config.h.in $(win_files) $(unix_files)
GError **error)
{
#ifdef G_OS_WIN32
+#elif !defined (HAVE_FORK) || !defined (HAVE_EXECV)
+ fprintf (stderr, "g_spawn_command_line_sync not supported on this platform\n");
+ return FALSE;
#else
pid_t pid;
gchar **argv;
GError **error)
{
#ifdef G_OS_WIN32
+#elif !defined (HAVE_FORK) || !defined (HAVE_EXECVE)
+ fprintf (stderr, "g_spawn_async_with_pipes is not supported on this platform\n");
+ return FALSE;
#else
pid_t pid;
int info_pipe [2];
is_utf8 = FALSE;
#else
/* These shouldn't be heap allocated */
-#if HAVE_LOCALCHARSET_H
- my_charset = locale_charset ();
-#elif defined(HAVE_LANGINFO_H)
+#if defined(HAVE_LANGINFO_H)
my_charset = nl_langinfo (CODESET);
+#elif defined(HAVE_LOCALCHARSET_H)
+ my_charset = locale_charset ();
#else
my_charset = "UTF-8";
#endif
-Subproject commit dab43d5cf4bf3b8b9a5b5f8cb175dee38a5fe69f
+Subproject commit d6b00edf218008ecd8cfe90bc66b9b607431428f
-Subproject commit 3976a6088118b35ed318f8e78767066cb78ffdf9
+Subproject commit a09accbcb9771db77a3b0370c954f643d59f4ce7
-AM_CPPFLAGS = $(GMODULE_CFLAGS)
+AM_CPPFLAGS = $(GLIB_CFLAGS)
lib_LTLIBRARIES = libikvm-native.la
libikvm_native_la_SOURCES = jni.c os.c jni.h
libikvm_native_la_LDFLAGS = -avoid-version
-libikvm_native_la_LIBADD = $(GMODULE_LIBS)
+libikvm_native_la_LIBADD = $(GLIB_LIBS)
-include $(topdir)/build/profiles/net_4_5.make
+include $(topdir)/build/profiles/net_4_x.make
PROFILE_MCS_FLAGS += -d:NO_SYSTEM_DRAWING_DEPENDENCY -d:NO_WINFORMS_DEPENDENCY -d:NO_SYSTEM_WEB_DEPENDENCY -d:XAMMAC_4_5
XAMMAC_4_5=1
NO_WINDOWS_BASE=1
System.Diagnostics.Process System.Diagnostics.TextWriterTraceListener System.Diagnostics.TraceEvent System.Diagnostics.TraceSource System.Globalization.Calendars \
System.IO.Compression System.IO.Compression.ZipFile System.IO.FileSystem System.IO.FileSystem.DriveInfo System.IO.FileSystem.Primitives \
System.IO.IsolatedStorage System.IO.MemoryMappedFiles System.IO.UnmanagedMemoryStream System.Net.AuthenticationManager System.Net.Cache \
- System.Net.Http.WebRequestHandler System.Net.HttpListener System.Net.Mail System.Net.NameResolution System.Net.Security System.Net.ServicePoint System.Net.Sockets \
+ System.Net.HttpListener System.Net.Mail System.Net.NameResolution System.Net.Security System.Net.ServicePoint System.Net.Sockets \
System.Net.Utilities System.Net.WebHeaderCollection System.Net.WebSockets System.Net.WebSockets.Client System.Resources.ReaderWriter System.Runtime.CompilerServices.VisualC \
System.Security.AccessControl System.Security.Claims System.Security.Cryptography.DeriveBytes System.Security.Cryptography.Encoding System.Security.Cryptography.Encryption \
System.Security.Cryptography.Encryption.Aes System.Security.Cryptography.Encryption.ECDiffieHellman System.Security.Cryptography.Encryption.ECDsa System.Security.Cryptography.Hashing \
mobile_static_SUBDIRS = $(monotouch_SUBDIRS)
net_4_5_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS) System.Diagnostics.PerformanceCounter \
- System.IO.FileSystem.Watcher System.IO.Pipes System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController
+ System.IO.FileSystem.Watcher System.IO.Pipes System.Security.Cryptography.ProtectedData System.ServiceProcess.ServiceController System.Net.Http.WebRequestHandler
monodroid_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS)
-xammac_SUBDIRS = $(net_4_5_SUBDIRS)
-xammac_net_4_5_SUBDIRS = $(net_4_5_SUBDIRS)
+xammac_SUBDIRS = $(monotouch_SUBDIRS)
+xammac_net_4_5_SUBDIRS = $(monotouch_SUBDIRS) $(reflection_SUBDIRS)
monotouch_watch_SUBDIRS = $(monotouch_SUBDIRS)
// THE SOFTWARE.
//
-#if !MOBILE
+#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.CallbackBehaviorAttribute))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexChannelFactory<>))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.DuplexClientBase<>))]
// THE SOFTWARE.
//
-#if !MOBILE
+#if !MOBILE && !XAMMAC_4_5
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.ConnectionOrientedTransportBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.SslStreamSecurityBindingElement))]
[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.ServiceModel.Channels.TcpConnectionPoolSettings))]
System.ComponentModel.DataAnnotations \
System.ComponentModel.Composition.4.5 \
System.Net \
+ System.Net.Http \
+ System.Net.Http.WebRequest \
System.Windows \
System.Xml.Serialization \
Mono.CSharp \
mobile_dynamic_dirs := \
$(mobile_common_dirs) \
Mono.CompilerServices.SymbolWriter \
- System.Net.Http \
- System.Net.Http.WebRequest \
$(pcl_facade_dirs)
xammac_dirs := \
BuildItemGroup big;
BuildItem bi = new BuildItem (this);
- bi.finalItemSpec = ((ITaskItem2)taskitem).EvaluatedIncludeEscaped;
+ bi.finalItemSpec = taskitem.ItemSpec;
foreach (DictionaryEntry de in taskitem.CloneCustomMetadata ()) {
bi.unevaluatedMetadata.Add ((string) de.Key, (string) de.Value);
for (int i = 0; i < lists.Count; i++) {
foreach (object o in lists [i]) {
if (o is string)
- expressionCollection.Add ((string) o);
+ expressionCollection.Add (MSBuildUtils.Unescape ((string) o));
else if (!allowItems && o is ItemReference)
expressionCollection.Add (((ItemReference) o).OriginalString);
else if (!allowMd && o is MetadataReference) {
// Trim and Remove empty items
List<ITaskItem> toRemove = new List<ITaskItem> ();
for (int i = 0; i < finalItems.Count; i ++) {
- string s = ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped.Trim ();
+ string s = finalItems [i].ItemSpec.Trim ();
if (s.Length == 0)
toRemove.Add (finalItems [i]);
else
- ((ITaskItem2)finalItems [i]).EvaluatedIncludeEscaped = s;
+ finalItems [i].ItemSpec = s;
}
foreach (ITaskItem ti in toRemove)
finalItems.Remove (ti);
<Message Text='Text5' Importance='normal'/>
<Message Text='Text6' Importance='high'/>
<Message Text='Text7' />
+ <Message Text='%22abc test%22 123 %22def%22' />
<Message Text='Text8' Importance='weird_importance'/>
</Target>
</Project>
Assert.AreEqual (0, testLogger.CheckAny ("Text5", MessageImportance.Normal), "A5");
Assert.AreEqual (0, testLogger.CheckAny ("Text6", MessageImportance.High), "A6");
Assert.AreEqual (0, testLogger.CheckAny ("Text7", MessageImportance.Normal), "A7");
- Assert.AreEqual (1, testLogger.CheckAny ("Text8", MessageImportance.Normal), "A8");
+ Assert.AreEqual (0, testLogger.CheckAny ("\"abc test\" 123 \"def\"", MessageImportance.Normal), "A8");
+ Assert.AreEqual (1, testLogger.CheckAny ("Text8", MessageImportance.Normal), "A9");
}
}
}
}
[Test]
+ [Category("NotWorking")] // this fails due to an xbuild bug, it works on MS.NET
public void TestLineWithEscapedSemicolon ()
{
string[] lines = new string[] { "abc%3Btest%3B%3B", "%3Bdef" };
}
[Test]
+ [Category("NotWorking")] // this fails due to an xbuild bug, it works on MS.NET
public void TestLineWithEscapedSpace ()
{
string[] lines = new string[] { " %20%20abc%20test ", " def%20%20" };
});
}
+ [Test]
+ public void TestLineWithEscapedQuote ()
+ {
+ string[] lines = new string[] { "%22abc test%22 123 %22def%22" };
+ CreateProjectAndCheck (full_filepath, lines, false, true, delegate () {
+ CheckFileExists (full_filepath, true);
+ CheckLines (full_filepath, new string [] {"\"abc test\" 123 \"def\""});
+ });
+ }
+
[Test]
public void TestNoOverwrite ()
{
}
public override string ToString ()
{
- return ItemSpec;
+ return escapedItemSpec;
}
public string ItemSpec {
Assert.AreEqual(dr["Company.Name"], "Test CO");
i += 2;
}
- Assert.IsTrue(dr.FieldCount>0);
+ Assert.IsTrue(dr.FieldCount>0, i.ToString ());
}
- if (BCL.Tests.TestRuntime.CheckSystemVersion (8, 2))
- Assert.IsTrue (false, "Apple fixed bug 27864, this check can now be removed");
}
} catch (SqliteException ex) {
-
- if (BCL.Tests.TestRuntime.CheckSystemVersion (8, 2)) // Expected Exception on iOS 8.2+, if this does not happen anymore it means apple fixed it
+ // Expected Exception from iOS 8.2 (broken) to 9.0 (fixed)
+ if (BCL.Tests.TestRuntime.CheckSystemVersion (8,2) && !BCL.Tests.TestRuntime.CheckSystemVersion (9,0))
Assert.That (ex.Message.Contains ("no such column: com.Name"));
else
throw new AssertionException ("Unexpected Sqlite Error", ex); // This should not happen
* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 40;
+ internal const int MINOR_VERSION = 41;
enum WPSuspendPolicy {
NONE = 0,
return res;
}
+ public string ReadUTF16String () {
+ int len = decode_int (packet, ref offset);
+ string res = new String (Encoding.Unicode.GetChars (packet, offset, len));
+ offset += len;
+ return res;
+ }
+
public ValueImpl ReadValue () {
ElementType etype = (ElementType)ReadByte ();
* STRINGS
*/
internal string String_GetValue (long id) {
- return SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id)).ReadString ();
+ var r = SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id));
+
+ bool is_utf16 = false;
+ if (Version.AtLeast (2, 41))
+ is_utf16 = r.ReadByte () == 1;
+
+ if (is_utf16)
+ return r.ReadUTF16String ();
+ else
+ return r.ReadString ();
}
internal int String_GetLength (long id) {
public static void arguments () {
arg1 (SByte.MaxValue - 5, Byte.MaxValue - 5, true, Int16.MaxValue - 5, UInt16.MaxValue - 5, 'F', Int32.MaxValue - 5, UInt32.MaxValue - 5, Int64.MaxValue - 5, UInt64.MaxValue - 5, 1.2345f, 6.78910, new IntPtr (Int32.MaxValue - 5), new UIntPtr (UInt32.MaxValue - 5));
int i = 42;
- arg2 ("FOO", null, "BLA", ref i, new GClass <int> { field = 42 }, new object ());
+ arg2 ("FOO", null, "BLA", ref i, new GClass <int> { field = 42 }, new object (), '\0'.ToString () + "A");
Tests t = new Tests () { field_i = 42, field_s = "S" };
t.arg3 ("BLA");
}
}
[MethodImplAttribute (MethodImplOptions.NoInlining)]
- public static string arg2 (string s, string s3, object o, ref int i, GClass <int> gc, object o2) {
+ public static string arg2 (string s, string s3, object o, ref int i, GClass <int> gc, object o2, string s4) {
return s + (s3 != null ? "" : "") + o + i + gc.field + o2;
}
public void invoke2 () {
}
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public void invoke3 () {
+ }
+
[MethodImplAttribute (MethodImplOptions.NoInlining)]
public void invoke_ex () {
invoke_ex_inner ();
invoke_results.Add (res);
}
+ [Test]
+ public void InvokeNested () {
+ Event e = run_until ("invoke1");
+
+ MethodMirror m = entry_point.DeclaringType.GetMethod ("invoke2");
+ Assert.IsNotNull (m);
+ vm.SetBreakpoint (m, 0);
+
+ StackFrame frame = e.Thread.GetFrames () [0];
+ var o = frame.GetThis () as ObjectMirror;
+
+ bool failed = false;
+
+ bool finished = false;
+ object wait = new object ();
+
+ Thread t = new Thread (delegate () {
+ try {
+ o.InvokeMethod (e.Thread, m, null);
+ } catch {
+ failed = true;
+ }
+ lock (wait) {
+ finished = true;
+ Monitor.Pulse (wait);
+ }
+ });
+
+ t.Start ();
+
+ StackFrame invoke_frame = null;
+
+ e = GetNextEvent ();
+ Assert.IsInstanceOfType (typeof (BreakpointEvent), e);
+
+ // Check that nested invokes are not allowed
+ AssertThrows<VMNotSuspendedException> (delegate {
+ o.InvokeMethod (e.Thread, m, null);
+ });
+
+ vm.Resume ();
+ lock (wait) {
+ if (!finished)
+ Monitor.Wait (wait);
+ }
+ }
+
[Test]
public void GetThreads () {
vm.GetThreads ();
Assert.AreEqual ("System.Exception", types [0].FullName);
}
+ [Test]
+ public void String_GetValue () {
+ // Embedded nulls
+ object val;
+
+ // Reuse this test
+ var e = run_until ("arg2");
+
+ var frame = e.Thread.GetFrames () [0];
+
+ val = frame.GetArgument (6);
+ Assert.AreEqual ('\0'.ToString () + "A", (val as StringMirror).Value);
+ }
+
[Test]
public void String_GetChars () {
object val;
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
<ItemGroup>\r
<Compile Include="Test\Mono.Unix.Native\RealTimeSignumTests.cs" />\r
+ <Compile Include="Test\Mono.Unix.Native\SocketTest.cs" />\r
<Compile Include="Test\Mono.Unix.Native\StdlibTest.cs" />\r
<Compile Include="Test\Mono.Unix\ReadlinkTest.cs" />\r
<Compile Include="Test\Mono.Unix\StdioFileStreamTest.cs" />\r
Mono.Unix/UnixPathTest.cs
Mono.Unix/UnixSignalTest.cs
Mono.Unix/UnixUserTest.cs
+Mono.Unix.Android/TestHelper.cs
Mono.Unix.Native/RealTimeSignumTests.cs
+Mono.Unix.Native/SocketTest.cs
Mono.Unix.Native/StdlibTest.cs
//
// Non-generated exports
//
-
+#if !MONODROID
[DllImport (LIB, EntryPoint="Mono_Posix_FromRealTimeSignum")]
private static extern int FromRealTimeSignum (Int32 offset, out Int32 rval);
-
+#endif
// convert a realtime signal to os signal
public static int FromRealTimeSignum (RealTimeSignum sig)
{
/*
- * This file was automatically generated by create-native-map from ../../class/lib/net_2_0/Mono.Posix.dll.
+ * This file was automatically generated by create-native-map from ./../../class/lib/net_4_x/Mono.Posix.dll.
*
* DO NOT MODIFY.
*/
return ToIovec (source, out destination) == 0;
}
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromLinger")]
+ private static extern int FromLinger (ref Linger source, IntPtr destination);
+
+ public static bool TryCopy (ref Linger source, IntPtr destination)
+ {
+ return FromLinger (ref source, destination) == 0;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToLinger")]
+ private static extern int ToLinger (IntPtr source, out Linger destination);
+
+ public static bool TryCopy (IntPtr source, out Linger destination)
+ {
+ return ToLinger (source, out destination) == 0;
+ }
+
[DllImport (LIB, EntryPoint="Mono_Posix_FromLockType")]
private static extern int FromLockType (LockType value, out Int16 rval);
return rval;
}
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromMessageFlags")]
+ private static extern int FromMessageFlags (MessageFlags value, out Int32 rval);
+
+ public static bool TryFromMessageFlags (MessageFlags value, out Int32 rval)
+ {
+ return FromMessageFlags (value, out rval) == 0;
+ }
+
+ public static Int32 FromMessageFlags (MessageFlags value)
+ {
+ Int32 rval;
+ if (FromMessageFlags (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToMessageFlags")]
+ private static extern int ToMessageFlags (Int32 value, out MessageFlags rval);
+
+ public static bool TryToMessageFlags (Int32 value, out MessageFlags rval)
+ {
+ return ToMessageFlags (value, out rval) == 0;
+ }
+
+ public static MessageFlags ToMessageFlags (Int32 value)
+ {
+ MessageFlags rval;
+ if (ToMessageFlags (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
[DllImport (LIB, EntryPoint="Mono_Posix_FromMlockallFlags")]
private static extern int FromMlockallFlags (MlockallFlags value, out Int32 rval);
return rval;
}
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromShutdownOption")]
+ private static extern int FromShutdownOption (ShutdownOption value, out Int32 rval);
+
+ public static bool TryFromShutdownOption (ShutdownOption value, out Int32 rval)
+ {
+ return FromShutdownOption (value, out rval) == 0;
+ }
+
+ public static Int32 FromShutdownOption (ShutdownOption value)
+ {
+ Int32 rval;
+ if (FromShutdownOption (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToShutdownOption")]
+ private static extern int ToShutdownOption (Int32 value, out ShutdownOption rval);
+
+ public static bool TryToShutdownOption (Int32 value, out ShutdownOption rval)
+ {
+ return ToShutdownOption (value, out rval) == 0;
+ }
+
+ public static ShutdownOption ToShutdownOption (Int32 value)
+ {
+ ShutdownOption rval;
+ if (ToShutdownOption (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
[DllImport (LIB, EntryPoint="Mono_Posix_FromSignum")]
private static extern int FromSignum (Signum value, out Int32 rval);
return ToTimezone (source, out destination) == 0;
}
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixAddressFamily")]
+ private static extern int FromUnixAddressFamily (UnixAddressFamily value, out Int32 rval);
+
+ public static bool TryFromUnixAddressFamily (UnixAddressFamily value, out Int32 rval)
+ {
+ return FromUnixAddressFamily (value, out rval) == 0;
+ }
+
+ public static Int32 FromUnixAddressFamily (UnixAddressFamily value)
+ {
+ Int32 rval;
+ if (FromUnixAddressFamily (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixAddressFamily")]
+ private static extern int ToUnixAddressFamily (Int32 value, out UnixAddressFamily rval);
+
+ public static bool TryToUnixAddressFamily (Int32 value, out UnixAddressFamily rval)
+ {
+ return ToUnixAddressFamily (value, out rval) == 0;
+ }
+
+ public static UnixAddressFamily ToUnixAddressFamily (Int32 value)
+ {
+ UnixAddressFamily rval;
+ if (ToUnixAddressFamily (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketFlags")]
+ private static extern int FromUnixSocketFlags (UnixSocketFlags value, out Int32 rval);
+
+ public static bool TryFromUnixSocketFlags (UnixSocketFlags value, out Int32 rval)
+ {
+ return FromUnixSocketFlags (value, out rval) == 0;
+ }
+
+ public static Int32 FromUnixSocketFlags (UnixSocketFlags value)
+ {
+ Int32 rval;
+ if (FromUnixSocketFlags (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketFlags")]
+ private static extern int ToUnixSocketFlags (Int32 value, out UnixSocketFlags rval);
+
+ public static bool TryToUnixSocketFlags (Int32 value, out UnixSocketFlags rval)
+ {
+ return ToUnixSocketFlags (value, out rval) == 0;
+ }
+
+ public static UnixSocketFlags ToUnixSocketFlags (Int32 value)
+ {
+ UnixSocketFlags rval;
+ if (ToUnixSocketFlags (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketOptionName")]
+ private static extern int FromUnixSocketOptionName (UnixSocketOptionName value, out Int32 rval);
+
+ public static bool TryFromUnixSocketOptionName (UnixSocketOptionName value, out Int32 rval)
+ {
+ return FromUnixSocketOptionName (value, out rval) == 0;
+ }
+
+ public static Int32 FromUnixSocketOptionName (UnixSocketOptionName value)
+ {
+ Int32 rval;
+ if (FromUnixSocketOptionName (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketOptionName")]
+ private static extern int ToUnixSocketOptionName (Int32 value, out UnixSocketOptionName rval);
+
+ public static bool TryToUnixSocketOptionName (Int32 value, out UnixSocketOptionName rval)
+ {
+ return ToUnixSocketOptionName (value, out rval) == 0;
+ }
+
+ public static UnixSocketOptionName ToUnixSocketOptionName (Int32 value)
+ {
+ UnixSocketOptionName rval;
+ if (ToUnixSocketOptionName (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketProtocol")]
+ private static extern int FromUnixSocketProtocol (UnixSocketProtocol value, out Int32 rval);
+
+ public static bool TryFromUnixSocketProtocol (UnixSocketProtocol value, out Int32 rval)
+ {
+ return FromUnixSocketProtocol (value, out rval) == 0;
+ }
+
+ public static Int32 FromUnixSocketProtocol (UnixSocketProtocol value)
+ {
+ Int32 rval;
+ if (FromUnixSocketProtocol (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketProtocol")]
+ private static extern int ToUnixSocketProtocol (Int32 value, out UnixSocketProtocol rval);
+
+ public static bool TryToUnixSocketProtocol (Int32 value, out UnixSocketProtocol rval)
+ {
+ return ToUnixSocketProtocol (value, out rval) == 0;
+ }
+
+ public static UnixSocketProtocol ToUnixSocketProtocol (Int32 value)
+ {
+ UnixSocketProtocol rval;
+ if (ToUnixSocketProtocol (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_FromUnixSocketType")]
+ private static extern int FromUnixSocketType (UnixSocketType value, out Int32 rval);
+
+ public static bool TryFromUnixSocketType (UnixSocketType value, out Int32 rval)
+ {
+ return FromUnixSocketType (value, out rval) == 0;
+ }
+
+ public static Int32 FromUnixSocketType (UnixSocketType value)
+ {
+ Int32 rval;
+ if (FromUnixSocketType (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
+ [DllImport (LIB, EntryPoint="Mono_Posix_ToUnixSocketType")]
+ private static extern int ToUnixSocketType (Int32 value, out UnixSocketType rval);
+
+ public static bool TryToUnixSocketType (Int32 value, out UnixSocketType rval)
+ {
+ return ToUnixSocketType (value, out rval) == 0;
+ }
+
+ public static UnixSocketType ToUnixSocketType (Int32 value)
+ {
+ UnixSocketType rval;
+ if (ToUnixSocketType (value, out rval) == -1)
+ ThrowArgumentException (value);
+ return rval;
+ }
+
[DllImport (LIB, EntryPoint="Mono_Posix_FromUtimbuf")]
private static extern int FromUtimbuf (ref Utimbuf source, IntPtr destination);
MREMAP_MAYMOVE = 0x1,
}
+ [Map]
+ [CLSCompliant (false)]
+ public enum UnixSocketType : int {
+ SOCK_STREAM = 1, // Byte-stream socket
+ SOCK_DGRAM = 2, // Datagram socket
+ SOCK_RAW = 3, // Raw protocol interface (linux specific)
+ SOCK_RDM = 4, // Reliably-delivered messages (linux specific)
+ SOCK_SEQPACKET = 5, // Sequenced-packet socket
+ SOCK_DCCP = 6, // Datagram Congestion Control Protocol (linux specific)
+ SOCK_PACKET = 10, // Linux specific
+ }
+
+ [Map][Flags]
+ [CLSCompliant (false)]
+ public enum UnixSocketFlags : int {
+ SOCK_CLOEXEC = 0x80000, /* Atomically set close-on-exec flag for the new descriptor(s). */
+ SOCK_NONBLOCK = 0x00800, /* Atomically mark descriptor(s) as non-blocking. */
+ }
+
+ [Map]
+ [CLSCompliant (false)]
+ public enum UnixSocketProtocol : int {
+ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */
+ IPPROTO_IGMP = 2, /* Internet Group Management Protocol */
+ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
+ IPPROTO_TCP = 6, /* Transmission Control Protocol */
+ IPPROTO_EGP = 8, /* Exterior Gateway Protocol */
+ IPPROTO_PUP = 12, /* PUP protocol */
+ IPPROTO_UDP = 17, /* User Datagram Protocol */
+ IPPROTO_IDP = 22, /* XNS IDP protocol */
+ IPPROTO_TP = 29, /* SO Transport Protocol Class 4 */
+ IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
+ IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
+ IPPROTO_RSVP = 46, /* RSVP Protocol */
+ IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
+ IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */
+ IPPROTO_AH = 51, /* Authentication Header protocol */
+ IPPROTO_MTP = 92, /* Multicast Transport Protocol */
+ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */
+ IPPROTO_ENCAP = 98, /* Encapsulation Header */
+ IPPROTO_PIM = 103, /* Protocol Independent Multicast */
+ IPPROTO_COMP = 108, /* Compression Header Protocol */
+ IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */
+ IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
+ IPPROTO_RAW = 255, /* Raw IP packets */
+
+ // Number used by linux (0) has a special meaning for socket()
+ IPPROTO_IP = 1024, /* Dummy protocol for TCP */
+ // Number used by linux (1) clashes with IPPROTO_ICMP
+ SOL_SOCKET = 2048, /* For setsockopt() / getsockopt(): Options to be accessed at socket level, not protocol level. */
+ }
+
+ [Map]
+ [CLSCompliant (false)]
+ public enum UnixAddressFamily : int {
+ AF_UNSPEC = 0, /* Unspecified. */
+ AF_UNIX = 1, /* Local to host (pipes and file-domain). */
+ AF_INET = 2, /* IP protocol family. */
+ AF_AX25 = 3, /* Amateur Radio AX.25. */
+ AF_IPX = 4, /* Novell Internet Protocol. */
+ AF_APPLETALK = 5, /* Appletalk DDP. */
+ AF_NETROM = 6, /* Amateur radio NetROM. */
+ AF_BRIDGE = 7, /* Multiprotocol bridge. */
+ AF_ATMPVC = 8, /* ATM PVCs. */
+ AF_X25 = 9, /* Reserved for X.25 project. */
+ AF_INET6 = 10, /* IP version 6. */
+ AF_ROSE = 11, /* Amateur Radio X.25 PLP. */
+ AF_DECnet = 12, /* Reserved for DECnet project. */
+ AF_NETBEUI = 13, /* Reserved for 802.2LLC project. */
+ AF_SECURITY = 14, /* Security callback pseudo AF. */
+ AF_KEY = 15, /* PF_KEY key management API. */
+ AF_NETLINK = 16,
+ AF_PACKET = 17, /* Packet family. */
+ AF_ASH = 18, /* Ash. */
+ AF_ECONET = 19, /* Acorn Econet. */
+ AF_ATMSVC = 20, /* ATM SVCs. */
+ AF_RDS = 21, /* RDS sockets. */
+ AF_SNA = 22, /* Linux SNA Project */
+ AF_IRDA = 23, /* IRDA sockets. */
+ AF_PPPOX = 24, /* PPPoX sockets. */
+ AF_WANPIPE = 25, /* Wanpipe API sockets. */
+ AF_LLC = 26, /* Linux LLC. */
+ AF_CAN = 29, /* Controller Area Network. */
+ AF_TIPC = 30, /* TIPC sockets. */
+ AF_BLUETOOTH = 31, /* Bluetooth sockets. */
+ AF_IUCV = 32, /* IUCV sockets. */
+ AF_RXRPC = 33, /* RxRPC sockets. */
+ AF_ISDN = 34, /* mISDN sockets. */
+ AF_PHONET = 35, /* Phonet sockets. */
+ AF_IEEE802154 = 36, /* IEEE 802.15.4 sockets. */
+ AF_CAIF = 37, /* CAIF sockets. */
+ AF_ALG = 38, /* Algorithm sockets. */
+ AF_NFC = 39, /* NFC sockets. */
+ AF_VSOCK = 40, /* vSockets. */
+ }
+
+ [Map]
+ [CLSCompliant (false)]
+ public enum UnixSocketOptionName : int {
+ SO_DEBUG = 1,
+ SO_REUSEADDR = 2,
+ SO_TYPE = 3,
+ SO_ERROR = 4,
+ SO_DONTROUTE = 5,
+ SO_BROADCAST = 6,
+ SO_SNDBUF = 7,
+ SO_RCVBUF = 8,
+ SO_SNDBUFFORCE = 32,
+ SO_RCVBUFFORCE = 33,
+ SO_KEEPALIVE = 9,
+ SO_OOBINLINE = 10,
+ SO_NO_CHECK = 11,
+ SO_PRIORITY = 12,
+ SO_LINGER = 13,
+ SO_BSDCOMPAT = 14,
+ SO_REUSEPORT = 15,
+ SO_PASSCRED = 16,
+ SO_PEERCRED = 17,
+ SO_RCVLOWAT = 18,
+ SO_SNDLOWAT = 19,
+ SO_RCVTIMEO = 20,
+ SO_SNDTIMEO = 21,
+ SO_SECURITY_AUTHENTICATION = 22,
+ SO_SECURITY_ENCRYPTION_TRANSPORT = 23,
+ SO_SECURITY_ENCRYPTION_NETWORK = 24,
+ SO_BINDTODEVICE = 25,
+ SO_ATTACH_FILTER = 26,
+ SO_DETACH_FILTER = 27,
+ SO_PEERNAME = 28,
+ SO_TIMESTAMP = 29,
+ SO_ACCEPTCONN = 30,
+ SO_PEERSEC = 31,
+ SO_PASSSEC = 34,
+ SO_TIMESTAMPNS = 35,
+ SO_MARK = 36,
+ SO_TIMESTAMPING = 37,
+ SO_PROTOCOL = 38,
+ SO_DOMAIN = 39,
+ SO_RXQ_OVFL = 40,
+ SO_WIFI_STATUS = 41,
+ SO_PEEK_OFF = 42,
+ SO_NOFCS = 43,
+ SO_LOCK_FILTER = 44,
+ SO_SELECT_ERR_QUEUE = 45,
+ SO_BUSY_POLL = 46,
+ SO_MAX_PACING_RATE = 47,
+ }
+
+ [Flags][Map]
+ [CLSCompliant (false)]
+ public enum MessageFlags : int {
+ MSG_OOB = 0x01, /* Process out-of-band data. */
+ MSG_PEEK = 0x02, /* Peek at incoming messages. */
+ MSG_DONTROUTE = 0x04, /* Don't use local routing. */
+ MSG_CTRUNC = 0x08, /* Control data lost before delivery. */
+ MSG_PROXY = 0x10, /* Supply or ask second address. */
+ MSG_TRUNC = 0x20,
+ MSG_DONTWAIT = 0x40, /* Nonblocking IO. */
+ MSG_EOR = 0x80, /* End of record. */
+ MSG_WAITALL = 0x100, /* Wait for a full request. */
+ MSG_FIN = 0x200,
+ MSG_SYN = 0x400,
+ MSG_CONFIRM = 0x800, /* Confirm path validity. */
+ MSG_RST = 0x1000,
+ MSG_ERRQUEUE = 0x2000, /* Fetch message from error queue. */
+ MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */
+ MSG_MORE = 0x8000, /* Sender will send more. */
+ MSG_WAITFORONE = 0x10000, /* Wait for at least one packet to return.*/
+ MSG_FASTOPEN = 0x20000000, /* Send data in TCP SYN. */
+ MSG_CMSG_CLOEXEC = 0x40000000, /* Set close_on_exit for file descriptor received through SCM_RIGHTS. */
+ }
+
+ [Map]
+ [CLSCompliant (false)]
+ public enum ShutdownOption : int {
+ SHUT_RD = 0x01, /* No more receptions. */
+ SHUT_WR = 0x02, /* No more transmissions. */
+ SHUT_RDWR = 0x03, /* No more receptions or transmissions. */
+ }
+
#endregion
#region Structures
[FieldOffset (4)]
public ulong u64;
}
+
+ [Map ("struct linger")]
+ [CLSCompliant (false)]
+ public struct Linger {
+ public int l_onoff;
+ public int l_linger;
+ }
+
#endregion
#region Classes
return sys_pwritev (fd, iov, iov.Length, offset);
}
#endregion
+
+ #region <socket.h> Declarations
+ //
+ // <socket.h>
+ //
+
+ // socket(2)
+ // int socket(int domain, int type, int protocol);
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="socket")]
+ static extern int sys_socket (int domain, int type, int protocol);
+
+ public static int socket (UnixAddressFamily domain, UnixSocketType type, UnixSocketFlags flags, UnixSocketProtocol protocol)
+ {
+ var _domain = NativeConvert.FromUnixAddressFamily (domain);
+ var _type = NativeConvert.FromUnixSocketType (type);
+ var _flags = NativeConvert.FromUnixSocketFlags (flags);
+ // protocol == 0 is a special case (uses default protocol)
+ var _protocol = protocol == 0 ? 0 : NativeConvert.FromUnixSocketProtocol (protocol);
+
+ return sys_socket (_domain, _type | _flags, _protocol);
+ }
+
+ public static int socket (UnixAddressFamily domain, UnixSocketType type, UnixSocketProtocol protocol)
+ {
+ return socket (domain, type, 0, protocol);
+ }
+
+ // socketpair(2)
+ // int socketpair(int domain, int type, int protocol, int sv[2]);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_socketpair")]
+ static extern int sys_socketpair (int domain, int type, int protocol, out int socket1, out int socket2);
+
+ public static int socketpair (UnixAddressFamily domain, UnixSocketType type, UnixSocketFlags flags, UnixSocketProtocol protocol, out int socket1, out int socket2)
+ {
+ var _domain = NativeConvert.FromUnixAddressFamily (domain);
+ var _type = NativeConvert.FromUnixSocketType (type);
+ var _flags = NativeConvert.FromUnixSocketFlags (flags);
+ // protocol == 0 is a special case (uses default protocol)
+ var _protocol = protocol == 0 ? 0 : NativeConvert.FromUnixSocketProtocol (protocol);
+
+ return sys_socketpair (_domain, _type | _flags, _protocol, out socket1, out socket2);
+ }
+
+ public static int socketpair (UnixAddressFamily domain, UnixSocketType type, UnixSocketProtocol protocol, out int socket1, out int socket2)
+ {
+ return socketpair (domain, type, 0, protocol, out socket1, out socket2);
+ }
+
+ // sockatmark(2)
+ // int sockatmark(int sockfd);
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int sockatmark (int socket);
+
+ // listen(2)
+ // int listen(int sockfd, int backlog);
+ [DllImport (LIBC, SetLastError=true)]
+ public static extern int listen (int socket, int backlog);
+
+ // getsockopt(2)
+ // int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_getsockopt")]
+ static extern unsafe int sys_getsockopt (int socket, int level, int option_name, void *option_value, ref long option_len);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_getsockopt_timeval")]
+ static extern unsafe int sys_getsockopt_timeval (int socket, int level, int option_name, out Timeval option_value);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_getsockopt_linger")]
+ static extern unsafe int sys_getsockopt_linger (int socket, int level, int option_name, out Linger option_value);
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, void *option_value, ref long option_len)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_getsockopt (socket, _level, _option_name, option_value, ref option_len);
+ }
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, IntPtr option_value, ref long option_len)
+ {
+ return getsockopt (socket, level, option_name, (void*) option_value, ref option_len);
+ }
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out int option_value)
+ {
+ int value;
+ long size = sizeof (int);
+ int ret = getsockopt (socket, level, option_name, &value, ref size);
+ if (ret != -1 && size != sizeof (int)) {
+ SetLastError (Errno.EINVAL);
+ ret = -1;
+ }
+ option_value = value;
+ return ret;
+ }
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, byte[] option_value, ref long option_len)
+ {
+ if (option_len > (option_value == null ? 0 : option_value.Length))
+ throw new ArgumentOutOfRangeException ("option_len", "option_len > (option_value == null ? 0 : option_value.Length)");
+ fixed (byte* ptr = option_value)
+ return getsockopt (socket, level, option_name, ptr, ref option_len);
+ }
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out Timeval option_value)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_getsockopt_timeval (socket, _level, _option_name, out option_value);
+ }
+
+ public static unsafe int getsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, out Linger option_value)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_getsockopt_linger (socket, _level, _option_name, out option_value);
+ }
+
+ // setsockopt(2)
+ // int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_setsockopt")]
+ static extern unsafe int sys_setsockopt (int socket, int level, int option_name, void *option_value, long option_len);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_setsockopt_timeval")]
+ static extern unsafe int sys_setsockopt_timeval (int socket, int level, int option_name, ref Timeval option_value);
+
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_setsockopt_linger")]
+ static extern unsafe int sys_setsockopt_linger (int socket, int level, int option_name, ref Linger option_value);
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, void *option_value, long option_len)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_setsockopt (socket, _level, _option_name, option_value, option_len);
+ }
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, IntPtr option_value, long option_len)
+ {
+ return setsockopt (socket, level, option_name, (void*) option_value, option_len);
+ }
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, int option_value)
+ {
+ return setsockopt (socket, level, option_name, &option_value, sizeof (int));
+ }
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, byte[] option_value, long option_len)
+ {
+ if (option_len > (option_value == null ? 0 : option_value.Length))
+ throw new ArgumentOutOfRangeException ("option_len", "option_len > (option_value == null ? 0 : option_value.Length)");
+ fixed (byte* ptr = option_value)
+ return setsockopt (socket, level, option_name, ptr, option_len);
+ }
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, Timeval option_value)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_setsockopt_timeval (socket, _level, _option_name, ref option_value);
+ }
+
+ public static unsafe int setsockopt (int socket, UnixSocketProtocol level, UnixSocketOptionName option_name, Linger option_value)
+ {
+ var _level = NativeConvert.FromUnixSocketProtocol (level);
+ var _option_name = NativeConvert.FromUnixSocketOptionName (option_name);
+ return sys_setsockopt_linger (socket, _level, _option_name, ref option_value);
+ }
+
+ // shutdown(2)
+ // int shutdown(int sockfd, int how);
+ [DllImport (LIBC, SetLastError=true,
+ EntryPoint="shutdown")]
+ static extern int sys_shutdown (int socket, int how);
+
+ public static int shutdown (int socket, ShutdownOption how)
+ {
+ var _how = NativeConvert.FromShutdownOption (how);
+ return sys_shutdown (socket, _how);
+ }
+
+ // recv(2)
+ // ssize_t recv(int sockfd, void *buf, size_t len, int flags);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_recv")]
+ static extern unsafe long sys_recv (int socket, void *buffer, ulong length, int flags);
+
+ public static unsafe long recv (int socket, void *buffer, ulong length, MessageFlags flags)
+ {
+ int _flags = NativeConvert.FromMessageFlags (flags);
+ return sys_recv (socket, buffer, length, _flags);
+ }
+
+ public static unsafe long recv (int socket, IntPtr buffer, ulong length, MessageFlags flags)
+ {
+ return recv (socket, (void*) buffer, length, flags);
+ }
+
+ public static unsafe long recv (int socket, byte[] buffer, ulong length, MessageFlags flags)
+ {
+ if (length > (ulong) (buffer == null ? 0 : buffer.LongLength))
+ throw new ArgumentOutOfRangeException ("length", "length > (buffer == null ? 0 : buffer.LongLength)");
+ fixed (byte* ptr = buffer)
+ return recv (socket, ptr, length, flags);
+ }
+
+ // send(2)
+ // ssize_t send(int sockfd, const void *buf, size_t len, int flags);
+ [DllImport (MPH, SetLastError=true,
+ EntryPoint="Mono_Posix_Syscall_send")]
+ static extern unsafe long sys_send (int socket, void *message, ulong length, int flags);
+
+ public static unsafe long send (int socket, void *message, ulong length, MessageFlags flags)
+ {
+ int _flags = NativeConvert.FromMessageFlags (flags);
+ return sys_send (socket, message, length, _flags);
+ }
+
+ public static unsafe long send (int socket, IntPtr message, ulong length, MessageFlags flags)
+ {
+ return send (socket, (void*) message, length, flags);
+ }
+
+ public static unsafe long send (int socket, byte[] message, ulong length, MessageFlags flags)
+ {
+ if (length > (ulong) (message == null ? 0 : message.LongLength))
+ throw new ArgumentOutOfRangeException ("length", "length > (message == null ? 0 : message.LongLength)");
+ fixed (byte* ptr = message)
+ return send (socket, ptr, length, flags);
+ }
+
+ #endregion
}
#endregion
--- /dev/null
+namespace Mono.Unix.Android
+{
+ // Another version of this class is used by the Xamarin.Android test suite
+ // It is here to keep the test code #ifdef free as much as possible
+ public class TestHelper
+ {
+ public static bool CanUseRealTimeSignals ()
+ {
+ return true;
+ }
+ }
+}
\ No newline at end of file
using System.Text;
using System.Threading;
using Mono.Unix;
+using Mono.Unix.Android;
using Mono.Unix.Native;
namespace MonoTests.Mono.Unix.Native {
[ExpectedException (typeof (ArgumentOutOfRangeException))]
public void TestRealTimeOutOfRange ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts = new RealTimeSignum (int.MaxValue);
}
[ExpectedException (typeof (ArgumentOutOfRangeException))]
public void TestRealTimeSignumNegativeOffset ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts1 = new RealTimeSignum (-1);
}
[Test]
public void TestRTSignalEquality ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts1 = new RealTimeSignum (0);
RealTimeSignum rts2 = new RealTimeSignum (0);
Assert.That (rts1 == rts2, Is.True);
[Test]
public void TestRTSignalInequality ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts1 = new RealTimeSignum (0);
RealTimeSignum rts2 = new RealTimeSignum (1);
Assert.That (rts1 == rts2, Is.False);
[Test]
public void TestRTSignalGetHashCodeEquality ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts1 = new RealTimeSignum (0);
RealTimeSignum rts2 = new RealTimeSignum (0);
Assert.That (rts1.GetHashCode (), Is.EqualTo(rts2.GetHashCode ()));
[Test]
public void TestRTSignalGetHashCodeInequality ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts1 = new RealTimeSignum (0);
RealTimeSignum rts2 = new RealTimeSignum (1);
Assert.That (rts1.GetHashCode (), Is.Not.EqualTo(rts2.GetHashCode ()));
[Test]
public void TestIsRTSignalPropertyForRTSignum ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
UnixSignal signal1 = new UnixSignal(new RealTimeSignum (0));
Assert.That (signal1.IsRealTimeSignal, Is.True);
}
[Test]
public void TestIsRTSignalPropertyForSignum ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
Assert.That (signal1.IsRealTimeSignal, Is.False);
}
--- /dev/null
+//
+// socket-related test cases
+//
+// Authors:
+// Steffen Kiess (s-kiess@web.de)
+//
+// Copyright (C) 2015 Steffen Kiess
+//
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Runtime.InteropServices;
+
+using Mono.Unix;
+using Mono.Unix.Native;
+
+using NUnit.Framework;
+
+namespace MonoTests.Mono.Unix.Native
+{
+ [TestFixture, Category ("NotDotNet")]
+ public class SocketTest {
+
+ string TempFolder;
+
+ [SetUp]
+ public void SetUp ()
+ {
+ TempFolder = Path.Combine (Path.GetTempPath (), this.GetType ().FullName);
+
+ if (Directory.Exists (TempFolder))
+ Directory.Delete (TempFolder, true);
+
+ Directory.CreateDirectory (TempFolder);
+ }
+
+ [TearDown]
+ public void TearDown()
+ {
+ if (Directory.Exists (TempFolder))
+ Directory.Delete (TempFolder, true);
+ }
+
+ // Set a timeout on all sockets to make sure that if a test fails it
+ // won't cause the program to hang
+ void SetTimeout (int socket)
+ {
+ var timeout = new Timeval {
+ tv_sec = 0,
+ tv_usec = 500000,
+ };
+ if (Syscall.setsockopt (socket, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_RCVTIMEO, timeout) < 0 ||
+ Syscall.setsockopt (socket, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_SNDTIMEO, timeout) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+
+ void WithSocketPair (Action<int, int> f)
+ {
+ int socket1, socket2;
+ if (Syscall.socketpair (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ try {
+ SetTimeout (socket1);
+ SetTimeout (socket2);
+
+ f (socket1, socket2);
+ } finally {
+ int r0 = Syscall.close (socket1);
+ int r1 = Syscall.close (socket2);
+ if (r0 < 0 || r1 < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+ }
+
+ void WithSockets (UnixAddressFamily af, UnixSocketType type, UnixSocketProtocol protocol, Action<int, int> f)
+ {
+ int so1, so2;
+ if ((so1 = Syscall.socket (af, type, protocol)) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ try {
+ if ((so2 = Syscall.socket (af, type, protocol)) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ try {
+ SetTimeout (so1);
+ SetTimeout (so2);
+
+ f (so1, so2);
+ } finally {
+ if (Syscall.close (so2) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+ } finally {
+ if (Syscall.close (so1) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+ }
+
+ [Test]
+ public void Socket ()
+ {
+ int socket;
+ if ((socket = Syscall.socket (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0)) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ if (Syscall.close (socket) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+
+ [Test]
+ public void SocketPair ()
+ {
+ int socket1, socket2;
+ if (Syscall.socketpair (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, out socket1, out socket2) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ int r0 = Syscall.close (socket1);
+ int r1 = Syscall.close (socket2);
+ if (r0 < 0 || r1 < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ }
+
+ [Test]
+ public void SendRecv ()
+ {
+ WithSocketPair ((so1, so2) => {
+ long ret;
+ var buffer1 = new byte[] { 42, 43, 44 };
+ ret = Syscall.send (so1, buffer1, (ulong) buffer1.Length, 0);
+ if (ret < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ var buffer2 = new byte[1024];
+ ret = Syscall.recv (so2, buffer2, (ulong) buffer2.Length, 0);
+ if (ret < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ Assert.AreEqual (buffer1.Length, ret);
+ for (int i = 0; i < buffer1.Length; i++)
+ Assert.AreEqual (buffer1[i], buffer2[i]);
+ });
+ }
+
+ [Test]
+ public void SockOpt ()
+ {
+ WithSockets (UnixAddressFamily.AF_UNIX, UnixSocketType.SOCK_STREAM, 0, (so1, so2) => {
+ // Set SO_REUSEADDR to 1
+ if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, 1) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ // Get and check SO_REUSEADDR
+ int value;
+ if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, out value) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ Assert.AreEqual (value, 1);
+
+ // Set SO_REUSEADDR to 0
+ if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, new byte[10], 4) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ // Get and check SO_REUSEADDR
+ var buffer = new byte[15];
+ long size = 12;
+ if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_REUSEADDR, buffer, ref size) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ Assert.AreEqual (size, 4);
+ for (int i = 0; i < size; i++)
+ Assert.AreEqual (buffer[i], 0);
+ });
+ }
+
+ [Test]
+ public void SockOptLinger ()
+ {
+ WithSockets (UnixAddressFamily.AF_INET, UnixSocketType.SOCK_STREAM, UnixSocketProtocol.IPPROTO_TCP, (so1, so2) => {
+ Linger linger = new Linger {
+ l_onoff = 1,
+ l_linger = 42,
+ };
+ // Set SO_LINGER
+ if (Syscall.setsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, linger) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ // Get and check SO_LINGER
+ Linger value;
+ if (Syscall.getsockopt (so1, UnixSocketProtocol.SOL_SOCKET, UnixSocketOptionName.SO_LINGER, out value) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+ Assert.AreEqual (linger, value);
+ });
+ }
+
+ [Test]
+ public void Shutdown ()
+ {
+ WithSocketPair ((so1, so2) => {
+ if (Syscall.shutdown (so1, ShutdownOption.SHUT_WR) < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ var buffer2 = new byte[1024];
+ long ret = Syscall.recv (so2, buffer2, (ulong) buffer2.Length, 0);
+ if (ret < 0)
+ UnixMarshal.ThrowExceptionForLastError ();
+
+ Assert.AreEqual (ret, 0);
+ });
+ }
+ }
+}
+
+// vim: noexpandtab
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// End:
using System.Text;
using System.Threading;
using Mono.Unix;
+using Mono.Unix.Android;
using Mono.Unix.Native;
#if !MONODROID
namespace NUnit.Framework.SyntaxHelpers { class Dummy {} }
}
[Test]
+ [Category ("AndroidNotWorking")] // Crashes (silently) the runtime in similar fashion to real-time signals
public void TestSignumProperty ()
{
UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
[Category ("NotOnMac")]
public void TestRealTimeCstor ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts = new RealTimeSignum (0);
using (UnixSignal s = new UnixSignal (rts))
{
[Category ("NotOnMac")]
public void TestSignumPropertyThrows ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
UnixSignal signal1 = new UnixSignal (new RealTimeSignum (0));
Signum s = signal1.Signum;
}
[Category ("NotOnMac")]
public void TestRealTimeSignumProperty ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts = new RealTimeSignum (0);
UnixSignal signal1 = new UnixSignal (rts);
Assert.That (signal1.RealTimeSignum, Is.EqualTo (rts));
[Category ("NotOnMac")]
public void TestRealTimePropertyThrows ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
UnixSignal signal1 = new UnixSignal (Signum.SIGSEGV);
RealTimeSignum s = signal1.RealTimeSignum;
}
[Category ("NotOnMac")]
public void TestRaiseRTMINSignal ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
RealTimeSignum rts = new RealTimeSignum (0);
using (UnixSignal signal = new UnixSignal (rts))
{
[Category ("NotOnMac")]
public void TestRaiseRTMINPlusOneSignal ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
/*this number is a guestimate, but it's ok*/
for (int i = 1; i < 10; ++i) {
RealTimeSignum rts = new RealTimeSignum (i);
[Category ("NotOnMac")]
public void TestCanRegisterRTSignalMultipleTimes ()
{
+ if (!TestHelper.CanUseRealTimeSignals ())
+ return;
/*this number is a guestimate, but it's ok*/
for (int i = 1; i < 10; ++i) {
RealTimeSignum rts = new RealTimeSignum (i);
-#include net_4_5_System.Core.dll.sources
+#include net_4_x_System.Core.dll.sources
-#include net_4_5_System.Data.dll.sources
+#include net_4_x_System.Data.dll.sources
first = false;
}
+ // Return null for empty values list
+ if (first)
+ return null;
+
return sb.ToString ();
}
using System.Threading.Tasks;
using System.Collections.Specialized;
using System.Net.Http.Headers;
+using System.Linq;
namespace System.Net.Http
{
// Add request headers
var headers = wr.Headers;
foreach (var header in request.Headers) {
- headers.AddValue (header.Key, HttpRequestHeaders.GetSingleHeaderString (header.Key, header.Value));
+ var values = header.Value;
+ if (header.Key == "Transfer-Encoding") {
+ // Chunked Transfer-Encoding is never set for HttpWebRequest. It's detected
+ // from ContentLength by HttpWebRequest
+ values = values.Where (l => l != "chunked");
+ }
+
+ var values_formated = HttpRequestHeaders.GetSingleHeaderString (header.Key, values);
+ if (values_formated == null)
+ continue;
+
+ headers.AddValue (header.Key, values_formated);
}
return wr;
}
}
+ [Test]
+ public void Send_Transfer_Encoding_Chunked ()
+ {
+ bool? failed = null;
+
+ var listener = CreateListener (l => {
+ var request = l.Request;
+
+ try {
+ Assert.AreEqual (1, request.Headers.Count, "#1");
+ failed = false;
+ } catch {
+ failed = true;
+ }
+ });
+
+ try {
+ var client = new HttpClient ();
+ client.DefaultRequestHeaders.TransferEncodingChunked = true;
+
+ client.GetAsync (LocalServer).Wait ();
+
+ Assert.AreEqual (false, failed, "#102");
+ } finally {
+ listener.Abort ();
+ listener.Close ();
+ }
+ }
+
+ [Test]
+ public void Send_Transfer_Encoding_Custom ()
+ {
+ bool? failed = null;
+
+ var listener = CreateListener (l => {
+ failed = true;
+ });
+
+ try {
+ var client = new HttpClient ();
+ client.DefaultRequestHeaders.TransferEncoding.Add (new TransferCodingHeaderValue ("chunked2"));
+
+ var request = new HttpRequestMessage (HttpMethod.Get, LocalServer);
+
+ try {
+ client.SendAsync (request, HttpCompletionOption.ResponseHeadersRead).Wait ();
+ Assert.Fail ("#1");
+ } catch (AggregateException e) {
+ Assert.AreEqual (typeof (ProtocolViolationException), e.InnerException.GetType (), "#2");
+ }
+ Assert.IsNull (failed, "#102");
+ } finally {
+ listener.Abort ();
+ listener.Close ();
+ }
+ }
[Test]
public void Send_Complete_Content ()
+++ /dev/null
-../../build/common/Consts.cs
-Assembly/AssemblyInfo.cs
-System.Net.Http/ByteArrayContent.cs
-System.Net.Http/ClientCertificateOption.cs
-System.Net.Http/DelegatingHandler.cs
-System.Net.Http/FormUrlEncodedContent.cs
-System.Net.Http/HttpClient.cs
-System.Net.Http/HttpClientHandler.cs
-System.Net.Http/HttpCompletionOption.cs
-System.Net.Http/HttpContent.cs
-System.Net.Http/HttpMessageHandler.cs
-System.Net.Http/HttpMessageInvoker.cs
-System.Net.Http/HttpMethod.cs
-System.Net.Http/HttpRequestException.cs
-System.Net.Http/HttpRequestMessage.cs
-System.Net.Http/HttpResponseMessage.cs
-System.Net.Http/MessageProcessingHandler.cs
-System.Net.Http/MultipartContent.cs
-System.Net.Http/MultipartFormDataContent.cs
-System.Net.Http/StreamContent.cs
-System.Net.Http/StringContent.cs
-System.Net.Http.Headers/AuthenticationHeaderValue.cs
-System.Net.Http.Headers/CacheControlHeaderValue.cs
-System.Net.Http.Headers/CollectionExtensions.cs
-System.Net.Http.Headers/CollectionParser.cs
-System.Net.Http.Headers/ContentDispositionHeaderValue.cs
-System.Net.Http.Headers/ContentRangeHeaderValue.cs
-System.Net.Http.Headers/EntityTagHeaderValue.cs
-System.Net.Http.Headers/HashCodeCalculator.cs
-System.Net.Http.Headers/HeaderInfo.cs
-System.Net.Http.Headers/HttpContentHeaders.cs
-System.Net.Http.Headers/HttpHeaderKind.cs
-System.Net.Http.Headers/HttpHeaders.cs
-System.Net.Http.Headers/HttpHeaderValueCollection.cs
-System.Net.Http.Headers/HttpRequestHeaders.cs
-System.Net.Http.Headers/HttpResponseHeaders.cs
-System.Net.Http.Headers/Lexer.cs
-System.Net.Http.Headers/MediaTypeHeaderValue.cs
-System.Net.Http.Headers/MediaTypeWithQualityHeaderValue.cs
-System.Net.Http.Headers/NameValueHeaderValue.cs
-System.Net.Http.Headers/NameValueWithParametersHeaderValue.cs
-System.Net.Http.Headers/Parser.cs
-System.Net.Http.Headers/ProductHeaderValue.cs
-System.Net.Http.Headers/ProductInfoHeaderValue.cs
-System.Net.Http.Headers/QualityValue.cs
-System.Net.Http.Headers/RangeConditionHeaderValue.cs
-System.Net.Http.Headers/RangeHeaderValue.cs
-System.Net.Http.Headers/RangeItemHeaderValue.cs
-System.Net.Http.Headers/RetryConditionHeaderValue.cs
-System.Net.Http.Headers/StringWithQualityHeaderValue.cs
-System.Net.Http.Headers/TransferCodingHeaderValue.cs
-System.Net.Http.Headers/TransferCodingWithQualityHeaderValue.cs
-System.Net.Http.Headers/ViaHeaderValue.cs
-System.Net.Http.Headers/WarningHeaderValue.cs
\ No newline at end of file
+++ /dev/null
-#include monotouch_System.Net.Http.dll.sources
\ No newline at end of file
};
[Test] // HttpChannel.Parse ()
- [Ignore ("Fails on MS")]
+ [Category ("NotWorking")] // Fails on MS
public void ParseURL ()
{
HttpChannel channel;
-#include net_4_5_System.Runtime.Serialization.dll.sources
+#include net_4_x_System.Runtime.Serialization.dll.sources
{
Message msg;
var input = (IInputChannel) result.AsyncState;
- if (input.EndTryReceive (result, out msg))
- ProcessInput (input, msg);
- else
+ try {
+ if (input.EndTryReceive (result, out msg))
+ ProcessInput (input, msg);
+ else
+ input.Close ();
+ } catch (ObjectDisposedException) {
input.Close ();
+ }
}
void ProcessRequest (IReplyChannel reply, RequestContext rc)
if (p == parameters)
return retval;
- if (p.Length != parameters.Length)
- throw new InvalidOperationException ();
Array.Copy (p, parameters, p.Length);
return retval;
}
System.ServiceModel.Dispatcher/ActionFilterTest.cs
System.ServiceModel.Dispatcher/Bug652331Test.cs
System.ServiceModel.Dispatcher/Bug652331_2Test.cs
+System.ServiceModel.Dispatcher/Bug32886Test.cs
System.ServiceModel.Dispatcher/ChannelDispatcherTest.cs
System.ServiceModel.Dispatcher/DispatchOperationTest.cs
System.ServiceModel.Dispatcher/DispatchRuntimeTest.cs
--- /dev/null
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2015 Xamarin, Inc.
+//
+// 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;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.ServiceModel;
+using System.ServiceModel.Description;
+using System.Threading;
+using NUnit.Framework;
+
+using WebServiceMoonlightTest.ServiceReference1;
+
+using MonoTests.Helpers;
+
+namespace MonoTests.System.ServiceModel.Dispatcher
+{
+ [TestFixture]
+ public class Bug32886
+ {
+ [Test]
+ public void Bug32886_Test () // test in one of the comment
+ {
+ // Init service
+ int port = NetworkHelpers.FindFreePort ();
+ ServiceHost serviceHost = new ServiceHost (typeof (TempConvertSoapImpl), new Uri ("http://localhost:" + port + "/TempConvertSoap"));
+ serviceHost.AddServiceEndpoint (typeof (TempConvertSoap), new BasicHttpBinding (), string.Empty);
+
+ // Enable metadata exchange (WSDL publishing)
+ var mexBehavior = new ServiceMetadataBehavior ();
+ mexBehavior.HttpGetEnabled = true;
+ serviceHost.Description.Behaviors.Add (mexBehavior);
+ serviceHost.AddServiceEndpoint (typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
+
+ serviceHost.Open ();
+
+ try {
+ // client
+ var binding = new BasicHttpBinding ();
+ var remoteAddress = new EndpointAddress ("http://localhost:" + port + "/TempConvertSoap");
+ var client = new TempConvertSoapClient (binding, remoteAddress);
+
+ var wait = new ManualResetEvent (false);
+ client.CelsiusToFahrenheitCompleted += delegate (object o, CelsiusToFahrenheitCompletedEventArgs e) {
+ if (e.Error != null)
+ throw e.Error;
+ Assert.AreEqual ("76.1", e.Result, "#1");
+ wait.Set ();
+ };
+
+ client.CelsiusToFahrenheitAsync ("24.5");
+ if (!wait.WaitOne (TimeSpan.FromSeconds (20)))
+ Assert.Fail ("timeout");
+ } finally {
+ serviceHost.Close ();
+ }
+ }
+
+ class TempConvertSoapImpl : TempConvertSoap
+ {
+ public FahrenheitToCelsiusResponse FarenheitToCelsius (FahrenheitToCelsiusRequest request)
+ {
+ var farenheit = double.Parse (request.Body.Fahrenheit);
+ var celsius = ((farenheit - 32) / 9) * 5;
+ return new FahrenheitToCelsiusResponse (new FahrenheitToCelsiusResponseBody (celsius.ToString ()));
+ }
+
+ public CelsiusToFahrenheitResponse CelsiusToFarenheit (CelsiusToFahrenheitRequest request)
+ {
+ var celsius = double.Parse (request.Body.Celsius);
+ var farenheit = ((celsius * 9) / 5) + 32;
+ return new CelsiusToFahrenheitResponse (new CelsiusToFahrenheitResponseBody (farenheit.ToString ()));
+ }
+
+ Func<FahrenheitToCelsiusRequest,FahrenheitToCelsiusResponse> farenheitToCelsius;
+ Func<CelsiusToFahrenheitRequest,CelsiusToFahrenheitResponse> celsiusToFarenheit;
+
+ public IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, AsyncCallback callback, object asyncState)
+ {
+ if (farenheitToCelsius == null)
+ farenheitToCelsius = new Func<FahrenheitToCelsiusRequest,FahrenheitToCelsiusResponse> (FarenheitToCelsius);
+ return farenheitToCelsius.BeginInvoke (request, callback, asyncState);
+ }
+
+ public FahrenheitToCelsiusResponse EndFahrenheitToCelsius (IAsyncResult result)
+ {
+ return farenheitToCelsius.EndInvoke (result);
+ }
+
+ public IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, AsyncCallback callback, object asyncState)
+ {
+ if (celsiusToFarenheit == null)
+ celsiusToFarenheit = new Func<CelsiusToFahrenheitRequest,CelsiusToFahrenheitResponse> (CelsiusToFarenheit);
+ return celsiusToFarenheit.BeginInvoke (request, callback, asyncState);
+ }
+
+ public CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (IAsyncResult result)
+ {
+ return celsiusToFarenheit.EndInvoke (result);
+ }
+ }
+ }
+}
+
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.34003
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+//
+// This code was auto-generated by SlSvcUtil, version 5.0.61118.0
+//
+
+
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ServiceModel.ServiceContractAttribute (Namespace = "http://www.w3schools.com/webservices/", ConfigurationName = "TempConvertSoap")]
+public interface TempConvertSoap
+{
+
+ [System.ServiceModel.OperationContractAttribute (AsyncPattern = true, Action = "http://www.w3schools.com/webservices/FahrenheitToCelsius", ReplyAction = "*")]
+ System.IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState);
+
+ FahrenheitToCelsiusResponse EndFahrenheitToCelsius (System.IAsyncResult result);
+
+ [System.ServiceModel.OperationContractAttribute (AsyncPattern = true, Action = "http://www.w3schools.com/webservices/CelsiusToFahrenheit", ReplyAction = "*")]
+ System.IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState);
+
+ CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (System.IAsyncResult result);
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class FahrenheitToCelsiusRequest
+{
+
+ [System.ServiceModel.MessageBodyMemberAttribute (Name = "FahrenheitToCelsius", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+ public FahrenheitToCelsiusRequestBody Body;
+
+ public FahrenheitToCelsiusRequest ()
+ {
+ }
+
+ public FahrenheitToCelsiusRequest (FahrenheitToCelsiusRequestBody Body)
+ {
+ this.Body = Body;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class FahrenheitToCelsiusRequestBody
+{
+
+ [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+ public string Fahrenheit;
+
+ public FahrenheitToCelsiusRequestBody ()
+ {
+ }
+
+ public FahrenheitToCelsiusRequestBody (string Fahrenheit)
+ {
+ this.Fahrenheit = Fahrenheit;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class FahrenheitToCelsiusResponse
+{
+
+ [System.ServiceModel.MessageBodyMemberAttribute (Name = "FahrenheitToCelsiusResponse", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+ public FahrenheitToCelsiusResponseBody Body;
+
+ public FahrenheitToCelsiusResponse ()
+ {
+ }
+
+ public FahrenheitToCelsiusResponse (FahrenheitToCelsiusResponseBody Body)
+ {
+ this.Body = Body;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class FahrenheitToCelsiusResponseBody
+{
+
+ [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+ public string FahrenheitToCelsiusResult;
+
+ public FahrenheitToCelsiusResponseBody ()
+ {
+ }
+
+ public FahrenheitToCelsiusResponseBody (string FahrenheitToCelsiusResult)
+ {
+ this.FahrenheitToCelsiusResult = FahrenheitToCelsiusResult;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class CelsiusToFahrenheitRequest
+{
+
+ [System.ServiceModel.MessageBodyMemberAttribute (Name = "CelsiusToFahrenheit", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+ public CelsiusToFahrenheitRequestBody Body;
+
+ public CelsiusToFahrenheitRequest ()
+ {
+ }
+
+ public CelsiusToFahrenheitRequest (CelsiusToFahrenheitRequestBody Body)
+ {
+ this.Body = Body;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class CelsiusToFahrenheitRequestBody
+{
+
+ [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+ public string Celsius;
+
+ public CelsiusToFahrenheitRequestBody ()
+ {
+ }
+
+ public CelsiusToFahrenheitRequestBody (string Celsius)
+ {
+ this.Celsius = Celsius;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.ServiceModel.MessageContractAttribute (IsWrapped = false)]
+public partial class CelsiusToFahrenheitResponse
+{
+
+ [System.ServiceModel.MessageBodyMemberAttribute (Name = "CelsiusToFahrenheitResponse", Namespace = "http://www.w3schools.com/webservices/", Order = 0)]
+ public CelsiusToFahrenheitResponseBody Body;
+
+ public CelsiusToFahrenheitResponse ()
+ {
+ }
+
+ public CelsiusToFahrenheitResponse (CelsiusToFahrenheitResponseBody Body)
+ {
+ this.Body = Body;
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+[System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+[System.Runtime.Serialization.DataContractAttribute (Namespace = "http://www.w3schools.com/webservices/")]
+public partial class CelsiusToFahrenheitResponseBody
+{
+
+ [System.Runtime.Serialization.DataMemberAttribute (EmitDefaultValue = false, Order = 0)]
+ public string CelsiusToFahrenheitResult;
+
+ public CelsiusToFahrenheitResponseBody ()
+ {
+ }
+
+ public CelsiusToFahrenheitResponseBody (string CelsiusToFahrenheitResult)
+ {
+ this.CelsiusToFahrenheitResult = CelsiusToFahrenheitResult;
+ }
+}
+
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public interface TempConvertSoapChannel : TempConvertSoap, System.ServiceModel.IClientChannel
+{
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class FahrenheitToCelsiusCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
+{
+
+ private object[] results;
+
+ public FahrenheitToCelsiusCompletedEventArgs (object[] results, System.Exception exception, bool cancelled, object userState) :
+ base (exception, cancelled, userState)
+ {
+ this.results = results;
+ }
+
+ public string Result {
+ get {
+ base.RaiseExceptionIfNecessary ();
+ return ((string)(this.results [0]));
+ }
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class CelsiusToFahrenheitCompletedEventArgs : System.ComponentModel.AsyncCompletedEventArgs
+{
+
+ private object[] results;
+
+ public CelsiusToFahrenheitCompletedEventArgs (object[] results, System.Exception exception, bool cancelled, object userState) :
+ base (exception, cancelled, userState)
+ {
+ this.results = results;
+ }
+
+ public string Result {
+ get {
+ base.RaiseExceptionIfNecessary ();
+ return ((string)(this.results [0]));
+ }
+ }
+}
+
+[System.Diagnostics.DebuggerStepThroughAttribute ()]
+[System.CodeDom.Compiler.GeneratedCodeAttribute ("System.ServiceModel", "4.0.0.0")]
+public partial class TempConvertSoapClient : System.ServiceModel.ClientBase<TempConvertSoap>, TempConvertSoap
+{
+
+ private BeginOperationDelegate onBeginFahrenheitToCelsiusDelegate;
+
+ private EndOperationDelegate onEndFahrenheitToCelsiusDelegate;
+
+ private System.Threading.SendOrPostCallback onFahrenheitToCelsiusCompletedDelegate;
+
+ private BeginOperationDelegate onBeginCelsiusToFahrenheitDelegate;
+
+ private EndOperationDelegate onEndCelsiusToFahrenheitDelegate;
+
+ private System.Threading.SendOrPostCallback onCelsiusToFahrenheitCompletedDelegate;
+
+ private BeginOperationDelegate onBeginOpenDelegate;
+
+ private EndOperationDelegate onEndOpenDelegate;
+
+ private System.Threading.SendOrPostCallback onOpenCompletedDelegate;
+
+ private BeginOperationDelegate onBeginCloseDelegate;
+
+ private EndOperationDelegate onEndCloseDelegate;
+
+ private System.Threading.SendOrPostCallback onCloseCompletedDelegate;
+
+ public TempConvertSoapClient ()
+ {
+ }
+
+ public TempConvertSoapClient (string endpointConfigurationName) :
+ base (endpointConfigurationName)
+ {
+ }
+
+ public TempConvertSoapClient (string endpointConfigurationName, string remoteAddress) :
+ base (endpointConfigurationName, remoteAddress)
+ {
+ }
+
+ public TempConvertSoapClient (string endpointConfigurationName, System.ServiceModel.EndpointAddress remoteAddress) :
+ base (endpointConfigurationName, remoteAddress)
+ {
+ }
+
+ public TempConvertSoapClient (System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
+ base (binding, remoteAddress)
+ {
+ }
+
+ public System.Net.CookieContainer CookieContainer {
+ get {
+ System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager> ();
+ if ((httpCookieContainerManager != null)) {
+ return httpCookieContainerManager.CookieContainer;
+ } else {
+ return null;
+ }
+ }
+ set {
+ System.ServiceModel.Channels.IHttpCookieContainerManager httpCookieContainerManager = this.InnerChannel.GetProperty<System.ServiceModel.Channels.IHttpCookieContainerManager> ();
+ if ((httpCookieContainerManager != null)) {
+ httpCookieContainerManager.CookieContainer = value;
+ } else {
+ throw new System.InvalidOperationException ("Unable to set the CookieContainer. Please make sure the binding contains an HttpC" +
+ "ookieContainerBindingElement.");
+ }
+ }
+ }
+
+ public event System.EventHandler<FahrenheitToCelsiusCompletedEventArgs> FahrenheitToCelsiusCompleted;
+
+ public event System.EventHandler<CelsiusToFahrenheitCompletedEventArgs> CelsiusToFahrenheitCompleted;
+
+ public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> OpenCompleted;
+
+ public event System.EventHandler<System.ComponentModel.AsyncCompletedEventArgs> CloseCompleted;
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ System.IAsyncResult TempConvertSoap.BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState)
+ {
+ return base.Channel.BeginFahrenheitToCelsius (request, callback, asyncState);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ private System.IAsyncResult BeginFahrenheitToCelsius (string Fahrenheit, System.AsyncCallback callback, object asyncState)
+ {
+ FahrenheitToCelsiusRequest inValue = new FahrenheitToCelsiusRequest ();
+ inValue.Body = new FahrenheitToCelsiusRequestBody ();
+ inValue.Body.Fahrenheit = Fahrenheit;
+ return ((TempConvertSoap)(this)).BeginFahrenheitToCelsius (inValue, callback, asyncState);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ FahrenheitToCelsiusResponse TempConvertSoap.EndFahrenheitToCelsius (System.IAsyncResult result)
+ {
+ return base.Channel.EndFahrenheitToCelsius (result);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ private string EndFahrenheitToCelsius (System.IAsyncResult result)
+ {
+ FahrenheitToCelsiusResponse retVal = ((TempConvertSoap)(this)).EndFahrenheitToCelsius (result);
+ return retVal.Body.FahrenheitToCelsiusResult;
+ }
+
+ private System.IAsyncResult OnBeginFahrenheitToCelsius (object[] inValues, System.AsyncCallback callback, object asyncState)
+ {
+ string Fahrenheit = ((string)(inValues [0]));
+ return this.BeginFahrenheitToCelsius (Fahrenheit, callback, asyncState);
+ }
+
+ private object[] OnEndFahrenheitToCelsius (System.IAsyncResult result)
+ {
+ string retVal = this.EndFahrenheitToCelsius (result);
+ return new object[] {
+ retVal
+ };
+ }
+
+ private void OnFahrenheitToCelsiusCompleted (object state)
+ {
+ if ((this.FahrenheitToCelsiusCompleted != null)) {
+ InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+ this.FahrenheitToCelsiusCompleted (this, new FahrenheitToCelsiusCompletedEventArgs (e.Results, e.Error, e.Cancelled, e.UserState));
+ }
+ }
+
+ public void FahrenheitToCelsiusAsync (string Fahrenheit)
+ {
+ this.FahrenheitToCelsiusAsync (Fahrenheit, null);
+ }
+
+ public void FahrenheitToCelsiusAsync (string Fahrenheit, object userState)
+ {
+ if ((this.onBeginFahrenheitToCelsiusDelegate == null)) {
+ this.onBeginFahrenheitToCelsiusDelegate = new BeginOperationDelegate (this.OnBeginFahrenheitToCelsius);
+ }
+ if ((this.onEndFahrenheitToCelsiusDelegate == null)) {
+ this.onEndFahrenheitToCelsiusDelegate = new EndOperationDelegate (this.OnEndFahrenheitToCelsius);
+ }
+ if ((this.onFahrenheitToCelsiusCompletedDelegate == null)) {
+ this.onFahrenheitToCelsiusCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnFahrenheitToCelsiusCompleted);
+ }
+ base.InvokeAsync (this.onBeginFahrenheitToCelsiusDelegate, new object[] {
+ Fahrenheit
+ }, this.onEndFahrenheitToCelsiusDelegate, this.onFahrenheitToCelsiusCompletedDelegate, userState);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ System.IAsyncResult TempConvertSoap.BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState)
+ {
+ return base.Channel.BeginCelsiusToFahrenheit (request, callback, asyncState);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ private System.IAsyncResult BeginCelsiusToFahrenheit (string Celsius, System.AsyncCallback callback, object asyncState)
+ {
+ CelsiusToFahrenheitRequest inValue = new CelsiusToFahrenheitRequest ();
+ inValue.Body = new CelsiusToFahrenheitRequestBody ();
+ inValue.Body.Celsius = Celsius;
+ return ((TempConvertSoap)(this)).BeginCelsiusToFahrenheit (inValue, callback, asyncState);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ CelsiusToFahrenheitResponse TempConvertSoap.EndCelsiusToFahrenheit (System.IAsyncResult result)
+ {
+ return base.Channel.EndCelsiusToFahrenheit (result);
+ }
+
+ [System.ComponentModel.EditorBrowsableAttribute (System.ComponentModel.EditorBrowsableState.Advanced)]
+ private string EndCelsiusToFahrenheit (System.IAsyncResult result)
+ {
+ CelsiusToFahrenheitResponse retVal = ((TempConvertSoap)(this)).EndCelsiusToFahrenheit (result);
+ return retVal.Body.CelsiusToFahrenheitResult;
+ }
+
+ private System.IAsyncResult OnBeginCelsiusToFahrenheit (object[] inValues, System.AsyncCallback callback, object asyncState)
+ {
+ string Celsius = ((string)(inValues [0]));
+ return this.BeginCelsiusToFahrenheit (Celsius, callback, asyncState);
+ }
+
+ private object[] OnEndCelsiusToFahrenheit (System.IAsyncResult result)
+ {
+ string retVal = this.EndCelsiusToFahrenheit (result);
+ return new object[] {
+ retVal
+ };
+ }
+
+ private void OnCelsiusToFahrenheitCompleted (object state)
+ {
+ if ((this.CelsiusToFahrenheitCompleted != null)) {
+ InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+ this.CelsiusToFahrenheitCompleted (this, new CelsiusToFahrenheitCompletedEventArgs (e.Results, e.Error, e.Cancelled, e.UserState));
+ }
+ }
+
+ public void CelsiusToFahrenheitAsync (string Celsius)
+ {
+ this.CelsiusToFahrenheitAsync (Celsius, null);
+ }
+
+ public void CelsiusToFahrenheitAsync (string Celsius, object userState)
+ {
+ if ((this.onBeginCelsiusToFahrenheitDelegate == null)) {
+ this.onBeginCelsiusToFahrenheitDelegate = new BeginOperationDelegate (this.OnBeginCelsiusToFahrenheit);
+ }
+ if ((this.onEndCelsiusToFahrenheitDelegate == null)) {
+ this.onEndCelsiusToFahrenheitDelegate = new EndOperationDelegate (this.OnEndCelsiusToFahrenheit);
+ }
+ if ((this.onCelsiusToFahrenheitCompletedDelegate == null)) {
+ this.onCelsiusToFahrenheitCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnCelsiusToFahrenheitCompleted);
+ }
+ base.InvokeAsync (this.onBeginCelsiusToFahrenheitDelegate, new object[] {
+ Celsius
+ }, this.onEndCelsiusToFahrenheitDelegate, this.onCelsiusToFahrenheitCompletedDelegate, userState);
+ }
+
+ private System.IAsyncResult OnBeginOpen (object[] inValues, System.AsyncCallback callback, object asyncState)
+ {
+ return ((System.ServiceModel.ICommunicationObject)(this)).BeginOpen (callback, asyncState);
+ }
+
+ private object[] OnEndOpen (System.IAsyncResult result)
+ {
+ ((System.ServiceModel.ICommunicationObject)(this)).EndOpen (result);
+ return null;
+ }
+
+ private void OnOpenCompleted (object state)
+ {
+ if ((this.OpenCompleted != null)) {
+ InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+ this.OpenCompleted (this, new System.ComponentModel.AsyncCompletedEventArgs (e.Error, e.Cancelled, e.UserState));
+ }
+ }
+
+ public void OpenAsync ()
+ {
+ this.OpenAsync (null);
+ }
+
+ public void OpenAsync (object userState)
+ {
+ if ((this.onBeginOpenDelegate == null)) {
+ this.onBeginOpenDelegate = new BeginOperationDelegate (this.OnBeginOpen);
+ }
+ if ((this.onEndOpenDelegate == null)) {
+ this.onEndOpenDelegate = new EndOperationDelegate (this.OnEndOpen);
+ }
+ if ((this.onOpenCompletedDelegate == null)) {
+ this.onOpenCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnOpenCompleted);
+ }
+ base.InvokeAsync (this.onBeginOpenDelegate, null, this.onEndOpenDelegate, this.onOpenCompletedDelegate, userState);
+ }
+
+ private System.IAsyncResult OnBeginClose (object[] inValues, System.AsyncCallback callback, object asyncState)
+ {
+ return ((System.ServiceModel.ICommunicationObject)(this)).BeginClose (callback, asyncState);
+ }
+
+ private object[] OnEndClose (System.IAsyncResult result)
+ {
+ ((System.ServiceModel.ICommunicationObject)(this)).EndClose (result);
+ return null;
+ }
+
+ private void OnCloseCompleted (object state)
+ {
+ if ((this.CloseCompleted != null)) {
+ InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state));
+ this.CloseCompleted (this, new System.ComponentModel.AsyncCompletedEventArgs (e.Error, e.Cancelled, e.UserState));
+ }
+ }
+
+ public void CloseAsync ()
+ {
+ this.CloseAsync (null);
+ }
+
+ public void CloseAsync (object userState)
+ {
+ if ((this.onBeginCloseDelegate == null)) {
+ this.onBeginCloseDelegate = new BeginOperationDelegate (this.OnBeginClose);
+ }
+ if ((this.onEndCloseDelegate == null)) {
+ this.onEndCloseDelegate = new EndOperationDelegate (this.OnEndClose);
+ }
+ if ((this.onCloseCompletedDelegate == null)) {
+ this.onCloseCompletedDelegate = new System.Threading.SendOrPostCallback (this.OnCloseCompleted);
+ }
+ base.InvokeAsync (this.onBeginCloseDelegate, null, this.onEndCloseDelegate, this.onCloseCompletedDelegate, userState);
+ }
+
+ protected override TempConvertSoap CreateChannel ()
+ {
+ return new TempConvertSoapClientChannel (this);
+ }
+
+ private class TempConvertSoapClientChannel : ChannelBase<TempConvertSoap>, TempConvertSoap
+ {
+
+ public TempConvertSoapClientChannel (System.ServiceModel.ClientBase<TempConvertSoap> client) :
+ base (client)
+ {
+ }
+
+ public System.IAsyncResult BeginFahrenheitToCelsius (FahrenheitToCelsiusRequest request, System.AsyncCallback callback, object asyncState)
+ {
+ object[] _args = new object[1];
+ _args [0] = request;
+ System.IAsyncResult _result = base.BeginInvoke ("FahrenheitToCelsius", _args, callback, asyncState);
+ return _result;
+ }
+
+ public FahrenheitToCelsiusResponse EndFahrenheitToCelsius (System.IAsyncResult result)
+ {
+ object[] _args = new object[0];
+ FahrenheitToCelsiusResponse _result = ((FahrenheitToCelsiusResponse)(base.EndInvoke ("FahrenheitToCelsius", _args, result)));
+ return _result;
+ }
+
+ public System.IAsyncResult BeginCelsiusToFahrenheit (CelsiusToFahrenheitRequest request, System.AsyncCallback callback, object asyncState)
+ {
+ object[] _args = new object[1];
+ _args [0] = request;
+ System.IAsyncResult _result = base.BeginInvoke ("CelsiusToFahrenheit", _args, callback, asyncState);
+ return _result;
+ }
+
+ public CelsiusToFahrenheitResponse EndCelsiusToFahrenheit (System.IAsyncResult result)
+ {
+ object[] _args = new object[0];
+ CelsiusToFahrenheitResponse _result = ((CelsiusToFahrenheitResponse)(base.EndInvoke ("CelsiusToFahrenheit", _args, result)));
+ return _result;
+ }
+ }
+}
serviceHost.AddServiceEndpoint (typeof (IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding (), "mex");
serviceHost.Open ();
+ Thread.Sleep (2000); // let WCF spin up
try {
// client
using System.Collections.Generic;
using System.Security;
using System.Threading;
+using Microsoft.Win32.SafeHandles;
namespace System.Diagnostics {
return(ret);
}
- private static bool Start_noshell (ProcessStartInfo startInfo,
- Process process)
+ //
+ // Creates a pipe with read and write descriptors
+ //
+ static void CreatePipe (out IntPtr read, out IntPtr write, bool writeDirection)
{
- ProcInfo proc_info=new ProcInfo();
- IntPtr stdin_rd = IntPtr.Zero, stdin_wr = IntPtr.Zero;
- IntPtr stdout_wr;
- IntPtr stderr_wr;
- bool ret;
- MonoIOError error;
+ //
+ // Creates read/write pipe from parent -> child perspective
+ // a child process uses same descriptors after fork. That's
+ // 4 descriptors in total where only 2. One in child, one in parent
+ // should be active and the other 2 closed. Which ones depends on
+ // comunication direction
+ //
+ // parent --------> child (parent can write, child can read)
+ //
+ // read: closed read: used
+ // write: used write: closed
+ //
+ //
+ // parent <-------- child (parent can read, child can write)
+ //
+ // read: used read: closed
+ // write: closed write: used
+ //
+ // It can still be tricky for predefined descriptiors http://unixwiz.net/techtips/remap-pipe-fds.html
+ //
+ var ret = MonoIO.CreatePipe (out read, out write);
+ if (!ret)
+ throw new IOException ("Error creating process pipe");
+
+ if (IsWindows) {
+ const int DUPLICATE_SAME_ACCESS = 0x00000002;
+ var tmp = writeDirection ? write : read;
+
+ ret = MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, tmp,
+ Process.GetCurrentProcess ().Handle, out tmp, 0, 0, DUPLICATE_SAME_ACCESS);
+ if (!ret)
+ return;
+
+ MonoIOError error;
+ if (writeDirection) {
+ MonoIO.Close (write, out error);
+ write = tmp;
+ } else {
+ MonoIO.Close (read, out error);
+ read = tmp;
+ }
+ }
+ }
+
+ static bool Start_noshell (ProcessStartInfo startInfo, Process process)
+ {
+ var proc_info = new ProcInfo ();
if (startInfo.HaveEnvVars) {
string [] strs = new string [startInfo.EnvironmentVariables.Count];
proc_info.envValues = strs;
}
- if (startInfo.RedirectStandardInput == true) {
- if (IsWindows) {
- int DUPLICATE_SAME_ACCESS = 0x00000002;
- IntPtr stdin_wr_tmp;
+ MonoIOError error;
+ IntPtr stdin_read = IntPtr.Zero, stdin_write = IntPtr.Zero;
+ IntPtr stdout_read = IntPtr.Zero, stdout_write = IntPtr.Zero;
+ IntPtr stderr_read = IntPtr.Zero, stderr_write = IntPtr.Zero;
- ret = MonoIO.CreatePipe (out stdin_rd,
- out stdin_wr_tmp);
- if (ret) {
- ret = MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, stdin_wr_tmp,
- Process.GetCurrentProcess ().Handle, out stdin_wr, 0, 0, DUPLICATE_SAME_ACCESS);
- MonoIO.Close (stdin_wr_tmp, out error);
- }
- }
- else
- {
- ret = MonoIO.CreatePipe (out stdin_rd,
- out stdin_wr);
- }
- if (ret == false) {
- throw new IOException ("Error creating standard input pipe");
+ try {
+ if (startInfo.RedirectStandardInput) {
+ CreatePipe (out stdin_read, out stdin_write, true);
+ } else {
+ stdin_read = MonoIO.ConsoleInput;
+ stdin_write = IntPtr.Zero;
}
- } else {
- stdin_rd = MonoIO.ConsoleInput;
- /* This is required to stop the
- * &$*£ing stupid compiler moaning
- * that stdin_wr is unassigned, below.
- */
- stdin_wr = (IntPtr)0;
- }
-
- if (startInfo.RedirectStandardOutput == true) {
- IntPtr out_rd = IntPtr.Zero;
- if (IsWindows) {
- IntPtr out_rd_tmp;
- int DUPLICATE_SAME_ACCESS = 0x00000002;
-
- ret = MonoIO.CreatePipe (out out_rd_tmp,
- out stdout_wr);
- if (ret) {
- MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, out_rd_tmp,
- Process.GetCurrentProcess ().Handle, out out_rd, 0, 0, DUPLICATE_SAME_ACCESS);
- MonoIO.Close (out_rd_tmp, out error);
- }
+
+ if (startInfo.RedirectStandardOutput) {
+ CreatePipe (out stdout_read, out stdout_write, false);
+ process.stdout_rd = stdout_read;
+ } else {
+ process.stdout_rd = IntPtr.Zero;
+ stdout_write = MonoIO.ConsoleOutput;
}
- else {
- ret = MonoIO.CreatePipe (out out_rd,
- out stdout_wr);
+
+ if (startInfo.RedirectStandardError) {
+ CreatePipe (out stderr_read, out stderr_write, false);
+ process.stderr_rd = stderr_read;
+ } else {
+ process.stderr_rd = IntPtr.Zero;
+ stderr_write = MonoIO.ConsoleError;
}
- process.stdout_rd = out_rd;
- if (ret == false) {
- if (startInfo.RedirectStandardInput == true) {
- MonoIO.Close (stdin_rd, out error);
- MonoIO.Close (stdin_wr, out error);
- }
+ FillUserInfo (startInfo, ref proc_info);
- throw new IOException ("Error creating standard output pipe");
+ //
+ // FIXME: For redirected pipes we need to send descriptors of
+ // stdin_write, stdout_read, stderr_read to child process and
+ // close them there (fork makes exact copy of parent's descriptors)
+ //
+ if (!CreateProcess_internal (startInfo, stdin_read, stdout_write, stderr_write, ref proc_info)) {
+ throw new Win32Exception (-proc_info.pid,
+ "ApplicationName='" + startInfo.FileName +
+ "', CommandLine='" + startInfo.Arguments +
+ "', CurrentDirectory='" + startInfo.WorkingDirectory +
+ "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid));
}
- } else {
- process.stdout_rd = (IntPtr)0;
- stdout_wr = MonoIO.ConsoleOutput;
- }
-
- if (startInfo.RedirectStandardError == true) {
- IntPtr err_rd = IntPtr.Zero;
- if (IsWindows) {
- IntPtr err_rd_tmp;
- int DUPLICATE_SAME_ACCESS = 0x00000002;
-
- ret = MonoIO.CreatePipe (out err_rd_tmp,
- out stderr_wr);
- if (ret) {
- MonoIO.DuplicateHandle (Process.GetCurrentProcess ().Handle, err_rd_tmp,
- Process.GetCurrentProcess ().Handle, out err_rd, 0, 0, DUPLICATE_SAME_ACCESS);
- MonoIO.Close (err_rd_tmp, out error);
- }
+ } catch {
+ if (startInfo.RedirectStandardInput) {
+ if (stdin_read != IntPtr.Zero)
+ MonoIO.Close (stdin_read, out error);
+ if (stdin_write != IntPtr.Zero)
+ MonoIO.Close (stdin_write, out error);
}
- else {
- ret = MonoIO.CreatePipe (out err_rd,
- out stderr_wr);
+
+ if (startInfo.RedirectStandardOutput) {
+ if (stdout_read != IntPtr.Zero)
+ MonoIO.Close (stdout_read, out error);
+ if (stdout_write != IntPtr.Zero)
+ MonoIO.Close (stdout_write, out error);
}
- process.stderr_rd = err_rd;
- if (ret == false) {
- if (startInfo.RedirectStandardInput == true) {
- MonoIO.Close (stdin_rd, out error);
- MonoIO.Close (stdin_wr, out error);
- }
- if (startInfo.RedirectStandardOutput == true) {
- MonoIO.Close (process.stdout_rd, out error);
- MonoIO.Close (stdout_wr, out error);
- }
-
- throw new IOException ("Error creating standard error pipe");
+ if (startInfo.RedirectStandardError) {
+ if (stderr_read != IntPtr.Zero)
+ MonoIO.Close (stderr_read, out error);
+ if (stderr_write != IntPtr.Zero)
+ MonoIO.Close (stderr_write, out error);
}
- } else {
- process.stderr_rd = (IntPtr)0;
- stderr_wr = MonoIO.ConsoleError;
- }
- FillUserInfo (startInfo, ref proc_info);
- try {
- ret = CreateProcess_internal (startInfo,
- stdin_rd, stdout_wr, stderr_wr,
- ref proc_info);
+ throw;
} finally {
- if (proc_info.Password != IntPtr.Zero)
+ if (proc_info.Password != IntPtr.Zero) {
Marshal.ZeroFreeBSTR (proc_info.Password);
- proc_info.Password = IntPtr.Zero;
- }
- if (!ret) {
- if (startInfo.RedirectStandardInput == true) {
- MonoIO.Close (stdin_rd, out error);
- MonoIO.Close (stdin_wr, out error);
- }
-
- if (startInfo.RedirectStandardOutput == true) {
- MonoIO.Close (process.stdout_rd, out error);
- MonoIO.Close (stdout_wr, out error);
- }
-
- if (startInfo.RedirectStandardError == true) {
- MonoIO.Close (process.stderr_rd, out error);
- MonoIO.Close (stderr_wr, out error);
+ proc_info.Password = IntPtr.Zero;
}
-
- throw new Win32Exception (-proc_info.pid,
- "ApplicationName='" + startInfo.FileName +
- "', CommandLine='" + startInfo.Arguments +
- "', CurrentDirectory='" + startInfo.WorkingDirectory +
- "', Native error= " + Win32Exception.W32ErrorMessage (-proc_info.pid));
}
process.process_handle = proc_info.process_handle;
process.pid = proc_info.pid;
- if (startInfo.RedirectStandardInput == true) {
- MonoIO.Close (stdin_rd, out error);
- process.input_stream = new StreamWriter (new MonoSyncFileStream (stdin_wr, FileAccess.Write, true, 8192), Console.Out.Encoding);
- process.input_stream.AutoFlush = true;
+ if (startInfo.RedirectStandardInput) {
+ //
+ // FIXME: The descriptor needs to be closed but due to wapi io-layer
+ // not coping with duplicated descriptors any StandardInput write fails
+ //
+ // MonoIO.Close (stdin_read, out error);
+
+#if MOBILE
+ var stdinEncoding = Encoding.Default;
+#else
+ var stdinEncoding = Console.InputEncoding;
+#endif
+ process.input_stream = new StreamWriter (new FileStream (new SafeFileHandle (stdin_write, false), FileAccess.Write, 8192, false), stdinEncoding) {
+ AutoFlush = true
+ };
}
- Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
- Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
+ if (startInfo.RedirectStandardOutput) {
+ MonoIO.Close (stdout_write, out error);
+
+ Encoding stdoutEncoding = startInfo.StandardOutputEncoding ?? Console.Out.Encoding;
- if (startInfo.RedirectStandardOutput == true) {
- MonoIO.Close (stdout_wr, out error);
- process.output_stream = new StreamReader (new MonoSyncFileStream (process.stdout_rd, FileAccess.Read, true, 8192), stdoutEncoding, true, 8192);
+ process.output_stream = new StreamReader (new FileStream (new SafeFileHandle (stdout_read, false), FileAccess.Read, 8192, false), stdoutEncoding, true, 8192);
}
- if (startInfo.RedirectStandardError == true) {
- MonoIO.Close (stderr_wr, out error);
- process.error_stream = new StreamReader (new MonoSyncFileStream (process.stderr_rd, FileAccess.Read, true, 8192), stderrEncoding, true, 8192);
+ if (startInfo.RedirectStandardError) {
+ MonoIO.Close (stderr_write, out error);
+
+ Encoding stderrEncoding = startInfo.StandardErrorEncoding ?? Console.Out.Encoding;
+
+ process.error_stream = new StreamReader (new FileStream (new SafeFileHandle (stderr_read, false), FileAccess.Read, 8192, false), stderrEncoding, true, 8192);
}
process.StartExitCallbackIfNeeded ();
- return(ret);
+ return true;
}
// Note that ProcInfo.Password must be freed.
while (!requestStop) {
var changes = CreateChangeList (ref newFds);
- int numEvents = kevent_notimeout (conn, changes, changes.Length, eventBuffer, eventBuffer.Length, IntPtr.Zero);
+ // We are calling an icall, so have to marshal manually
+ // Marshal in
+ int ksize = Marshal.SizeOf<kevent> ();
+ var changesNative = Marshal.AllocHGlobal (ksize * changes.Length);
+ for (int i = 0; i < changes.Length; ++i)
+ Marshal.StructureToPtr (changes [i], changesNative + (i * ksize), false);
+ var eventBufferNative = Marshal.AllocHGlobal (ksize * eventBuffer.Length);
+
+ int numEvents = kevent_notimeout (ref conn, changesNative, changes.Length, eventBufferNative, eventBuffer.Length);
+
+ // Marshal out
+ Marshal.FreeHGlobal (changesNative);
+ for (int i = 0; i < numEvents; ++i)
+ eventBuffer [i] = Marshal.PtrToStructure<kevent> (eventBufferNative + (i * ksize));
+ Marshal.FreeHGlobal (eventBufferNative);
if (numEvents == -1) {
// Stop () signals us to stop by closing the connection
continue;
}
-
retries = 0;
for (var i = 0; i < numEvents; i++) {
[DllImport ("libc")]
extern static int kevent (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, [In] ref timespec time);
- [DllImport ("libc", EntryPoint="kevent")]
- extern static int kevent_notimeout (int kq, [In]kevent[] ev, int nchanges, [Out]kevent[] evtlist, int nevents, IntPtr ptr);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern static int kevent_notimeout (ref int kq, IntPtr ev, int nchanges, IntPtr evtlist, int nevents);
}
class KeventWatcher : IFileWatcher
+++ /dev/null
-//
-// System.IO.MonoSyncFileStream.cs: Synchronous FileStream with
-// asynchronous BeginRead/Write methods.
-//
-// Authors:
-// Robert Jordan (robertj@gmx.net)
-//
-// Copyright (C) 2007 Novell, Inc. (http://www.novell.com)
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Runtime.Remoting.Messaging;
-
-namespace System.IO
-{
- internal class MonoSyncFileStream : FileStream
- {
- public MonoSyncFileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize)
- : base (handle, access, ownsHandle, bufferSize, false)
- {
- }
-
- delegate void WriteDelegate (byte [] buffer, int offset, int count);
-
- public override IAsyncResult BeginWrite (byte [] buffer, int offset, int count,
- AsyncCallback cback, object state)
- {
- if (!CanWrite)
- throw new NotSupportedException ("This stream does not support writing");
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (count < 0)
- throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
-
- WriteDelegate d = new WriteDelegate (this.Write);
- return d.BeginInvoke (buffer, offset, count, cback, state);
- }
-
- public override void EndWrite (IAsyncResult asyncResult)
- {
- if (asyncResult == null)
- throw new ArgumentNullException ("asyncResult");
-
- AsyncResult ar = asyncResult as AsyncResult;
- if (ar == null)
- throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
- WriteDelegate d = ar.AsyncDelegate as WriteDelegate;
- if (d == null)
- throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
- d.EndInvoke (asyncResult);
- }
-
- delegate int ReadDelegate (byte [] buffer, int offset, int count);
-
- public override IAsyncResult BeginRead (byte [] buffer, int offset, int count,
- AsyncCallback cback, object state)
- {
- if (!CanRead)
- throw new NotSupportedException ("This stream does not support reading");
-
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (count < 0)
- throw new ArgumentOutOfRangeException ("count", "Must be >= 0");
-
- if (offset < 0)
- throw new ArgumentOutOfRangeException ("offset", "Must be >= 0");
-
- ReadDelegate d = new ReadDelegate (this.Read);
- return d.BeginInvoke (buffer, offset, count, cback, state);
- }
-
- public override int EndRead (IAsyncResult asyncResult)
- {
- if (asyncResult == null)
- throw new ArgumentNullException ("asyncResult");
-
- AsyncResult ar = asyncResult as AsyncResult;
- if (ar == null)
- throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
- ReadDelegate d = ar.AsyncDelegate as ReadDelegate;
- if (d == null)
- throw new ArgumentException ("Invalid IAsyncResult", "asyncResult");
-
- return d.EndInvoke (asyncResult);
- }
-
- }
-}
//
using System.Collections;
+using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
{
int count = chunks.Count;
int nread = 0;
+
+ var chunksForRemoving = new List<Chunk>(count);
for (int i = 0; i < count; i++) {
Chunk chunk = (Chunk) chunks [i];
- if (chunk == null)
- continue;
if (chunk.Offset == chunk.Bytes.Length) {
- chunks [i] = null;
+ chunksForRemoving.Add(chunk);
continue;
}
break;
}
+ foreach (var chunk in chunksForRemoving)
+ chunks.Remove(chunk);
+
return nread;
}
lock (this) {
idleSince = outIdleSince;
- if (removeList != null) {
+ if (removeList != null && groups != null) {
foreach (var group in removeList)
if (groups.ContainsKey (group.Name))
RemoveConnectionGroup (group);
if (setInternalLength && !no_writestream && writeBuffer != null)
request.InternalContentLength = writeBuffer.Length;
- if (!(sendChunked || request.ContentLength > -1 || no_writestream || webdav))
+ bool has_content = !no_writestream && (writeBuffer == null || request.ContentLength > -1);
+ if (!(sendChunked || has_content || no_writestream || webdav))
return false;
headersSent = true;
System.IO/InvalidDataException.cs
System.IO/IODescriptionAttribute.cs
System.IO/KeventWatcher.cs
-System.IO/MonoSyncFileStream.cs
System.IO/NotifyFilters.cs
System.IO.Ports/Handshake.cs
System.IO.Ports/ISerialStream.cs
builder.Append (scheme);
// note: mailto and news use ':', not "://", as their delimiter
- builder.Append (Uri.GetSchemeDelimiter (scheme));
+ if (UriParser.IsKnownScheme(scheme)) {
+ builder.Append (Uri.GetSchemeDelimiter (scheme));
+ }
+ else {
+ builder.Append (host.Length > 0 ? Uri.SchemeDelimiter : ":");
+ }
if (username != String.Empty) {
builder.Append (username);
if (path != String.Empty &&
builder [builder.Length - 1] != '/' &&
- path.Length > 0 && path [0] != '/')
+ path.Length > 0 && path [0] != '/' &&
+ host.Length > 0)
builder.Append ('/');
builder.Append (path);
builder.Append (query);
public int bytesRead = -1;
-// Not technically a 2.0 only test, but I use lambdas, so I need gmcs
-
[Test]
[NUnit.Framework.Category ("MobileNotWorking")]
// This was for bug #459450
p.StartInfo.RedirectStandardError = true;
var exitedCalledCounter = 0;
+ var exited = new ManualResetEventSlim ();
p.Exited += (object sender, EventArgs e) => {
exitedCalledCounter++;
Assert.IsTrue (p.HasExited);
+ exited.Set ();
};
p.EnableRaisingEvents = true;
p.BeginOutputReadLine ();
p.WaitForExit ();
+ exited.Wait (10000);
Assert.AreEqual (1, exitedCalledCounter);
Thread.Sleep (50);
Assert.AreEqual (1, exitedCalledCounter);
p.EnableRaisingEvents = true;
var exitedCalledCounter = 0;
+ var exited = new ManualResetEventSlim ();
p.Exited += (object sender, EventArgs e) => {
exitedCalledCounter++;
Assert.IsTrue (p.HasExited);
+ exited.Set ();
};
p.Start ();
p.BeginOutputReadLine ();
p.WaitForExit ();
+ exited.Wait (10000);
Assert.AreEqual (1, exitedCalledCounter);
Thread.Sleep (50);
Assert.AreEqual (1, exitedCalledCounter);
p.Dispose ();
}
+ [Test]
+ [NUnit.Framework.Category ("MobileNotWorking")]
+ public void StandardInputWrite ()
+ {
+ var psi = GetCrossPlatformStartInfo ();
+ psi.RedirectStandardInput = true;
+ psi.RedirectStandardOutput = true;
+ psi.UseShellExecute = false;
+
+ using (var p = Process.Start (psi)) {
+ for (int i = 0; i < 1024 * 9; ++i)
+ p.StandardInput.Write ('x');
+ }
+ }
+
[Test]
public void Modules () {
var modules = Process.GetCurrentProcess ().Modules;
serverThread.Start ();
Thread clientThread = new Thread (() => StartClientAndAuthenticate (state, endPoint));
clientThread.Start ();
- Assert.AreEqual (server, state.ServerAuthenticated.WaitOne (TimeSpan.FromSeconds (2)),
+ Assert.AreEqual (server, state.ServerAuthenticated.WaitOne (TimeSpan.FromSeconds (5)),
"server not authenticated");
- Assert.AreEqual (client, state.ClientAuthenticated.WaitOne (TimeSpan.FromSeconds (2)),
+ Assert.AreEqual (client, state.ClientAuthenticated.WaitOne (TimeSpan.FromSeconds (5)),
"client not authenticated");
} finally {
if (state.ClientStream != null)
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnCrapStatusCodeTest ()
{
// On purpose,
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnWrongUpgradeHeader ()
{
#pragma warning disable 4014
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ServerHandshakeReturnWrongConnectionHeader ()
{
#pragma warning disable 4014
}
[Test]
- [Category ("AndroidNotWorking")] // The test hangs when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // The test hangs when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void EchoTest ()
{
const string Payload = "This is a websocket test";
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void CloseOutputAsyncTest ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void CloseAsyncTest ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test, ExpectedException (typeof (ArgumentNullException))]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncArgTest_NoArray ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test, ExpectedException (typeof (ArgumentNullException))]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ReceiveAsyncArgTest_NoArray ()
{
Assert.IsTrue (socket.ConnectAsync (new Uri (EchoServerUrl), CancellationToken.None).Wait (5000));
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void ReceiveAsyncWrongState_Closed ()
{
try {
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncWrongState_Closed ()
{
try {
}
[Test]
- [Category ("AndroidNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
+ [Category ("MobileNotWorking")] // Fails when ran as part of the entire BCL test suite. Works when only this fixture is ran
public void SendAsyncWrongState_CloseSent ()
{
try {
// this is what ASP.NET really means (the ?)
Assert.AreEqual ("http://192.168.0.21/error404.aspx?aspxerrorpath=/WebResource.axd", ub.Uri.ToString ());
}
+
+ [Test]
+ public void NoHostname ()
+ {
+ UriBuilder ub = new UriBuilder ("about", null, -1, "config");
+ Assert.AreEqual ("about:config", ub.ToString ());
+ }
}
}
System.IO.Compression/GZipStream.cs
System.IO/InternalBufferOverflowException.cs
System.IO/InvalidDataException.cs
-System.IO/MonoSyncFileStream.cs
System.Net.Cache/HttpCacheAgeControl.cs
System.Net.Cache/HttpRequestCacheLevel.cs
System.Net.Cache/HttpRequestCachePolicy.cs
private PackageRelationship CreateRelationship (Uri targetUri, TargetMode targetMode, string relationshipType, string id, bool loading)
{
- Package.CheckIsReadOnly ();
+ if (!loading)
+ Package.CheckIsReadOnly ();
Check.TargetUri (targetUri);
Check.RelationshipTypeIsValid (relationshipType);
Check.IdIsValid (id);
{\r
Assert.IsFalse (package.PartExists(new Uri ("[Content_Types].xml", UriKind.Relative)));\r
}\r
+\r
+ [Test]\r
+ public void CheckCanGetRelationshipsIfReadOnly ()\r
+ {\r
+ using (var stream = new MemoryStream ()) {\r
+ var package = Package.Open (stream, FileMode.OpenOrCreate);\r
+ var part = package.CreatePart (uris [0], contentType);\r
+ part.CreateRelationship (part.Uri, TargetMode.Internal, "self");\r
+ package.Close ();\r
+ package = Package.Open (new MemoryStream (stream.ToArray ()), FileMode.Open, FileAccess.Read);\r
+ part = package.GetPart (uris [0]);\r
+ part.GetRelationships ();\r
+ }\r
+ }\r
}\r
}\r
{
partial class TextInfo
{
- unsafe static ushort *to_lower_data_low;
- unsafe static ushort *to_lower_data_high;
- unsafe static ushort *to_upper_data_low;
- unsafe static ushort *to_upper_data_high;
-
- [MethodImplAttribute(System.Runtime.CompilerServices.MethodImplOptions.InternalCall)]
- unsafe static extern void GetDataTablePointersLite (out ushort *to_lower_data_low, out ushort *to_lower_data_high, out ushort *to_upper_data_low, out ushort *to_upper_data_high);
-
unsafe string ToUpperInternal (string str)
{
if (str.Length == 0)
public const int METHODS_TO_SKIP = 0;
private StackFrame[] frames;
+ readonly StackTrace[] captured_traces;
private bool debug_info;
public StackTrace ()
}
public StackTrace (Exception e, int skipFrames, bool fNeedFileInfo)
- : this (e, skipFrames, fNeedFileInfo, false)
- {
- }
-
- internal StackTrace (Exception e, int skipFrames, bool fNeedFileInfo, bool returnNativeFrames)
{
if (e == null)
throw new ArgumentNullException ("e");
frames = get_trace (e, skipFrames, fNeedFileInfo);
- if (!returnNativeFrames) {
- bool resize = false;
- for (int i = 0; i < frames.Length; ++i)
- if (frames [i].GetMethod () == null)
- resize = true;
-
- if (resize) {
- var l = new List<StackFrame> ();
-
- for (int i = 0; i < frames.Length; ++i)
- if (frames [i].GetMethod () != null)
- l.Add (frames [i]);
-
- frames = l.ToArray ();
- }
- }
+ captured_traces = e.captured_traces;
}
public StackTrace (StackFrame frame)
return frames;
}
- internal bool AddFrames (StringBuilder sb, bool isException = false)
+ bool AddFrames (StringBuilder sb, bool isException = false)
{
bool printOffset;
string debugInfo, indentation;
public override string ToString ()
{
StringBuilder sb = new StringBuilder ();
+
+ //
+ // Add traces captured using ExceptionDispatchInfo
+ //
+ if (captured_traces != null) {
+ foreach (var t in captured_traces) {
+ if (!t.AddFrames (sb, true))
+ continue;
+
+ sb.Append (Environment.NewLine);
+ sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
+ sb.Append (Environment.NewLine);
+ }
+ }
+
AddFrames (sb);
return sb.ToString ();
}
: this (handle, access, ownsHandle, bufferSize, isAsync, false) {}
[SecurityPermission (SecurityAction.Demand, UnmanagedCode = true)]
- internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isZeroSize)
+ internal FileStream (IntPtr handle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isConsoleWrapper)
{
if (handle == MonoIO.InvalidHandle)
throw new ArgumentException ("handle", Locale.GetText ("Invalid."));
- Init (new SafeFileHandle (handle, false), access, ownsHandle, bufferSize, isAsync, isZeroSize);
+ Init (new SafeFileHandle (handle, false), access, ownsHandle, bufferSize, isAsync, isConsoleWrapper);
}
// construct from filename
{
}
-#if !NET_2_1
public FileStream (SafeFileHandle handle, FileAccess access)
:this(handle, access, DefaultBufferSize, false)
{
Init (handle, access, false, bufferSize, isAsync, false);
}
+#if !MOBILE
[MonoLimitation ("This ignores the rights parameter")]
public FileStream (string path, FileMode mode,
FileSystemRights rights, FileShare share,
}
}
- private void Init (SafeFileHandle safeHandle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isZeroSize)
+ private void Init (SafeFileHandle safeHandle, FileAccess access, bool ownsHandle, int bufferSize, bool isAsync, bool isConsoleWrapper)
{
+ if (!isConsoleWrapper && safeHandle.IsInvalid)
+ throw new ArgumentException(Environment.GetResourceString("Arg_InvalidHandle"), "handle");
if (access < FileAccess.Read || access > FileAccess.ReadWrite)
throw new ArgumentOutOfRangeException ("access");
+ if (!isConsoleWrapper && bufferSize <= 0)
+ throw new ArgumentOutOfRangeException("bufferSize", Environment.GetResourceString("ArgumentOutOfRange_NeedPosNum"));
MonoIOError error;
MonoFileType ftype = MonoIO.GetFileType (safeHandle, out error);
+++ /dev/null
-//
-// System.IO.IntPtrStream: A stream that is backed up by unmanaged memory
-//
-// Author:
-// Miguel de Icaza (miguel@ximian.com)
-//
-// Based on the code for MemoryStream.cs:
-//
-// Authors: Marcin Szczepanski (marcins@zipworld.com.au)
-// Patrik Torstensson
-// Gonzalo Paniagua Javier (gonzalo@ximian.com)
-//
-// (c) 2001,2002 Marcin Szczepanski, Patrik Torstensson
-// (c) 2003 Ximian, Inc. (http://www.ximian.com)
-//
-
-//
-// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.InteropServices;
-namespace System.IO {
-
- internal class IntPtrStream : Stream {
- unsafe byte *base_address;
- int size;
- int position;
- bool closed;
-
- public event EventHandler Closed;
-
- public IntPtrStream (IntPtr base_address, int size)
- {
- unsafe {
- this.base_address = (byte*)((void *)base_address);
- }
- this.size = size;
- position = 0;
- }
-
- internal IntPtr BaseAddress {
- get {
- unsafe {
- return new IntPtr ((void*) base_address);
- }
- }
- }
-
- public override bool CanRead {
- get {
- return true;
- }
- }
-
- public override bool CanSeek {
- get {
- return true;
- }
- }
-
- public override bool CanWrite {
- get {
- return false;
- }
- }
-
- public override long Position {
- get {
- return position;
- }
-
- set {
- if (position < 0)
- throw new ArgumentOutOfRangeException ("Position", "Can not be negative");
- if (position > size)
- throw new ArgumentOutOfRangeException ("Position", "Pointer falls out of range");
-
- position = (int) value;
- }
- }
-
- public override long Length {
- get {
- return size;
- }
- }
-
- public override int Read (byte [] buffer, int offset, int count)
- {
- if (buffer == null)
- throw new ArgumentNullException ("buffer");
-
- if (offset < 0 || count < 0)
- throw new ArgumentOutOfRangeException ("offset or count less than zero.");
-
- if (buffer.Length - offset < count )
- throw new ArgumentException ("offset+count",
- "The size of the buffer is less than offset + count.");
-
- if (closed)
- throw new ObjectDisposedException ("Stream has been closed");
-
- if (position >= size || count == 0)
- return 0;
-
- if (position > size - count)
- count = size - position;
-
- unsafe {
- Marshal.Copy ((IntPtr) (base_address + position), buffer, offset, count);
- }
- position += count;
- return count;
- }
-
- public override int ReadByte ()
- {
- if (position >= size)
- return -1;
-
- if (closed)
- throw new ObjectDisposedException ("Stream has been closed");
-
- unsafe {
- return base_address [position++];
- }
- }
-
- public override long Seek (long offset, SeekOrigin loc)
- {
- // It's funny that they don't throw this exception for < Int32.MinValue
- if (offset > (long) Int32.MaxValue)
- throw new ArgumentOutOfRangeException ("Offset out of range. " + offset);
-
- if (closed)
- throw new ObjectDisposedException ("Stream has been closed");
-
- int ref_point;
- switch (loc) {
- case SeekOrigin.Begin:
- if (offset < 0)
- throw new IOException ("Attempted to seek before start of MemoryStream.");
- ref_point = 0;
- break;
- case SeekOrigin.Current:
- ref_point = position;
- break;
- case SeekOrigin.End:
- ref_point = size;
- break;
- default:
- throw new ArgumentException ("loc", "Invalid SeekOrigin");
- }
-
- checked {
- try {
- ref_point += (int) offset;
- } catch {
- throw new ArgumentOutOfRangeException ("Too large seek destination");
- }
-
- if (ref_point < 0)
- throw new IOException ("Attempted to seek before start of MemoryStream.");
- }
-
- position = ref_point;
- return position;
- }
-
- public override void SetLength (long value)
- {
- throw new NotSupportedException ("This stream can not change its size");
- }
-
- public override void Write (byte [] buffer, int offset, int count)
- {
- throw new NotSupportedException ("This stream can not change its size");
- }
-
- public override void WriteByte (byte value)
- {
- throw new NotSupportedException ("This stream can not change its size");
- }
-
- public override void Flush ()
- {
- }
-
- public override void Close ()
- {
- closed = true;
-
- if (Closed != null)
- Closed (this, null);
- }
- }
-}
[MethodImplAttribute (MethodImplOptions.InternalCall)]
get;
}
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static int GetTempPath(out string path);
}
}
}
}
+ public override Module Module {
+ get {
+ return GetRuntimeModule ();
+ }
+ }
+
+ internal RuntimeType GetDeclaringTypeInternal ()
+ {
+ return (RuntimeType) DeclaringType;
+ }
+
RuntimeType ReflectedTypeInternal {
get {
return (RuntimeType) ReflectedType;
}
}
+ internal RuntimeModule GetRuntimeModule ()
+ {
+ return GetDeclaringTypeInternal ().GetRuntimeModule ();
+ }
+
#region ISerializable
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
}
+ public override Module Module {
+ get {
+ return GetRuntimeModule ();
+ }
+ }
+
+ internal RuntimeType GetDeclaringTypeInternal ()
+ {
+ return (RuntimeType) DeclaringType;
+ }
+
RuntimeType ReflectedTypeInternal {
get {
return (RuntimeType) ReflectedType;
}
}
+ internal RuntimeModule GetRuntimeModule ()
+ {
+ return GetDeclaringTypeInternal ().GetRuntimeModule ();
+ }
+
#region Object Overrides
public override String ToString()
{
[MethodImplAttribute(MethodImplOptions.InternalCall)]
extern static void try_enter_with_atomic_var (object obj, int millisecondsTimeout, ref bool lockTaken);
+ [MethodImplAttribute(MethodImplOptions.InternalCall)]
+ extern static void enter_with_atomic_var (object obj, ref bool lockTaken);
+
+ // Can't make this an icall since it has the same name as the other Enter method
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Enter (object obj, ref bool lockTaken)
{
- TryEnter (obj, Timeout.Infinite, ref lockTaken);
+ enter_with_atomic_var (obj, ref lockTaken);
}
public static void TryEnter (object obj, ref bool lockTaken)
+++ /dev/null
-//
-// System.Threading.ThreadPool.cs
-//
-// Author:
-// Patrik Torstensson
-// Dick Porter (dick@ximian.com)
-// Maurer Dietmar (dietmar@ximian.com)
-//
-// (C) Ximian, Inc. http://www.ximian.com
-// Copyright (C) 2004-2005 Novell, Inc (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Collections;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Runtime.CompilerServices;
-using System.Runtime.Remoting.Messaging;
-using System.Runtime.InteropServices;
-using System.Security;
-using System.Security.Permissions;
-
-namespace System.Threading {
-
- public static class ThreadPool {
-
- [Obsolete("This method is obsolete, use BindHandle(SafeHandle) instead")]
- public static bool BindHandle (IntPtr osHandle)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.BindHandle (osHandle);
- else
- return true;
- }
-
- public static bool BindHandle (SafeHandle osHandle)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
- return Microsoft.ThreadPool.BindHandle (osHandle);
- } else {
- if (osHandle == null)
- throw new ArgumentNullException ("osHandle");
-
- return true;
- }
- }
-
- public static void GetAvailableThreads (out int workerThreads, out int completionPortThreads)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.GetAvailableThreads (out workerThreads, out completionPortThreads);
- else
- GetAvailableThreads_internal (out workerThreads, out completionPortThreads);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern void GetAvailableThreads_internal (out int workerThreads, out int completionPortThreads);
-
- public static void GetMaxThreads (out int workerThreads, out int completionPortThreads)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.GetMaxThreads (out workerThreads, out completionPortThreads);
- else
- GetMaxThreads_internal (out workerThreads, out completionPortThreads);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern void GetMaxThreads_internal (out int workerThreads, out int completionPortThreads);
-
- public static void GetMinThreads (out int workerThreads, out int completionPortThreads)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.GetMinThreads (out workerThreads, out completionPortThreads);
- else
- GetMinThreads_internal (out workerThreads, out completionPortThreads);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern void GetMinThreads_internal (out int workerThreads, out int completionPortThreads);
-
- [MonoTODO("The min number of completion port threads is not evaluated.")]
- [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
- public static bool SetMinThreads (int workerThreads, int completionPortThreads)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.SetMinThreads (workerThreads, completionPortThreads);
- else
- return SetMinThreads_internal (workerThreads, completionPortThreads);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern bool SetMinThreads_internal (int workerThreads, int completionPortThreads);
-
- [SecurityPermission (SecurityAction.Demand, ControlThread=true)]
- public static bool SetMaxThreads (int workerThreads, int completionPortThreads)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.SetMaxThreads (workerThreads, completionPortThreads);
- else
- return SetMaxThreads_internal (workerThreads, completionPortThreads);
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern bool SetMaxThreads_internal (int workerThreads, int completionPortThreads);
-
- public static bool QueueUserWorkItem (WaitCallback callBack)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.QueueUserWorkItem (callBack, null);
- else
- return QueueUserWorkItem (callBack, null);
- }
-
- public static bool QueueUserWorkItem (WaitCallback callBack, object state)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
- return Microsoft.ThreadPool.QueueUserWorkItem (callBack, state);
- } else {
- if (callBack == null)
- throw new ArgumentNullException ("callBack");
-
- if (callBack.IsTransparentProxy ()) {
- IAsyncResult ar = callBack.BeginInvoke (state, null, null);
- if (ar == null)
- return false;
- } else {
- AsyncResult ares = new AsyncResult (callBack, state, !ExecutionContext.IsFlowSuppressed());
- pool_queue (ares);
- }
- return true;
- }
- }
-
- [MethodImplAttribute(MethodImplOptions.InternalCall)]
- static extern void pool_queue (AsyncResult ares);
-
- // TODO: It should be interface interface only to avoid extra allocation
- internal static void QueueWorkItem (WaitCallback callBack, object state)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.QueueUserWorkItem (callBack, state);
- else
- pool_queue (new AsyncResult (callBack, state, false));
- }
-
- public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- object state,
- int millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- else
- return RegisterWaitForSingleObject (waitObject, callBack, state, (long) millisecondsTimeOutInterval, executeOnlyOnce);
- }
-
- public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- object state,
- long millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
- return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- } else {
- if (waitObject == null)
- throw new ArgumentNullException ("waitObject");
-
- if (callBack == null)
- throw new ArgumentNullException ("callBack");
-
- if (millisecondsTimeOutInterval < -1)
- throw new ArgumentOutOfRangeException ("timeout", "timeout < -1");
-
- if (millisecondsTimeOutInterval > Int32.MaxValue)
- throw new NotSupportedException ("Timeout is too big. Maximum is Int32.MaxValue");
-
- TimeSpan timeout = new TimeSpan (0, 0, 0, 0, (int) millisecondsTimeOutInterval);
-
- RegisteredWaitHandle waiter = new RegisteredWaitHandle (waitObject, callBack, state,
- timeout, executeOnlyOnce);
- QueueUserWorkItem (new WaitCallback (waiter.Wait), null);
- return waiter;
- }
- }
-
- public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- object state,
- TimeSpan timeout,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, timeout, executeOnlyOnce);
- else
- return RegisterWaitForSingleObject (waitObject, callBack, state, (long) timeout.TotalMilliseconds, executeOnlyOnce);
-
- }
-
- [CLSCompliant(false)]
- public static RegisteredWaitHandle RegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack,
- object state,
- uint millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.RegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- else
- return RegisterWaitForSingleObject (waitObject, callBack, state, (long) millisecondsTimeOutInterval, executeOnlyOnce);
- }
-
- [CLSCompliant (false)]
- unsafe public static bool UnsafeQueueNativeOverlapped (NativeOverlapped *overlapped)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.UnsafeQueueNativeOverlapped (overlapped);
- else
- throw new NotImplementedException ();
- }
-
-#if !NET_2_1 || MOBILE
-
- [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
- public static bool UnsafeQueueUserWorkItem (WaitCallback callBack, object state)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool) {
- return Microsoft.ThreadPool.UnsafeQueueUserWorkItem (callBack, state);
- } else {
- if (callBack == null)
- throw new ArgumentNullException ("callBack");
-
- // no stack propagation here (that's why it's unsafe and requires extra security permissions)
- if (!callBack.IsTransparentProxy ()) {
- AsyncResult ares = new AsyncResult (callBack, state, false);
- pool_queue (ares);
- return true;
- }
- try {
- if (!ExecutionContext.IsFlowSuppressed ())
- ExecutionContext.SuppressFlow (); // on current thread only
- IAsyncResult ar = callBack.BeginInvoke (state, null, null);
- if (ar == null)
- return false;
- } finally {
- if (ExecutionContext.IsFlowSuppressed ())
- ExecutionContext.RestoreFlow ();
- }
- return true;
- }
- }
-
- [MonoTODO("Not implemented")]
- [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
- public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack, object state, int millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- else
- throw new NotImplementedException ();
- }
-
- [MonoTODO("Not implemented")]
- [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
- public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack, object state, long millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- else
- throw new NotImplementedException ();
- }
-
- [MonoTODO("Not implemented")]
- [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
- public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack, object state, TimeSpan timeout,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, timeout, executeOnlyOnce);
- else
- throw new NotImplementedException ();
- }
-
- [MonoTODO("Not implemented")]
- [CLSCompliant (false)]
- [SecurityPermission (SecurityAction.Demand, ControlEvidence=true, ControlPolicy=true)]
- public static RegisteredWaitHandle UnsafeRegisterWaitForSingleObject (WaitHandle waitObject,
- WaitOrTimerCallback callBack, object state, uint millisecondsTimeOutInterval,
- bool executeOnlyOnce)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.UnsafeRegisterWaitForSingleObject (waitObject, callBack, state, millisecondsTimeOutInterval, executeOnlyOnce);
- else
- throw new NotImplementedException ();
- }
-
-#endif
-
-#region ReferenceSources
- // Extracted from ../../../../external/referencesource/mscorlib/system/threading/threadpool.cs
- internal static void UnsafeQueueCustomWorkItem(IThreadPoolWorkItem workItem, bool forceGlobal)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.UnsafeQueueCustomWorkItem (workItem, forceGlobal);
- else
- QueueWorkItem ((obj) => ((IThreadPoolWorkItem)obj).ExecuteWorkItem (), workItem);
- }
-
- internal static IEnumerable<IThreadPoolWorkItem> GetQueuedWorkItems()
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.GetQueuedWorkItems ();
- else
- return new IThreadPoolWorkItem [0];
- }
-
- internal static bool TryPopCustomWorkItem(IThreadPoolWorkItem workItem)
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- return Microsoft.ThreadPool.TryPopCustomWorkItem (workItem);
- else
- return false;
- }
-
- internal static void NotifyWorkItemProgress()
- {
- if (Microsoft.ThreadPool.UseMicrosoftThreadPool)
- Microsoft.ThreadPool.NotifyWorkItemProgress ();
- }
-#endregion
- }
-}
private static Stream Open (IntPtr handle, FileAccess access, int bufferSize)
{
try {
- return new FileStream (handle, access, false, bufferSize, false, bufferSize == 0);
+ // TODO: Should use __ConsoleStream from reference sources
+ return new FileStream (handle, access, false, bufferSize, false, true);
} catch (IOException) {
return Stream.Null;
}
* of icalls, do not require an increment.
*/
#pragma warning disable 169
- private const int mono_corlib_version = 135;
+ private const int mono_corlib_version = 136;
#pragma warning restore 169
[ComVisible (true)]
IDictionary _data;
internal StackTrace[] captured_traces;
IntPtr[] native_trace_ips;
+ object dynamic_methods;
#endregion
#pragma warning restore 169, 649
/* Not thrown yet */
return null;
- StringBuilder sb = new StringBuilder ();
-
- // Add traces captured using ExceptionDispatchInfo
- if (captured_traces != null) {
- foreach (var t in captured_traces) {
- if (!t.AddFrames (sb, true))
- continue;
-
- sb.Append (Environment.NewLine);
- sb.Append ("--- End of stack trace from previous location where exception was thrown ---");
- sb.Append (Environment.NewLine);
- }
- }
-
- StackTrace st = new StackTrace (this, 0, true, true);
- st.AddFrames (sb, true);
-
- stack_trace = sb.ToString ();
-
- return stack_trace;
+ StackTrace st = new StackTrace (this, 0, true);
+ return stack_trace = st.ToString ();
}
}
{
captured_traces = (StackTrace[]) exceptionDispatchInfo.BinaryStackTraceArray;
trace_ips = null;
+ stack_trace = null;
}
//
+++ /dev/null
-//
-// System.Math.cs
-//
-// Authors:
-// Bob Smith (bob@thestuff.net)
-// Dan Lewis (dihlewis@yahoo.co.uk)
-// Pedro MartÃnez Juliá (yoros@wanadoo.es)
-// Andreas Nahr (ClassDevelopment@A-SoftTech.com)
-//
-// (C) 2001 Bob Smith. http://www.thestuff.net
-// Copyright (C) 2003 Pedro MartÃnez Juliá <yoros@wanadoo.es>
-// Copyright (C) 2004 Novell (http://www.novell.com)
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System.Runtime.CompilerServices;
-using System.Runtime.ConstrainedExecution;
-
-namespace System
-{
- public static class Math
- {
- public const double E = 2.7182818284590452354;
- public const double PI = 3.14159265358979323846;
-
- public static decimal Abs (decimal value)
- {
- return (value < 0)? -value: value;
- }
-
- public static double Abs (double value)
- {
- return (value < 0)? -value: value;
- }
-
- public static float Abs (float value)
- {
- return (value < 0)? -value: value;
- }
-
- public static int Abs (int value)
- {
- if (value == Int32.MinValue)
- throw new OverflowException (Locale.GetText ("Value is too small."));
- return (value < 0)? -value: value;
- }
-
- public static long Abs (long value)
- {
- if (value == Int64.MinValue)
- throw new OverflowException (Locale.GetText ("Value is too small."));
- return (value < 0)? -value: value;
- }
-
- [CLSCompliant (false)]
- public static sbyte Abs (sbyte value)
- {
- if (value == SByte.MinValue)
- throw new OverflowException (Locale.GetText ("Value is too small."));
- return (sbyte)((value < 0)? -value: value);
- }
-
- public static short Abs (short value)
- {
- if (value == Int16.MinValue)
- throw new OverflowException (Locale.GetText ("Value is too small."));
- return (short)((value < 0)? -value: value);
- }
-
- public static decimal Ceiling (decimal d)
- {
- decimal result = Floor(d);
- if (result != d) {
- result++;
- }
- return result;
- }
-
- public static double Ceiling (double a)
- {
- double result = Floor(a);
- if (result != a) {
- result++;
- }
- return result;
- }
-
- // The following methods are defined in ECMA specs but they are
- // not implemented in MS.NET. However, they are in MS.NET 1.1
-
- public static long BigMul (int a, int b)
- {
- return ((long)a * (long)b);
- }
-
- public static int DivRem (int a, int b, out int result)
- {
- result = (a % b);
- return (int)(a / b);
- }
-
- public static long DivRem (long a, long b, out long result)
- {
- result = (a % b);
- return (long)(a / b);
- }
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Floor (double d);
-
- public static double IEEERemainder (double x, double y)
- {
- double r;
- if (y == 0)
- return Double.NaN;
- r = x - (y * Math.Round(x/y));
- if (r != 0)
- return r;
- /* Int64BitsToDouble is not endian-aware, but that is fine here */
- return (x > 0) ? 0: (BitConverter.Int64BitsToDouble (Int64.MinValue));
- }
-
- public static double Log (double a, double newBase)
- {
- if (newBase == 1.0)
- return Double.NaN;
- double result = Log(a) / Log(newBase);
- return (result == -0)? 0: result;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static byte Max (byte val1, byte val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static decimal Max (decimal val1, decimal val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static double Max (double val1, double val2)
- {
- if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
- return Double.NaN;
- }
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static float Max (float val1, float val2)
- {
- if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
- return Single.NaN;
- }
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static int Max (int val1, int val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static long Max (long val1, long val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static sbyte Max (sbyte val1, sbyte val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static short Max (short val1, short val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static uint Max (uint val1, uint val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static ulong Max (ulong val1, ulong val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static ushort Max (ushort val1, ushort val2)
- {
- return (val1 > val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static byte Min (byte val1, byte val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static decimal Min (decimal val1, decimal val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static double Min (double val1, double val2)
- {
- if (Double.IsNaN (val1) || Double.IsNaN (val2)) {
- return Double.NaN;
- }
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static float Min (float val1, float val2)
- {
- if (Single.IsNaN (val1) || Single.IsNaN (val2)) {
- return Single.NaN;
- }
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static int Min (int val1, int val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static long Min (long val1, long val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static sbyte Min (sbyte val1, sbyte val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public static short Min (short val1, short val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static uint Min (uint val1, uint val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static ulong Min (ulong val1, ulong val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- [CLSCompliant (false)]
- public static ushort Min (ushort val1, ushort val2)
- {
- return (val1 < val2)? val1: val2;
- }
-
- public static decimal Round (decimal d)
- {
- // Just call Decimal.Round(d, 0); when it rounds well.
- decimal int_part = Decimal.Floor(d);
- decimal dec_part = d - int_part;
- if (((dec_part == 0.5M) &&
- ((2.0M * ((int_part / 2.0M) -
- Decimal.Floor(int_part / 2.0M))) != 0.0M)) ||
- (dec_part > 0.5M)) {
- int_part++;
- }
- return int_part;
- }
-
- public static decimal Round (decimal d, int decimals)
- {
- return Decimal.Round (d, decimals);
- }
-
- public static decimal Round (decimal d, MidpointRounding mode)
- {
- if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
- throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
-
- if (mode == MidpointRounding.ToEven)
- return Round (d);
- else
- return RoundAwayFromZero (d);
- }
-
- static decimal RoundAwayFromZero (decimal d)
- {
- decimal int_part = Decimal.Floor(d);
- decimal dec_part = d - int_part;
- if (int_part >= 0 && dec_part >= 0.5M)
- int_part++;
- else if (int_part < 0 && dec_part > 0.5M)
- int_part++;
- return int_part;
- }
-
- public static decimal Round (decimal d, int decimals, MidpointRounding mode)
- {
- return Decimal.Round (d, decimals, mode);
- }
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Round (double a);
-
- public static double Round (double value, int digits)
- {
- if (digits < 0 || digits > 15)
- throw new ArgumentOutOfRangeException (Locale.GetText ("Value is too small or too big."));
- if (digits == 0)
- return Round (value);
-
- return Round2(value, digits, false);
- }
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- private extern static double Round2 (double value, int digits, bool away_from_zero);
-
-
- public static double Round (double value, MidpointRounding mode)
- {
- if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
- throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
-
- if (mode == MidpointRounding.ToEven)
- return Round (value);
- if (value > 0)
- return Floor (value + 0.5);
- else
- return Ceiling (value - 0.5);
- }
-
- public static double Round (double value, int digits, MidpointRounding mode)
- {
- if ((mode != MidpointRounding.ToEven) && (mode != MidpointRounding.AwayFromZero))
- throw new ArgumentException ("The value '" + mode + "' is not valid for this usage of the type MidpointRounding.", "mode");
- if (digits == 0)
- return Round (value, mode);
-
- if (mode == MidpointRounding.ToEven)
- return Round (value, digits);
- else
- return Round2 (value, digits, true);
- }
-
- public static double Truncate (double d)
- {
- if (d > 0D)
- return Floor (d);
- else if (d < 0D)
- return Ceiling (d);
- else
- return d;
- }
-
- public static decimal Truncate (decimal d)
- {
- return Decimal.Truncate (d);
- }
-
- public static decimal Floor (Decimal d)
- {
- return Decimal.Floor (d);
- }
-
- public static int Sign (decimal value)
- {
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- public static int Sign (double value)
- {
- if (Double.IsNaN (value))
- throw new ArithmeticException ("NAN");
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- public static int Sign (float value)
- {
- if (Single.IsNaN (value))
- throw new ArithmeticException ("NAN");
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- public static int Sign (int value)
- {
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- public static int Sign (long value)
- {
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- [CLSCompliant (false)]
- public static int Sign (sbyte value)
- {
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- public static int Sign (short value)
- {
- if (value > 0) return 1;
- return (value == 0)? 0: -1;
- }
-
- // internal calls
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Sin (double a);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Cos (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Tan (double a);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Sinh (double value);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Cosh (double value);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Tanh (double value);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Acos (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Asin (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Atan (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Atan2 (double y, double x);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Exp (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Log (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Log10 (double d);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- public extern static double Pow (double x, double y);
-
- [MethodImplAttribute (MethodImplOptions.InternalCall)]
- [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
- public extern static double Sqrt (double d);
- }
-}
return timeZoneInfo;
}
- static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+ static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
{
foreach (string id in AndroidTimeZones.GetAvailableIds ()) {
var tz = AndroidTimeZones.GetTimeZone (id, id);
}
}
- static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+ static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
{
foreach (string name in GetMonoTouchNames ()) {
using (Stream stream = GetMonoTouchData (name, false)) {
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Serialization;
+using System.Runtime.InteropServices;
using System.Text;
using System.Globalization;
using System.IO;
*/
private List<KeyValuePair<DateTime, TimeType>> transitions;
+ private static bool libcNotFound;
+
+ [DllImport ("libc")]
+ private static extern int readlink (string path, byte[] buffer, int buflen);
+
+ private static string readlink (string path)
+ {
+ if (libcNotFound)
+ return null;
+
+ byte[] buf = new byte [512];
+ int ret;
+
+ try {
+ ret = readlink (path, buf, buf.Length);
+ } catch (DllNotFoundException e) {
+ libcNotFound = true;
+ return null;
+ }
+
+ if (ret == -1) return null;
+ char[] cbuf = new char [512];
+ int chars = System.Text.Encoding.Default.GetChars (buf, 0, ret, cbuf, 0);
+ return new String (cbuf, 0, chars);
+ }
+
+ private static bool TryGetNameFromPath (string path, out string name)
+ {
+ name = null;
+ var linkPath = readlink (path);
+ if (linkPath != null)
+ path = linkPath;
+
+ path = Path.GetFullPath (path);
+
+ if (string.IsNullOrEmpty (TimeZoneDirectory))
+ return false;
+
+ var baseDir = TimeZoneDirectory;
+ if (baseDir [baseDir.Length-1] != Path.DirectorySeparatorChar)
+ baseDir += Path.DirectorySeparatorChar;
+
+ if (!path.StartsWith (baseDir, StringComparison.InvariantCulture))
+ return false;
+
+ name = path.Substring (baseDir.Length);
+ if (name == "localtime")
+ name = "Local";
+
+ return true;
+ }
+
#if !MOBILE || MOBILE_STATIC
static TimeZoneInfo CreateLocal ()
{
}
}
- try {
- return FindSystemTimeZoneByFileName ("Local", "/etc/localtime");
- } catch (TimeZoneNotFoundException) {
+ var tzFilePaths = new string [] {
+ "/etc/localtime",
+ Path.Combine (TimeZoneDirectory, "localtime")};
+
+ foreach (var tzFilePath in tzFilePaths) {
try {
- return FindSystemTimeZoneByFileName ("Local", Path.Combine (TimeZoneDirectory, "localtime"));
+ string tzName = null;
+ if (!TryGetNameFromPath (tzFilePath, out tzName))
+ tzName = "Local";
+ return FindSystemTimeZoneByFileName (tzName, tzFilePath);
} catch (TimeZoneNotFoundException) {
- return Utc;
+ continue;
}
}
+
+ return Utc;
}
static TimeZoneInfo FindSystemTimeZoneByIdCore (string id)
#endif
}
- static void GetSystemTimeZones (List<TimeZoneInfo> systemTimeZones)
+ static void GetSystemTimeZonesCore (List<TimeZoneInfo> systemTimeZones)
{
#if !MOBILE_STATIC
if (TimeZoneKey != null) {
{
if (systemTimeZones == null) {
var tz = new List<TimeZoneInfo> ();
- GetSystemTimeZones (tz);
+ GetSystemTimeZonesCore (tz);
Interlocked.CompareExchange (ref systemTimeZones, new ReadOnlyCollection<TimeZoneInfo> (tz), null);
}
isf.MoveFile (" ", "file-new-new");
Assert.Fail ("#Exc2");
} catch (ArgumentException e) {
- Console.WriteLine (e);
}
try {
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
+using Microsoft.Win32.SafeHandles;
namespace MonoTests.System.IO
{
DeleteFile (path);
}
}
+
+ [Test]
+ public void Ctor_InvalidSafeHandle ()
+ {
+ var sf = new SafeFileHandle (IntPtr.Zero, true);
+ try {
+ new FileStream (sf, FileAccess.ReadWrite);
+ Assert.Fail ("#1");
+ } catch (ArgumentException) {
+ }
+ }
#endif
}
}
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Text;
+using System.Diagnostics;
+using System.Runtime.ExceptionServices;
using NUnit.Framework;
public string Name;
}
+ class ExceptionHandling_Test_Support
+ {
+ public static Exception Caught;
+ public static string CaughtStackTrace;
+
+ public static void ThrowMe ()
+ {
+ Caught = null;
+ CaughtStackTrace = null;
+ throw new Exception("test");
+ }
+
+ public static void Handler (Exception e)
+ {
+ Caught = e;
+ CaughtStackTrace = e.StackTrace.ToString ();
+ }
+ }
+
+ [Test]
+ public void ExceptionHandling ()
+ {
+ var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+ var ig = method.GetILGenerator ();
+
+ ig.BeginExceptionBlock();
+ ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("ThrowMe"));
+
+ ig.BeginCatchBlock(typeof(Exception));
+ ig.Emit(OpCodes.Call, typeof(ExceptionHandling_Test_Support).GetMethod("Handler"));
+ ig.EndExceptionBlock();
+
+ ig.Emit(OpCodes.Ret);
+
+ var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+ invoke (456324);
+
+ Assert.IsNotNull (ExceptionHandling_Test_Support.Caught, "#1");
+ Assert.AreEqual (2, ExceptionHandling_Test_Support.CaughtStackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.None).Length, "#2");
+
+ var st = new StackTrace (ExceptionHandling_Test_Support.Caught, 0, true);
+
+ // Caught stack trace when dynamic method is gone
+ Assert.AreEqual (ExceptionHandling_Test_Support.CaughtStackTrace, st.ToString (), "#3");
+
+ // Catch handler stack trace inside dynamic method match
+ Assert.AreEqual (ExceptionHandling_Test_Support.Caught.StackTrace, st.ToString (), "#4");
+ }
+
+ class ExceptionHandlingWithExceptionDispatchInfo_Test_Support
+ {
+ public static Exception Caught;
+ public static string CaughtStackTrace;
+
+ public static void ThrowMe ()
+ {
+ Caught = null;
+ CaughtStackTrace = null;
+
+ Exception e;
+ try {
+ throw new Exception("test");
+ } catch (Exception e2) {
+ e = e2;
+ }
+
+ var edi = ExceptionDispatchInfo.Capture(e);
+
+ edi.Throw();
+ }
+
+ public static void Handler (Exception e)
+ {
+ var split = e.StackTrace.Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ Assert.AreEqual (5, split.Length, "#1");
+ Assert.IsTrue (split [1].Contains ("---"), "#2");
+ }
+ }
+
+ [Test]
+ public void ExceptionHandlingWithExceptionDispatchInfo ()
+ {
+ var method = new DynamicMethod ("", typeof(void), new[] { typeof(int) }, typeof (DynamicMethodTest));
+ var ig = method.GetILGenerator ();
+
+ ig.BeginExceptionBlock();
+ ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("ThrowMe"));
+
+ ig.BeginCatchBlock(typeof(Exception));
+ ig.Emit(OpCodes.Call, typeof(ExceptionHandlingWithExceptionDispatchInfo_Test_Support).GetMethod("Handler"));
+ ig.EndExceptionBlock();
+
+ ig.Emit(OpCodes.Ret);
+
+ var invoke = (Action<int>) method.CreateDelegate (typeof(Action<int>));
+ invoke (444);
+ }
+
#if !MONODROID
// RUNTIME: crash
[Test]
}
}
+ [Test] // ctor (String)
+ public void Constructor1_Quoted ()
+ {
+ AssemblyName an;
+
+ an = new AssemblyName ("'System', Version=\"10.0.0.0\", Culture='Neutral', PublicKeyToken='b67a5c561934e089', Retargetable='Yes', ProcessorArchitecture='AMD64'");
+ Assert.AreEqual ("System, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b67a5c561934e089, Retargetable=Yes", an.ToString ());
+ Assert.AreEqual (ProcessorArchitecture.Amd64, an.ProcessorArchitecture, "Amd64");
+ }
+
+ [Test] // ctor (String)
+ public void Constructor1_Quoted_Invalid ()
+ {
+ AssemblyName an;
+
+ try {
+ an = new AssemblyName ("System, Version=\"10.0.0.0'");
+ Assert.Fail ("#1");
+ } catch (FileLoadException) {
+ }
+ }
+
[Test (Description="Xamarin bug #99 - whitespaces in key=value")]
public void WhiteSpaceInKeyValue ()
{
var ctor = typeof (Gen<>).GetConstructor (Type.EmptyTypes);
Assert.IsTrue (ctor.ContainsGenericParameters);
}
+
+ [Test]
+ public void ConstructorInfoModule ()
+ {
+ Type type = typeof (Foo);
+ ConstructorInfo co = type.GetConstructors ()[0];
+
+ Assert.AreEqual (type.Module, co.Module);
+ }
}
}
} catch (InvalidOperationException) {}
}
+ [Test]
+ public void EventInfoModule ()
+ {
+ Type type = typeof (TestClass);
+ EventInfo ev = type.GetEvent ("pub");
+
+ Assert.AreEqual (type.Module, ev.Module);
+ }
+
#pragma warning disable 67
public class PrivateEvent
{
//Assert.IsTrue (pi.IsRetval, "#3");
}
+ [Test]
+ public void MethodInfoModule ()
+ {
+ Type type = typeof (MethodInfoTest);
+ MethodInfo me = type.GetMethod ("return_parameter_test");
+
+ Assert.AreEqual (type.Module, me.Module);
+ }
+
[Test]
public void InvokeOnRefOnlyAssembly ()
{
{
Type type = typeof (TestClass);
PropertyInfo property = type.GetProperty ("ReadOnlyProperty");
+ Assert.IsNotNull (property.Module, "#0");
MethodInfo [] methods = property.GetAccessors (true);
Assert.AreEqual (1, methods.Length, "#A1");
Assert.AreEqual (typeof (ClassWithNullableDateTime), siblingProperty.DeclaringType, "#3");
Assert.AreEqual (typeof (InheritsFromClassWithNullableDateTime), siblingProperty.ReflectedType, "#4");
}
-
-
+
+ class Super { public long A { get; private set; } }
+
+ class Sub : Super { }
+
+ [Test]
+ public void PrivateSetterFromDerivedType ()
+ {
+ var prop = typeof (Sub).GetProperty ("A");
+ Assert.AreEqual (1, prop.GetAccessors (true).Length, "#1");
+ Assert.IsFalse (prop.CanWrite, "#2");
+ Assert.IsNull (prop.GetSetMethod (true), "#3");
+ }
+
public class ClassWithNullableDateTime
{
public DateTime? Property1 { get; set; }
using NUnit.Framework;
using System.Runtime.ExceptionServices;
using System.Threading.Tasks;
+using System.Diagnostics;
namespace MonoTests.System.Runtime.ExceptionServices
{
Assert.IsTrue (split [1].Contains ("---"), "#2");
Assert.IsTrue (split [4].Contains ("---"), "#3");
}
- }
+ }
+
+ [Test]
+ public void StackTraceUserCopy ()
+ {
+ try {
+ try {
+ throw new NotImplementedException ();
+ } catch (Exception e) {
+ var edi = ExceptionDispatchInfo.Capture (e);
+ edi.Throw();
+ }
+ } catch (Exception ex) {
+ var st = new StackTrace (ex, true);
+ var split = st.ToString ().Split (new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ Assert.AreEqual (4, split.Length, "#1");
+ Assert.IsTrue (split [1].Contains ("---"), "#2");
+ }
+ }
}
}
[Test]
public void Test_Interrupt ()
{
+ ManualResetEvent mre = new ManualResetEvent (false);
bool interruptedExceptionThrown = false;
+
ThreadPool.QueueUserWorkItem (Test_Interrupt_Worker, Thread.CurrentThread);
try {
try {
- Thread.Sleep (3000);
+ mre.WaitOne (3000);
} finally {
try {
- Thread.Sleep (0);
+ mre.WaitOne (0);
} catch (ThreadInterruptedException) {
Assert.Fail ("ThreadInterruptedException thrown twice");
}
[Category ("NotDotNet")] // it crashes nunit.
public void Test_InterruptCurrentThread ()
{
+ ManualResetEvent mre = new ManualResetEvent (false);
bool interruptedExceptionThrown = false;
Thread.CurrentThread.Interrupt ();
try {
- Thread.Sleep (0);
+ mre.WaitOne (0);
Assert.Fail ();
} catch (ThreadInterruptedException) {
}
public void TestIEEERemainder ()
{
double a = Math.IEEERemainder (y, x);
- double b = 0.0050000000000007816;
+ double b = 0.0050000000000010592;
Assert.IsTrue ((Math.Abs (a - b) <= double_epsilon), a.ToString ("G99")
+ " != " + b.ToString ("G99"));
// MS docs say this should be PositiveInfinity
Assert.IsTrue (Math.Log (0, y) == double.NegativeInfinity);
Assert.IsTrue (Math.Log (double.PositiveInfinity, y) == double.PositiveInfinity);
- Assert.IsTrue (Math.Log (x, double.PositiveInfinity) == 0);
+
+ Assert.IsTrue (Double.IsNaN (Math.Log (x, double.PositiveInfinity)));
}
[Test]
//
// when using double_epsilon. Precision differs between different ARM CPUs, so we
// will just use a more conservative value
- precision = 0.000001;
+ precision = double_epsilon * 10;
#else
precision = double_epsilon;
#endif
- try {
- double a = Math.Pow (y, x);
- double b = 1.363609446060212;
-
- Assert.IsTrue ((Math.Abs (a - b) <= precision), a.ToString ("G99") + " != " + b.ToString ("G99"));
- iTest++;
- Assert.IsTrue (double.IsNaN (Math.Pow (y, double.NaN)));
- iTest++;
- Assert.IsTrue (double.IsNaN (Math.Pow (double.NaN, x)));
- iTest++;
- Assert.IsTrue (double.IsNegativeInfinity (Math.Pow (double.NegativeInfinity, 1)),
- "Math.Pow(double.NegativeInfinity, 1) should be NegativeInfinity");
- iTest++;
- Assert.IsTrue (double.IsPositiveInfinity (Math.Pow (double.NegativeInfinity, 2)),
- "Math.Pow(double.NegativeInfinity, 2) should be PositiveInfinity");
- // MS docs say this should be 0
- iTest++;
- Assert.IsTrue (double.IsNaN (Math.Pow (1, double.NegativeInfinity)));
- iTest++;
- Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, double.NegativeInfinity),
- "Math.Pow(double.PositiveInfinity, double.NegativeInfinity)");
- iTest++;
- Assert.IsTrue (double.IsPositiveInfinity (Math.Pow (double.PositiveInfinity, 1)),
- "Math.Pow(double.PositiveInfinity, 1) should be PositiveInfinity");
-
- // MS docs say this should be PositiveInfinity
- iTest++;
- Assert.IsTrue (double.IsNaN (Math.Pow (1, double.PositiveInfinity)),
- "Math.Pow(1, double.PositiveInfinity) should be NaN");
-
- iTest++;
- Assert.IsTrue (Double.IsNaN (Math.Pow (1, Double.NaN)),
- "Math.Pow(1, NaN) should be NaN");
- iTest++;
- Assert.IsTrue (Double.IsNaN (Math.Pow (Double.NaN, 0)),
- "Math.Pow(NaN, 0) should be NaN");
- iTest++;
- Assert.IsTrue (1.0 == Math.Pow (-1, Double.MaxValue),
- "Math.Pow(-1, MaxValue) should be 1.0");
-
- iTest++;
- Assert.IsTrue (1.0 == Math.Pow (-1, Double.MinValue),
- "Math.Pow(-1, MinValue) should be 1.0");
-
- iTest++;
- Assert.IsTrue (Double.IsPositiveInfinity (Math.Pow (Double.MinValue,
- Double.MaxValue)), "Math.Pow(MinValue, MaxValue) should be +Infinity");
-
- iTest++;
- Assert.IsTrue (0.0 == Math.Pow (Double.MinValue, Double.MinValue),
- "Math.Pow(MinValue, MinValue) should be 0.0");
-
- //
- // The following bugs were present because we tried to outsmart the C Pow:
- //
- double infinity = Double.PositiveInfinity;
- Assert.IsTrue (Math.Pow (0.5, infinity) == 0.0,
- "Math.Pow(0.5, Infinity) == 0.0");
- Assert.IsTrue (Math.Pow (0.5, -infinity) == infinity,
- "Math.Pow(0.5, -Infinity) == Infinity");
- Assert.IsTrue (Math.Pow (2, infinity) == infinity,
- "Math.Pow(2, Infinity) == Infinity");
- Assert.IsTrue (Math.Pow (2, -infinity) == 0.0,
- "Math.Pow(2, -Infinity) == 0");
- Assert.IsTrue (Math.Pow (infinity, 0) == 1.0,
- "Math.Pow(Infinity, 0) == 1.0");
- Assert.IsTrue (Math.Pow (-infinity, 0) == 1.0,
- "Math.Pow(-Infinity, 0) == 1.0");
- } catch (Exception e) {
- Assert.Fail ("Unexpected exception at iTest=" + iTest + ". e=" + e);
- }
+ /* documentation cases : https://msdn.microsoft.com/en-us/library/system.math.pow%28v=vs.110%29.aspx */
+
+ /* x or y = NaN -> NaN */
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, double.NaN)), "#1");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, double.NegativeInfinity)), "#2");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, -2)), "#2");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, -1)), "#3");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, 0)), "#4");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, 1)), "#5");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, 2)), "#6");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( double.NaN, double.PositiveInfinity)), "#7");
+ Assert.IsTrue (double.IsNaN (Math.Pow (double.NegativeInfinity, double.NaN)), "#8");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( -2, double.NaN)), "#9");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( -1, double.NaN)), "#10");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( 0, double.NaN)), "#11");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( 1, double.NaN)), "#12");
+ Assert.IsTrue (double.IsNaN (Math.Pow ( 2, double.NaN)), "#13");
+ Assert.IsTrue (double.IsNaN (Math.Pow (double.PositiveInfinity, double.NaN)), "#14");
+
+ /* x = Any value except NaN; y = 0 -> 1 */
+ Assert.AreEqual ((double) 1, Math.Pow (2, 0), "#15");
+
+ /* x = NegativeInfinity; y < 0 -> 0 */
+ Assert.AreEqual ((double) 0, Math.Pow (double.NegativeInfinity, -2), "#16");
+
+ /* x = NegativeInfinity; y is a positive odd integer -> NegativeInfinity */
+ Assert.AreEqual (double.NegativeInfinity, Math.Pow (double.NegativeInfinity, 3), "#17");
+
+ /* x = NegativeInfinity; y is positive but not an odd integer -> PositiveInfinity */
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.NegativeInfinity, 2), "#18");
+
+ /* x < 0 but not NegativeInfinity; y is not an integer, NegativeInfinity, or PositiveInfinity -> NaN */
+ Assert.IsTrue (double.IsNaN (Math.Pow (-1, 2.5)), "#19");
+
+ /* x = -1; y = NegativeInfinity or PositiveInfinity -> NaN */
+ Assert.IsTrue (double.IsNaN (Math.Pow (-1, double.PositiveInfinity)), "#20");
+ Assert.IsTrue (double.IsNaN (Math.Pow (-1, double.NegativeInfinity)), "#21");
+
+ /* -1 < x < 1; y = NegativeInfinity -> PositiveInfinity */
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (-0.5, double.NegativeInfinity), "#22");
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (+0.5, double.NegativeInfinity), "#23");
+
+ /* -1 < x < 1; y = PositiveInfinity -> 0 */
+ Assert.AreEqual ((double) 0, Math.Pow (-0.5, double.PositiveInfinity), "#24");
+ Assert.AreEqual ((double) 0, Math.Pow (+0.5, double.PositiveInfinity), "#25");
+
+ /* x < -1 or x > 1; y = NegativeInfinity -> 0 */
+ Assert.AreEqual ((double) 0, Math.Pow (-2, double.NegativeInfinity), "#26");
+ Assert.AreEqual ((double) 0, Math.Pow (+2, double.NegativeInfinity), "#27");
+
+ /* x < -1 or x > 1; y = PositiveInfinity -> PositiveInfinity */
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (-2, double.PositiveInfinity), "#28");
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (+2, double.PositiveInfinity), "#29");
+
+ /* x = 0; y < 0 -> PositiveInfinity */
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (0, -2), "#30");
+
+ /* x = 0; y > 0 -> PositiveInfinity */
+ Assert.AreEqual ((double) 0, Math.Pow (0, +2), "#31");
+
+ /* x = 1; y is any value except NaN -> 1 */
+ Assert.AreEqual ((double) 1, Math.Pow (1, double.NegativeInfinity), "#32");
+ Assert.AreEqual ((double) 1, Math.Pow (1, -2), "#33");
+ Assert.AreEqual ((double) 1, Math.Pow (1, 0), "#34");
+ Assert.AreEqual ((double) 1, Math.Pow (1, +2), "#35");
+ Assert.AreEqual ((double) 1, Math.Pow (1, double.PositiveInfinity), "#36");
+
+ /* x = PositiveInfinity; y < 0 -> 0 */
+ Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, -1), "#37");
+ Assert.AreEqual ((double) 0, Math.Pow (double.PositiveInfinity, -2), "#38");
+
+ /* x = PositiveInfinity; y > 0 -> PositiveInfinity */
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.PositiveInfinity, 1), "#39");
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.PositiveInfinity, 2), "#40");
+
+ /* other cases */
+
+ double a = Math.Pow (y, x);
+ double b = 1.363609446060212;
+
+ Assert.IsTrue (Math.Abs (a - b) <= precision, "#41 " + a.ToString ("G99") + " != " + b.ToString ("G99") + " +/- " + precision.ToString ("G99"));
+ Assert.AreEqual (double.NegativeInfinity, Math.Pow (double.NegativeInfinity, 1), "#42");
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (double.NegativeInfinity, 2), "#43");
+
+ Assert.AreEqual (Math.Pow (double.PositiveInfinity, double.NegativeInfinity), (double) 0, "#44");
+
+ Assert.AreEqual ((double) 1, Math.Pow (-1, Double.MaxValue), "#45");
+ Assert.AreEqual ((double) 1, Math.Pow (-1, Double.MinValue), "#46");
+ Assert.AreEqual ((double) 0, Math.Pow (Double.MinValue, Double.MinValue), "#47");
+ Assert.AreEqual (double.PositiveInfinity, Math.Pow (Double.MinValue, Double.MaxValue), "#48");
+
+ double infinity = double.PositiveInfinity;
+ Assert.AreEqual ((double) 0, Math.Pow ( 0.5, infinity), "#49");
+ Assert.AreEqual ( infinity, Math.Pow ( 0.5, -infinity), "#50");
+ Assert.AreEqual ( infinity, Math.Pow ( 2, infinity), "#51");
+ Assert.AreEqual ((double) 0, Math.Pow ( 2, -infinity), "#52");
+ Assert.AreEqual ((double) 1, Math.Pow ( infinity, 0), "#53");
+ Assert.AreEqual ((double) 1, Math.Pow (-infinity, 0), "#54");
}
[Test]
using System;
using System.IO;
+using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Collections;
using System.Reflection;
Assert.IsNotNull (local);
Assert.IsTrue (true);
}
+
+ [DllImport ("libc")]
+ private static extern int readlink (string path, byte[] buffer, int buflen);
+
+ [Test] // Covers #24958
+ public void LocalId ()
+ {
+ byte[] buf = new byte [512];
+
+ var path = "/etc/localtime";
+ try {
+ var ret = readlink (path, buf, buf.Length);
+ if (ret == -1)
+ return; // path is not a symbolic link, nothing to test
+ } catch (DllNotFoundException e) {
+ return;
+ }
+
+ Assert.IsTrue (TimeZoneInfo.Local.Id != "Local", "Local timezone id should not be \"Local\"");
+ }
}
[TestFixture]
}
Assert.Fail ("Europe/Brussels not found in SystemTZ");
}
+
+ [Test]
+ public void ReflectionReturnsTheCorrectMethod ()
+ {
+ var method = (MethodInfo) typeof (TimeZoneInfo).GetMember ("GetSystemTimeZones", MemberTypes.Method, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)[0];
+
+ var timeZones = (global::System.Collections.ObjectModel.ReadOnlyCollection<TimeZoneInfo>) method.Invoke (null, null);
+ Assert.IsTrue (timeZones.Count > 0, "GetSystemTimeZones should not return an empty collection.");
+ }
}
[TestFixture]
System/IntPtr.cs
System/KnownTerminals.cs
System/MarshalByRefObject.cs
-System/Math.cs
System/MonoAsyncCall.cs
System/MonoCQItem.cs
System/MonoCustomAttrs.cs
../../../external/referencesource/mscorlib/system/iserviceobjectprovider.cs
../../../external/referencesource/mscorlib/system/invalidtimezoneexception.cs
../../../external/referencesource/mscorlib/system/Lazy.cs
+../../../external/referencesource/mscorlib/system/math.cs
../../../external/referencesource/mscorlib/system/memberaccessexception.cs
../../../external/referencesource/mscorlib/system/methodaccessexception.cs
../../../external/referencesource/mscorlib/system/midpointrounding.cs
%token K_OFF\r
%token K_FORWARDER\r
%token K_CHARMAPERROR\r
+%token K_LEGACY\r
+%token K_LIBRARY\r
+%token K_AUTO\r
\r
/* end generated */\r
\r
}\r
;\r
\r
-assembly_head : D_ASSEMBLY asm_attr slashed_name\r
+assembly_head : D_ASSEMBLY legacylibrary_opt asm_attr slashed_name\r
{\r
- codegen.SetThisAssembly ((string) $3, (PEAPI.AssemAttr) $2);\r
+ codegen.SetThisAssembly ((string) $4, (PEAPI.AssemAttr) $3);\r
codegen.CurrentCustomAttrTarget = codegen.ThisAssembly;\r
codegen.CurrentDeclSecurityTarget = codegen.ThisAssembly;\r
}\r
assemblyref_all : assemblyref_head OPEN_BRACE assemblyref_decls CLOSE_BRACE\r
;\r
\r
-assemblyref_head : D_ASSEMBLY K_EXTERN asm_attr slashed_name\r
+assemblyref_head : D_ASSEMBLY K_EXTERN legacylibrary_opt asm_attr slashed_name\r
{\r
System.Reflection.AssemblyName asmb_name = \r
new System.Reflection.AssemblyName ();\r
- asmb_name.Name = (string) $4;\r
- codegen.BeginAssemblyRef ((string) $4, asmb_name, (PEAPI.AssemAttr) $3);\r
+ asmb_name.Name = (string) $5;\r
+ codegen.BeginAssemblyRef ((string) $5, asmb_name, (PEAPI.AssemAttr) $4);\r
}\r
- | D_ASSEMBLY K_EXTERN asm_attr slashed_name K_AS slashed_name\r
+ | D_ASSEMBLY K_EXTERN legacylibrary_opt asm_attr slashed_name K_AS slashed_name\r
{\r
System.Reflection.AssemblyName asmb_name = \r
new System.Reflection.AssemblyName ();\r
- asmb_name.Name = (string) $4;\r
- codegen.BeginAssemblyRef ((string) $6, asmb_name, (PEAPI.AssemAttr) $3);\r
+ asmb_name.Name = (string) $5;\r
+ codegen.BeginAssemblyRef ((string) $7, asmb_name, (PEAPI.AssemAttr) $4);\r
}\r
;\r
\r
if (codegen.CurrentCustomAttrTarget != null)\r
codegen.CurrentCustomAttrTarget.AddCustomAttribute ((CustomAttr) $1);\r
}\r
+ | K_AUTO /* MS ilasm uses this keyword to lookup the specified assembly in the GAC and embeds its attributes, we just ignore it */\r
;\r
\r
exptype_all : exptype_head OPEN_BRACE exptype_decls CLOSE_BRACE\r
| SEMICOLON\r
;\r
\r
+legacylibrary_opt : /* empty */\r
+ | K_LEGACY K_LIBRARY /* MS ilasm has these keywords for backwards compatibility, we just ignore them */\r
+ ;\r
+\r
%%\r
\r
}\r
keywords ["off"] = new ILToken (Token.K_OFF, "off");\r
keywords ["strict"] = new ILToken (Token.K_STRICT, "strict");\r
keywords ["forwarder"] = new ILToken (Token.K_FORWARDER, "forwarder");\r
+ keywords ["legacy"] = new ILToken (Token.K_LEGACY, "legacy");\r
+ keywords ["library"] = new ILToken (Token.K_LIBRARY, "library");\r
+ keywords ["auto"] = new ILToken (Token.K_AUTO, "auto");\r
\r
return keywords;\r
}\r
} else {
Builder.Save (module.Builder.ScopeName, pekind, machine);
}
+ } catch (ArgumentOutOfRangeException) {
+ Report.Error (16, "Output file `{0}' exceeds the 4GB limit");
} catch (Exception e) {
- Report.Error (16, "Could not write to file `" + name + "', cause: " + e.Message);
+ Report.Error (16, "Could not write to file `{0}'. {1}", name, e.Message);
}
Compiler.TimeReporter.Stop (TimeReporter.TimerType.OutputSave);
}
foreach (var existing in das) {
- if (DefiniteAssignmentBitSet.AreEqual (existing, DefiniteAssignment))
+ if (DefiniteAssignmentBitSet.IsIncluded (existing, DefiniteAssignment))
return true;
}
public bool parsing_catch_when;
int parsing_string_interpolation;
+ int string_interpolation_section;
Stack<bool> parsing_string_interpolation_quoted;
public bool parsing_interpolation_format;
public int current_token;
public object val;
public int parsing_string_interpolation;
+ public int string_interpolation_section;
public Stack<bool> parsing_string_interpolation_quoted;
public Position (Tokenizer t)
ifstack = new Stack<int> (clone);
}
parsing_generic_less_than = t.parsing_generic_less_than;
+ string_interpolation_section = t.string_interpolation_section;
current_token = t.current_token;
val = t.val;
parsing_string_interpolation = t.parsing_string_interpolation;
+ string_interpolation_section = t.string_interpolation_section;
if (t.parsing_string_interpolation_quoted != null && t.parsing_string_interpolation_quoted.Count != 0) {
var clone = t.parsing_string_interpolation_quoted.ToArray ();
Array.Reverse (clone);
case '{':
val = ltb.Create (current_source, ref_line, col);
+
+ if (parsing_string_interpolation > 0)
+ ++string_interpolation_section;
+
return Token.OPEN_BRACE;
case '}':
if (parsing_string_interpolation > 0) {
- --parsing_string_interpolation;
- bool quoted;
- if (parsing_string_interpolation_quoted != null && parsing_string_interpolation_quoted.Count > 0) {
- quoted = parsing_string_interpolation_quoted.Pop ();
- } else {
- quoted = false;
+ if (string_interpolation_section == 0) {
+ --parsing_string_interpolation;
+ bool quoted;
+ if (parsing_string_interpolation_quoted != null && parsing_string_interpolation_quoted.Count > 0) {
+ quoted = parsing_string_interpolation_quoted.Pop ();
+ } else {
+ quoted = false;
+ }
+
+ return TokenizeInterpolatedString (quoted);
}
- return TokenizeInterpolatedString (quoted);
+ --string_interpolation_section;
}
val = ltb.Create (current_source, ref_line, col);
return null;
ExpressionStatement es = e as ExpressionStatement;
- if (es == null || e is AnonymousMethodBody)
+ if (es == null || e is AnonymousMethodBody) {
+ var reduced = e as IReducedExpressionStatement;
+ if (reduced != null) {
+ return EmptyExpressionStatement.Instance;
+ }
+
Error_InvalidExpressionStatement (ec);
+ }
//
// This is quite expensive warning, try to limit the damage
}
}
+ interface IReducedExpressionStatement
+ {
+ }
+
/// <summary>
/// This kind of cast is used to encapsulate the child
/// whose type is child.Type into an expression that is
//
public class ReducedExpression : Expression
{
- public sealed class ReducedConstantExpression : EmptyConstantCast
+ public class ReducedConstantExpression : EmptyConstantCast
{
readonly Expression orig_expr;
}
}
+ sealed class ReducedConstantStatement : ReducedConstantExpression, IReducedExpressionStatement
+ {
+ public ReducedConstantStatement (Constant expr, Expression origExpr)
+ : base (expr, origExpr)
+ {
+ }
+ }
+
sealed class ReducedExpressionStatement : ExpressionStatement
{
readonly Expression orig_expr;
//
// Creates fully resolved expression switcher
//
- public static Constant Create (Constant expr, Expression original_expr)
+ public static Constant Create (Constant expr, Expression originalExpr)
{
if (expr.eclass == ExprClass.Unresolved)
throw new ArgumentException ("Unresolved expression");
- return new ReducedConstantExpression (expr, original_expr);
+ if (originalExpr is ExpressionStatement)
+ return new ReducedConstantStatement (expr, originalExpr);
+
+ return new ReducedConstantExpression (expr, originalExpr);
}
public static ExpressionStatement Create (ExpressionStatement s, Expression orig)
public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
{
- if (AreEqual (a, b))
+ if (IsEqual (a, b))
return a;
DefiniteAssignmentBitSet res;
public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
{
- if (AreEqual (a, b))
+ if (IsEqual (a, b))
return a;
DefiniteAssignmentBitSet res;
large_bits[index >> 5] |= (1 << (index & 31));
}
- public static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
+ static bool IsEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
{
if (a.large_bits == null)
return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag);
return true;
}
+
+ public static bool IsIncluded (DefiniteAssignmentBitSet set, DefiniteAssignmentBitSet test)
+ {
+ var set_bits = set.large_bits;
+ if (set_bits == null)
+ return (set.bits & test.bits & ~copy_on_write_flag) == (set.bits & ~copy_on_write_flag);
+
+ var test_bits = test.large_bits;
+ for (int i = 0; i < set_bits.Length; ++i) {
+ if ((set_bits[i] & test_bits[i]) != set_bits[i])
+ return false;
+ }
+
+ return true;
+ }
}
}
return false;
statement = Expr as ExpressionStatement;
- if (statement == null)
- Expr.Error_InvalidExpressionStatement (ec);
+ if (statement == null) {
+ var reduced = Expr as IReducedExpressionStatement;
+ if (reduced != null) {
+ statement = EmptyExpressionStatement.Instance;
+ } else {
+ Expr.Error_InvalidExpressionStatement (ec);
+ }
+ }
return true;
}
//
// The return type is actually Task<T> type argument
//
- if (expr.Type == async_type) {
+ if (expr.Type == async_type && async_type.TypeArguments [0] != ec.Module.PredefinedTypes.Task.TypeSpec) {
ec.Report.Error (4016, loc,
"`{0}': The return expression type of async method must be `{1}' rather than `Task<{1}>'",
ec.GetSignatureForError (), async_type.TypeArguments[0].GetSignatureForError ());
--- /dev/null
+using System;
+
+struct BB
+{}
+
+public class X
+{
+ public static void Main ()
+ {
+ // Reduced expression statements
+
+ new BB? ();
+ new float();
+
+ Action a = () => new float();
+ a ();
+ }
+}
\ No newline at end of file
--- /dev/null
+using System.Threading.Tasks;
+
+class X
+{
+ public async Task ReturnsTaskAsync (Task task)
+ {
+ await task;
+ }
+
+ public async Task<Task> ReturnsTaskOfTaskAsync ()
+ {
+ var t1 = Task.FromResult (ReturnsTaskAsync (null));
+ await t1;
+ Task<Task> t2 = Task.FromResult (ReturnsTaskAsync (null));
+ return t2;
+ }
+
+ public static void Main ()
+ {
+ new X ().ReturnsTaskOfTaskAsync ().Wait ();
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Collections.Generic;
+
+public class Program
+{
+ public static int Main ()
+ {
+ var x = $@"({
+ new Dictionary<int, object> {
+ { 1, "bbb" }
+ }.Count
+ });";
+
+ if (x != "(1);")
+ return 1;
+
+ return 0;
+ }
+}
\ No newline at end of file
</method>
</type>
</test>
+ <test name="gtest-633.cs">
+ <type name="X">
+ <method name="Void Main()" attrs="150">
+ <size>38</size>
+ </method>
+ <method name="Void <Main>m__0()" attrs="145">
+ <size>1</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="gtest-anontype-01.cs">
<type name="Test">
<method name="Int32 Main()" attrs="150">
</method>
</type>
</test>
+ <test name="test-async-68.cs">
+ <type name="X">
+ <method name="System.Threading.Tasks.Task ReturnsTaskAsync(System.Threading.Tasks.Task)" attrs="134">
+ <size>41</size>
+ </method>
+ <method name="System.Threading.Tasks.Task`1[System.Threading.Tasks.Task] ReturnsTaskOfTaskAsync()" attrs="134">
+ <size>41</size>
+ </method>
+ <method name="Void Main()" attrs="150">
+ <size>17</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ <type name="X+<ReturnsTaskAsync>c__async0">
+ <method name="Void MoveNext()" attrs="486">
+ <size>157</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ <type name="X+<ReturnsTaskOfTaskAsync>c__async1">
+ <method name="Void MoveNext()" attrs="486">
+ <size>217</size>
+ </method>
+ <method name="Void SetStateMachine(System.Runtime.CompilerServices.IAsyncStateMachine)" attrs="486">
+ <size>13</size>
+ </method>
+ </type>
+ </test>
<test name="test-async-69.cs">
<type name="Test">
<method name="System.Threading.Tasks.Task`1[System.Int32] YieldValue(Int32)" attrs="145">
</method>
</type>
</test>
+ <test name="test-interpolation-08.cs">
+ <type name="Program">
+ <method name="Int32 Main()" attrs="150">
+ <size>73</size>
+ </method>
+ <method name="Void .ctor()" attrs="6278">
+ <size>7</size>
+ </method>
+ </type>
+ </test>
<test name="test-iter-01.cs">
<type name="X">
<method name="Int32 Main()" attrs="150">
}
ctor_func = args [++i];
break;
+ case "--dos2unix":
+ case "--dos2unix=true":
+ use_dos2unix = true;
+ break;
+ case "--dos2unix=false":
+ use_dos2unix = false;
+ break;
default:
sources.Add (args [i]);
break;
" -L path Adds `path' to the search path for assemblies\n" +
" --nodeps Turns off automatic dependency embedding (default)\n" +
" --deps Turns on automatic dependency embedding\n" +
+ " --dos2unix[=true|false]\n" +
+ " When no value provided, or when `true` specified\n" +
+ " `dos2unix` will be invoked to convert paths on Windows.\n" +
+ " When `--dos2unix=false` used, dos2unix is NEVER used.\n" +
" --keeptemp Keeps the temporary files\n" +
" --config F Bundle system config file `F'\n" +
" --config-dir D Set MONO_CFG_DIR to `D'\n" +
return system (cmdLine);
}
-#if XAMARIN_ANDROID
// on Windows, we have to pipe the output of a
// `cmd` interpolation to dos2unix, because the shell does not
// strip the CRLFs generated by the native pkg-config distributed
}
// and if there is no dos2unix, just run cmd /c.
if (use_dos2unix == false) {
-#endif
Console.WriteLine (cmdLine);
ProcessStartInfo dos2unix = new ProcessStartInfo ();
dos2unix.UseShellExecute = false;
p.WaitForExit ();
return p.ExitCode;
}
-#if XAMARIN_ANDROID
}
-#endif
StringBuilder b = new StringBuilder ();
int count = 0;
for (int i = 0; i < cmdLine.Length; i++) {
if (cmdLine [i] == '`') {
-#if XAMARIN_ANDROID
if (count % 2 != 0) {
b.Append ("|dos2unix");
}
-#endif
count++;
}
b.Append (cmdLine [i]);
mkdir -p $(OUT_DIR); \
$(MCS) -debug $(TEST_CS) -out:$(TEST_EXE)
-check: all
+check: test-local
+
+test-local: all
$(BUILD_TEST_EXE)
@echo "Checking $(PROGRAM) without AOT"
$(CHECK_DIFF)
basic-tests:
for type in System.Array System.String 'System.Collections.Generic.List`1'; do \
- echo $$type; $(RUNTIME) $(build_lib) $$type >/dev/null || exit 1; done
\ No newline at end of file
+ echo $$type; MONO_PATH="$(topdir)/class/lib/$(PROFILE)$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(build_lib) $$type >/dev/null || exit 1; done
+++ /dev/null
-/*
- * Create trampolines to invoke arbitrary functions.
- * Copyright (c) 2002 Sergey Chaban <serge@wildwestsoftware.com>
- *
- * Contributions by Malte Hildingson
- */
-
-#include "arm-codegen.h"
-#include "arm-dis.h"
-
-#if defined(_WIN32_WCE) || defined (UNDER_CE)
-# include <windows.h>
-#else
-#include <unistd.h>
-#include <sys/mman.h>
-#endif
-
-#if !defined(PLATFORM_MACOSX)
-#include <errno.h>
-
-#include "mono/metadata/class.h"
-#include "mono/metadata/tabledefs.h"
-#include "mono/interpreter/interp.h"
-#include "mono/metadata/appdomain.h"
-
-
-#if 0
-# define ARM_DUMP_DISASM 1
-#endif
-
-/* prototypes for private functions (to avoid compiler warnings) */
-void flush_icache (void);
-void* alloc_code_buff (int num_instr);
-
-
-
-/*
- * The resulting function takes the form:
- * void func (void (*callme)(), void *retval, void *this_obj, stackval *arguments);
- * NOTE: all args passed in ARM registers (A1-A4),
- * then copied to R4-R7 (see definitions below).
- */
-
-#define REG_FUNC_ADDR ARMREG_R4
-#define REG_RETVAL ARMREG_R5
-#define REG_THIS ARMREG_R6
-#define REG_ARGP ARMREG_R7
-
-
-#define ARG_SIZE sizeof(stackval)
-
-
-
-
-void flush_icache ()
-{
-#if defined(_WIN32)
- FlushInstructionCache(GetCurrentProcess(), NULL, 0);
-#else
-# if 0
- asm ("mov r0, r0");
- asm ("mov r0, #0");
- asm ("mcr p15, 0, r0, c7, c7, 0");
-# else
- /* TODO: use (movnv pc, rx) method */
-# endif
-#endif
-}
-
-
-void* alloc_code_buff (int num_instr)
-{
- void* code_buff;
- int code_size = num_instr * sizeof(arminstr_t);
-
-#if defined(_WIN32) || defined(UNDER_CE)
- int old_prot = 0;
-
- code_buff = malloc(code_size);
- VirtualProtect(code_buff, code_size, PAGE_EXECUTE_READWRITE, &old_prot);
-#else
- int page_size = sysconf(_SC_PAGESIZE);
- int new_code_size;
-
- new_code_size = code_size + page_size - 1;
- code_buff = malloc(new_code_size);
- code_buff = (void *) (((int) code_buff + page_size - 1) & ~(page_size - 1));
-
- if (mprotect(code_buff, code_size, PROT_READ|PROT_WRITE|PROT_EXEC) != 0) {
- g_critical (G_GNUC_PRETTY_FUNCTION
- ": mprotect error: %s", g_strerror (errno));
- }
-#endif
-
- return code_buff;
-}
-
-
-/*
- * Refer to ARM Procedure Call Standard (APCS) for more info.
- */
-MonoPIFunc mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
-{
- MonoType* param;
- MonoPIFunc code_buff;
- arminstr_t* p;
- guint32 code_size, stack_size;
- guint32 simple_type;
- int i, hasthis, aregs, regc, stack_offs;
- int this_loaded;
- guchar reg_alloc [ARM_NUM_ARG_REGS];
-
- /* pessimistic estimation for prologue/epilogue size */
- code_size = 16 + 16;
- /* push/pop work regs */
- code_size += 2;
- /* call */
- code_size += 2;
- /* handle retval */
- code_size += 2;
-
- stack_size = 0;
- hasthis = sig->hasthis ? 1 : 0;
-
- aregs = ARM_NUM_ARG_REGS - hasthis;
-
- for (i = 0, regc = aregs; i < sig->param_count; ++i) {
- param = sig->params [i];
-
- /* keep track of argument sizes */
- if (i < ARM_NUM_ARG_REGS) reg_alloc [i] = 0;
-
- if (param->byref) {
- if (regc > 0) {
- code_size += 1;
- reg_alloc [i] = regc;
- --regc;
- } else {
- code_size += 2;
- stack_size += sizeof(gpointer);
- }
- } else {
- simple_type = param->type;
-enum_calc_size:
- switch (simple_type) {
- 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_R4:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- if (regc > 0) {
- /* register arg */
- code_size += 1;
- reg_alloc [i] = regc;
- --regc;
- } else {
- /* stack arg */
- code_size += 2;
- stack_size += 4;
- }
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- /* keep track of argument sizes */
- if (regc > 1) {
- /* fits into registers, two LDRs */
- code_size += 2;
- reg_alloc [i] = regc;
- regc -= 2;
- } else if (regc > 0) {
- /* first half fits into register, one LDR */
- code_size += 1;
- reg_alloc [i] = regc;
- --regc;
- /* the rest on the stack, LDR/STR */
- code_size += 2;
- stack_size += 4;
- } else {
- /* stack arg, 4 instrs - 2x(LDR/STR) */
- code_size += 4;
- stack_size += 2 * 4;
- }
- break;
- case MONO_TYPE_VALUETYPE:
- if (param->data.klass->enumtype) {
- simple_type = param->data.klass->enum_basetype->type;
- goto enum_calc_size;
- }
-
- if (mono_class_value_size(param->data.klass, NULL) != 4) {
- g_error("can only marshal enums, not generic structures (size: %d)", mono_class_value_size(param->data.klass, NULL));
- }
- if (regc > 0) {
- /* register arg */
- code_size += 1;
- reg_alloc [i] = regc;
- --regc;
- } else {
- /* stack arg */
- code_size += 2;
- stack_size += 4;
- }
- break;
- default :
- break;
- }
- }
- }
-
- code_buff = (MonoPIFunc)alloc_code_buff(code_size);
- p = (arminstr_t*)code_buff;
-
- /* prologue */
- p = arm_emit_lean_prologue(p, stack_size,
- /* save workset (r4-r7) */
- (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6) | (1 << ARMREG_R7));
-
-
- /* copy args into workset */
- /* callme - always present */
- ARM_MOV_REG_REG(p, ARMREG_R4, ARMREG_A1);
- /* retval */
- if (sig->ret->byref || string_ctor || (sig->ret->type != MONO_TYPE_VOID)) {
- ARM_MOV_REG_REG(p, ARMREG_R5, ARMREG_A2);
- }
- /* this_obj */
- if (sig->hasthis) {
- this_loaded = 0;
- if (stack_size == 0) {
- ARM_MOV_REG_REG(p, ARMREG_A1, ARMREG_A3);
- this_loaded = 1;
- } else {
- ARM_MOV_REG_REG(p, ARMREG_R6, ARMREG_A3);
- }
- }
- /* args */
- if (sig->param_count != 0) {
- ARM_MOV_REG_REG(p, ARMREG_R7, ARMREG_A4);
- }
-
- stack_offs = stack_size;
-
- /* handle arguments */
- /* in reverse order so we could use r0 (arg1) for memory transfers */
- for (i = sig->param_count; --i >= 0;) {
- param = sig->params [i];
- if (param->byref) {
- if (i < aregs && reg_alloc[i] > 0) {
- ARM_LDR_IMM(p, ARMREG_A1 + i, REG_ARGP, i*ARG_SIZE);
- } else {
- stack_offs -= sizeof(armword_t);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
- }
- } else {
- simple_type = param->type;
-enum_marshal:
- switch (simple_type) {
- 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_R4:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_STRING:
- if (i < aregs && reg_alloc [i] > 0) {
- /* pass in register */
- ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
- } else {
- stack_offs -= sizeof(armword_t);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
- }
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- if (i < aregs && reg_alloc [i] > 0) {
- if (reg_alloc [i] > 1) {
- /* pass in registers */
- ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
- ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]) + 1, REG_ARGP, i*ARG_SIZE + 4);
- } else {
- stack_offs -= sizeof(armword_t);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE + 4);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
- ARM_LDR_IMM(p, ARMREG_A1 + hasthis + (aregs - reg_alloc [i]), REG_ARGP, i*ARG_SIZE);
- }
- } else {
- /* two words transferred on the stack */
- stack_offs -= 2*sizeof(armword_t);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i*ARG_SIZE + 4);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs + 4);
- }
- break;
- case MONO_TYPE_VALUETYPE:
- if (param->data.klass->enumtype) {
- /* it's an enum value, proceed based on its base type */
- simple_type = param->data.klass->enum_basetype->type;
- goto enum_marshal;
- } else {
- if (i < aregs && reg_alloc[i] > 0) {
- int vtreg = ARMREG_A1 + hasthis +
- hasthis + (aregs - reg_alloc[i]);
- ARM_LDR_IMM(p, vtreg, REG_ARGP, i * ARG_SIZE);
- ARM_LDR_IMM(p, vtreg, vtreg, 0);
- } else {
- stack_offs -= sizeof(armword_t);
- ARM_LDR_IMM(p, ARMREG_R0, REG_ARGP, i * ARG_SIZE);
- ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R0, 0);
- ARM_STR_IMM(p, ARMREG_R0, ARMREG_SP, stack_offs);
- }
- }
- break;
-
- default:
- break;
- }
- }
- }
-
- if (sig->hasthis && !this_loaded) {
- /* [this] always passed in A1, regardless of sig->call_convention */
- ARM_MOV_REG_REG(p, ARMREG_A1, REG_THIS);
- }
-
- /* call [func] */
- ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
- ARM_MOV_REG_REG(p, ARMREG_PC, REG_FUNC_ADDR);
-
- /* handle retval */
- if (sig->ret->byref || string_ctor) {
- ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
- } else {
- simple_type = sig->ret->type;
-enum_retvalue:
- switch (simple_type) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- ARM_STRB_IMM(p, ARMREG_R0, REG_RETVAL, 0);
- break;
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- ARM_STRH_IMM(p, ARMREG_R0, REG_RETVAL, 0);
- break;
- /*
- * A 32-bit integer and integer-equivalent return value
- * is returned in R0.
- * Single-precision floating-point values are returned in R0.
- */
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_R4:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- case MONO_TYPE_STRING:
- ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
- break;
- /*
- * A 64-bit integer is returned in R0 and R1.
- * Double-precision floating-point values are returned in R0 and R1.
- */
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- ARM_STR_IMM(p, ARMREG_R0, REG_RETVAL, 0);
- ARM_STR_IMM(p, ARMREG_R1, REG_RETVAL, 4);
- break;
- case MONO_TYPE_VALUETYPE:
- if (sig->ret->data.klass->enumtype) {
- simple_type = sig->ret->data.klass->enum_basetype->type;
- goto enum_retvalue;
- }
- break;
- case MONO_TYPE_VOID:
- break;
- default:
- break;
- }
- }
-
- p = arm_emit_std_epilogue(p, stack_size,
- /* restore R4-R7 */
- (1 << ARMREG_R4) | (1 << ARMREG_R5) | (1 << ARMREG_R6) | (1 << ARMREG_R7));
-
- flush_icache();
-
-#ifdef ARM_DUMP_DISASM
- _armdis_decode((arminstr_t*)code_buff, ((guint8*)p) - ((guint8*)code_buff));
-#endif
-
- return code_buff;
-}
-
-
-
-#define MINV_OFFS(member) G_STRUCT_OFFSET(MonoInvocation, member)
-
-
-
-/*
- * 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 call convention specified in the method.
- * This function works by creating a MonoInvocation structure,
- * filling the fields in and calling ves_exec_method on it.
- * Still need to figure out how to handle the exception stuff
- * across the managed/unmanaged boundary.
- */
-void* mono_arch_create_method_pointer (MonoMethod* method)
-{
- MonoMethodSignature* sig;
- guchar* p, * p_method, * p_stackval_from_data, * p_exec;
- void* code_buff;
- int i, stack_size, arg_pos, arg_add, stackval_pos, offs;
- int areg, reg_args, shift, pos;
- MonoJitInfo *ji;
-
- code_buff = alloc_code_buff(128);
- p = (guchar*)code_buff;
-
- sig = method->signature;
-
- ARM_B(p, 3);
-
- /* embed magic number followed by method pointer */
- *p++ = 'M';
- *p++ = 'o';
- *p++ = 'n';
- *p++ = 'o';
- /* method ptr */
- *(void**)p = method;
- p_method = p;
- p += 4;
-
- /* call table */
- *(void**)p = stackval_from_data;
- p_stackval_from_data = p;
- p += 4;
- *(void**)p = ves_exec_method;
- p_exec = p;
- p += 4;
-
- stack_size = sizeof(MonoInvocation) + ARG_SIZE*(sig->param_count + 1) + ARM_NUM_ARG_REGS*2*sizeof(armword_t);
-
- /* prologue */
- p = (guchar*)arm_emit_lean_prologue((arminstr_t*)p, stack_size,
- (1 << ARMREG_R4) |
- (1 << ARMREG_R5) |
- (1 << ARMREG_R6) |
- (1 << ARMREG_R7));
-
- /* R7 - ptr to stack args */
- ARM_MOV_REG_REG(p, ARMREG_R7, ARMREG_IP);
-
- /*
- * Initialize MonoInvocation fields, first the ones known now.
- */
- ARM_MOV_REG_IMM8(p, ARMREG_R4, 0);
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(ex));
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(ex_handler));
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(parent));
-
- /* Set the method pointer. */
- ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, -(int)(p - p_method + sizeof(arminstr_t)*2));
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(method));
-
- if (sig->hasthis) {
- /* [this] in A1 */
- ARM_STR_IMM(p, ARMREG_A1, ARMREG_SP, MINV_OFFS(obj));
- } else {
- /* else set minv.obj to NULL */
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_SP, MINV_OFFS(obj));
- }
-
- /* copy args from registers to stack */
- areg = ARMREG_A1 + sig->hasthis;
- arg_pos = -(int)(ARM_NUM_ARG_REGS - sig->hasthis) * 2 * sizeof(armword_t);
- arg_add = 0;
- for (i = 0; i < sig->param_count; ++i) {
- if (areg >= ARM_NUM_ARG_REGS) break;
- ARM_STR_IMM(p, areg, ARMREG_R7, arg_pos);
- ++areg;
- if (!sig->params[i]->byref) {
- switch (sig->params[i]->type) {
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- if (areg >= ARM_NUM_ARG_REGS) {
- /* load second half of 64-bit arg */
- ARM_LDR_IMM(p, ARMREG_R4, ARMREG_R7, 0);
- ARM_STR_IMM(p, ARMREG_R4, ARMREG_R7, arg_pos + sizeof(armword_t));
- arg_add = sizeof(armword_t);
- } else {
- /* second half is already the register */
- ARM_STR_IMM(p, areg, ARMREG_R7, arg_pos + sizeof(armword_t));
- ++areg;
- }
- break;
- case MONO_TYPE_VALUETYPE:
- /* assert */
- default:
- break;
- }
- }
- arg_pos += 2 * sizeof(armword_t);
- }
- /* number of args passed in registers */
- reg_args = i;
-
-
-
- /*
- * Calc and save stack args ptr,
- * args follow MonoInvocation struct on the stack.
- */
- ARM_ADD_REG_IMM8(p, ARMREG_R1, ARMREG_SP, sizeof(MonoInvocation));
- ARM_STR_IMM(p, ARMREG_R1, ARMREG_SP, MINV_OFFS(stack_args));
-
- /* convert method args to stackvals */
- arg_pos = -(int)(ARM_NUM_ARG_REGS - sig->hasthis) * 2 * sizeof(armword_t);
- stackval_pos = sizeof(MonoInvocation);
- for (i = 0; i < sig->param_count; ++i) {
- if (i < reg_args) {
- ARM_SUB_REG_IMM8(p, ARMREG_A3, ARMREG_R7, -arg_pos);
- arg_pos += 2 * sizeof(armword_t);
- } else {
- if (arg_pos < 0) arg_pos = 0;
- pos = arg_pos + arg_add;
- if (pos <= 0xFF) {
- ARM_ADD_REG_IMM8(p, ARMREG_A3, ARMREG_R7, pos);
- } else {
- if (is_arm_const((armword_t)pos)) {
- shift = calc_arm_mov_const_shift((armword_t)pos);
- ARM_ADD_REG_IMM(p, ARMREG_A3, ARMREG_R7, pos >> ((32 - shift) & 31), shift >> 1);
- } else {
- p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R6, (armword_t)pos);
- ARM_ADD_REG_REG(p, ARMREG_A2, ARMREG_R7, ARMREG_R6);
- }
- }
- arg_pos += sizeof(armword_t);
- if (!sig->params[i]->byref) {
- switch (sig->params[i]->type) {
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- arg_pos += sizeof(armword_t);
- break;
- case MONO_TYPE_VALUETYPE:
- /* assert */
- default:
- break;
- }
- }
- }
-
- /* A2 = result */
- if (stackval_pos <= 0xFF) {
- ARM_ADD_REG_IMM8(p, ARMREG_A2, ARMREG_SP, stackval_pos);
- } else {
- if (is_arm_const((armword_t)stackval_pos)) {
- shift = calc_arm_mov_const_shift((armword_t)stackval_pos);
- ARM_ADD_REG_IMM(p, ARMREG_A2, ARMREG_SP, stackval_pos >> ((32 - shift) & 31), shift >> 1);
- } else {
- p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R6, (armword_t)stackval_pos);
- ARM_ADD_REG_REG(p, ARMREG_A2, ARMREG_SP, ARMREG_R6);
- }
- }
-
- /* A1 = type */
- p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_A1, (armword_t)sig->params [i]);
-
- stackval_pos += ARG_SIZE;
-
- offs = -(p + 2*sizeof(arminstr_t) - p_stackval_from_data);
- /* load function address */
- ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, offs);
- /* call stackval_from_data */
- ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
- ARM_MOV_REG_REG(p, ARMREG_PC, ARMREG_R4);
- }
-
- /* store retval ptr */
- p = (guchar*)arm_mov_reg_imm32((arminstr_t*)p, ARMREG_R5, (armword_t)stackval_pos);
- ARM_ADD_REG_REG(p, ARMREG_R5, ARMREG_SP, ARMREG_R4);
- ARM_STR_IMM(p, ARMREG_R5, ARMREG_SP, MINV_OFFS(retval));
-
- /*
- * Call the method.
- */
- /* A1 = MonoInvocation ptr */
- ARM_MOV_REG_REG(p, ARMREG_A1, ARMREG_SP);
- offs = -(p + 2*sizeof(arminstr_t) - p_exec);
- /* load function address */
- ARM_LDR_IMM(p, ARMREG_R4, ARMREG_PC, offs);
- /* call ves_exec */
- ARM_MOV_REG_REG(p, ARMREG_LR, ARMREG_PC);
- ARM_MOV_REG_REG(p, ARMREG_PC, ARMREG_R4);
-
-
- /*
- * Move retval into reg.
- */
- if (sig->ret->byref) {
- ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
- } else {
- switch (sig->ret->type) {
- case MONO_TYPE_BOOLEAN:
- case MONO_TYPE_I1:
- case MONO_TYPE_U1:
- ARM_LDRB_IMM(p, ARMREG_R0, ARMREG_R5, 0);
- break;
- case MONO_TYPE_CHAR:
- case MONO_TYPE_I2:
- case MONO_TYPE_U2:
- ARM_LDRH_IMM(p, ARMREG_R0, ARMREG_R5, 0);
- break;
- case MONO_TYPE_I:
- case MONO_TYPE_U:
- case MONO_TYPE_I4:
- case MONO_TYPE_U4:
- case MONO_TYPE_R4:
- case MONO_TYPE_OBJECT:
- case MONO_TYPE_CLASS:
- case MONO_TYPE_ARRAY:
- case MONO_TYPE_SZARRAY:
- ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
- break;
- case MONO_TYPE_I8:
- case MONO_TYPE_U8:
- case MONO_TYPE_R8:
- ARM_LDR_IMM(p, ARMREG_R0, ARMREG_R5, 0);
- ARM_LDR_IMM(p, ARMREG_R1, ARMREG_R5, 4);
- break;
- case MONO_TYPE_VOID:
- default:
- break;
- }
- }
-
-
- p = (guchar*)arm_emit_std_epilogue((arminstr_t*)p, stack_size,
- (1 << ARMREG_R4) |
- (1 << ARMREG_R5) |
- (1 << ARMREG_R6) |
- (1 << ARMREG_R7));
-
- flush_icache();
-
-#ifdef ARM_DUMP_DISASM
- _armdis_decode((arminstr_t*)code_buff, ((guint8*)p) - ((guint8*)code_buff));
-#endif
-
- ji = g_new0(MonoJitInfo, 1);
- ji->method = method;
- ji->code_size = ((guint8 *) p) - ((guint8 *) code_buff);
- ji->code_start = (gpointer) code_buff;
-
- mono_jit_info_table_add(mono_get_root_domain (), ji);
-
- return code_buff;
-}
-
-
-/*
- * mono_create_method_pointer () will insert a pointer to the MonoMethod
- * so that the interp can easily get at the data: this function will retrieve
- * the method from the code stream.
- */
-MonoMethod* mono_method_pointer_get (void* code)
-{
- unsigned char* c = code;
- /* check out magic number that follows unconditional branch */
- if (c[4] == 'M' &&
- c[5] == 'o' &&
- c[6] == 'n' &&
- c[7] == 'o') return ((MonoMethod**)code)[2];
- return NULL;
-}
-#endif
guint32 *lowest);
extern void _wapi_handle_unlock_handles (guint32 numhandles,
gpointer *handles);
-extern int _wapi_handle_wait_signal (gboolean poll);
-extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll);
-extern int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable);
-extern int _wapi_handle_timedwait_signal_handle (gpointer handle,
- struct timespec *timeout, gboolean alertable, gboolean poll);
+extern int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll, gboolean *alerted);
+extern int _wapi_handle_timedwait_signal_handle (gpointer handle, struct timespec *timeout, gboolean alertable, gboolean poll, gboolean *alerted);
extern gboolean _wapi_handle_get_or_set_share (guint64 device, guint64 inode,
guint32 new_sharemode,
guint32 new_access,
#include <mono/utils/mono-mutex.h>
#include <mono/utils/mono-proclib.h>
+#include <mono/utils/mono-threads.h>
#undef DEBUG_REFS
#if 0
return(ret);
}
-int _wapi_handle_wait_signal (gboolean poll)
+int
+_wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll, gboolean *alerted)
{
- return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, NULL, TRUE, poll);
+ return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll, alerted);
}
-int _wapi_handle_timedwait_signal (struct timespec *timeout, gboolean poll)
+static void
+signal_handle_and_unref (gpointer handle)
{
- return _wapi_handle_timedwait_signal_handle (_wapi_global_signal_handle, timeout, TRUE, poll);
-}
+ pthread_cond_t *cond;
+ mono_mutex_t *mutex;
+ guint32 idx;
-int _wapi_handle_wait_signal_handle (gpointer handle, gboolean alertable)
-{
- DEBUG ("%s: waiting for %p", __func__, handle);
-
- return _wapi_handle_timedwait_signal_handle (handle, NULL, alertable, FALSE);
+ g_assert (handle);
+
+ /* If we reach here, then interrupt token is set to the flag value, which
+ * means that the target thread is either
+ * - before the first CAS in timedwait, which means it won't enter the wait.
+ * - it is after the first CAS, so it is already waiting, or it will enter
+ * the wait, and it will be interrupted by the broadcast. */
+ idx = GPOINTER_TO_UINT (handle);
+ cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
+ mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
+
+ mono_mutex_lock (mutex);
+ mono_cond_broadcast (cond);
+ mono_mutex_unlock (mutex);
+
+ _wapi_handle_unref (handle);
}
-int _wapi_handle_timedwait_signal_handle (gpointer handle,
- struct timespec *timeout, gboolean alertable, gboolean poll)
+int
+_wapi_handle_timedwait_signal_handle (gpointer handle, struct timespec *timeout,
+ gboolean alertable, gboolean poll, gboolean *alerted)
{
DEBUG ("%s: waiting for %p (type %s)", __func__, handle,
_wapi_handle_typename[_wapi_handle_type (handle)]);
-
+
+ if (alertable)
+ g_assert (alerted);
+
+ if (alerted)
+ *alerted = FALSE;
+
if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
if (WAPI_SHARED_HANDLE_DATA(handle).signalled == TRUE) {
return (0);
pthread_cond_t *cond;
mono_mutex_t *mutex;
- if (alertable && !wapi_thread_set_wait_handle (handle))
- return 0;
+ if (alertable) {
+ mono_thread_info_install_interrupt (signal_handle_and_unref, handle, alerted);
+ if (*alerted)
+ return 0;
+ _wapi_handle_ref (handle);
+ }
cond = &_WAPI_PRIVATE_HANDLES (idx).signal_cond;
mutex = &_WAPI_PRIVATE_HANDLES (idx).signal_mutex;
res = mono_cond_wait (cond, mutex);
}
- if (alertable)
- wapi_thread_clear_wait_handle (handle);
+ if (alertable) {
+ mono_thread_info_uninstall_interrupt (alerted);
+ if (!*alerted) {
+ /* if it is alerted, then the handle is unref in the interrupt callback */
+ _wapi_handle_unref (handle);
+ }
+ }
return res;
}
return(TRUE);
}
-guint32 GetTempPath (guint32 len, gunichar2 *buf)
-{
- gchar *tmpdir=g_strdup (g_get_tmp_dir ());
- gunichar2 *tmpdir16=NULL;
- glong dirlen;
- gsize bytes;
- guint32 ret;
-
- if(tmpdir[strlen (tmpdir)]!='/') {
- g_free (tmpdir);
- tmpdir=g_strdup_printf ("%s/", g_get_tmp_dir ());
- }
-
- tmpdir16=mono_unicode_from_external (tmpdir, &bytes);
- if(tmpdir16==NULL) {
- g_free (tmpdir);
- return(0);
- } else {
- dirlen=(bytes/2);
-
- if(dirlen+1>len) {
- DEBUG ("%s: Size %d smaller than needed (%ld)",
- __func__, len, dirlen+1);
-
- ret=dirlen+1;
- } else {
- /* Add the terminator */
- memset (buf, '\0', bytes+2);
- memcpy (buf, tmpdir16, bytes);
-
- ret=dirlen;
- }
- }
-
- if(tmpdir16!=NULL) {
- g_free (tmpdir16);
- }
- g_free (tmpdir);
-
- return(ret);
-}
-
#ifdef HAVE_GETFSSTAT
/* Darwin has getfsstat */
gint32 GetLogicalDriveStrings (guint32 len, gunichar2 *buf)
extern gboolean SetCurrentDirectory (const gunichar2 *path);
extern gboolean CreatePipe (gpointer *readpipe, gpointer *writepipe,
WapiSecurityAttributes *security, guint32 size);
-extern guint32 GetTempPath (guint32 len, gunichar2 *buf);
extern gint32 GetLogicalDriveStrings (guint32 len, gunichar2 *buf);
extern gboolean GetDiskFreeSpaceEx(const gunichar2 *path_name, WapiULargeInteger *free_bytes_avail,
WapiULargeInteger *total_number_of_bytes,
WapiStartupInfo *startup,
WapiProcessInformation *process_info)
{
+#if defined (HAVE_FORK) && defined (HAVE_EXECVE)
char *cmd = NULL, *prog = NULL, *full_prog = NULL, *args = NULL, *args_after_prog = NULL;
char *dir = NULL, **env_strings = NULL, **argv = NULL;
guint32 i, env_count = 0;
mono_processes_cleanup ();
return ret;
+#else
+ SetLastError (ERROR_NOT_SUPPORTED);
+ return FALSE;
+#endif // defined (HAVE_FORK) && defined (HAVE_EXECVE)
}
static void
/* No proc name on OSX < 10.5 nor ppc nor iOS */
memset (buf, '\0', sizeof(buf));
proc_name (pid, buf, sizeof(buf));
- if (strlen (buf) > 0)
+
+ // Fixes proc_name triming values to 15 characters #32539
+ if (strlen (buf) >= MAXCOMLEN - 1) {
+ char path_buf [PROC_PIDPATHINFO_MAXSIZE];
+ char *name_buf;
+ int path_len;
+
+ memset (path_buf, '\0', sizeof(path_buf));
+ path_len = proc_pidpath (pid, path_buf, sizeof(path_buf));
+
+ if (path_len > 0 && path_len < sizeof(path_buf)) {
+ name_buf = path_buf + path_len;
+ for(;name_buf > path_buf; name_buf--) {
+ if (name_buf [0] == '/') {
+ name_buf++;
+ break;
+ }
+ }
+
+ if (memcmp (buf, name_buf, MAXCOMLEN - 1) == 0)
+ ret = g_strdup (name_buf);
+ }
+ }
+
+ if (ret == NULL && strlen (buf) > 0)
ret = g_strdup (buf);
#else
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0)
return 0;
}
+static guint32
+get_module_filename (gpointer process, gpointer module,
+ gunichar2 *basename, guint32 size)
+{
+ int pid, len;
+ gsize bytes;
+ char *path;
+ gunichar2 *proc_path;
+
+ size *= sizeof (gunichar2); /* adjust for unicode characters */
+
+ if (basename == NULL || size == 0)
+ return 0;
+
+ pid = GetProcessId (process);
+
+ path = wapi_process_get_path (pid);
+ if (path == NULL)
+ return 0;
+
+ proc_path = mono_unicode_from_external (path, &bytes);
+ g_free (path);
+
+ if (proc_path == NULL)
+ return 0;
+
+ len = (bytes / 2);
+
+ /* Add the terminator */
+ bytes += 2;
+
+ if (size < bytes) {
+ DEBUG ("%s: Size %d smaller than needed (%ld); truncating", __func__, size, bytes);
+
+ memcpy (basename, proc_path, size);
+ } else {
+ DEBUG ("%s: Size %d larger than needed (%ld)",
+ __func__, size, bytes);
+
+ memcpy (basename, proc_path, bytes);
+ }
+
+ g_free (proc_path);
+
+ return len;
+}
+
guint32
GetModuleBaseName (gpointer process, gpointer module,
gunichar2 *basename, guint32 size)
GetModuleFileNameEx (gpointer process, gpointer module,
gunichar2 *filename, guint32 size)
{
- return get_module_name (process, module, filename, size, FALSE);
+ return get_module_filename (process, module, filename, size);
}
gboolean
extern struct _WapiHandleOps _wapi_thread_ops;
-#define INTERRUPTION_REQUESTED_HANDLE (gpointer)0xFFFFFFFE
-
struct _WapiHandle_thread
{
pthread_t id;
GPtrArray *owned_mutexes;
- /*
- * Handle this thread waits on. If this is INTERRUPTION_REQUESTED_HANDLE,
- * it means the thread is interrupted by another thread, and shouldn't enter
- * a wait.
- * This also acts as a reference for the handle.
- */
- gpointer wait_handle;
};
typedef struct _WapiHandle_thread WapiHandle_thread;
-extern gboolean _wapi_thread_apc_pending (gpointer handle);
extern gboolean _wapi_thread_cur_apc_pending (void);
extern void _wapi_thread_own_mutex (gpointer mutex);
extern void _wapi_thread_disown_mutex (gpointer mutex);
extern void Sleep(guint32 ms);
extern guint32 SleepEx(guint32 ms, gboolean alertable);
-void wapi_clear_interruption (void);
-gboolean wapi_thread_set_wait_handle (gpointer handle);
-void wapi_thread_clear_wait_handle (gpointer handle);
-void wapi_self_interrupt (void);
-
-gpointer wapi_prepare_interrupt_thread (gpointer thread_handle);
-void wapi_finish_interrupt_thread (gpointer wait_handle);
-
gpointer wapi_create_thread_handle (void);
void wapi_thread_handle_set_exited (gpointer handle, guint32 exitstatus);
void wapi_ref_thread_handle (gpointer handle);
ret = _wapi_handle_ops_special_wait (handle, timeout, alertable);
- if (alertable && _wapi_thread_apc_pending (current_thread)) {
- apc_pending = TRUE;
+ if (alertable && _wapi_thread_cur_apc_pending ())
ret = WAIT_IO_COMPLETION;
- }
- goto check_pending;
+ return ret;
}
goto done;
}
}
-
- if (alertable && _wapi_thread_apc_pending (current_thread)) {
- apc_pending = TRUE;
- ret = WAIT_IO_COMPLETION;
- goto done;
- }
-
+
if (own_if_signalled (handle) == TRUE) {
DEBUG ("%s: handle %p already signalled", __func__,
handle);
ret = WAIT_OBJECT_0;
goto done;
}
-
- if (timeout == INFINITE) {
- waited = _wapi_handle_wait_signal_handle (handle, alertable);
- } else {
- waited = _wapi_handle_timedwait_signal_handle (handle, &abstime, alertable, FALSE);
- }
-
- if (alertable)
- apc_pending = _wapi_thread_apc_pending (current_thread);
+
+ waited = _wapi_handle_timedwait_signal_handle (handle, timeout == INFINITE ? NULL : &abstime, alertable, FALSE, &apc_pending);
if(waited==0 && !apc_pending) {
/* Condition was signalled, so hopefully
DEBUG ("%s: wait on handle %p error: %s", __func__, handle,
strerror (waited));
- ret = WAIT_TIMEOUT;
-
+ ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
+
done:
DEBUG ("%s: unlocking handle %p", __func__, handle);
thr_ret = _wapi_handle_unlock_handle (handle);
g_assert (thr_ret == 0);
-
-check_pending:
- if (apc_pending)
- ret = WAIT_IO_COMPLETION;
-
+
return(ret);
}
goto done;
}
}
-
- if (alertable && _wapi_thread_apc_pending (current_thread)) {
- apc_pending = TRUE;
- ret = WAIT_IO_COMPLETION;
- goto done;
- }
-
+
if (own_if_signalled (wait)) {
DEBUG ("%s: handle %p already signalled", __func__, wait);
ret = WAIT_OBJECT_0;
goto done;
}
-
- if (timeout == INFINITE) {
- waited = _wapi_handle_wait_signal_handle (wait, alertable);
- } else {
- waited = _wapi_handle_timedwait_signal_handle (wait, &abstime, alertable, FALSE);
- }
- if (alertable) {
- apc_pending = _wapi_thread_apc_pending (current_thread);
- }
+ waited = _wapi_handle_timedwait_signal_handle (wait, timeout == INFINITE ? NULL : &abstime, alertable, FALSE, &apc_pending);
if (waited==0 && !apc_pending) {
/* Condition was signalled, so hopefully
DEBUG ("%s: wait on handle %p error: %s", __func__, wait,
strerror (ret));
- ret = WAIT_TIMEOUT;
-
+ ret = apc_pending ? WAIT_IO_COMPLETION : WAIT_TIMEOUT;
+
done:
DEBUG ("%s: unlocking handle %p", __func__, wait);
thr_ret = _wapi_handle_unlock_handle (wait);
g_assert (thr_ret == 0);
- if (apc_pending)
- ret = WAIT_IO_COMPLETION;
-
return(ret);
}
guint32 retval;
gboolean poll;
gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
+ gboolean apc_pending = FALSE;
if (current_thread == NULL) {
SetLastError (ERROR_INVALID_HANDLE);
_wapi_calc_timeout (&abstime, timeout);
}
- if (alertable && _wapi_thread_apc_pending (current_thread))
- return WAIT_IO_COMPLETION;
-
for (i = 0; i < numobjects; i++) {
/* Add a reference, as we need to ensure the handle wont
* disappear from under us while we're waiting in the loop
if (!done) {
/* Enter the wait */
- if (timeout == INFINITE) {
- ret = _wapi_handle_wait_signal (poll);
- } else {
- ret = _wapi_handle_timedwait_signal (&abstime, poll);
- }
+ ret = _wapi_handle_timedwait_signal (timeout == INFINITE ? NULL : &abstime, poll, &apc_pending);
} else {
/* No need to wait */
ret = 0;
thr_ret = _wapi_handle_unlock_signal_mutex (NULL);
g_assert (thr_ret == 0);
- if (alertable && _wapi_thread_apc_pending (current_thread)) {
+ if (alertable && apc_pending) {
retval = WAIT_IO_COMPLETION;
break;
}
#define GetCurrentDirectory wapi_GetCurrentDirectory
#define SetCurrentDirectory wapi_SetCurrentDirectory
#define CreatePipe wapi_CreatePipe
-#define GetTempPath wapi_GetTempPath
#define GetLogicalDriveStrings wapi_GetLogicalDriveStrings
#define GetDiskFreeSpaceEx wapi_GetDiskFreeSpaceEx
#define GetDriveType wapi_GetDriveType
if (alertable) {
current_thread = get_current_thread_handle ();
- if (_wapi_thread_apc_pending (current_thread))
+ if (_wapi_thread_cur_apc_pending ())
return WAIT_IO_COMPLETION;
}
while (TRUE) {
ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL);
- if (alertable && _wapi_thread_apc_pending (current_thread))
+ if (alertable && _wapi_thread_cur_apc_pending ())
return WAIT_IO_COMPLETION;
if (ret == 0)
memset (&rem, 0, sizeof (rem));
ret=nanosleep(&req, &rem);
- if (alertable && _wapi_thread_apc_pending (current_thread))
+ if (alertable && _wapi_thread_cur_apc_pending ())
return WAIT_IO_COMPLETION;
if(ret==-1) {
gboolean
_wapi_thread_cur_apc_pending (void)
{
- return _wapi_thread_apc_pending (get_current_thread_handle ());
-}
-
-gboolean
-_wapi_thread_apc_pending (gpointer handle)
-{
- WapiHandle_thread *thread;
-
- thread = lookup_thread (handle);
-
- return thread->wait_handle == INTERRUPTION_REQUESTED_HANDLE;
-}
-
-/*
- * wapi_interrupt_thread:
- *
- * The state of the thread handle HANDLE is set to 'interrupted' which means that
- * if the thread calls one of the WaitFor functions, the function will return with
- * WAIT_IO_COMPLETION instead of waiting. Also, if the thread was waiting when
- * this function was called, the wait will be broken.
- * It is possible that the wait functions return WAIT_IO_COMPLETION, but the
- * target thread didn't receive the interrupt signal yet, in this case it should
- * call the wait function again. This essentially means that the target thread will
- * busy wait until it is ready to process the interruption.
- */
-gpointer
-wapi_prepare_interrupt_thread (gpointer thread_handle)
-{
- WapiHandle_thread *thread;
- gpointer prev_handle, wait_handle;
-
- thread = lookup_thread (thread_handle); /* FIXME this is wrong, move this whole thing to MonoThreads where it can be done lockfree */
-
- while (TRUE) {
- wait_handle = thread->wait_handle;
-
- /*
- * Atomically obtain the handle the thread is waiting on, and
- * change it to a flag value.
- */
- prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
- INTERRUPTION_REQUESTED_HANDLE, wait_handle);
- if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
- /* Already interrupted */
- return 0;
- if (prev_handle == wait_handle)
- break;
-
- /* Try again */
- }
-
- WAIT_DEBUG (printf ("%p: state -> INTERRUPTED.\n", thread->id););
-
- return wait_handle;
-}
-
-void
-wapi_finish_interrupt_thread (gpointer wait_handle)
-{
- pthread_cond_t *cond;
- mono_mutex_t *mutex;
- guint32 idx;
-
- if (!wait_handle)
- /* Not waiting */
- return;
-
- /* If we reach here, then wait_handle is set to the flag value,
- * which means that the target thread is either
- * - before the first CAS in timedwait, which means it won't enter the
- * wait.
- * - it is after the first CAS, so it is already waiting, or it will
- * enter the wait, and it will be interrupted by the broadcast.
- */
- idx = GPOINTER_TO_UINT(wait_handle);
- cond = &_WAPI_PRIVATE_HANDLES(idx).signal_cond;
- mutex = &_WAPI_PRIVATE_HANDLES(idx).signal_mutex;
-
- mono_mutex_lock (mutex);
- mono_cond_broadcast (cond);
- mono_mutex_unlock (mutex);
-
- /* ref added by set_wait_handle */
- _wapi_handle_unref (wait_handle);
-}
-
-/*
- * wapi_self_interrupt:
- *
- * This is not part of the WIN32 API.
- * Set the 'interrupted' state of the calling thread if it's NULL.
- */
-void
-wapi_self_interrupt (void)
-{
- gpointer wait_handle;
-
- wait_handle = wapi_prepare_interrupt_thread (get_current_thread_handle ());
- if (wait_handle)
- /* ref added by set_wait_handle */
- _wapi_handle_unref (wait_handle);
-}
-
-/*
- * wapi_clear_interruption:
- *
- * This is not part of the WIN32 API.
- * Clear the 'interrupted' state of the calling thread.
- * This function is signal safe
- */
-void
-wapi_clear_interruption (void)
-{
- WapiHandle_thread *thread;
- gpointer prev_handle;
-
- thread = get_current_thread ();
-
- prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
- NULL, INTERRUPTION_REQUESTED_HANDLE);
- if (prev_handle == INTERRUPTION_REQUESTED_HANDLE)
- WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
-}
-
-/**
- * wapi_thread_set_wait_handle:
- *
- * Set the wait handle for the current thread to HANDLE. Return TRUE on success, FALSE
- * if the thread is in interrupted state, and cannot start waiting.
- */
-gboolean
-wapi_thread_set_wait_handle (gpointer handle)
-{
- WapiHandle_thread *thread;
- gpointer prev_handle;
-
- thread = get_current_thread ();
-
- prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
- handle, NULL);
- if (prev_handle == NULL) {
- /* thread->wait_handle acts as an additional reference to the handle */
- _wapi_handle_ref (handle);
-
- WAIT_DEBUG (printf ("%p: state -> WAITING.\n", GetCurrentThreadId ()););
- } else {
- g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE);
- WAIT_DEBUG (printf ("%p: unable to set state to WAITING.\n", GetCurrentThreadId ()););
- }
-
- return prev_handle == NULL;
-}
-
-/**
- * wapi_thread_clear_wait_handle:
- *
- * Clear the wait handle of the current thread.
- */
-void
-wapi_thread_clear_wait_handle (gpointer handle)
-{
- WapiHandle_thread *thread;
- gpointer prev_handle;
-
- thread = get_current_thread ();
-
- prev_handle = InterlockedCompareExchangePointer (&thread->wait_handle,
- NULL, handle);
- if (prev_handle == handle) {
- _wapi_handle_unref (handle);
- WAIT_DEBUG (printf ("%p: state -> NORMAL.\n", GetCurrentThreadId ()););
- } else {
- /*It can be NULL if it was asynchronously cleared*/
- g_assert (prev_handle == INTERRUPTION_REQUESTED_HANDLE || prev_handle == NULL);
- WAIT_DEBUG (printf ("%p: finished waiting.\n", GetCurrentThreadId ()););
- }
+ return mono_thread_info_is_interrupt_state (mono_thread_info_current ());
}
void
WapiHandle_thread *thread;
gpointer thread_handle;
int i;
- gpointer handle;
GString* text;
char *res;
thread_handle = get_current_thread_handle ();
thread = lookup_thread (thread_handle);
- handle = thread->wait_handle;
text = g_string_new (0);
g_string_append_printf (text, "thread handle %p state : ", thread_handle);
- if (!handle)
- g_string_append_printf (text, "not waiting");
- else if (handle == INTERRUPTION_REQUESTED_HANDLE)
- g_string_append_printf (text, "interrupted state");
- else
- g_string_append_printf (text, "waiting on %p : %s ", handle, _wapi_handle_typename[_wapi_handle_type (handle)]);
+ mono_thread_info_describe_interrupt_token (mono_thread_info_current (), text);
+
g_string_append_printf (text, " owns (");
- for (i = 0; i < thread->owned_mutexes->len; i++) {
- gpointer mutex = g_ptr_array_index (thread->owned_mutexes, i);
- if (i > 0)
- g_string_append_printf (text, ", %p", mutex);
- else
- g_string_append_printf (text, "%p", mutex);
- }
+ for (i = 0; i < thread->owned_mutexes->len; i++)
+ g_string_append_printf (text, i > 0 ? ", %p" : "%p", g_ptr_array_index (thread->owned_mutexes, i));
g_string_append_printf (text, ")");
res = text->str;
sgen-os-posix.c \
sgen-os-mach.c \
sgen-os-win32.c \
+ sgen-os-coop.c \
sgen-bridge.c \
sgen-bridge.h \
sgen-bridge-internal.h \
* Changes which are already detected at runtime, like the addition
* of icalls, do not require an increment.
*/
-#define MONO_CORLIB_VERSION 135
+#define MONO_CORLIB_VERSION 136
typedef struct
{
gchar *filename;
} RuntimeConfig;
-mono_mutex_t mono_delegate_section;
-
static gunichar2 process_guid [36];
static gboolean process_guid_set = FALSE;
domain->domain = ad;
domain->setup = setup;
- mono_mutex_init_recursive (&mono_delegate_section);
-
mono_thread_attach (domain);
mono_type_initialization_init ();
MONO_CHECK_ARG_NULL (name, NULL);
- g_assert (ad != NULL);
+ g_assert (ad);
add = ad->data;
- g_assert (add != NULL);
+ g_assert (add);
str = mono_string_to_utf8 (name);
MONO_CHECK_ARG_NULL (name,);
- g_assert (ad != NULL);
+ g_assert (ad);
add = ad->data;
- g_assert (add != NULL);
+ g_assert (add);
mono_domain_lock (add);
MonoAppDomainSetup *
ves_icall_System_AppDomain_getSetup (MonoAppDomain *ad)
{
- g_assert (ad != NULL);
- g_assert (ad->data != NULL);
+ g_assert (ad);
+ g_assert (ad->data);
return ad->data->setup;
}
MonoString *
ves_icall_System_AppDomain_getFriendlyName (MonoAppDomain *ad)
{
- g_assert (ad != NULL);
- g_assert (ad->data != NULL);
+ g_assert (ad);
+ g_assert (ad->data);
return mono_string_new (ad->data, ad->data->friendly_name);
}
gchar *name;
gboolean parsed;
- g_assert (assRef != NULL);
+ g_assert (assRef);
name = mono_string_to_utf8 (assRef);
parsed = mono_assembly_name_parse (name, &aname);
{
guint32 result;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
result = WaitForSingleObjectEx (handle, timeout, alertable);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return result;
}
{"I18N.Other", 0},
{"I18N.Rare", 0},
{"I18N.West", 0},
+ {"Microsoft.Build.Engine", 2},
+ {"Microsoft.Build.Framework", 2},
{"Microsoft.VisualBasic", 1},
{"Microsoft.VisualC", 1},
{"Mono.Cairo", 0},
#endif
+static char* unquote (const char *str);
+
/* This protects loaded_assemblies and image->references */
#define mono_assemblies_lock() mono_mutex_lock (&assemblies_mutex)
#define mono_assemblies_unlock() mono_mutex_unlock (&assemblies_mutex)
mono_assembly_name_parse_full (const char *name, MonoAssemblyName *aname, gboolean save_public_key, gboolean *is_version_defined, gboolean *is_token_defined)
{
gchar *dllname;
+ gchar *dllname_uq;
gchar *version = NULL;
+ gchar *version_uq;
gchar *culture = NULL;
+ gchar *culture_uq;
gchar *token = NULL;
+ gchar *token_uq;
gchar *key = NULL;
+ gchar *key_uq;
gchar *retargetable = NULL;
+ gchar *retargetable_uq;
+ gchar *procarch;
+ gchar *procarch_uq;
gboolean res;
gchar *value, *part_name;
guint32 part_name_len;
if (part_name_len == 12 && !g_ascii_strncasecmp (part_name, "Retargetable", part_name_len)) {
retargetable = value;
- if (strlen (retargetable) == 0) {
- goto cleanup_and_fail;
- }
+ retargetable_uq = unquote (retargetable);
+ if (retargetable_uq != NULL)
+ retargetable = retargetable_uq;
+
if (!g_ascii_strcasecmp (retargetable, "yes")) {
flags |= ASSEMBLYREF_RETARGETABLE_FLAG;
} else if (g_ascii_strcasecmp (retargetable, "no")) {
+ free (retargetable_uq);
goto cleanup_and_fail;
}
+
+ free (retargetable_uq);
tmp++;
continue;
}
if (part_name_len == 21 && !g_ascii_strncasecmp (part_name, "ProcessorArchitecture", part_name_len)) {
- if (!g_ascii_strcasecmp (value, "MSIL"))
+ procarch = value;
+ procarch_uq = unquote (procarch);
+ if (procarch_uq != NULL)
+ procarch = procarch_uq;
+
+ if (!g_ascii_strcasecmp (procarch, "MSIL"))
arch = MONO_PROCESSOR_ARCHITECTURE_MSIL;
- else if (!g_ascii_strcasecmp (value, "X86"))
+ else if (!g_ascii_strcasecmp (procarch, "X86"))
arch = MONO_PROCESSOR_ARCHITECTURE_X86;
- else if (!g_ascii_strcasecmp (value, "IA64"))
+ else if (!g_ascii_strcasecmp (procarch, "IA64"))
arch = MONO_PROCESSOR_ARCHITECTURE_IA64;
- else if (!g_ascii_strcasecmp (value, "AMD64"))
+ else if (!g_ascii_strcasecmp (procarch, "AMD64"))
arch = MONO_PROCESSOR_ARCHITECTURE_AMD64;
- else
+ else {
+ free (procarch_uq);
goto cleanup_and_fail;
+ }
+
+ free (procarch_uq);
tmp++;
continue;
}
goto cleanup_and_fail;
}
- res = build_assembly_name (dllname, version, culture, token, key, flags, arch,
- aname, save_public_key);
+ dllname_uq = unquote (dllname);
+ version_uq = unquote (version);
+ culture_uq = unquote (culture);
+ token_uq = unquote (token);
+ key_uq = unquote (key);
+
+ res = build_assembly_name (
+ dllname_uq == NULL ? dllname : dllname_uq,
+ version_uq == NULL ? version : version_uq,
+ culture_uq == NULL ? culture : culture_uq,
+ token_uq == NULL ? token : token_uq,
+ key_uq == NULL ? key : key_uq,
+ flags, arch, aname, save_public_key);
+
+ free (dllname_uq);
+ free (version_uq);
+ free (culture_uq);
+ free (token_uq);
+ free (key_uq);
+
g_strfreev (parts);
return res;
return FALSE;
}
+static char*
+unquote (const char *str)
+{
+ gint slen;
+ const char *end;
+
+ if (str == NULL)
+ return NULL;
+
+ slen = strlen (str);
+ if (slen < 2)
+ return NULL;
+
+ if (*str != '\'' && *str != '\"')
+ return NULL;
+
+ end = str + slen - 1;
+ if (*str != *end)
+ return NULL;
+
+ return g_strndup (str + 1, slen - 2);
+}
+
/**
* mono_assembly_name_parse:
* @name: name to parse
unsigned int is_inflated:1; /* whether we're a MonoMethodInflated */
unsigned int skip_visibility:1; /* whenever to skip JIT visibility checks */
unsigned int verification_success:1; /* whether this method has been verified successfully.*/
- /* TODO we MUST get rid of this field, it's an ugly hack nobody is proud of. */
- unsigned int is_mb_open : 1; /* This is the fully open instantiation of a generic method_builder. Worse than is_tb_open, but it's temporary */
signed int slot : 16;
/*
MonoMethodInflated *iresult, *cached;
MonoMethodSignature *sig;
MonoGenericContext tmp_context;
- gboolean is_mb_open = FALSE;
mono_error_init (error);
(method->klass->generic_container && context->class_inst)))
return method;
- /*
- * The reason for this hack is to fix the behavior of inflating generic methods that come from a MethodBuilder.
- * What happens is that instantiating a generic MethodBuilder with its own arguments should create a diferent object.
- * This is opposite to the way non-SRE MethodInfos behave.
- *
- * This happens, for example, when we want to emit a recursive generic method. Given the following C# code:
- *
- * void Example<T> () {
- * Example<T> ();
- * }
- *
- * In Example, the method token must be encoded as: "void Example<!!0>()"
- *
- * The reference to the first generic argument, "!!0", must be explicit otherwise it won't be inflated
- * properly. To get that we need to inflate the MethodBuilder with its own arguments.
- *
- * On the other hand, inflating a non-SRE generic method with its own arguments should
- * return itself. For example:
- *
- * MethodInfo m = ... //m is a generic method definition
- * MethodInfo res = m.MakeGenericMethod (m.GetGenericArguments ());
- * res == m
- *
- * To allow such scenarios we must allow inflation of MethodBuilder to happen in a diferent way than
- * what happens with regular methods.
- *
- * There is one last touch to this madness, once a TypeBuilder is finished, IOW CreateType() is called,
- * everything should behave like a regular type or method.
- *
- */
- is_mb_open = method->is_generic &&
- image_is_dynamic (method->klass->image) && !method->klass->wastypebuilder && /* that is a MethodBuilder from an unfinished TypeBuilder */
- context->method_inst == mono_method_get_generic_container (method)->context.method_inst; /* and it's been instantiated with its own arguments. */
-
iresult = g_new0 (MonoMethodInflated, 1);
iresult->context = *context;
iresult->declaring = method;
- iresult->method.method.is_mb_open = is_mb_open;
if (!context->method_inst && method->is_generic)
iresult->context.method_inst = mono_method_get_generic_container (method)->context.method_inst;
result->is_generic = FALSE;
result->sre_method = FALSE;
result->signature = NULL;
- result->is_mb_open = is_mb_open;
if (!context->method_inst) {
/* Set the generic_container of the result to the generic_container of method */
if (image->name_cache)
return;
- mono_image_lock (image);
-
- if (image->name_cache) {
- mono_image_unlock (image);
- return;
- }
-
the_name_cache = g_hash_table_new (g_str_hash, g_str_equal);
if (image_is_dynamic (image)) {
- mono_atomic_store_release (&image->name_cache, the_name_cache);
+ mono_image_lock (image);
+ if (image->name_cache) {
+ /* Somebody initialized it before us */
+ g_hash_table_destroy (the_name_cache);
+ } else {
+ mono_atomic_store_release (&image->name_cache, the_name_cache);
+ }
mono_image_unlock (image);
return;
}
}
g_hash_table_destroy (name_cache2);
- mono_atomic_store_release (&image->name_cache, the_name_cache);
+ if (image->name_cache) {
+ /* Somebody initialized it before us */
+ g_hash_table_destroy (the_name_cache);
+ } else {
+ mono_atomic_store_release (&image->name_cache, the_name_cache);
+ }
mono_image_unlock (image);
}
}
static MonoClass *
-mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, MonoGHashTable* visited_images)
+mono_class_from_name_checked_aux (MonoImage *image, const char* name_space, const char *name, MonoError *error, GHashTable* visited_images)
{
GHashTable *nspace_table;
MonoImage *loaded_image;
mono_error_init (error);
// Checking visited images avoids stack overflows when cyclic references exist.
- if (mono_g_hash_table_lookup (visited_images, image))
+ if (g_hash_table_lookup (visited_images, image))
return NULL;
- mono_g_hash_table_insert (visited_images, image, GUINT_TO_POINTER(1));
+ g_hash_table_insert (visited_images, image, GUINT_TO_POINTER(1));
if ((nested = strchr (name, '/'))) {
int pos = nested - name;
mono_class_from_name_checked (MonoImage *image, const char* name_space, const char *name, MonoError *error)
{
MonoClass *klass;
- MonoGHashTable *visited_images;
+ GHashTable *visited_images;
- visited_images = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
+ visited_images = g_hash_table_new (g_direct_hash, g_direct_equal);
klass = mono_class_from_name_checked_aux (image, name_space, name, error, visited_images);
- mono_g_hash_table_destroy (visited_images);
+ g_hash_table_destroy (visited_images);
return klass;
}
#include <mono/io-layer/io-layer.h>
#include <mono/metadata/mempool-internals.h>
-
-extern mono_mutex_t mono_delegate_section;
-
/*
* If this is set, the memory belonging to appdomains is not freed when a domain is
* unloaded, and assemblies loaded by the appdomain are not unloaded either. This
/* that require wrappers */
GHashTable *ftnptrs_hash;
+ /* Maps MonoMethod* to weak links to DynamicMethod objects */
+ GHashTable *method_to_dyn_method;
+
guint32 execution_context_field_offset;
};
gboolean mono_dont_free_domains;
-#define mono_appdomains_lock() mono_mutex_lock (&appdomains_mutex)
+#define mono_appdomains_lock() do { \
+ MONO_TRY_BLOCKING; \
+ mono_mutex_lock (&appdomains_mutex); \
+ MONO_FINISH_TRY_BLOCKING; \
+} while (0);
+
#define mono_appdomains_unlock() mono_mutex_unlock (&appdomains_mutex)
static mono_mutex_t appdomains_mutex;
MonoAssembly *ass = NULL;
MonoImageOpenStatus status = MONO_IMAGE_OK;
const MonoRuntimeInfo* runtimes [G_N_ELEMENTS (supported_runtimes) + 1];
- int n;
+ int n, dummy;
#ifdef DEBUG_DOMAIN_UNLOAD
debug_domain_unload = TRUE;
mono_counters_register ("Total code space allocated", MONO_COUNTER_INT|MONO_COUNTER_JIT, &total_domain_code_alloc);
mono_gc_base_init ();
+ mono_thread_info_attach (&dummy);
MONO_FAST_TLS_INIT (tls_appdomain);
mono_native_tls_alloc (&appdomain_thread_id, NULL);
g_hash_table_destroy (domain->ftnptrs_hash);
domain->ftnptrs_hash = NULL;
}
+ if (domain->method_to_dyn_method) {
+ g_hash_table_destroy (domain->method_to_dyn_method);
+ domain->method_to_dyn_method = NULL;
+ }
mono_mutex_destroy (&domain->finalizable_objects_hash_lock);
mono_mutex_destroy (&domain->assemblies_lock);
void
mono_domain_lock (MonoDomain *domain)
{
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_locks_acquire (&(domain)->lock, DomainLock);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
}
void
ves_icall_System_IO_MonoIO_CreateDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
ves_icall_System_IO_MonoIO_RemoveDirectory (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
static gchar *
-get_search_dir (MonoString *pattern)
+get_search_dir (const gunichar2 *pattern)
{
gchar *p;
gchar *result;
- p = mono_string_to_utf8 (pattern);
+ p = g_utf16_to_utf8 (pattern, -1, NULL, NULL, NULL);
result = g_path_get_dirname (p);
g_free (p);
return result;
}
static GPtrArray *
-get_filesystem_entries (MonoString *path,
- MonoString *path_with_pattern,
+get_filesystem_entries (const gunichar2 *path,
+ const gunichar2 *path_with_pattern,
gint attrs, gint mask,
gint32 *error)
{
gint32 attributes;
mask = convert_attrs (mask);
- attributes = get_file_attributes (mono_string_chars (path));
+ attributes = get_file_attributes (path);
if (attributes != -1) {
if ((attributes & FILE_ATTRIBUTE_DIRECTORY) == 0) {
*error = ERROR_INVALID_NAME;
goto fail;
}
- find_handle = FindFirstFile (mono_string_chars (path_with_pattern), &data);
+ find_handle = FindFirstFile (path_with_pattern, &data);
if (find_handle == INVALID_HANDLE_VALUE) {
gint32 find_error = GetLastError ();
*error = ERROR_SUCCESS;
- MONO_PREPARE_BLOCKING
- names = get_filesystem_entries (path, path_with_pattern, attrs, mask, error);
- MONO_FINISH_BLOCKING
+ MONO_PREPARE_BLOCKING;
+ names = get_filesystem_entries (mono_string_chars (path), mono_string_chars (path_with_pattern), attrs, mask, error);
+ MONO_FINISH_BLOCKING;
if (!names) {
// If there's no array and no error, then return an empty array.
IncrementalFind *ifh = handle;
gint32 error;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if (FindClose (ifh->find_handle) == FALSE){
error = GetLastError ();
} else
error = ERROR_SUCCESS;
g_free (ifh->utf8_path);
g_free (ifh);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return error;
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
gboolean ret;
gunichar2 *utf16_sourceFileName = NULL, *utf16_destinationFileName = NULL, *utf16_destinationBackupFileName = NULL;
guint32 replaceFlags = REPLACEFILE_WRITE_THROUGH;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if (sourceFileName)
utf16_sourceFileName = mono_string_chars (sourceFileName);
if (ret == FALSE)
*error = GetLastError ();
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return ret;
}
MonoBoolean overwrite, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
ves_icall_System_IO_MonoIO_DeleteFile (MonoString *path, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileAttributes (MonoString *path, gint32 *error)
{
gint32 ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
ves_icall_System_IO_MonoIO_GetFileType (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
{
gboolean result;
WIN32_FILE_ATTRIBUTE_DATA data;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
memset (stat, 0, sizeof (MonoIOStat));
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return result;
}
HANDLE ret;
int attributes, attrs;
gunichar2 *chars;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
chars = mono_string_chars (filename);
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
ves_icall_System_IO_MonoIO_Close (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
buffer = mono_array_addr (dest, guchar, dest_offset);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
result = ReadFile (handle, buffer, count, &n, NULL);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (!result) {
*error=GetLastError ();
}
buffer = mono_array_addr (src, guchar, src_offset);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
result = WriteFile (handle, buffer, count, &n, NULL);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (!result) {
*error=GetLastError ();
gint32 *error)
{
gint32 offset_hi;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return offset | ((gint64)offset_hi << 32);
}
ves_icall_System_IO_MonoIO_Flush (HANDLE handle, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
{
gint64 length;
guint32 length_hi;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return length | ((gint64)length_hi << 32);
}
const FILETIME *creation_filetime;
const FILETIME *last_access_filetime;
const FILETIME *last_write_filetime;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error=GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return(ret);
}
attr.bInheritHandle=TRUE;
attr.lpSecurityDescriptor=NULL;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret=CreatePipe (read_handle, write_handle, &attr, 0);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==FALSE) {
/* FIXME: throw an exception? */
/* This is only used on Windows */
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret=DuplicateHandle (source_process_handle, source_handle, target_process_handle, target_handle, access, inherit, options);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==FALSE) {
/* FIXME: throw an exception? */
return chars;
}
-gint32
-ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name)
-{
- gunichar2 *name;
- int ret;
-
- MONO_PREPARE_BLOCKING
- name=g_new0 (gunichar2, 256);
-
- ret=GetTempPath (256, name);
- if(ret>255) {
- /* Buffer was too short. Try again... */
- g_free (name);
- name=g_new0 (gunichar2, ret+2); /* include the terminator */
- ret=GetTempPath (ret, name);
- }
- MONO_FINISH_BLOCKING
-
- if(ret>0) {
-#ifdef DEBUG
- g_message ("%s: Temp path is [%s] (len %d)", __func__, name, ret);
-#endif
-
- mono_gc_wbarrier_generic_store ((gpointer) mono_name,
- (MonoObject*) mono_string_new_utf16 (mono_domain_get (), name, ret));
- }
-
- g_free (name);
-
- return(ret);
-}
-
void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
gint64 length, gint32 *error)
{
gboolean ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error=ERROR_SUCCESS;
*error = GetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
//Support for io-layer free mmap'd files.
gint64 res;
char *path = mono_string_to_utf8 (string);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if (stat (path, &buf) == -1)
res = -1;
else
g_free (path);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return res;
}
struct stat buf;
int res;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = fstat (fd, &buf);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (res == -1)
return (gint64)-1;
extern MonoArray *
ves_icall_System_IO_MonoIO_get_InvalidPathChars (void);
-extern gint32
-ves_icall_System_IO_MonoIO_GetTempPath (MonoString **mono_name);
-
extern void ves_icall_System_IO_MonoIO_Lock (HANDLE handle, gint64 position,
gint64 length, gint32 *error);
extern void ves_icall_System_IO_MonoIO_Unlock (HANDLE handle, gint64 position,
#include <config.h>
#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_EVENT_H
+#include <sys/event.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
#include <mono/metadata/appdomain.h>
#include <mono/metadata/exception.h>
#include <mono/metadata/filewatcher.h>
}
#endif
+#if HAVE_KQUEUE
+
+static void
+interrupt_kevent (gpointer data)
+{
+ int *kq_ptr = data;
+
+ /* Interrupt the kevent () call by closing the fd */
+ close (*kq_ptr);
+ /* Signal to managed code that the fd is closed */
+ *kq_ptr = -1;
+}
+
+/*
+ * ves_icall_System_IO_KqueueMonitor_kevent_notimeout:
+ *
+ * Call kevent (), while handling runtime interruptions.
+ */
+int
+ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
+{
+ int res;
+ gboolean interrupted;
+
+ mono_thread_info_install_interrupt (interrupt_kevent, kq_ptr, &interrupted);
+ if (interrupted) {
+ close (*kq_ptr);
+ *kq_ptr = -1;
+ return -1;
+ }
+
+ MONO_PREPARE_BLOCKING;
+ res = kevent (*kq_ptr, changelist, nchanges, eventlist, nevents, NULL);
+ MONO_FINISH_BLOCKING;
+
+ mono_thread_info_uninstall_interrupt (&interrupted);
+
+ return res;
+}
+
+#else
+
+int
+ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq_ptr, gpointer changelist, int nchanges, gpointer eventlist, int nevents)
+{
+ g_assert_not_reached ();
+ return -1;
+}
+
+#endif /* #if HAVE_KQUEUE */
+
int ves_icall_System_IO_InotifyWatcher_AddWatch (int fd, MonoString *directory, gint32 mask);
int ves_icall_System_IO_InotifyWatcher_RemoveWatch (int fd, gint32 watch_descriptor);
+int ves_icall_System_IO_KqueueMonitor_kevent_notimeout (int *kq, gpointer changelist, int nchanges, gpointer eventlist, int nevents);
+
G_END_DECLS
#endif
GCStats gc_stats = {};
#else
GCStats gc_stats;
-#endif
\ No newline at end of file
+#endif
{
guint32 result;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
result = WaitForSingleObjectEx (handle, timeout, alertable);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
return result;
}
MonoDomain *domain;
RuntimeInvokeFunction runtime_invoke;
+ // This function is called from the innards of the GC, so our best alternative for now is to do polling here
+ MONO_SUSPEND_CHECK ();
+
o = (MonoObject*)((char*)obj + GPOINTER_TO_UINT (data));
if (log_finalizers)
* end up running them while or after the domain is being cleared, so
* the objects will not be valid anymore.
*/
- if (!mono_domain_is_unloading (domain))
+ if (!mono_domain_is_unloading (domain)) {
+ MONO_TRY_BLOCKING;
mono_gc_register_for_finalization (obj, callback);
+ MONO_FINISH_TRY_BLOCKING;
+ }
#endif
}
{NULL, NULL, 0, HANDLE_PINNED, 0}
};
-#define lock_handles(handles) mono_mutex_lock (&handle_section)
+#define lock_handles(handles) do { \
+ MONO_TRY_BLOCKING; \
+ mono_mutex_lock (&handle_section); \
+ MONO_FINISH_TRY_BLOCKING; \
+} while (0)
+
#define unlock_handles(handles) mono_mutex_unlock (&handle_section)
static int
g_assert (mono_domain_get () == mono_get_root_domain ());
mono_gc_set_skip_thread (TRUE);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if (wait) {
/* An alertable wait is required so this thread can be suspended on windows */
#endif
}
wait = TRUE;
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
mono_gc_set_skip_thread (FALSE);
mono_threads_perform_thread_dump ();
ICALL(INOW_2, "GetInotifyInstance", ves_icall_System_IO_InotifyWatcher_GetInotifyInstance)
ICALL(INOW_3, "RemoveWatch", ves_icall_System_IO_InotifyWatcher_RemoveWatch)
+ICALL_TYPE(KQUEM, "System.IO.KqueueMonitor", KQUEM_1)
+ICALL(KQUEM_1, "kevent_notimeout", ves_icall_System_IO_KqueueMonitor_kevent_notimeout)
+
ICALL_TYPE(MMAPIMPL, "System.IO.MemoryMappedFiles.MemoryMapImpl", MMAPIMPL_1)
ICALL(MMAPIMPL_1, "CloseMapping", mono_mmap_close)
ICALL(MMAPIMPL_2, "ConfigureHandleInheritability", mono_mmap_configure_inheritability)
ICALL(MONOIO_11, "GetFileType(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetFileType)
ICALL(MONOIO_12, "GetLength(intptr,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_GetLength)
#ifndef PLATFORM_RO_FS
-ICALL(MONOIO_13, "GetTempPath(string&)", ves_icall_System_IO_MonoIO_GetTempPath)
ICALL(MONOIO_14, "Lock(intptr,long,long,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_Lock)
ICALL(MONOIO_15, "MoveFile(string,string,System.IO.MonoIOError&)", ves_icall_System_IO_MonoIO_MoveFile)
#endif /* !PLATFORM_RO_FS */
ICALL_TYPE(IOPATH, "System.IO.Path", IOPATH_1)
ICALL(IOPATH_1, "get_temp_path", ves_icall_System_IO_get_temp_path)
-ICALL_TYPE(MATH, "System.Math", MATH_1)
+ICALL_TYPE(MATH, "System.Math", MATH_19)
+ICALL(MATH_19, "Abs(double)", ves_icall_System_Math_Abs_double)
+ICALL(MATH_20, "Abs(single)", ves_icall_System_Math_Abs_single)
ICALL(MATH_1, "Acos", ves_icall_System_Math_Acos)
ICALL(MATH_2, "Asin", ves_icall_System_Math_Asin)
ICALL(MATH_3, "Atan", ves_icall_System_Math_Atan)
ICALL(MATH_4, "Atan2", ves_icall_System_Math_Atan2)
+ICALL(MATH_21, "Ceiling", ves_icall_System_Math_Ceiling)
ICALL(MATH_5, "Cos", ves_icall_System_Math_Cos)
ICALL(MATH_6, "Cosh", ves_icall_System_Math_Cosh)
ICALL(MATH_7, "Exp", ves_icall_System_Math_Exp)
ICALL(MATH_10, "Log10", ves_icall_System_Math_Log10)
ICALL(MATH_11, "Pow", ves_icall_System_Math_Pow)
ICALL(MATH_12, "Round", ves_icall_System_Math_Round)
-ICALL(MATH_13, "Round2", ves_icall_System_Math_Round2)
ICALL(MATH_14, "Sin", ves_icall_System_Math_Sin)
ICALL(MATH_15, "Sinh", ves_icall_System_Math_Sinh)
+ICALL(MATH_22, "SplitFractionDouble", ves_icall_System_Math_SplitFractionDouble)
ICALL(MATH_16, "Sqrt", ves_icall_System_Math_Sqrt)
ICALL(MATH_17, "Tan", ves_icall_System_Math_Tan)
ICALL(MATH_18, "Tanh", ves_icall_System_Math_Tanh)
ICALL(MONIT_5, "Monitor_test_synchronised", ves_icall_System_Threading_Monitor_Monitor_test_synchronised)
ICALL(MONIT_6, "Monitor_try_enter", ves_icall_System_Threading_Monitor_Monitor_try_enter)
ICALL(MONIT_7, "Monitor_wait", ves_icall_System_Threading_Monitor_Monitor_wait)
+ICALL(MONIT_10, "enter_with_atomic_var", mono_monitor_enter_v4)
ICALL(MONIT_9, "try_enter_with_atomic_var", ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var)
ICALL_TYPE(MUTEX, "System.Threading.Mutex", MUTEX_1)
} PInfo;
ICALL_EXPORT void
-ves_icall_get_property_info (MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
+ves_icall_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
{
MonoDomain *domain = mono_object_domain (property);
+ const MonoProperty *pproperty = property->property;
if ((req_info & PInfo_ReflectedType) != 0)
MONO_STRUCT_SETREF (info, parent, mono_type_get_object (domain, &property->klass->byval_arg));
if ((req_info & PInfo_DeclaringType) != 0)
- MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &property->property->parent->byval_arg));
+ MONO_STRUCT_SETREF (info, declaring_type, mono_type_get_object (domain, &pproperty->parent->byval_arg));
if ((req_info & PInfo_Name) != 0)
- MONO_STRUCT_SETREF (info, name, mono_string_new (domain, property->property->name));
+ MONO_STRUCT_SETREF (info, name, mono_string_new (domain, pproperty->name));
if ((req_info & PInfo_Attributes) != 0)
- info->attrs = property->property->attrs;
+ info->attrs = pproperty->attrs;
if ((req_info & PInfo_GetMethod) != 0)
- MONO_STRUCT_SETREF (info, get, property->property->get ?
- mono_method_get_object (domain, property->property->get, property->klass): NULL);
-
+ MONO_STRUCT_SETREF (info, get, pproperty->get &&
+ (((pproperty->get->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) || pproperty->get->klass == property->klass) ?
+ mono_method_get_object (domain, pproperty->get, property->klass): NULL);
if ((req_info & PInfo_SetMethod) != 0)
- MONO_STRUCT_SETREF (info, set, property->property->set ?
- mono_method_get_object (domain, property->property->set, property->klass): NULL);
+ MONO_STRUCT_SETREF (info, set, pproperty->set &&
+ (((pproperty->set->flags & METHOD_ATTRIBUTE_MEMBER_ACCESS_MASK) != METHOD_ATTRIBUTE_PRIVATE) || pproperty->set->klass == property->klass) ?
+ mono_method_get_object (domain, pproperty->set, property->klass): NULL);
/*
* There may be other methods defined for properties, though, it seems they are not exposed
* in the reflection API
{
guint8 *src_buf, *dest_buf;
+ if (count < 0) {
+ mono_set_pending_exception (mono_get_exception_argument ("count", "is negative"));
+ return FALSE;
+ }
+
+ g_assert (count >= 0);
+
/* This is called directly from the class libraries without going through the managed wrapper */
MONO_CHECK_ARG_NULL (src, FALSE);
MONO_CHECK_ARG_NULL (dest, FALSE);
g_direct_hash,
class_key_extract,
class_next_value);
- image->field_cache = mono_conc_hashtable_new (&image->lock, NULL, NULL);
+ image->field_cache = mono_conc_hashtable_new (NULL, NULL);
image->typespec_cache = g_hash_table_new (NULL, NULL);
image->memberref_signatures = g_hash_table_new (NULL, NULL);
}
}
- if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container)
+ if (field && field->parent && !field->parent->generic_class && !field->parent->generic_container) {
+ mono_image_lock (image);
mono_conc_hashtable_insert (image->field_cache, GUINT_TO_POINTER (token), field);
+ mono_image_unlock (image);
+ }
mono_loader_assert_no_error ();
return field;
switch (frame->type) {
case FRAME_TYPE_DEBUGGER_INVOKE:
case FRAME_TYPE_MANAGED_TO_NATIVE:
+ case FRAME_TYPE_TRAMPOLINE:
return FALSE;
case FRAME_TYPE_MANAGED:
g_assert (frame->ji);
- return d->func (mono_jit_info_get_method (frame->ji), frame->native_offset, frame->il_offset, frame->managed, d->user_data);
+ return d->func (frame->actual_method, frame->native_offset, frame->il_offset, frame->managed, d->user_data);
break;
default:
g_assert_not_reached ();
switch (frame->type) {
case FRAME_TYPE_DEBUGGER_INVOKE:
case FRAME_TYPE_MANAGED_TO_NATIVE:
+ case FRAME_TYPE_TRAMPOLINE:
return FALSE;
case FRAME_TYPE_MANAGED:
if (!frame->ji)
return FALSE;
- if (frame->ji->async)
+ if (frame->ji->async) {
return d->func (NULL, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
- else
+ } else {
return d->func (frame->actual_method, frame->domain, frame->ji->code_start, frame->native_offset, d->user_data);
+ }
break;
default:
g_assert_not_reached ();
void
mono_loader_lock (void)
{
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_locks_acquire (&loader_mutex, LoaderLock);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
if (G_UNLIKELY (loader_lock_track_ownership)) {
mono_native_tls_set_value (loader_lock_nest_id, GUINT_TO_POINTER (GPOINTER_TO_UINT (mono_native_tls_get_value (loader_lock_nest_id)) + 1));
add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
{
int i = 0;
- gpointer frames[10];
+ const int no_frames = 6;
+ gpointer frames[no_frames];
+
char *msg;
if (!trace_file)
return;
- memset (frames, 0, sizeof (gpointer));
- mono_backtrace (frames, 6);
- for (i = 0; i < 6; ++i)
+ memset (frames, 0, sizeof (gpointer) * no_frames);
+ mono_backtrace (frames, no_frames);
+ for (i = 0; i < no_frames; ++i)
frames [i] = (gpointer)((size_t)frames[i] - base_address);
/*We only dump 5 frames, which should be more than enough to most analysis.*/
#ifdef USE_COOP_GC
register_icall (mono_threads_prepare_blocking, "mono_threads_prepare_blocking", "int", FALSE);
register_icall (mono_threads_finish_blocking, "mono_threads_finish_blocking", "void int", FALSE);
- register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", FALSE);
- register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", FALSE);
+ register_icall (mono_threads_reset_blocking_start, "mono_threads_reset_blocking_start","int", TRUE);
+ register_icall (mono_threads_reset_blocking_end, "mono_threads_reset_blocking_end","void int", TRUE);
#endif
}
}
MonoMethodBuilder *mb;
MonoMethod *res;
GHashTable *cache;
- int i, pos, this_local, ret_local = 0;
+ int i, pos, pos2, this_local, taken_local, ret_local = 0;
MonoGenericContext *ctx = NULL;
MonoMethod *orig_method = NULL;
MonoGenericContainer *container = NULL;
mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_SYNCHRONIZED);
#ifndef DISABLE_JIT
+ mb->skip_visibility = 1;
/* result */
if (!MONO_TYPE_IS_VOID (sig->ret))
ret_local = mono_mb_add_local (mb, sig->ret);
#ifndef DISABLE_JIT
/* this */
this_local = mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
+ taken_local = mono_mb_add_local (mb, &mono_defaults.boolean_class->byval_arg);
clause = mono_image_alloc0 (method->klass->image, sizeof (MonoExceptionClause));
clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY;
if (!enter_method) {
MonoMethodDesc *desc;
- desc = mono_method_desc_new ("Monitor:Enter", FALSE);
+ desc = mono_method_desc_new ("Monitor:enter_with_atomic_var(object,bool&)", FALSE);
enter_method = mono_method_desc_search_in_class (desc, mono_defaults.monitor_class);
g_assert (enter_method);
mono_method_desc_free (desc);
/* Call Monitor::Enter() */
mono_mb_emit_ldloc (mb, this_local);
+ mono_mb_emit_ldloc_addr (mb, taken_local);
mono_mb_emit_managed_call (mb, enter_method, NULL);
clause->try_offset = mono_mb_get_label (mb);
clause->try_len = mono_mb_get_pos (mb) - clause->try_offset;
clause->handler_offset = mono_mb_get_label (mb);
- /* Call Monitor::Exit() */
+ /* Call Monitor::Exit() if needed */
+ mono_mb_emit_ldloc (mb, taken_local);
+ pos2 = mono_mb_emit_branch (mb, CEE_BRFALSE);
mono_mb_emit_ldloc (mb, this_local);
mono_mb_emit_managed_call (mb, exit_method, NULL);
+ mono_mb_patch_branch (mb, pos2);
mono_mb_emit_byte (mb, CEE_ENDFINALLY);
clause->handler_len = mono_mb_get_pos (mb) - clause->handler_offset;
GHashTable *cache;
MonoMethod *res;
int i, param_count, sig_size, pos_leave;
+#ifdef USE_COOP_GC
+ int coop_gc_var;
+#endif
g_assert (method);
if (!MONO_TYPE_IS_VOID (sig->ret))
mono_mb_add_local (mb, sig->ret);
+#ifdef USE_COOP_GC
+ /* local 4, the local to be used when calling the reset_blocking funcs */
+ /* tons of code hardcode 3 to be the return var */
+ coop_gc_var = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+#endif
+
/* clear exception arg */
mono_mb_emit_ldarg (mb, param_count - 1);
mono_mb_emit_byte (mb, CEE_LDNULL);
mono_mb_emit_byte (mb, CEE_STIND_REF);
+#ifdef USE_COOP_GC
+ /* FIXME this is technically wrong as the callback itself must be executed in gc unsafe context. */
+ mono_mb_emit_icall (mb, mono_threads_reset_blocking_start);
+ mono_mb_emit_stloc (mb, coop_gc_var);
+#endif
+
/* try */
clause = mono_image_alloc0 (image, sizeof (MonoExceptionClause));
clause->try_offset = mono_mb_get_label (mb);
mono_mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type (sig->ret));
}
+#ifdef USE_COOP_GC
+ /* XXX merge reset_blocking_end with detach */
+ mono_mb_emit_ldloc (mb, coop_gc_var);
+ mono_mb_emit_icall (mb, mono_threads_reset_blocking_end);
+#endif
+
mono_mb_emit_byte (mb, CEE_RET);
#endif
if (marshal_mutex_initialized)
mono_marshal_unlock ();
}
-
-static gboolean
-signature_pointer_pair_matches_signature (gpointer key, gpointer value, gpointer user_data)
-{
- SignaturePointerPair *pair = (SignaturePointerPair*)key;
- MonoMethodSignature *sig = (MonoMethodSignature*)user_data;
-
- return mono_metadata_signature_equal (pair->sig, sig);
-}
const MonoMethodInflated *mb = b;
if (ma->declaring != mb->declaring)
return FALSE;
- if (ma->method.method.is_mb_open != mb->method.method.is_mb_open)
- return FALSE;
return mono_metadata_generic_context_equal (&ma->context, &mb->context);
}
inflated_method_hash (gconstpointer a)
{
const MonoMethodInflated *ma = a;
- return (mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring)) + ma->method.method.is_mb_open;
+ return (mono_metadata_generic_context_hash (&ma->context) ^ mono_aligned_addr_hash (ma->declaring));
}
static gboolean
*
* Bacon's thin locks have a fast path that doesn't need a lock record
* for the common case of locking an unlocked or shallow-nested
- * object, but the technique relies on encoding the thread ID in 15
- * bits (to avoid too much per-object space overhead.) Unfortunately
- * I don't think it's possible to reliably encode a pthread_t into 15
- * bits. (The JVM implementation used seems to have a 15-bit
- * per-thread identifier available.)
- *
- * This implementation then combines Dice's basic lock model with
- * Bacon's simplification of keeping a lock record for the lifetime of
- * an object.
+ * object.
*/
static MonitorArray *monitor_allocated;
static int array_size = 16;
+/* MonoThreadsSync status helpers */
+
static inline guint32
mon_status_get_owner (guint32 status)
{
return status & ENTRY_COUNT_WAITERS;
}
+/* LockWord helpers */
+
+static inline MonoThreadsSync*
+lock_word_get_inflated_lock (LockWord lw)
+{
+ lw.lock_word &= (~LOCK_WORD_STATUS_MASK);
+ return lw.sync;
+}
+
+static inline gboolean
+lock_word_is_inflated (LockWord lw)
+{
+ return lw.lock_word & LOCK_WORD_INFLATED;
+}
+
+static inline gboolean
+lock_word_has_hash (LockWord lw)
+{
+ return lw.lock_word & LOCK_WORD_HAS_HASH;
+}
+
+static inline LockWord
+lock_word_set_has_hash (LockWord lw)
+{
+ LockWord nlw;
+ nlw.lock_word = lw.lock_word | LOCK_WORD_HAS_HASH;
+ return nlw;
+}
+
+static inline gboolean
+lock_word_is_free (LockWord lw)
+{
+ return !lw.lock_word;
+}
+
+static inline gboolean
+lock_word_is_flat (LockWord lw)
+{
+ /* Return whether the lock is flat or free */
+ return (lw.lock_word & LOCK_WORD_STATUS_MASK) == LOCK_WORD_FLAT;
+}
+
+static inline gint32
+lock_word_get_hash (LockWord lw)
+{
+ return (gint32) (lw.lock_word >> LOCK_WORD_HASH_SHIFT);
+}
+
+static inline gint32
+lock_word_get_nest (LockWord lw)
+{
+ if (lock_word_is_free (lw))
+ return 0;
+ /* Inword nest count starts from 0 */
+ return ((lw.lock_word & LOCK_WORD_NEST_MASK) >> LOCK_WORD_NEST_SHIFT) + 1;
+}
+
+static inline gboolean
+lock_word_is_nested (LockWord lw)
+{
+ return lw.lock_word & LOCK_WORD_NEST_MASK;
+}
+
+static inline gboolean
+lock_word_is_max_nest (LockWord lw)
+{
+ return (lw.lock_word & LOCK_WORD_NEST_MASK) == LOCK_WORD_NEST_MASK;
+}
+
+static inline LockWord
+lock_word_increment_nest (LockWord lw)
+{
+ lw.lock_word += 1 << LOCK_WORD_NEST_SHIFT;
+ return lw;
+}
+
+static inline LockWord
+lock_word_decrement_nest (LockWord lw)
+{
+ lw.lock_word -= 1 << LOCK_WORD_NEST_SHIFT;
+ return lw;
+}
+
+static inline gint32
+lock_word_get_owner (LockWord lw)
+{
+ return lw.lock_word >> LOCK_WORD_OWNER_SHIFT;
+}
+
+static inline LockWord
+lock_word_new_thin_hash (gint32 hash)
+{
+ LockWord lw;
+ lw.lock_word = (guint32)hash;
+ lw.lock_word = (lw.lock_word << LOCK_WORD_HASH_SHIFT) | LOCK_WORD_HAS_HASH;
+ return lw;
+}
+
+static inline LockWord
+lock_word_new_inflated (MonoThreadsSync *mon)
+{
+ LockWord lw;
+ lw.sync = mon;
+ lw.lock_word |= LOCK_WORD_INFLATED;
+ return lw;
+}
+
+static inline LockWord
+lock_word_new_flat (gint32 owner)
+{
+ LockWord lw;
+ lw.lock_word = owner;
+ lw.lock_word <<= LOCK_WORD_OWNER_SHIFT;
+ return lw;
+}
+
void
mono_monitor_init (void)
{
return new;
}
-/*
- * Format of the lock word:
- * thinhash | fathash | data
- *
- * thinhash is the lower bit: if set data is the shifted hashcode of the object.
- * fathash is another bit: if set the hash code is stored in the MonoThreadsSync
- * struct pointed to by data
- * if neither bit is set and data is non-NULL, data is a MonoThreadsSync
- */
-typedef union {
- gsize lock_word;
- MonoThreadsSync *sync;
-} LockWord;
+static MonoThreadsSync*
+alloc_mon (MonoObject *obj, gint32 id)
+{
+ MonoThreadsSync *mon;
-enum {
- LOCK_WORD_THIN_HASH = 1,
- LOCK_WORD_FAT_HASH = 1 << 1,
- LOCK_WORD_BITS_MASK = 0x3,
- LOCK_WORD_HASH_SHIFT = 2
-};
+ mono_monitor_allocator_lock ();
+ mon = mon_new (id);
+ mono_gc_weak_link_add (&mon->data, obj, TRUE);
+ mono_monitor_allocator_unlock ();
+
+ return mon;
+}
+
+
+static void
+discard_mon (MonoThreadsSync *mon)
+{
+ mono_monitor_allocator_lock ();
+ mono_gc_weak_link_remove (&mon->data, TRUE);
+ mon_finalize (mon);
+ mono_monitor_allocator_unlock ();
+}
+
+static void
+mono_monitor_inflate_owned (MonoObject *obj, int id)
+{
+ MonoThreadsSync *mon;
+ LockWord nlw, old_lw, tmp_lw;
+ guint32 nest;
+
+ old_lw.sync = obj->synchronisation;
+ LOCK_DEBUG (g_message ("%s: (%d) Inflating owned lock object %p; LW = %p", __func__, id, obj, old_lw.sync));
+
+ if (lock_word_is_inflated (old_lw)) {
+ /* Someone else inflated the lock in the meantime */
+ return;
+ }
+
+ mon = alloc_mon (obj, id);
+
+ nest = lock_word_get_nest (old_lw);
+ mon->nest = nest;
+
+ nlw = lock_word_new_inflated (mon);
+
+ mono_memory_write_barrier ();
+ tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync);
+ if (tmp_lw.sync != old_lw.sync) {
+ /* Someone else inflated the lock in the meantime */
+ discard_mon (mon);
+ }
+}
+
+static void
+mono_monitor_inflate (MonoObject *obj)
+{
+ MonoThreadsSync *mon;
+ LockWord nlw, old_lw;
+
+ LOCK_DEBUG (g_message ("%s: (%d) Inflating lock object %p; LW = %p", __func__, mono_thread_info_get_small_id (), obj, obj->synchronisation));
+
+ mon = alloc_mon (obj, 0);
+
+ nlw = lock_word_new_inflated (mon);
+
+ old_lw.sync = obj->synchronisation;
+
+ for (;;) {
+ LockWord tmp_lw;
+
+ if (lock_word_is_inflated (old_lw)) {
+ break;
+ }
+#ifdef HAVE_MOVING_COLLECTOR
+ else if (lock_word_has_hash (old_lw)) {
+ mon->hash_code = lock_word_get_hash (old_lw);
+ mon->status = mon_status_set_owner (mon->status, 0);
+ nlw = lock_word_set_has_hash (nlw);
+ }
+#endif
+ else if (lock_word_is_free (old_lw)) {
+ mon->status = mon_status_set_owner (mon->status, 0);
+ mon->nest = 1;
+ } else {
+ /* Lock is flat */
+ mon->status = mon_status_set_owner (mon->status, lock_word_get_owner (old_lw));
+ mon->nest = lock_word_get_nest (old_lw);
+ }
+ mono_memory_write_barrier ();
+ tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync);
+ if (tmp_lw.sync == old_lw.sync) {
+ /* Successfully inflated the lock */
+ return;
+ }
+
+ old_lw.sync = tmp_lw.sync;
+ }
+
+ /* Someone else inflated the lock before us */
+ discard_mon (mon);
+}
#define MONO_OBJECT_ALIGNMENT_SHIFT 3
if (!obj)
return 0;
lw.sync = obj->synchronisation;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- /*g_print ("fast thin hash %d for obj %p store\n", (unsigned int)lw.lock_word >> LOCK_WORD_HASH_SHIFT, obj);*/
- return (unsigned int)lw.lock_word >> LOCK_WORD_HASH_SHIFT;
- }
- if (lw.lock_word & LOCK_WORD_FAT_HASH) {
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- /*g_print ("fast fat hash %d for obj %p store\n", lw.sync->hash_code, obj);*/
- return lw.sync->hash_code;
+
+ LOCK_DEBUG (g_message("%s: (%d) Get hash for object %p; LW = %p", __func__, mono_thread_info_get_small_id (), obj, obj->synchronisation));
+
+ if (lock_word_has_hash (lw)) {
+ if (lock_word_is_inflated (lw)) {
+ return lock_word_get_inflated_lock (lw)->hash_code;
+ } else {
+ return lock_word_get_hash (lw);
+ }
}
/*
* while we are inside this function, the GC will keep this object pinned,
* with the same value.
*/
hash = (GPOINTER_TO_UINT (obj) >> MONO_OBJECT_ALIGNMENT_SHIFT) * 2654435761u;
+#if SIZEOF_VOID_P == 4
/* clear the top bits as they can be discarded */
- hash &= ~(LOCK_WORD_BITS_MASK << 30);
- /* no hash flags were set, so it must be a MonoThreadsSync pointer if not NULL */
- if (lw.sync) {
- lw.sync->hash_code = hash;
- /*g_print ("storing hash code %d for obj %p in sync %p\n", hash, obj, lw.sync);*/
- lw.lock_word |= LOCK_WORD_FAT_HASH;
- /* this is safe since we don't deflate locks */
- obj->synchronisation = lw.sync;
- } else {
- /*g_print ("storing thin hash code %d for obj %p\n", hash, obj);*/
- lw.lock_word = LOCK_WORD_THIN_HASH | (hash << LOCK_WORD_HASH_SHIFT);
- if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL) == NULL)
+ hash &= ~(LOCK_WORD_STATUS_MASK << (32 - LOCK_WORD_STATUS_BITS));
+#endif
+ if (lock_word_is_free (lw)) {
+ LockWord old_lw;
+ lw = lock_word_new_thin_hash (hash);
+
+ old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL);
+ if (old_lw.sync == NULL) {
return hash;
- /*g_print ("failed store\n");*/
- /* someone set the hash flag or someone inflated the object */
- lw.sync = obj->synchronisation;
- if (lw.lock_word & LOCK_WORD_THIN_HASH)
+ }
+
+ if (lock_word_has_hash (old_lw)) {
+ /* Done by somebody else */
return hash;
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- lw.sync->hash_code = hash;
- lw.lock_word |= LOCK_WORD_FAT_HASH;
- /* this is safe since we don't deflate locks */
- obj->synchronisation = lw.sync;
+ }
+
+ mono_monitor_inflate (obj);
+ lw.sync = obj->synchronisation;
+ } else if (lock_word_is_flat (lw)) {
+ int id = mono_thread_info_get_small_id ();
+ if (lock_word_get_owner (lw) == id)
+ mono_monitor_inflate_owned (obj, id);
+ else
+ mono_monitor_inflate (obj);
+ lw.sync = obj->synchronisation;
}
+
+ /* At this point, the lock is inflated */
+ lock_word_get_inflated_lock (lw)->hash_code = hash;
+ lw = lock_word_set_has_hash (lw);
+ mono_memory_write_barrier ();
+ obj->synchronisation = lw.sync;
return hash;
#else
/*
#endif
}
+static void
+mono_monitor_ensure_owned (LockWord lw, guint32 id)
+{
+ if (lock_word_is_flat (lw)) {
+ if (lock_word_get_owner (lw) == id)
+ return;
+ } else if (lock_word_is_inflated (lw)) {
+ if (mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) == id)
+ return;
+ }
+
+ mono_set_pending_exception (mono_get_exception_synchronization_lock ("Object synchronization method was called from an unsynchronized block of code."));
+}
+
+/*
+ * When this function is called it has already been established that the
+ * current thread owns the monitor.
+ */
+static void
+mono_monitor_exit_inflated (MonoObject *obj)
+{
+ LockWord lw;
+ MonoThreadsSync *mon;
+ guint32 nest;
+
+ lw.sync = obj->synchronisation;
+ mon = lock_word_get_inflated_lock (lw);
+
+ nest = mon->nest - 1;
+ if (nest == 0) {
+ guint32 new_status, old_status, tmp_status;
+
+ old_status = mon->status;
+
+ /*
+ * Release lock and do the wakeup stuff. It's possible that
+ * the last blocking thread gave up waiting just before we
+ * release the semaphore resulting in a negative entry count
+ * and a futile wakeup next time there's contention for this
+ * object.
+ */
+ for (;;) {
+ gboolean have_waiters = mon_status_have_waiters (old_status);
+
+ new_status = mon_status_set_owner (old_status, 0);
+ if (have_waiters)
+ new_status = mon_status_decrement_entry_count (new_status);
+ tmp_status = InterlockedCompareExchange ((gint32*)&mon->status, new_status, old_status);
+ if (tmp_status == old_status) {
+ if (have_waiters)
+ ReleaseSemaphore (mon->entry_sem, 1, NULL);
+ break;
+ }
+ old_status = tmp_status;
+ }
+ LOCK_DEBUG (g_message ("%s: (%d) Object %p is now unlocked", __func__, mono_thread_info_get_small_id (), obj));
+
+ /* object is now unlocked, leave nest==1 so we don't
+ * need to set it when the lock is reacquired
+ */
+ } else {
+ LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times", __func__, mono_thread_info_get_small_id (), obj, nest));
+ mon->nest = nest;
+ }
+}
+
+/*
+ * When this function is called it has already been established that the
+ * current thread owns the monitor.
+ */
+static void
+mono_monitor_exit_flat (MonoObject *obj, LockWord old_lw)
+{
+ LockWord new_lw, tmp_lw;
+ if (G_UNLIKELY (lock_word_is_nested (old_lw)))
+ new_lw = lock_word_decrement_nest (old_lw);
+ else
+ new_lw.lock_word = 0;
+
+ tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, new_lw.sync, old_lw.sync);
+ if (old_lw.sync != tmp_lw.sync) {
+ /* Someone inflated the lock in the meantime */
+ mono_monitor_exit_inflated (obj);
+ }
+
+ LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times; LW = %p", __func__, mono_thread_info_get_small_id (), obj, lock_word_get_nest (new_lw), obj->synchronisation));
+}
+
static void
mon_decrement_entry_count (MonoThreadsSync *mon)
{
* is requested. In this case it returns -1.
*/
static inline gint32
-mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption)
+mono_monitor_try_enter_inflated (MonoObject *obj, guint32 ms, gboolean allow_interruption, guint32 id)
{
+ LockWord lw;
MonoThreadsSync *mon;
- gsize id = mono_thread_info_get_small_id ();
HANDLE sem;
guint32 then = 0, now, delta;
guint32 waitms;
LOCK_DEBUG (g_message("%s: (%d) Trying to lock object %p (%d ms)", __func__, id, obj, ms));
if (G_UNLIKELY (!obj)) {
- mono_raise_exception (mono_get_exception_argument_null ("obj"));
+ mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
return FALSE;
}
+ lw.sync = obj->synchronisation;
+ mon = lock_word_get_inflated_lock (lw);
retry:
- mon = obj->synchronisation;
-
- /* If the object has never been locked... */
- if (G_UNLIKELY (mon == NULL)) {
- mono_monitor_allocator_lock ();
- mon = mon_new (id);
- if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, mon, NULL) == NULL) {
- mono_gc_weak_link_add (&mon->data, obj, TRUE);
- mono_monitor_allocator_unlock ();
- /* Successfully locked */
- return 1;
- } else {
-#ifdef HAVE_MOVING_COLLECTOR
- LockWord lw;
- lw.sync = obj->synchronisation;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- MonoThreadsSync *oldlw = lw.sync;
- /* move the already calculated hash */
- mon->hash_code = lw.lock_word >> LOCK_WORD_HASH_SHIFT;
- lw.sync = mon;
- lw.lock_word |= LOCK_WORD_FAT_HASH;
- if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, oldlw) == oldlw) {
- mono_gc_weak_link_add (&mon->data, obj, TRUE);
- mono_monitor_allocator_unlock ();
- /* Successfully locked */
- return 1;
- } else {
- mon_finalize (mon);
- mono_monitor_allocator_unlock ();
- goto retry;
- }
- } else if (lw.lock_word & LOCK_WORD_FAT_HASH) {
- mon_finalize (mon);
- mono_monitor_allocator_unlock ();
- /* get the old lock without the fat hash bit */
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- } else {
- mon_finalize (mon);
- mono_monitor_allocator_unlock ();
- mon = obj->synchronisation;
- }
-#else
- mon_finalize (mon);
- mono_monitor_allocator_unlock ();
- mon = obj->synchronisation;
-#endif
- }
- } else {
-#ifdef HAVE_MOVING_COLLECTOR
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- MonoThreadsSync *oldlw = lw.sync;
- mono_monitor_allocator_lock ();
- mon = mon_new (id);
- /* move the already calculated hash */
- mon->hash_code = lw.lock_word >> LOCK_WORD_HASH_SHIFT;
- lw.sync = mon;
- lw.lock_word |= LOCK_WORD_FAT_HASH;
- if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, oldlw) == oldlw) {
- mono_gc_weak_link_add (&mon->data, obj, TRUE);
- mono_monitor_allocator_unlock ();
- /* Successfully locked */
- return 1;
- } else {
- mon_finalize (mon);
- mono_monitor_allocator_unlock ();
- goto retry;
- }
- }
-#endif
- }
-
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
-
- /* If the object has previously been locked but isn't now... */
-
/* This case differs from Dice's case 3 because we don't
* deflate locks or cache unused lock records
*/
* We pass TRUE instead of allow_interruption since we have to check for the
* StopRequested case below.
*/
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = WaitForSingleObjectEx (mon->entry_sem, waitms, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
}
}
+/*
+ * If allow_interruption == TRUE, the method will be interrupted if abort or suspend
+ * is requested. In this case it returns -1.
+ */
+static inline gint32
+mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_interruption)
+{
+ LockWord lw;
+ int id = mono_thread_info_get_small_id ();
+
+ LOCK_DEBUG (g_message("%s: (%d) Trying to lock object %p (%d ms)", __func__, id, obj, ms));
+
+ if (G_UNLIKELY (!obj)) {
+ mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
+ return FALSE;
+ }
+
+ lw.sync = obj->synchronisation;
+
+ if (G_LIKELY (lock_word_is_free (lw))) {
+ LockWord nlw = lock_word_new_flat (id);
+ if (InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, NULL) == NULL) {
+ return 1;
+ } else {
+ /* Someone acquired it in the meantime or put a hash */
+ mono_monitor_inflate (obj);
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ }
+ } else if (lock_word_is_inflated (lw)) {
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ } else if (lock_word_is_flat (lw)) {
+ if (lock_word_get_owner (lw) == id) {
+ if (lock_word_is_max_nest (lw)) {
+ mono_monitor_inflate_owned (obj, id);
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ } else {
+ LockWord nlw, old_lw;
+ nlw = lock_word_increment_nest (lw);
+ old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, lw.sync);
+ if (old_lw.sync != lw.sync) {
+ /* Someone else inflated it in the meantime */
+ g_assert (lock_word_is_inflated (old_lw));
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ }
+ return 1;
+ }
+ } else {
+ mono_monitor_inflate (obj);
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ }
+ } else if (lock_word_has_hash (lw)) {
+ mono_monitor_inflate (obj);
+ return mono_monitor_try_enter_inflated (obj, ms, allow_interruption, id);
+ }
+
+ g_assert_not_reached ();
+ return -1;
+}
+
gboolean
mono_monitor_enter (MonoObject *obj)
{
void
mono_monitor_exit (MonoObject *obj)
{
- MonoThreadsSync *mon;
- guint32 nest;
- guint32 new_status, old_status, tmp_status;
+ LockWord lw;
LOCK_DEBUG (g_message ("%s: (%d) Unlocking %p", __func__, mono_thread_info_get_small_id (), obj));
if (G_UNLIKELY (!obj)) {
- mono_raise_exception (mono_get_exception_argument_null ("obj"));
+ mono_set_pending_exception (mono_get_exception_argument_null ("obj"));
return;
}
- mon = obj->synchronisation;
+ lw.sync = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH)
- return;
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (G_UNLIKELY (mon == NULL)) {
- /* No one ever used Enter. Just ignore the Exit request as MS does */
- return;
- }
+ mono_monitor_ensure_owned (lw, mono_thread_info_get_small_id ());
- old_status = mon->status;
- if (G_UNLIKELY (mon_status_get_owner (old_status) != mono_thread_info_get_small_id ())) {
- return;
- }
-
- nest = mon->nest - 1;
- if (nest == 0) {
- /*
- * Release lock and do the wakeup stuff. It's possible that
- * the last blocking thread gave up waiting just before we
- * release the semaphore resulting in a negative entry count
- * and a futile wakeup next time there's contention for this
- * object.
- */
- for (;;) {
- gboolean have_waiters = mon_status_have_waiters (old_status);
-
- new_status = mon_status_set_owner (old_status, 0);
- if (have_waiters)
- new_status = mon_status_decrement_entry_count (new_status);
- tmp_status = InterlockedCompareExchange ((gint32*)&mon->status, new_status, old_status);
- if (tmp_status == old_status) {
- if (have_waiters)
- ReleaseSemaphore (mon->entry_sem, 1, NULL);
- break;
- }
- old_status = tmp_status;
- }
- LOCK_DEBUG (g_message ("%s: (%d) Object %p is now unlocked", __func__, mono_thread_info_get_small_id (), obj));
-
- /* object is now unlocked, leave nest==1 so we don't
- * need to set it when the lock is reacquired
- */
-
- } else {
- LOCK_DEBUG (g_message ("%s: (%d) Object %p is now locked %d times", __func__, mono_thread_info_get_small_id (), obj, nest));
- mon->nest = nest;
- }
+ if (G_UNLIKELY (lock_word_is_inflated (lw)))
+ mono_monitor_exit_inflated (obj);
+ else
+ mono_monitor_exit_flat (obj, lw);
}
void**
mono_monitor_get_object_monitor_weak_link (MonoObject *object)
{
LockWord lw;
- MonoThreadsSync *sync = NULL;
lw.sync = object->synchronisation;
- if (lw.lock_word & LOCK_WORD_FAT_HASH) {
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- sync = lw.sync;
- } else if (!(lw.lock_word & LOCK_WORD_THIN_HASH)) {
- sync = lw.sync;
- }
- if (sync && sync->data)
- return &sync->data;
+ if (lock_word_is_inflated (lw)) {
+ MonoThreadsSync *mon = lock_word_get_inflated_lock (lw);
+ if (mon->data)
+ return &mon->data;
+ }
return NULL;
}
void
mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken)
{
- if (*lock_taken == 1)
- mono_raise_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true"));
+
+ if (*lock_taken == 1) {
+ mono_set_pending_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true"));
+ return;
+ }
ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (obj, INFINITE, lock_taken);
}
gboolean
ves_icall_System_Threading_Monitor_Monitor_test_owner (MonoObject *obj)
{
- MonoThreadsSync *mon;
-
+ LockWord lw;
+
LOCK_DEBUG (g_message ("%s: Testing if %p is owned by thread %d", __func__, obj, mono_thread_info_get_small_id()));
- mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH)
- return FALSE;
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (mon == NULL) {
- return FALSE;
- }
-
- if (mon_status_get_owner (mon->status) == mono_thread_info_get_small_id ()) {
- return(TRUE);
+ lw.sync = obj->synchronisation;
+
+ if (lock_word_is_flat (lw)) {
+ return lock_word_get_owner (lw) == mono_thread_info_get_small_id ();
+ } else if (lock_word_is_inflated (lw)) {
+ return mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) == mono_thread_info_get_small_id ();
}
return(FALSE);
gboolean
ves_icall_System_Threading_Monitor_Monitor_test_synchronised (MonoObject *obj)
{
- MonoThreadsSync *mon;
+ LockWord lw;
LOCK_DEBUG (g_message("%s: (%d) Testing if %p is owned by any thread", __func__, mono_thread_info_get_small_id (), obj));
-
- mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH)
- return FALSE;
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (mon == NULL) {
- return FALSE;
- }
-
- if (mon_status_get_owner (mon->status) != 0) {
- return TRUE;
+
+ lw.sync = obj->synchronisation;
+
+ if (lock_word_is_flat (lw)) {
+ return !lock_word_is_free (lw);
+ } else if (lock_word_is_inflated (lw)) {
+ return mon_status_get_owner (lock_word_get_inflated_lock (lw)->status) != 0;
}
-
+
return FALSE;
}
void
ves_icall_System_Threading_Monitor_Monitor_pulse (MonoObject *obj)
{
+ int id;
+ LockWord lw;
MonoThreadsSync *mon;
-
+
LOCK_DEBUG (g_message ("%s: (%d) Pulsing %p", __func__, mono_thread_info_get_small_id (), obj));
- mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return;
- }
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (mon == NULL) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return;
- }
- if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
+ id = mono_thread_info_get_small_id ();
+ lw.sync = obj->synchronisation;
+
+ mono_monitor_ensure_owned (lw, id);
+
+ if (!lock_word_is_inflated (lw)) {
+ /* No threads waiting. A wait would have inflated the lock */
return;
}
+ mon = lock_word_get_inflated_lock (lw);
+
LOCK_DEBUG (g_message ("%s: (%d) %d threads waiting", __func__, mono_thread_info_get_small_id (), g_slist_length (mon->wait_list)));
-
+
if (mon->wait_list != NULL) {
LOCK_DEBUG (g_message ("%s: (%d) signalling and dequeuing handle %p", __func__, mono_thread_info_get_small_id (), mon->wait_list->data));
void
ves_icall_System_Threading_Monitor_Monitor_pulse_all (MonoObject *obj)
{
+ int id;
+ LockWord lw;
MonoThreadsSync *mon;
LOCK_DEBUG (g_message("%s: (%d) Pulsing all %p", __func__, mono_thread_info_get_small_id (), obj));
- mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return;
- }
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (mon == NULL) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return;
- }
- if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
+ id = mono_thread_info_get_small_id ();
+ lw.sync = obj->synchronisation;
+
+ mono_monitor_ensure_owned (lw, id);
+
+ if (!lock_word_is_inflated (lw)) {
+ /* No threads waiting. A wait would have inflated the lock */
return;
}
+ mon = lock_word_get_inflated_lock (lw);
+
LOCK_DEBUG (g_message ("%s: (%d) %d threads waiting", __func__, mono_thread_info_get_small_id (), g_slist_length (mon->wait_list)));
while (mon->wait_list != NULL) {
gboolean
ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
{
+ LockWord lw;
MonoThreadsSync *mon;
HANDLE event;
guint32 nest;
gboolean success = FALSE;
gint32 regain;
MonoInternalThread *thread = mono_thread_internal_current ();
+ int id = mono_thread_info_get_small_id ();
LOCK_DEBUG (g_message ("%s: (%d) Trying to wait for %p with timeout %dms", __func__, mono_thread_info_get_small_id (), obj, ms));
-
- mon = obj->synchronisation;
-#ifdef HAVE_MOVING_COLLECTOR
- {
- LockWord lw;
- lw.sync = mon;
- if (lw.lock_word & LOCK_WORD_THIN_HASH) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return FALSE;
- }
- lw.lock_word &= ~LOCK_WORD_BITS_MASK;
- mon = lw.sync;
- }
-#endif
- if (mon == NULL) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked"));
- return FALSE;
- }
- if (mon_status_get_owner (mon->status) != mono_thread_info_get_small_id ()) {
- mono_set_pending_exception (mono_get_exception_synchronization_lock ("Not locked by this thread"));
- return FALSE;
+
+ lw.sync = obj->synchronisation;
+
+ mono_monitor_ensure_owned (lw, id);
+
+ if (!lock_word_is_inflated (lw)) {
+ mono_monitor_inflate_owned (obj, id);
+ lw.sync = obj->synchronisation;
}
+ mon = lock_word_get_inflated_lock (lw);
+
/* Do this WaitSleepJoin check before creating the event handle */
mono_thread_current_check_pending_interrupt ();
/* Save the nest count, and release the lock */
nest = mon->nest;
mon->nest = 1;
- mono_monitor_exit (obj);
+ mono_memory_write_barrier ();
+ mono_monitor_exit_inflated (obj);
LOCK_DEBUG (g_message ("%s: (%d) Unlocked %p lock %p", __func__, mono_thread_info_get_small_id (), obj, mon));
* is private to this thread. Therefore even if the event was
* signalled before we wait, we still succeed.
*/
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = WaitForSingleObjectEx (event, ms, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
/* Reset the thread state fairly early, so we don't have to worry
* about the monitor error checking
/* Regain the lock with the previous nest count */
do {
- regain = mono_monitor_try_enter_internal (obj, INFINITE, TRUE);
+ regain = mono_monitor_try_enter_inflated (obj, INFINITE, TRUE, id);
if (regain == -1)
mono_thread_interruption_checkpoint ();
} while (regain == -1);
/* Poll the event again, just in case it was signalled
* while we were trying to regain the monitor lock
*/
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = WaitForSingleObjectEx (event, 0, FALSE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
/* Pulse will have popped our event from the queue if it signalled
void *data;
};
+/*
+ * Lock word format:
+ *
+ * The least significant bit stores whether a hash for the object is computed
+ * which is stored either in the lock word or in the MonoThreadsSync structure
+ * that the lock word points to.
+ *
+ * The second bit stores whether the lock word is inflated, containing an
+ * address to the MonoThreadsSync structure.
+ *
+ * If both bits are 0, either the lock word is free (entire lock word is 0)
+ * or it is a thin/flat lock.
+ *
+ * 32-bit
+ * LOCK_WORD_FLAT: [owner:22 | nest:8 | status:2]
+ * LOCK_WORD_THIN_HASH: [hash:30 | status:2]
+ * LOCK_WORD_INFLATED: [sync:30 | status:2]
+ * LOCK_WORD_FAT_HASH: [sync:30 | status:2]
+ *
+ * 64-bit
+ * LOCK_WORD_FLAT: [unused:22 | owner:32 | nest:8 | status:2]
+ * LOCK_WORD_THIN_HASH: [hash:62 | status:2]
+ * LOCK_WORD_INFLATED: [sync:62 | status:2]
+ * LOCK_WORD_FAT_HASH: [sync:62 | status:2]
+ *
+ * In order to save processing time and to have one additional value, the nest
+ * count starts from 0 for the lock word (just valid thread ID in the lock word
+ * means that the thread holds the lock once, although nest is 0).
+ * FIXME Have the same convention on inflated locks
+ */
+
+typedef union {
+#if SIZEOF_REGISTER == 8
+ guint64 lock_word;
+#elif SIZEOF_REGISTER == 4
+ guint32 lock_word;
+#endif
+ MonoThreadsSync *sync;
+} LockWord;
+
+
+enum {
+ LOCK_WORD_FLAT = 0,
+ LOCK_WORD_HAS_HASH = 1,
+ LOCK_WORD_INFLATED = 2,
+
+ LOCK_WORD_STATUS_BITS = 2,
+ LOCK_WORD_NEST_BITS = 8,
+
+ LOCK_WORD_STATUS_MASK = (1 << LOCK_WORD_STATUS_BITS) - 1,
+ LOCK_WORD_NEST_MASK = ((1 << LOCK_WORD_NEST_BITS) - 1) << LOCK_WORD_STATUS_BITS,
+
+ LOCK_WORD_HASH_SHIFT = LOCK_WORD_STATUS_BITS,
+ LOCK_WORD_NEST_SHIFT = LOCK_WORD_STATUS_BITS,
+ LOCK_WORD_OWNER_SHIFT = LOCK_WORD_STATUS_BITS + LOCK_WORD_NEST_BITS
+};
MONO_API void mono_locks_dump (gboolean include_untaken);
#include <glib.h>
#include "mono-hash.h"
#include "metadata/gc-internal.h"
+#include <mono/utils/checked-build.h>
#ifdef HAVE_BOEHM_GC
#define mg_new0(type,n) ((type *) GC_MALLOC(sizeof(type) * (n)))
MonoGHashGCType gc_type;
};
+static MonoGHashTable *
+mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func);
+
#ifdef HAVE_SGEN_GC
static MonoGCDescriptor table_hash_descr = MONO_GC_DESCRIPTOR_NULL;
return hash;
}
-MonoGHashTable *
+static MonoGHashTable *
mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func)
{
MonoGHashTable *hash;
return hash;
}
-MonoGHashTable *
-mono_g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func,
- GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
-{
- MonoGHashTable *hash = mono_g_hash_table_new (hash_func, key_equal_func);
- if (hash == NULL)
- return NULL;
-
- hash->key_destroy_func = key_destroy_func;
- hash->value_destroy_func = value_destroy_func;
-
- return hash;
-}
-
typedef struct {
MonoGHashTable *hash;
int new_size;
static void
rehash (MonoGHashTable *hash)
{
+ MONO_REQ_GC_UNSAFE_MODE; //we must run in unsafe mode to make rehash safe
+
int diff = ABS (hash->last_rehash - hash->in_use);
RehashData data;
void *old_table G_GNUC_UNUSED; /* unused on Boehm */
data.new_size = g_spaced_primes_closest (hash->in_use);
data.table = mg_new0 (Slot *, data.new_size);
+#ifdef USE_COOP_GC
+ /* We cannot be preempted */
+ old_table = do_rehash (&data);
+#else
old_table = mono_gc_invoke_with_gc_lock (do_rehash, &data);
+#endif
mg_free (old_table);
}
typedef struct _MonoGHashTable MonoGHashTable;
MONO_API MonoGHashTable *mono_g_hash_table_new_type (GHashFunc hash_func, GEqualFunc key_equal_func, MonoGHashGCType type);
-MONO_API MonoGHashTable *mono_g_hash_table_new (GHashFunc hash_func, GEqualFunc key_equal_func);
-MONO_API MonoGHashTable *mono_g_hash_table_new_full (GHashFunc hash_func, GEqualFunc key_equal_func,
- GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
MONO_API guint mono_g_hash_table_size (MonoGHashTable *hash);
MONO_API gpointer mono_g_hash_table_lookup (MonoGHashTable *hash, gconstpointer key);
MONO_API gboolean mono_g_hash_table_lookup_extended (MonoGHashTable *hash, gconstpointer key, gpointer *orig_key, gpointer *value);
MonoObject *_data;
MonoObject *captured_traces;
MonoArray *native_trace_ips;
+ /* Dynamic methods referenced by the stack trace */
+ MonoObject *dynamic_methods;
};
typedef struct {
MonoObject *state, gpointer data, MonoObject *object_data);
MonoObject *
-mono_async_result_invoke (MonoAsyncResult *ares, MonoObject **exc);
-
-MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this_obj);
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares);
MonoWaitHandle *
mono_wait_handle_new (MonoDomain *domain, HANDLE handle);
#include <mono/utils/mono-counters.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/checked-build.h>
#include "cominterop.h"
static void
void
mono_runtime_object_init (MonoObject *this)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *method = NULL;
MonoClass *klass = this->vtable->klass;
} TypeInitializationLock;
/* for locking access to type_initialization_hash and blocked_thread_hash */
-#define mono_type_initialization_lock() mono_mutex_lock (&type_initialization_section)
-#define mono_type_initialization_unlock() mono_mutex_unlock (&type_initialization_section)
static mono_mutex_t type_initialization_section;
+static inline void
+mono_type_initialization_lock (void)
+{
+ /* The critical sections protected by this lock in mono_runtime_class_init_full () can block */
+ MONO_PREPARE_BLOCKING;
+ mono_mutex_lock (&type_initialization_section);
+ MONO_FINISH_BLOCKING;
+}
+
+static inline void
+mono_type_initialization_unlock (void)
+{
+ mono_mutex_unlock (&type_initialization_section);
+}
static void
mono_type_init_lock (TypeInitializationLock *lock)
{
- MONO_TRY_BLOCKING
+ MONO_REQ_GC_NEUTRAL_MODE;
+
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&lock->initialization_section);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
}
static void
void
mono_thread_set_main (MonoThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static gboolean registered = FALSE;
if (!registered) {
MonoThread*
mono_thread_get_main (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return main_thread;
}
static MonoException*
get_type_init_exception_for_vtable (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = vtable->domain;
MonoClass *klass = vtable->klass;
MonoException *ex;
void
mono_runtime_class_init (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_runtime_class_init_full (vtable, TRUE);
}
MonoException *
mono_runtime_class_init_full (MonoVTable *vtable, gboolean raise_exception)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoException *exc;
MonoException *exc_to_throw;
MonoMethod *method = NULL;
MonoClass *klass;
gchar *full_name;
+ MonoDomain *domain = vtable->domain;
+ TypeInitializationLock *lock;
+ guint32 tid;
+ int do_initialization = 0;
+ MonoDomain *last_domain = NULL;
if (vtable->initialized)
return NULL;
}
}
method = mono_class_get_cctor (klass);
+ if (!method) {
+ vtable->initialized = 1;
+ return NULL;
+ }
+
+ tid = GetCurrentThreadId ();
+
+ mono_type_initialization_lock ();
+ /* double check... */
+ if (vtable->initialized) {
+ mono_type_initialization_unlock ();
+ return NULL;
+ }
+ if (vtable->init_failed) {
+ mono_type_initialization_unlock ();
- if (method) {
- MonoDomain *domain = vtable->domain;
- TypeInitializationLock *lock;
- guint32 tid = GetCurrentThreadId();
- int do_initialization = 0;
- MonoDomain *last_domain = NULL;
+ /* The type initialization already failed once, rethrow the same exception */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
+ }
+ lock = g_hash_table_lookup (type_initialization_hash, vtable);
+ if (lock == NULL) {
+ /* This thread will get to do the initialization */
+ if (mono_domain_get () != domain) {
+ /* Transfer into the target domain */
+ last_domain = mono_domain_get ();
+ if (!mono_domain_set (domain, FALSE)) {
+ vtable->initialized = 1;
+ mono_type_initialization_unlock ();
+ if (raise_exception)
+ mono_raise_exception (mono_get_exception_appdomain_unloaded ());
+ return mono_get_exception_appdomain_unloaded ();
+ }
+ }
+ lock = g_malloc (sizeof(TypeInitializationLock));
+ mono_mutex_init_recursive (&lock->initialization_section);
+ lock->initializing_tid = tid;
+ lock->waiting_count = 1;
+ lock->done = FALSE;
+ /* grab the vtable lock while this thread still owns type_initialization_section */
+ /* This is why type_initialization_lock needs to enter blocking mode */
+ mono_type_init_lock (lock);
+ g_hash_table_insert (type_initialization_hash, vtable, lock);
+ do_initialization = 1;
+ } else {
+ gpointer blocked;
+ TypeInitializationLock *pending_lock;
- mono_type_initialization_lock ();
- /* double check... */
- if (vtable->initialized) {
+ if (lock->initializing_tid == tid || lock->done) {
mono_type_initialization_unlock ();
return NULL;
}
- if (vtable->init_failed) {
- mono_type_initialization_unlock ();
-
- /* The type initialization already failed once, rethrow the same exception */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
- lock = g_hash_table_lookup (type_initialization_hash, vtable);
- if (lock == NULL) {
- /* This thread will get to do the initialization */
- if (mono_domain_get () != domain) {
- /* Transfer into the target domain */
- last_domain = mono_domain_get ();
- if (!mono_domain_set (domain, FALSE)) {
- vtable->initialized = 1;
+ /* see if the thread doing the initialization is already blocked on this thread */
+ blocked = GUINT_TO_POINTER (lock->initializing_tid);
+ while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
+ if (pending_lock->initializing_tid == tid) {
+ if (!pending_lock->done) {
mono_type_initialization_unlock ();
- if (raise_exception)
- mono_raise_exception (mono_get_exception_appdomain_unloaded ());
- return mono_get_exception_appdomain_unloaded ();
- }
- }
- lock = g_malloc (sizeof(TypeInitializationLock));
- mono_mutex_init_recursive (&lock->initialization_section);
- lock->initializing_tid = tid;
- lock->waiting_count = 1;
- lock->done = FALSE;
- /* grab the vtable lock while this thread still owns type_initialization_section */
- mono_type_init_lock (lock);
- g_hash_table_insert (type_initialization_hash, vtable, lock);
- do_initialization = 1;
- } else {
- gpointer blocked;
- TypeInitializationLock *pending_lock;
-
- if (lock->initializing_tid == tid || lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- }
- /* see if the thread doing the initialization is already blocked on this thread */
- blocked = GUINT_TO_POINTER (lock->initializing_tid);
- while ((pending_lock = (TypeInitializationLock*) g_hash_table_lookup (blocked_thread_hash, blocked))) {
- if (pending_lock->initializing_tid == tid) {
- if (!pending_lock->done) {
- mono_type_initialization_unlock ();
- return NULL;
- } else {
- /* the thread doing the initialization is blocked on this thread,
- but on a lock that has already been freed. It just hasn't got
- time to awake */
- break;
- }
+ return NULL;
+ } else {
+ /* the thread doing the initialization is blocked on this thread,
+ but on a lock that has already been freed. It just hasn't got
+ time to awake */
+ break;
}
- blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- ++lock->waiting_count;
- /* record the fact that we are waiting on the initializing thread */
- g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ blocked = GUINT_TO_POINTER (pending_lock->initializing_tid);
}
- mono_type_initialization_unlock ();
+ ++lock->waiting_count;
+ /* record the fact that we are waiting on the initializing thread */
+ g_hash_table_insert (blocked_thread_hash, GUINT_TO_POINTER (tid), lock);
+ }
+ mono_type_initialization_unlock ();
- if (do_initialization) {
- mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
+ if (do_initialization) {
+ mono_runtime_invoke (method, NULL, NULL, (MonoObject **) &exc);
- /* If the initialization failed, mark the class as unusable. */
- /* Avoid infinite loops */
- if (!(exc == NULL ||
- (klass->image == mono_defaults.corlib &&
- !strcmp (klass->name_space, "System") &&
- !strcmp (klass->name, "TypeInitializationException")))) {
- vtable->init_failed = 1;
+ /* If the initialization failed, mark the class as unusable. */
+ /* Avoid infinite loops */
+ if (!(exc == NULL ||
+ (klass->image == mono_defaults.corlib &&
+ !strcmp (klass->name_space, "System") &&
+ !strcmp (klass->name, "TypeInitializationException")))) {
+ vtable->init_failed = 1;
- if (klass->name_space && *klass->name_space)
- full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
- else
- full_name = g_strdup (klass->name);
- exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
- g_free (full_name);
-
- /*
- * Store the exception object so it could be thrown on subsequent
- * accesses.
- */
- mono_domain_lock (domain);
- if (!domain->type_init_exception_hash)
- domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
- mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
- mono_domain_unlock (domain);
- }
+ if (klass->name_space && *klass->name_space)
+ full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
+ else
+ full_name = g_strdup (klass->name);
+ exc_to_throw = mono_get_exception_type_initialization (full_name, exc);
+ g_free (full_name);
- if (last_domain)
- mono_domain_set (last_domain, TRUE);
- lock->done = TRUE;
- mono_type_init_unlock (lock);
- } else {
- /* this just blocks until the initializing thread is done */
- mono_type_init_lock (lock);
- mono_type_init_unlock (lock);
+ /*
+ * Store the exception object so it could be thrown on subsequent
+ * accesses.
+ */
+ mono_domain_lock (domain);
+ if (!domain->type_init_exception_hash)
+ domain->type_init_exception_hash = mono_g_hash_table_new_type (mono_aligned_addr_hash, NULL, MONO_HASH_VALUE_GC);
+ mono_g_hash_table_insert (domain->type_init_exception_hash, klass, exc_to_throw);
+ mono_domain_unlock (domain);
}
- mono_type_initialization_lock ();
- if (lock->initializing_tid != tid)
- g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
- --lock->waiting_count;
- if (lock->waiting_count == 0) {
- mono_mutex_destroy (&lock->initialization_section);
- g_hash_table_remove (type_initialization_hash, vtable);
- g_free (lock);
- }
- mono_memory_barrier ();
- if (!vtable->init_failed)
- vtable->initialized = 1;
- mono_type_initialization_unlock ();
-
- if (vtable->init_failed) {
- /* Either we were the initializing thread or we waited for the initialization */
- if (raise_exception)
- mono_raise_exception (get_type_init_exception_for_vtable (vtable));
- return get_type_init_exception_for_vtable (vtable);
- }
+ if (last_domain)
+ mono_domain_set (last_domain, TRUE);
+ lock->done = TRUE;
+ mono_type_init_unlock (lock);
} else {
+ /* this just blocks until the initializing thread is done */
+ mono_type_init_lock (lock);
+ mono_type_init_unlock (lock);
+ }
+
+ mono_type_initialization_lock ();
+ if (lock->initializing_tid != tid)
+ g_hash_table_remove (blocked_thread_hash, GUINT_TO_POINTER (tid));
+ --lock->waiting_count;
+ if (lock->waiting_count == 0) {
+ mono_mutex_destroy (&lock->initialization_section);
+ g_hash_table_remove (type_initialization_hash, vtable);
+ g_free (lock);
+ }
+ mono_memory_barrier ();
+ if (!vtable->init_failed)
vtable->initialized = 1;
- return NULL;
+ mono_type_initialization_unlock ();
+
+ if (vtable->init_failed) {
+ /* Either we were the initializing thread or we waited for the initialization */
+ if (raise_exception)
+ mono_raise_exception (get_type_init_exception_for_vtable (vtable));
+ return get_type_init_exception_for_vtable (vtable);
}
return NULL;
}
static
gboolean release_type_locks (gpointer key, gpointer value, gpointer user)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoVTable *vtable = (MonoVTable*)key;
TypeInitializationLock *lock = (TypeInitializationLock*) value;
void
mono_release_type_locks (MonoInternalThread *thread)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_type_initialization_lock ();
g_hash_table_foreach_remove (type_initialization_hash, release_type_locks, (gpointer)(gsize)(thread->tid));
mono_type_initialization_unlock ();
gpointer
mono_compile_method (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!default_mono_compile_method) {
g_error ("compile method called on uninitialized runtime");
return NULL;
gpointer
mono_runtime_create_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_jump_trampoline (domain, method, add_sync_wrapper);
}
gpointer
mono_runtime_create_delegate_trampoline (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
return arch_create_delegate_trampoline (mono_domain_get (), klass);
}
void
mono_runtime_free_method (MonoDomain *domain, MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (default_mono_free_method != NULL)
default_mono_free_method (domain, method);
static gsize*
compute_class_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassField *field;
MonoClass *p;
guint32 pos;
gsize*
mono_class_compute_bitmap (MonoClass *class, gsize *bitmap, int size, int offset, int *max_set, gboolean static_fields)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
return compute_class_bitmap (class, bitmap, size, offset, max_set, static_fields);
}
MonoString*
mono_string_alloc (int length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
return mono_string_new_size (mono_domain_get (), length);
}
void
mono_class_compute_gc_descriptor (MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int max_set = 0;
gsize *bitmap;
gsize default_bitmap [4] = {0};
static gint32
field_is_special_static (MonoClass *fklass, MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoCustomAttrInfo *ainfo;
int i;
ainfo = mono_custom_attrs_from_field (fklass, field);
guint32
mono_method_get_imt_slot (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethodSignature *sig;
int hashes_count;
guint32 *hashes_start, *hashes;
static void
add_imt_builder_entry (MonoImtBuilderEntry **imt_builder, MonoMethod *method, guint32 *imt_collisions_bitmap, int vtable_slot, int slot_num) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 imt_slot = mono_method_get_imt_slot (method);
MonoImtBuilderEntry *entry;
static int
imt_emit_ir (MonoImtBuilderEntry **sorted_array, int start, int end, GPtrArray *out_array)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int count = end - start;
int chunk_start = out_array->len;
if (count < 4) {
static GPtrArray*
imt_sort_slot_entries (MonoImtBuilderEntry *entries) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int number_of_entries = entries->children + 1;
MonoImtBuilderEntry **sorted_array = malloc (sizeof (MonoImtBuilderEntry*) * number_of_entries);
GPtrArray *result = g_ptr_array_new ();
static gpointer
initialize_imt_slot (MonoVTable *vtable, MonoDomain *domain, MonoImtBuilderEntry *imt_builder_entry, gpointer fail_tramp)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (imt_builder_entry != NULL) {
if (imt_builder_entry->children == 0 && !fail_tramp) {
/* No collision, return the vtable slot contents */
static void
build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces, int slot_num)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
GSList *list_item;
guint32 imt_collisions_bitmap = 0;
static void
build_imt (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer* imt, GSList *extra_interfaces) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
build_imt_slots (klass, vt, domain, imt, extra_interfaces, -1);
}
void
mono_vtable_build_imt_slot (MonoVTable* vtable, int imt_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *imt = (gpointer*)vtable;
imt -= MONO_IMT_SIZE;
g_assert (imt_slot >= 0 && imt_slot < MONO_IMT_SIZE);
static void
init_thunk_free_lists (MonoDomain *domain)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (domain->thunk_free_lists)
return;
domain->thunk_free_lists = mono_domain_alloc0 (domain, sizeof (gpointer) * NUM_FREE_LISTS);
gpointer
mono_method_alloc_generic_virtual_thunk (MonoDomain *domain, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int generic_virtual_thunks_size = 0;
static void
invalidate_generic_virtual_thunk (MonoDomain *domain, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 *p = code;
MonoThunkFreeList *l = (MonoThunkFreeList*)(p - 1);
gboolean found = FALSE;
static MonoImtBuilderEntry*
get_generic_virtual_entries (MonoDomain *domain, gpointer *vtable_slot)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
GenericVirtualCase *list;
MonoImtBuilderEntry *entries;
gpointer *vtable_slot,
MonoMethod *method, gpointer code)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
static gboolean inited = FALSE;
static int num_added = 0;
MonoVTable *
mono_class_vtable_full (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
MonoVTable *
mono_class_try_get_vtable (MonoDomain *domain, MonoClass *class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoClassRuntimeInfo *runtime_info;
g_assert (class);
static gpointer*
alloc_vtable (MonoDomain *domain, size_t vtable_size, size_t imt_table_bytes)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
size_t alloc_offset;
/*
static MonoVTable *
mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean raise_on_error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
MonoClassRuntimeInfo *runtime_info, *old_info;
MonoClassField *field;
static MonoVTable *
mono_class_proxy_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRemotingTarget target_type)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoVTable *vt, *pvt;
int i, j, vtsize, max_interface_id, extra_interface_vtsize = 0;
gboolean
mono_class_field_is_special_static (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return FALSE;
if (mono_field_is_deleted (field))
guint32
mono_class_field_get_special_static_type (MonoClassField *field)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC))
return SPECIAL_STATIC_NONE;
if (mono_field_is_deleted (field))
gboolean
mono_class_has_special_static_fields (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
MonoClassField *field;
gpointer iter;
static gpointer*
create_remote_class_key (MonoRemoteClass *remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
gpointer *key;
int i, j;
static gpointer*
copy_remote_class_key (MonoDomain *domain, gpointer *key)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
int key_size = (GPOINTER_TO_UINT (key [0]) + 1) * sizeof (gpointer);
gpointer *mp_key = mono_domain_alloc (domain, key_size);
MonoRemoteClass*
mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoRemoteClass *rc;
gpointer* key, *mp_key;
static MonoRemoteClass*
clone_remote_class (MonoDomain *domain, MonoRemoteClass* remote_class, MonoClass *extra_class)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoRemoteClass *rc;
gpointer* key, *mp_key;
gpointer
mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *rp)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_loader_lock (); /*FIXME mono_class_from_mono_type and mono_class_proxy_vtable take it*/
mono_domain_lock (domain);
if (rp->target_domain_id != -1) {
void
mono_upgrade_remote_class (MonoDomain *domain, MonoObject *proxy_object, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoTransparentProxy *tproxy;
MonoRemoteClass *remote_class;
gboolean redo_vtable;
MonoMethod*
mono_object_get_virtual_method (MonoObject *obj, MonoMethod *method)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
MonoMethod **vtable;
gboolean is_proxy = FALSE;
MonoObject*
mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *result;
if (mono_runtime_get_no_exec ())
gpointer
mono_method_get_unmanaged_thunk (MonoMethod *method)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+ MONO_REQ_API_ENTRYPOINT;
+
+ gpointer res;
+
+ MONO_PREPARE_RESET_BLOCKING
method = mono_marshal_get_thunk_invoke_wrapper (method);
- return mono_compile_method (method);
+ res = mono_compile_method (method);
+ MONO_FINISH_RESET_BLOCKING
+
+ return res;
}
void
mono_copy_value (MonoType *type, void *dest, void *value, int deref_pointer)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int t;
if (type->byref) {
/* object fields cannot be byref, so we don't need a
void
mono_field_set_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (!(field->type->attrs & FIELD_ATTRIBUTE_STATIC));
void
mono_field_static_set_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *dest;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void *
mono_vtable_get_static_field_data (MonoVTable *vt)
{
+ MONO_REQ_GC_NEUTRAL_MODE
+
if (!vt->has_static_fields)
return NULL;
return vt->vtable [vt->klass->vtable_size];
static guint8*
mono_field_get_addr (MonoObject *obj, MonoVTable *vt, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
guint8 *src;
if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
void
mono_field_get_value (MonoObject *obj, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_assert (obj);
MonoObject *
mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoClass *klass;
MonoVTable *vtable = NULL;
int
mono_get_constant_value_from_blob (MonoDomain* domain, MonoTypeEnum type, const char *blob, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int retval = 0;
const char *p = blob;
mono_metadata_decode_blob_size (p, &p);
static void
get_default_field_value (MonoDomain* domain, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoTypeEnum def_type;
const char* data;
void
mono_field_static_get_value_for_thread (MonoInternalThread *thread, MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
void *src;
g_return_if_fail (field->type->attrs & FIELD_ATTRIBUTE_STATIC);
void
mono_field_static_get_value (MonoVTable *vt, MonoClassField *field, void *value)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
mono_field_static_get_value_for_thread (mono_thread_internal_current (), vt, field, value);
}
void
mono_property_set_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
default_mono_runtime_invoke (prop->set, obj, params, exc);
}
MonoObject*
mono_property_get_value (MonoProperty *prop, void *obj, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return default_mono_runtime_invoke (prop->get, obj, params, exc);
}
void
mono_nullable_init (guint8 *buf, MonoObject *value, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoObject*
mono_nullable_box (guint8 *buf, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
MonoMethod *
mono_get_delegate_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_begin_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoMethod *
mono_get_delegate_end_invoke (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoMethod *im;
/* This is called at runtime, so avoid the slower search in metadata */
MonoObject*
mono_runtime_delegate_invoke (MonoObject *delegate, void **params, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im;
MonoClass *klass = delegate->vtable->klass;
MonoArray*
mono_runtime_get_main_args (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *res;
int i;
MonoDomain *domain = mono_domain_get ();
static void
free_main_args (void)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
for (i = 0; i < num_main_args; ++i)
int
mono_runtime_set_main_args (int argc, char* argv[])
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
free_main_args ();
mono_runtime_run_main (MonoMethod *method, int argc, char* argv[],
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int i;
MonoArray *args = NULL;
MonoDomain *domain = mono_domain_get ();
static MonoObject*
deserialize_object (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *deserialize_method;
void *params [1];
static MonoObject*
make_transparent_proxy (MonoObject *obj, gboolean *failure, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *get_proxy_method;
MonoDomain *domain = mono_domain_get ();
MonoObject*
mono_object_xdomain_representation (MonoObject *obj, MonoDomain *target_domain, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *deserialized = NULL;
gboolean failure = FALSE;
static MonoObject *
create_unhandled_exception_eventargs (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
gpointer args [2];
MonoMethod *method = NULL;
/* Used in mono_unhandled_exception */
static void
call_unhandled_exception_delegate (MonoDomain *domain, MonoObject *delegate, MonoObject *exc) {
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *e = NULL;
gpointer pa [2];
MonoDomain *current_domain = mono_domain_get ();
void
mono_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *current_domain = mono_domain_get ();
MonoDomain *root_domain = mono_get_root_domain ();
MonoClassField *field;
int
mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain;
gpointer pa [1];
int rval;
mono_runtime_invoke_array (MonoMethod *method, void *obj, MonoArray *params,
MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
gpointer *pa = NULL;
MonoObject *res;
static void
arith_overflow (void)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_raise_exception (mono_get_exception_overflow ());
}
MonoObject *
mono_object_new (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_pinned (MonoDomain *domain, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vtable;
vtable = mono_class_vtable (domain, klass);
MonoObject *
mono_object_new_specific (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
/* check for is_com_object for COM Interop */
MonoObject *
mono_object_new_alloc_specific (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o = mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
if (G_UNLIKELY (vtable->klass->has_finalize))
MonoObject*
mono_object_new_fast (MonoVTable *vtable)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_gc_alloc_obj (vtable, vtable->klass->instance_size);
}
void*
mono_class_get_allocation_ftn (MonoVTable *vtable, gboolean for_box, gboolean *pass_size_in_words)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
*pass_size_in_words = FALSE;
if (mono_class_has_finalizer (vtable->klass) || mono_class_is_marshalbyref (vtable->klass) || (mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS))
MonoObject *
mono_object_new_from_token (MonoDomain *domain, MonoImage *image, guint32 token)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
MonoClass *class;
MonoObject *
mono_object_clone (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
int size = obj->vtable->klass->instance_size;
void
mono_array_full_copy (MonoArray *src, MonoArray *dest)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t size;
MonoClass *klass = src->obj.vtable->klass;
MonoArray*
mono_array_clone_in_domain (MonoDomain *domain, MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoArray *o;
uintptr_t size, i;
uintptr_t *sizes;
MonoArray*
mono_array_clone (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_array_clone_in_domain (((MonoObject *)array)->vtable->domain, array);
}
gboolean
mono_array_calc_byte_len (MonoClass *class, uintptr_t len, uintptr_t *res)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
uintptr_t byte_len;
byte_len = mono_array_element_size (class);
MonoArray*
mono_array_new_full (MonoDomain *domain, MonoClass *array_class, uintptr_t *lengths, intptr_t *lower_bounds)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
uintptr_t byte_len = 0, len, bounds_size;
MonoObject *o;
MonoArray *array;
MonoArray *
mono_array_new (MonoDomain *domain, MonoClass *eclass, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *ac;
ac = mono_array_class_get (eclass, 1);
MonoArray *
mono_array_new_specific (MonoVTable *vtable, uintptr_t n)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *o;
MonoArray *ao;
uintptr_t byte_len;
MonoString *
mono_string_new_utf16 (MonoDomain *domain, const guint16 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
s = mono_string_new_size (domain, len);
MonoString *
mono_string_new_utf32 (MonoDomain *domain, const mono_unichar4 *text, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
mono_unichar2 *utf16_output = NULL;
gint32 utf16_len = 0;
MonoString *
mono_string_new_size (MonoDomain *domain, gint32 len)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString *s;
MonoVTable *vtable;
size_t size;
MonoString*
mono_string_new_len (MonoDomain *domain, const char *text, guint length)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new (MonoDomain *domain, const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GError *error = NULL;
MonoString *o = NULL;
guint16 *ut;
MonoString*
mono_string_new_wrapper (const char *text)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
if (text)
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *class, gpointer value)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *res;
int size;
MonoVTable *vtable;
void
mono_value_copy (gpointer dest, gpointer src, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_gc_wbarrier_value_copy (dest, src, 1, klass);
}
void
mono_value_copy_array (MonoArray *dest, int dest_idx, gpointer src, int count)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size = mono_array_element_size (dest->obj.vtable->klass);
char *d = mono_array_addr_with_size_fast (dest, size, dest_idx);
g_assert (size == mono_class_value_size (mono_object_class (dest)->element_class, NULL));
MonoDomain*
mono_object_get_domain (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_domain (obj);
}
MonoClass*
mono_object_get_class (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_object_class (obj);
}
/**
guint
mono_object_get_size (MonoObject* o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass* klass = mono_object_class (o);
if (klass == mono_defaults.string_class) {
return sizeof (MonoString) + 2 * mono_string_length ((MonoString*) o) + 2;
gpointer
mono_object_unbox (MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/* add assert for valuetypes? */
g_assert (obj->vtable->klass->valuetype);
return ((char*)obj) + sizeof (MonoObject);
MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!klass->inited)
mono_class_init (klass);
MonoObject *
mono_object_isinst_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
if (!obj)
MonoObject *
mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!obj) return NULL;
if (mono_object_isinst_mbyref (obj, klass)) return obj;
static void
str_lookup (MonoDomain *domain, gpointer user_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
LDStrInfo *info = user_data;
if (info->res || domain == info->orig_domain)
return;
static MonoString*
mono_string_get_pinned (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int size;
MonoString *news;
size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
static MonoString*
mono_string_is_interned_lookup (MonoString *str, int insert)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoGHashTable *ldstr_table;
MonoString *s, *res;
MonoDomain *domain;
MonoString*
mono_string_is_interned (MonoString *o)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (o, FALSE);
}
MonoString*
mono_string_intern (MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_is_interned_lookup (str, TRUE);
}
MonoString*
mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (image->dynamic) {
MonoString *str = mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
return str;
static MonoString*
mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
const char *str = sig;
MonoString *o, *interned;
size_t len2;
char *
mono_string_to_utf8 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoError error;
char *result = mono_string_to_utf8_checked (s, &error);
char *
mono_string_to_utf8_checked (MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
GError *gerror = NULL;
char *
mono_string_to_utf8_ignore (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
long written = 0;
char *as;
char *
mono_string_to_utf8_image_ignore (MonoImage *image, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, TRUE, NULL);
}
char *
mono_string_to_utf8_mp_ignore (MonoMemPool *mp, MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, TRUE, NULL);
}
mono_unichar2*
mono_string_to_utf16 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *as;
if (s == NULL)
mono_unichar4*
mono_string_to_utf32 (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
mono_unichar4 *utf32_output = NULL;
GError *error = NULL;
glong items_written;
MonoString *
mono_string_from_utf16 (gunichar2 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
int len = 0;
MonoString *
mono_string_from_utf32 (mono_unichar4 *data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString* result = NULL;
mono_unichar2 *utf16_output = NULL;
GError *error = NULL;
static char *
mono_string_to_utf8_internal (MonoMemPool *mp, MonoImage *image, MonoString *s, gboolean ignore_error, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *r;
char *mp_s;
int len;
char *
mono_string_to_utf8_image (MonoImage *image, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (NULL, image, s, FALSE, error);
}
char *
mono_string_to_utf8_mp (MonoMemPool *mp, MonoString *s, MonoError *error)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return mono_string_to_utf8_internal (mp, NULL, s, FALSE, error);
}
void
mono_raise_exception (MonoException *ex)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/*
* NOTE: Do NOT annotate this function with G_GNUC_NORETURN, since
* that will cause gcc to omit the function epilog, causing problems when
void
mono_raise_exception_with_context (MonoException *ex, MonoContext *ctx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
eh_callbacks.mono_raise_exception_with_ctx (ex, ctx);
}
MonoWaitHandle *
mono_wait_handle_new (MonoDomain *domain, HANDLE handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoWaitHandle *res;
gpointer params [1];
static MonoMethod *handle_set;
HANDLE
mono_wait_handle_get_handle (MonoWaitHandle *handle)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClassField *f_os_handle;
static MonoClassField *f_safe_handle;
static MonoObject*
mono_runtime_capture_context (MonoDomain *domain)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
RuntimeInvokeFunction runtime_invoke;
if (!domain->capture_context_runtime_invoke || !domain->capture_context_method) {
MonoAsyncResult *
mono_async_result_new (MonoDomain *domain, HANDLE handle, MonoObject *state, gpointer data, MonoObject *object_data)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoAsyncResult *res = (MonoAsyncResult *)mono_object_new (domain, mono_defaults.asyncresult_class);
MonoObject *context = mono_runtime_capture_context (domain);
/* we must capture the execution context from the original thread */
}
MonoObject *
-mono_async_result_invoke (MonoAsyncResult *ares, MonoObject **exc)
+ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *ares)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoAsyncCall *ac;
MonoObject *res;
- MonoInternalThread *thread;
g_assert (ares);
g_assert (ares->async_delegate);
- thread = mono_thread_internal_current ();
-
ac = (MonoAsyncCall*) ares->object_data;
if (!ac) {
- res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, exc);
+ res = mono_runtime_delegate_invoke (ares->async_delegate, (void**) &ares->async_state, NULL);
} else {
- MonoArray *out_args = NULL;
gpointer wait_event = NULL;
ac->msg->exc = NULL;
- res = mono_message_invoke (ares->async_delegate, ac->msg, exc, &out_args);
- MONO_OBJECT_SETREF (ac->msg, exc, *exc);
+ res = mono_message_invoke (ares->async_delegate, ac->msg, &ac->msg->exc, &ac->out_args);
MONO_OBJECT_SETREF (ac, res, res);
- MONO_OBJECT_SETREF (ac, out_args, out_args);
mono_monitor_enter ((MonoObject*) ares);
ares->completed = 1;
if (wait_event != NULL)
SetEvent (wait_event);
- if (!ac->cb_method) {
- *exc = NULL;
- } else {
- mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, exc);
+ if (ac->cb_method) {
+ /* we swallow the excepton as it is the behavior on .NET */
+ MonoObject *exc = NULL;
+ mono_runtime_invoke (ac->cb_method, ac->cb_target, (gpointer*) &ares, &exc);
+ if (exc)
+ mono_unhandled_exception (exc);
}
}
return res;
}
-MonoObject *
-ves_icall_System_Runtime_Remoting_Messaging_AsyncResult_Invoke (MonoAsyncResult *this_obj)
-{
- MonoObject *exc = NULL;
- MonoObject *res = mono_async_result_invoke (this_obj, &exc);
- if (exc)
- mono_raise_exception ((MonoException*) exc);
- return res;
-}
-
void
mono_message_init (MonoDomain *domain,
MonoMethodMessage *this_obj,
MonoReflectionMethod *method,
MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClass *object_array_klass;
static MonoClass *byte_array_klass;
static MonoClass *string_array_klass;
mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
MonoObject **exc, MonoArray **out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
gpointer pa [4];
mono_message_invoke (MonoObject *target, MonoMethodMessage *msg,
MonoObject **exc, MonoArray **out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoClass *object_array_klass;
MonoDomain *domain;
MonoMethod *method;
object_array_klass = klass;
}
- /* FIXME: GC ensure we insert a write barrier for out_args, maybe in the caller? */
- *out_args = mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count);
+ mono_gc_wbarrier_generic_store (out_args, (MonoObject*) mono_array_new_specific (mono_class_vtable (domain, object_array_klass), outarg_count));
*exc = NULL;
ret = mono_runtime_invoke_array (method, method->klass->valuetype? mono_object_unbox (target): target, msg->args, exc);
MonoString *
mono_object_to_string (MonoObject *obj, MonoObject **exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *to_string = NULL;
MonoMethod *method;
void *target = obj;
void
mono_print_unhandled_exception (MonoObject *exc)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoString * str;
char *message = (char*)"";
gboolean free_message = FALSE;
void
mono_delegate_ctor_with_method (MonoObject *this_obj, MonoObject *target, gpointer addr, MonoMethod *method)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDelegate *delegate = (MonoDelegate *)this_obj;
g_assert (this_obj);
void
mono_delegate_ctor (MonoObject *this_obj, MonoObject *target, gpointer addr)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoJitInfo *ji;
MonoMethod *method = NULL;
mono_method_call_message_new (MonoMethod *method, gpointer *params, MonoMethod *invoke,
MonoDelegate **cb, MonoObject **state)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDomain *domain = mono_domain_get ();
MonoMethodSignature *sig = mono_method_signature (method);
MonoMethodMessage *msg;
void
mono_method_return_message_restore (MonoMethod *method, gpointer *params, MonoArray *out_args)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoMethodSignature *sig = mono_method_signature (method);
int i, j, type, size, out_len;
gpointer
mono_load_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer *res)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
MonoObject *
mono_load_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *getter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
void
mono_store_remote_field (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, gpointer val)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
void
mono_store_remote_field_new (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, MonoObject *arg)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
static MonoMethod *setter = NULL;
MonoDomain *domain = mono_domain_get ();
MonoTransparentProxy *tp = (MonoTransparentProxy *) this_obj;
gunichar2 *
mono_string_chars (MonoString *s)
{
+ // MONO_REQ_GC_UNSAFE_MODE; //FIXME too much trouble for now
+
return s->chars;
}
int
mono_string_length (MonoString *s)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return s->length;
}
uintptr_t
mono_array_length (MonoArray *array)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return array->max_length;
}
char*
mono_array_addr_with_size (MonoArray *array, int size, uintptr_t idx)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
return ((char*)(array)->vector) + size * idx;
}
typedef void (*MonoMainThreadFunc) (void* user_data);
#define MONO_OBJECT_SETREF(obj,fieldname,value) do { \
+ g_assert (sizeof((obj)->fieldname) == sizeof (gpointer*)); \
mono_gc_wbarrier_set_field ((MonoObject*)(obj), &((obj)->fieldname), (MonoObject*)value); \
/*(obj)->fieldname = (value);*/ \
} while (0)
} else {
process_info->process_handle = shellex.hProcess;
process_info->thread_handle = NULL;
- /* It appears that there's no way to get the pid from a
- * process handle before windows xp. Really.
- */
-#if defined(HAVE_GETPROCESSID) && !defined(MONO_CROSS_COMPILE)
+#if !defined(MONO_CROSS_COMPILE)
process_info->pid = GetProcessId (shellex.hProcess);
#else
process_info->pid = 0;
{
guint32 ret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if(ms<0) {
/* Wait forever */
ret=WaitForSingleObjectEx (process, INFINITE, TRUE);
} else {
ret=WaitForSingleObjectEx (process, ms, TRUE);
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==WAIT_OBJECT_0) {
return(TRUE);
#include <mono/metadata/mono-ptr-array.h>
#include <mono/utils/mono-string.h>
#include <mono/utils/mono-error-internals.h>
+#include <mono/utils/checked-build.h>
static gboolean is_usertype (MonoReflectionType *ref);
static MonoReflectionType *mono_reflection_type_resolve_user_types (MonoReflectionType *type);
static inline void
dynamic_image_lock (MonoDynamicImage *image)
{
+ MONO_TRY_BLOCKING;
mono_image_lock ((MonoImage*)image);
+ MONO_FINISH_TRY_BLOCKING;
}
static inline void
static void
register_dyn_token (MonoDynamicImage *assembly, guint32 token, MonoObject *obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
dynamic_image_lock (assembly);
mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), obj);
dynamic_image_unlock (assembly);
static MonoObject*
lookup_dyn_token (MonoDynamicImage *assembly, guint32 token)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoObject *obj;
dynamic_image_lock (assembly);
static void
sigbuffer_init (SigBuffer *buf, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
buf->buf = g_malloc (size);
buf->p = buf->buf;
buf->end = buf->buf + size;
static void
sigbuffer_make_room (SigBuffer *buf, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (buf->end - buf->p < size) {
int new_size = buf->end - buf->buf + size + 32;
char *p = g_realloc (buf->buf, new_size);
static void
sigbuffer_add_value (SigBuffer *buf, guint32 val)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
sigbuffer_make_room (buf, 6);
mono_metadata_encode_value (val, buf->p, &buf->p);
}
static void
sigbuffer_add_byte (SigBuffer *buf, guint8 val)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
sigbuffer_make_room (buf, 1);
buf->p [0] = val;
buf->p++;
static void
sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
sigbuffer_make_room (buf, size);
memcpy (buf->p, p, size);
buf->p += size;
static void
sigbuffer_free (SigBuffer *buf)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
g_free (buf->buf);
}
static gpointer
image_g_malloc (MonoImage *image, guint size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (image)
return mono_image_alloc (image, size);
else
static gpointer
image_g_malloc0 (MonoImage *image, guint size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (image)
return mono_image_alloc0 (image, size);
else
static char*
image_strdup (MonoImage *image, const char *s)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (image)
return mono_image_strdup (image, s);
else
static void
alloc_table (MonoDynamicTable *table, guint nrows)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
table->rows = nrows;
g_assert (table->columns);
if (nrows + 1 >= table->alloc_rows) {
static void
make_room_in_stream (MonoDynamicStream *stream, int size)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (size <= stream->alloc_size)
return;
static guint32
string_heap_insert (MonoDynamicStream *sh, const char *str)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 idx;
guint32 len;
gpointer oldkey, oldval;
static guint32
string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *name = mono_string_to_utf8 (str);
guint32 idx;
idx = string_heap_insert (sh, name);
static void
string_heap_init (MonoDynamicStream *sh)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
sh->index = 0;
sh->alloc_size = 4096;
sh->data = g_malloc (4096);
static guint32
mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 idx;
make_room_in_stream (stream, stream->index + len);
static guint32
mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 idx;
make_room_in_stream (stream, stream->index + len);
static void
stream_data_align (MonoDynamicStream *stream)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
char buf [4] = {0};
guint32 count = stream->index % 4;
static int
mono_blob_entry_hash (const char* str)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint len, h;
const char *end;
len = mono_metadata_decode_blob_size (str, &str);
static gboolean
mono_blob_entry_equal (const char *str1, const char *str2) {
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int len, len2;
const char *end1;
const char *end2;
static guint32
add_to_blob_cached (MonoDynamicImage *assembly, char *b1, int s1, char *b2, int s2)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 idx;
char *copy;
gpointer oldkey, oldval;
static guint32
sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
char blob_size [8];
char *b = blob_size;
guint32 size = buf->p - buf->buf;
*/
static void
swap_with_size (char *dest, const char* val, int len, int nelem) {
+ MONO_REQ_GC_NEUTRAL_MODE;
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
int elem;
static guint32
add_mono_string_to_blob_cached (MonoDynamicImage *assembly, MonoString *str)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char blob_size [64];
char *b = blob_size;
guint32 idx = 0, len;
static MonoClass *
default_class_from_mono_type (MonoType *type)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
switch (type->type) {
case MONO_TYPE_OBJECT:
return mono_defaults.object_class;
gpointer
mono_class_get_ref_info (MonoClass *klass)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (klass->ref_info_handle == 0)
return NULL;
else
void
mono_class_set_ref_info (MonoClass *klass, gpointer obj)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
klass->ref_info_handle = mono_gchandle_new ((MonoObject*)obj, FALSE);
g_assert (klass->ref_info_handle != 0);
}
void
mono_class_free_ref_info (MonoClass *klass)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (klass->ref_info_handle) {
mono_gchandle_free (klass->ref_info_handle);
klass->ref_info_handle = 0;
static void
encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
MonoGenericInst *class_inst;
MonoClass *klass;
static void
encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (!type) {
g_assert_not_reached ();
return;
static void
encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
if (!type) {
sigbuffer_add_value (buf, MONO_TYPE_VOID);
return;
static void
encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int i;
if (modreq) {
static guint32
method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
SigBuffer buf;
int i;
guint32 nparams = sig->param_count;
static guint32
method_builder_encode_signature (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/*
* FIXME: reuse code from method_encode_signature().
*/
static guint32
encode_locals (MonoDynamicImage *assembly, MonoReflectionILGen *ilgen)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint32 idx, sig_idx;
static guint32
method_count_clauses (MonoReflectionILGen *ilgen)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
guint32 num_clauses = 0;
int i;
static MonoExceptionClause*
method_encode_clauses (MonoImage *image, MonoDynamicImage *assembly, MonoReflectionILGen *ilgen, guint32 num_clauses)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoExceptionClause *clauses;
MonoExceptionClause *clause;
MonoILExceptionInfo *ex_info;
static guint32
method_encode_code (MonoDynamicImage *assembly, ReflectionMethodBuilder *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char flags = 0;
guint32 idx;
guint32 code_size;
static guint32
find_index_in_table (MonoDynamicImage *assembly, int table_idx, int col, guint32 token)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
int i;
MonoDynamicTable *table;
guint32 *values;
static MonoCustomAttrInfo*
lookup_custom_attr (MonoImage *image, gpointer member)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoCustomAttrInfo* res;
res = mono_image_property_lookup (image, member, MONO_PROP_DYNAMIC_CATTR);
static gboolean
custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
/* FIXME: Need to do more checks */
if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
static MonoCustomAttrInfo*
mono_custom_attrs_from_builders (MonoImage *alloc_img, MonoImage *image, MonoArray *cattrs)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
int i, index, count, not_visible;
MonoCustomAttrInfo *ainfo;
MonoReflectionCustomAttr *cattr;
static void
mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoCustomAttrInfo *ainfo, *tmp;
if (!cattrs || !mono_array_length (cattrs))
void
mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
if (!ainfo->cached)
g_free (ainfo);
}
static void
mono_image_add_cattrs (MonoDynamicImage *assembly, guint32 idx, guint32 type, MonoArray *cattrs)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
MonoReflectionCustomAttr *cattr;
guint32 *values;
static void
mono_image_add_decl_security (MonoDynamicImage *assembly, guint32 parent_token, MonoArray *permissions)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint32 count, i, idx;
static void
mono_image_basic_method (ReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint i, count;
static void
reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
static void
reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
static void
reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
static void
mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
MonoDynamicTable *table;
guint32 *values;
static void
mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
ReflectionMethodBuilder rmb;
static void
mono_image_get_ctor_info (MonoDomain *domain, MonoReflectionCtorBuilder *mb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
ReflectionMethodBuilder rmb;
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
static char*
type_get_fully_qualified_name (MonoType *type)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
}
static char*
-type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
+type_get_qualified_name (MonoType *type, MonoAssembly *ass)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoClass *klass;
MonoAssembly *ta;
static guint32
fieldref_encode_signature (MonoDynamicImage *assembly, MonoImage *field_image, MonoType *type)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
SigBuffer buf;
guint32 idx, i, token;
static guint32
field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
SigBuffer buf;
guint32 idx;
guint32 typespec = 0;
}
static guint32
-encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type) {
+encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char blob_size [64];
char *b = blob_size;
char *box_val;
}
static guint32
-encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
+encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
char *str;
SigBuffer buf;
guint32 idx, len;
static void
mono_image_get_field_info (MonoReflectionFieldBuilder *fb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
static guint32
property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
SigBuffer buf;
guint32 nparams = 0;
MonoReflectionMethodBuilder *mb = fb->get_method;
static void
mono_image_get_property_info (MonoReflectionPropertyBuilder *pb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint num_methods = 0;
static void
mono_image_get_event_info (MonoReflectionEventBuilder *eb, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint num_methods = 0;
static void
encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 num_constraints, i;
guint32 *values;
static void
mono_image_get_generic_param_info (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
GenericParamTableEntry *entry;
/*
static void
write_generic_param_entry (MonoDynamicImage *assembly, GenericParamTableEntry *entry)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
MonoGenericParam *param;
guint32 *values;
static guint32
resolution_scope_from_image (MonoDynamicImage *assembly, MonoImage *image)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 token;
guint32 *values;
static guint32
create_typespec (MonoDynamicImage *assembly, MonoType *type)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint32 token;
static guint32
mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint32 token, scope, enclosing;
static guint32
mono_image_add_memberef_row (MonoDynamicImage *assembly, guint32 parent, const char *name, guint32 sig)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
MonoDynamicTable *table;
guint32 *values;
guint32 token, pclass;
static guint32
mono_image_get_memberref_token (MonoDynamicImage *assembly, MonoType *type, const char *name, guint32 sig)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 parent = mono_image_typedef_or_ref (assembly, type);
return mono_image_add_memberef_row (assembly, parent, name, sig);
}
static guint32
mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method, gboolean create_typespec)
{
+ MONO_REQ_GC_NEUTRAL_MODE;
+
guint32 token;
MonoMethodSignature *sig;
free_dynamic_method (void *dynamic_method)
{
DynamicMethodReleaseData *data = dynamic_method;
+ MonoDomain *domain = data->domain;
+ MonoMethod *method = data->handle;
+ gpointer *dis_link;
+
+ mono_domain_lock (domain);
+ dis_link = g_hash_table_lookup (domain->method_to_dyn_method, method);
+ g_hash_table_remove (domain->method_to_dyn_method, method);
+ mono_domain_unlock (domain);
+ g_assert (dis_link);
+ mono_gc_weak_link_remove (dis_link, TRUE);
+ g_free (dis_link);
- mono_runtime_free_method (data->domain, data->handle);
+ mono_runtime_free_method (domain, method);
g_free (data);
}
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
MonoClass *klass;
+ MonoDomain *domain;
GSList *l;
+ void *dis_link;
int i;
if (mono_runtime_is_shutting_down ())
/* ilgen is no longer needed */
mb->ilgen = NULL;
+
+ domain = mono_domain_get ();
+ mono_domain_lock (domain);
+ if (!domain->method_to_dyn_method)
+ domain->method_to_dyn_method = g_hash_table_new (NULL, NULL);
+ dis_link = g_new0 (gpointer, 1);
+ mono_gc_weak_link_add (dis_link, (MonoObject*)mb, TRUE);
+ g_hash_table_insert (domain->method_to_dyn_method, handle, dis_link);
+ mono_domain_unlock (domain);
}
#endif /* DISABLE_REFLECTION_EMIT */
--- /dev/null
+/*
+ * sgen-os-coop.c: SGen Cooperative backend support.
+ *
+ * Author:
+ * João Matos (joao.matos@xamarin.com)
+ * Copyright (C) 2015 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+#ifdef HAVE_SGEN_GC
+
+
+#include <glib.h>
+#include "sgen/sgen-gc.h"
+#include "sgen/sgen-archdep.h"
+#include "sgen/sgen-protocol.h"
+#include "metadata/object-internals.h"
+#include "metadata/gc-internal.h"
+
+
+#if defined(USE_COOP_GC)
+
+gboolean
+sgen_resume_thread (SgenThreadInfo *info)
+{
+ g_error ("FIXME");
+ return FALSE;
+}
+
+gboolean
+sgen_suspend_thread (SgenThreadInfo *info)
+{
+ g_error ("FIXME");
+ return FALSE;
+}
+
+void
+sgen_wait_for_suspend_ack (int count)
+{
+}
+
+/* LOCKING: assumes the GC lock is held */
+int
+sgen_thread_handshake (BOOL suspend)
+{
+ g_error ("FIXME");
+ return 0;
+}
+
+void
+sgen_os_init (void)
+{
+}
+
+int
+mono_gc_get_suspend_signal (void)
+{
+ return -1;
+}
+
+int
+mono_gc_get_restart_signal (void)
+{
+ return -1;
+}
+
+#endif
+#endif
\ No newline at end of file
} END_FOREACH_THREAD_SAFE
return count;
}
-#endif
void
sgen_os_init (void)
}
#endif
#endif
+#endif
#include "config.h"
-#ifdef HAVE_SGEN_GC
+#if defined(HAVE_SGEN_GC) && !defined(USE_COOP_GC)
#if !defined(__MACH__) && !MONO_MACH_ARCH_SUPPORTED && defined(HAVE_PTHREAD_KILL)
#include <errno.h>
#ifdef USE_MONO_CTX
memset (&info->client_info.ctx, 0, sizeof (MonoContext));
#ifdef TARGET_AMD64
- info->client_info.ctx.rip = context.Rip;
- info->client_info.ctx.rax = context.Rax;
- info->client_info.ctx.rcx = context.Rcx;
- info->client_info.ctx.rdx = context.Rdx;
- info->client_info.ctx.rbx = context.Rbx;
- info->client_info.ctx.rsp = context.Rsp;
- info->client_info.ctx.rbp = context.Rbp;
- info->client_info.ctx.rsi = context.Rsi;
- info->client_info.ctx.rdi = context.Rdi;
- info->client_info.ctx.r8 = context.R8;
- info->client_info.ctx.r9 = context.R9;
- info->client_info.ctx.r10 = context.R10;
- info->client_info.ctx.r11 = context.R11;
- info->client_info.ctx.r12 = context.R12;
- info->client_info.ctx.r13 = context.R13;
- info->client_info.ctx.r14 = context.R14;
- info->client_info.ctx.r15 = context.R15;
- info->client_info.stopped_ip = info->client_info.ctx.rip;
- info->client_info.stack_start = (char*)info->client_info.ctx.rsp - REDZONE_SIZE;
+ info->client_info.ctx.gregs[AMD64_RIP] = context.Rip;
+ info->client_info.ctx.gregs[AMD64_RAX] = context.Rax;
+ info->client_info.ctx.gregs[AMD64_RCX] = context.Rcx;
+ info->client_info.ctx.gregs[AMD64_RDX] = context.Rdx;
+ info->client_info.ctx.gregs[AMD64_RBX] = context.Rbx;
+ info->client_info.ctx.gregs[AMD64_RSP] = context.Rsp;
+ info->client_info.ctx.gregs[AMD64_RBP] = context.Rbp;
+ info->client_info.ctx.gregs[AMD64_RSI] = context.Rsi;
+ info->client_info.ctx.gregs[AMD64_RDI] = context.Rdi;
+ info->client_info.ctx.gregs[AMD64_R8] = context.R8;
+ info->client_info.ctx.gregs[AMD64_R9] = context.R9;
+ info->client_info.ctx.gregs[AMD64_R10] = context.R10;
+ info->client_info.ctx.gregs[AMD64_R11] = context.R11;
+ info->client_info.ctx.gregs[AMD64_R12] = context.R12;
+ info->client_info.ctx.gregs[AMD64_R13] = context.R13;
+ info->client_info.ctx.gregs[AMD64_R14] = context.R14;
+ info->client_info.ctx.gregs[AMD64_R15] = context.R15;
+ info->client_info.stopped_ip = info->client_info.ctx.gregs[AMD64_RIP];
+ info->client_info.stack_start = (char*)info->client_info.ctx.gregs[AMD64_RSP] - REDZONE_SIZE;
#else
info->client_info.ctx.edi = context.Edi;
info->client_info.ctx.esi = context.Esi;
{
SOCKET newsock;
MonoInternalThread* curthread G_GNUC_UNUSED = mono_thread_internal_current ();
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error = 0;
#ifdef HOST_WIN32
#else
newsock = _wapi_accept (sock, NULL, 0);
#endif
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(newsock==INVALID_SOCKET) {
*error = WSAGetLastError ();
return NULL;
}
sa = (salen <= 128) ? alloca (salen) : g_malloc0 (salen);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_getsockname (sock, (struct sockaddr *)sa, &salen);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
}
sa = (salen <= 128) ? alloca (salen) : g_malloc0 (salen);
/* Note: linux returns just 2 for AF_UNIX. Always. */
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_getpeername (sock, (struct sockaddr *)sa, &salen);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
if (salen > 128)
LOGDEBUG (g_message("%s: connecting to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_connect (sock, sa, sa_size);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
LPFN_DISCONNECTEX _wapi_disconnectex = NULL;
LPFN_TRANSMITFILE _wapi_transmitfile = NULL;
gboolean bret;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
*error = 0;
*error = WSAGetLastError ();
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
gint32 ves_icall_System_Net_Sockets_Socket_Receive_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error)
return (0);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
#ifdef HOST_WIN32
{
curthread->interrupt_on_stop = (gpointer)TRUE;
#else
ret = _wapi_recv (sock, buf, count, recvflags);
#endif
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
return (0);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_recvfrom (sock, buf, count, recvflags, sa, &sa_size);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
g_free(sa);
return (0);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_send (sock, buf, count, sendflags);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
return(0);
return (0);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = _wapi_sendto (sock, buf, count, sendflags, sa, sa_size);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
}
gint32 *error)
{
int ret;
- MONO_PREPARE_BLOCKING
*error = 0;
/* Currently, the values for how (recv=0, send=1, both=2) match
* the BSD API
*/
+ MONO_PREPARE_BLOCKING;
ret = _wapi_shutdown (sock, how);
+ MONO_FINISH_BLOCKING;
if(ret==SOCKET_ERROR) {
*error = WSAGetLastError ();
}
-
- MONO_FINISH_BLOCKING
}
gint
char *hostname = mono_string_to_utf8 (host);
int hint = get_addrinfo_family_hint ();
- MONO_PREPARE_BLOCKING
-
if (*hostname == '\0') {
add_local_ips = TRUE;
*h_name = host;
}
+ MONO_PREPARE_BLOCKING;
if (!add_local_ips && gethostname (this_hostname, sizeof (this_hostname)) != -1) {
if (!strcmp (hostname, this_hostname)) {
add_local_ips = TRUE;
add_info_ok = FALSE;
g_free(hostname);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (add_info_ok)
return addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips);
int hint = get_addrinfo_family_hint ();
gboolean add_info_ok;
- MONO_PREPARE_BLOCKING
-
address = mono_string_to_utf8 (addr);
if (inet_pton (AF_INET, address, &saddr.sin_addr ) <= 0) {
}
g_free(address);
+ MONO_PREPARE_BLOCKING;
+
if(family == AF_INET) {
#if HAVE_SOCKADDR_IN_SIN_LEN
saddr.sin_len = sizeof (saddr);
}
add_info_ok = !mono_get_address_info (hostname, 0, hint | MONO_HINT_CANONICAL_NAME | MONO_HINT_CONFIGURED_ONLY, &info);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (add_info_ok)
return addrinfo_to_IPHostEntry (info, h_name, h_aliases, h_addr_list, FALSE);
*
* Author:
* Mono Project (http://www.mono-project.com)
+ * Ludovic Henry (ludovic@xamarin.com)
*
* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2009 Novell, Inc (http://www.novell.com)
+ * Copyright 2015 Xamarin, Inc (https://www.xamarin.com)
*/
+
+//
+// Copyright (c) Microsoft. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+//
+// Files:
+// - src/classlibnative/float/floatnative.cpp
+// - src/pal/src/cruntime/floatnative.cpp
+//
+// Ported from C++ to C and adjusted to Mono runtime
+
#define __USE_ISOC99
+
#include <math.h>
#include <mono/metadata/sysmath.h>
-#include <mono/metadata/exception.h>
-
-#ifndef NAN
-# if G_BYTE_ORDER == G_BIG_ENDIAN
-# define __nan_bytes { 0x7f, 0xc0, 0, 0 }
-# endif
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# define __nan_bytes { 0, 0, 0xc0, 0x7f }
-# endif
-
-static union { unsigned char __c[4]; float __d; } __nan_union = { __nan_bytes };
-# define NAN (__nan_union.__d)
-#endif
-
-#ifndef HUGE_VAL
-#define __huge_val_t union { unsigned char __c[8]; double __d; }
-# if G_BYTE_ORDER == G_BIG_ENDIAN
-# define __HUGE_VAL_bytes { 0x7f, 0xf0, 0, 0, 0, 0, 0, 0 }
-# endif
-# if G_BYTE_ORDER == G_LITTLE_ENDIAN
-# define __HUGE_VAL_bytes { 0, 0, 0, 0, 0, 0, 0xf0, 0x7f }
-# endif
-static __huge_val_t __huge_val = { __HUGE_VAL_bytes };
-# define HUGE_VAL (__huge_val.__d)
-#endif
-
-
-gdouble ves_icall_System_Math_Floor (gdouble x) {
+
+#include "number-ms.h"
+#include "utils/mono-compiler.h"
+
+static const MonoDouble_double NaN = { .s = { .sign = 0x0, .exp = 0x7FF, .mantHi = 0x80000, .mantLo = 0x0 } };
+
+/* +Infinity */
+static const MonoDouble_double PInfinity = { .s = { .sign = 0x0, .exp = 0x7FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* -Infinity */
+static const MonoDouble_double MInfinity = { .s = { .sign = 0x1, .exp = 0x7FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* +1 */
+static const MonoDouble_double POne = { .s = { .sign = 0x0, .exp = 0x3FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+/* -1 */
+static const MonoDouble_double MOne = { .s = { .sign = 0x1, .exp = 0x3FF, .mantHi = 0x0, .mantLo = 0x0 } };
+
+static MONO_ALWAYS_INLINE gboolean
+isplusinfinity (gdouble d)
+{
+ return d == PInfinity.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isminusinfinity (gdouble d)
+{
+ return d == MInfinity.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isinfinity (gdouble d)
+{
+ return isplusinfinity (d) || isminusinfinity (d);
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isplusone (gdouble d)
+{
+ return d == POne.d;
+}
+
+static MONO_ALWAYS_INLINE gboolean
+isminusone (gdouble d)
+{
+ return d == MOne.d;
+}
+
+gdouble
+ves_icall_System_Math_Floor (gdouble x)
+{
return floor(x);
}
-gdouble ves_icall_System_Math_Round (gdouble x) {
- double int_part, dec_part;
+gdouble
+ves_icall_System_Math_Round (gdouble x)
+{
+ gdouble tmp, floor_tmp;
- int_part = floor(x);
- dec_part = x - int_part;
- if (((dec_part == 0.5) &&
- ((2.0 * ((int_part / 2.0) - floor(int_part / 2.0))) != 0.0)) ||
- (dec_part > 0.5)) {
- int_part++;
+ /* If the number has no fractional part do nothing This shortcut is necessary
+ * to workaround precision loss in borderline cases on some platforms */
+ if (x == (gdouble)(gint64) x)
+ return x;
+
+ tmp = x + 0.5;
+ floor_tmp = floor (tmp);
+
+ if (floor_tmp == tmp) {
+ if (fmod (tmp, 2.0) != 0)
+ floor_tmp -= 1.0;
}
- return int_part;
-}
-
-gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits, gboolean away_from_zero) {
-#if !defined (HAVE_ROUND) || !defined (HAVE_RINT)
- double int_part, dec_part;
-#endif
- double p;
-
- if (value == HUGE_VAL)
- return HUGE_VAL;
- if (value == -HUGE_VAL)
- return -HUGE_VAL;
- p = pow(10, digits);
-#if defined (HAVE_ROUND) && defined (HAVE_RINT)
- if (away_from_zero)
- return round (value * p) / p;
- else
- return rint (value * p) / p;
-#else
- dec_part = modf (value, &int_part);
- dec_part *= 1000000000000000ULL;
- if (away_from_zero && dec_part > 0)
- dec_part = ceil (dec_part);
- else
- dec_part = floor (dec_part);
- dec_part /= (1000000000000000ULL / p);
- if (away_from_zero) {
- if (dec_part > 0)
- dec_part = floor (dec_part + 0.5);
- else
- dec_part = ceil (dec_part - 0.5);
- } else
- dec_part = ves_icall_System_Math_Round (dec_part);
- dec_part /= p;
- return ves_icall_System_Math_Round ((int_part + dec_part) * p) / p;
-#endif
+
+ return copysign (floor_tmp, x);
}
gdouble
ves_icall_System_Math_Acos (gdouble x)
{
if (x < -1 || x > 1)
- return NAN;
+ return NaN.d;
return acos (x);
}
ves_icall_System_Math_Asin (gdouble x)
{
if (x < -1 || x > 1)
- return NAN;
+ return NaN.d;
return asin (x);
}
gdouble
ves_icall_System_Math_Atan2 (gdouble y, gdouble x)
{
- double result;
+ gdouble result;
+
+ if (isinfinity (x) && isinfinity (y))
+ return NaN.d;
- if ((y == HUGE_VAL && x == HUGE_VAL) ||
- (y == HUGE_VAL && x == -HUGE_VAL) ||
- (y == -HUGE_VAL && x == HUGE_VAL) ||
- (y == -HUGE_VAL && x == -HUGE_VAL)) {
- return NAN;
- }
result = atan2 (y, x);
- return (result == -0)? 0: result;
+ return result == -0.0 ? 0.0: result;
}
gdouble
ves_icall_System_Math_Exp (gdouble x)
{
+ if (isinfinity (x))
+ return x < 0 ? 0.0 : x;
+
return exp (x);
}
ves_icall_System_Math_Log (gdouble x)
{
if (x == 0)
- return -HUGE_VAL;
+ return MInfinity.d;
else if (x < 0)
- return NAN;
+ return NaN.d;
return log (x);
}
ves_icall_System_Math_Log10 (gdouble x)
{
if (x == 0)
- return -HUGE_VAL;
+ return MInfinity.d;
else if (x < 0)
- return NAN;
+ return NaN.d;
return log10 (x);
}
gdouble
ves_icall_System_Math_Pow (gdouble x, gdouble y)
{
- double result;
-
- if (isnan(x) || isnan(y)) {
- return NAN;
- }
-
- if ((x == 1 || x == -1) && (y == HUGE_VAL || y == -HUGE_VAL)) {
- return NAN;
+ gdouble result;
+
+ if (isnan (y))
+ return y;
+ if (isnan (x))
+ return x;
+
+ if (isinfinity (y)) {
+ if (isplusone (x))
+ return x;
+ if (isminusone (x))
+ return NaN.d;
}
- /* This code is for return the same results as MS.NET for certain
- * limit values */
- if (x < -9007199254740991.0) {
- if (y > 9007199254740991.0)
- return HUGE_VAL;
- if (y < -9007199254740991.0)
- return 0;
- }
-
- result = pow (x, y);
+ /* following are cases from PAL_pow which abstract the implementation of pow for posix and win32 platforms
+ * (https://github.com/dotnet/coreclr/blob/master/src/pal/src/cruntime/finite.cpp#L331) */
- /* This code is for return the same results as MS.NET for certain
- * limit values */
- if (isnan(result) &&
- (x == -1.0) &&
- ((y > 9007199254740991.0) || (y < -9007199254740991.0))) {
- return 1;
+ if (isplusinfinity (y) && !isnan (x)) {
+ if (isplusone (x) || isminusone (x))
+ result = NaN.d;
+ else if (x > MOne.d && x < POne.d)
+ result = 0.0;
+ else
+ result = PInfinity.d;
+ } else if (isminusinfinity (y) && !isnan (x)) {
+ if (isplusone (x) || isminusone (x))
+ result = NaN.d;
+ if (x > MOne.d && x < POne.d)
+ result = PInfinity.d;
+ else
+ result = 0.0;
+ } else if (x == 0.0 && y < 0.0) {
+ result = PInfinity.d;
+ } else if (y == 0.0 && isnan (x)) {
+ /* Windows returns NaN for pow(NaN, 0), but POSIX specifies
+ * a return value of 1 for that case. We need to return
+ * the same result as Windows. */
+ result = NaN.d;
+ } else {
+ result = pow (x, y);
}
- return (result == -0)? 0: result;
+ if (result == PInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) != floor (y / 2))
+ result = MInfinity.d;
+
+ /*
+ * The even/odd test in the if (this one and the one above) used to be ((long long) y % 2 == 0)
+ * on SPARC (long long) y for large y (>2**63) is always 0x7fffffff7fffffff, which
+ * is an odd number, so the test ((long long) y % 2 == 0) will always fail for
+ * large y. Since large double numbers are always even (e.g., the representation of
+ * 1E20+1 is the same as that of 1E20, the last .+1. is too insignificant to be part
+ * of the representation), this test will always return the wrong result for large y.
+ *
+ * The (ceil(y/2) == floor(y/2)) test is slower, but more robust.
+ */
+ if (result == MInfinity.d && x < 0.0 && isfinite (x) && ceil (y / 2) == floor (y / 2))
+ result = PInfinity.d;
+
+ return result == -0.0 ? 0 : result;
}
gdouble
ves_icall_System_Math_Sqrt (gdouble x)
{
if (x < 0)
- return NAN;
+ return NaN.d;
return sqrt (x);
}
+
+gdouble
+ves_icall_System_Math_Abs_double (gdouble v)
+{
+ return fabs (v);
+}
+
+gfloat
+ves_icall_System_Math_Abs_single (gfloat v)
+{
+ return fabsf (v);
+}
+
+gdouble
+ves_icall_System_Math_Ceiling (gdouble v)
+{
+ return ceil (v);
+}
+
+gdouble
+ves_icall_System_Math_SplitFractionDouble (gdouble *v)
+{
+ return modf (*v, v);
+}
*
* Author:
* Dan Lewis (dihlewis@yahoo.co.uk)
+ * Ludovic Henry (ludovic@xamarin.com)
*
* (C) Ximian, Inc. 2002
+ * Copyright 2015 Xamarin, Inc (https://www.xamarin.com)
*/
#ifndef __METADATA_SYSMATH_H__
#include <config.h>
#include <glib.h>
-#include "mono/utils/mono-compiler.h"
-extern gdouble ves_icall_System_Math_Floor (gdouble x);
-extern gdouble ves_icall_System_Math_Round (gdouble x);
-extern gdouble ves_icall_System_Math_Round2 (gdouble value, gint32 digits, gboolean away_from_zero);
+gdouble
+ves_icall_System_Math_Floor (gdouble x);
-extern gdouble
+gdouble
+ves_icall_System_Math_Round (gdouble x);
+
+gdouble
ves_icall_System_Math_Sin (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Cos (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Tan (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Sinh (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Cosh (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Tanh (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Acos (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Asin (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Atan (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Atan2 (gdouble y, gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Exp (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Log (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Log10 (gdouble x);
-extern gdouble
+gdouble
ves_icall_System_Math_Pow (gdouble x, gdouble y);
-extern gdouble
+gdouble
ves_icall_System_Math_Sqrt (gdouble x);
+gdouble
+ves_icall_System_Math_Abs_double (gdouble v);
+
+gfloat
+ves_icall_System_Math_Abs_single (gfloat v);
+
+gdouble
+ves_icall_System_Math_SplitFractionDouble (gdouble *v);
+
+gdouble
+ves_icall_System_Math_Ceiling (gdouble v);
+
#endif
static void
epoll_register_fd (gint fd, gint events, gboolean is_new)
{
- if (events == 0) {
- if (!is_new && epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1)
- g_error ("epoll_register_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
- } else {
- struct epoll_event event;
+ struct epoll_event event;
#ifndef EPOLLONESHOT
/* it was only defined on android in May 2013 */
#define EPOLLONESHOT 0x40000000
#endif
- event.data.fd = fd;
- event.events = EPOLLONESHOT;
- if ((events & MONO_POLLIN) != 0)
- event.events |= EPOLLIN;
- if ((events & MONO_POLLOUT) != 0)
- event.events |= EPOLLOUT;
+ event.data.fd = fd;
+ event.events = EPOLLONESHOT;
+ if ((events & EVENT_IN) != 0)
+ event.events |= EPOLLIN;
+ if ((events & EVENT_OUT) != 0)
+ event.events |= EPOLLOUT;
- if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
- g_error ("epoll_register_fd: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
- }
+ if (epoll_ctl (epoll_fd, is_new ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, event.data.fd, &event) == -1)
+ g_error ("epoll_register_fd: epoll_ctl(%s) failed, error (%d) %s", is_new ? "EPOLL_CTL_ADD" : "EPOLL_CTL_MOD", errno, g_strerror (errno));
+}
+
+static void
+epoll_remove_fd (gint fd)
+{
+ if (epoll_ctl (epoll_fd, EPOLL_CTL_DEL, fd, NULL) == -1)
+ g_error ("epoll_remove_fd: epoll_ctl (EPOLL_CTL_DEL) failed, error (%d) %s", errno, g_strerror (errno));
}
static gint
-epoll_event_wait (void)
+epoll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
- gint ready;
+ gint i, ready;
memset (epoll_events, 0, sizeof (struct epoll_event) * EPOLL_NEVENTS);
+ mono_gc_set_skip_thread (TRUE);
+
ready = epoll_wait (epoll_fd, epoll_events, EPOLL_NEVENTS, -1);
+
+ mono_gc_set_skip_thread (FALSE);
+
if (ready == -1) {
switch (errno) {
case EINTR:
}
}
- return ready;
-}
+ if (ready == -1)
+ return -1;
-static gint
-epoll_event_get_fd_max (void)
-{
- return EPOLL_NEVENTS;
-}
+ for (i = 0; i < ready; ++i) {
+ gint fd, events = 0;
-static gint
-epoll_event_get_fd_at (gint i, gint *events)
-{
- g_assert (events);
+ fd = epoll_events [i].data.fd;
+ if (epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
+ events |= EVENT_IN;
+ if (epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
+ events |= EVENT_OUT;
- *events = ((epoll_events [i].events & (EPOLLIN | EPOLLERR | EPOLLHUP)) ? MONO_POLLIN : 0)
- | ((epoll_events [i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP)) ? MONO_POLLOUT : 0);
+ callback (fd, events, user_data);
+ }
- return epoll_events [i].data.fd;
+ return 0;
}
static ThreadPoolIOBackend backend_epoll = {
.init = epoll_init,
.cleanup = epoll_cleanup,
.register_fd = epoll_register_fd,
+ .remove_fd = epoll_remove_fd,
.event_wait = epoll_event_wait,
- .event_get_fd_max = epoll_event_get_fd_max,
- .event_get_fd_at = epoll_event_get_fd_at,
};
#endif
static gint kqueue_fd;
static struct kevent *kqueue_events;
-static gboolean
-kqueue_init (gint wakeup_pipe_fd)
+static gint
+KQUEUE_INIT_FD (gint fd, gint events, gint flags)
{
struct kevent event;
+ EV_SET (&event, fd, events, flags, 0, 0, 0);
+ return kevent (kqueue_fd, &event, 1, NULL, 0, NULL);
+}
+static gboolean
+kqueue_init (gint wakeup_pipe_fd)
+{
kqueue_fd = kqueue ();
if (kqueue_fd == -1) {
- g_warning ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
+ g_error ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
return FALSE;
}
- EV_SET (&event, wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
- if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1) {
- g_warning ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
+ if (KQUEUE_INIT_FD (wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1) {
+ g_error ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
close (kqueue_fd);
return FALSE;
}
static void
kqueue_register_fd (gint fd, gint events, gboolean is_new)
{
- struct kevent event;
-
- if (events == 0)
- return;
-
- if ((events & MONO_POLLIN) != 0)
- EV_SET (&event, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
- if ((events & MONO_POLLOUT) != 0)
- EV_SET (&event, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
+ if (events & EVENT_IN) {
+ if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1)
+ g_error ("kqueue_register_fd: kevent(read,enable) failed, error (%d) %s", errno, g_strerror (errno));
+ } else {
+ if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_DISABLE) == -1)
+ g_error ("kqueue_register_fd: kevent(read,disable) failed, error (%d) %s", errno, g_strerror (errno));
+ }
+ if (events & EVENT_OUT) {
+ if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_ENABLE) == -1)
+ g_error ("kqueue_register_fd: kevent(write,enable) failed, error (%d) %s", errno, g_strerror (errno));
+ } else {
+ if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_DISABLE) == -1)
+ g_error ("kqueue_register_fd: kevent(write,disable) failed, error (%d) %s", errno, g_strerror (errno));
+ }
+}
- if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1)
- g_warning ("kqueue_register_fd: kevent(update) failed, error (%d) %s", errno, g_strerror (errno));
+static void
+kqueue_remove_fd (gint fd)
+{
+ /* FIXME: a race between closing and adding operation in the Socket managed code trigger a ENOENT error */
+ if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_DELETE) == -1)
+ g_error ("kqueue_register_fd: kevent(read,delete) failed, error (%d) %s", errno, g_strerror (errno));
+ if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_DELETE) == -1)
+ g_error ("kqueue_register_fd: kevent(write,delete) failed, error (%d) %s", errno, g_strerror (errno));
}
static gint
-kqueue_event_wait (void)
+kqueue_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
- gint ready;
+ gint i, ready;
+
+ memset (kqueue_events, 0, sizeof (struct kevent) * KQUEUE_NEVENTS);
+
+ mono_gc_set_skip_thread (TRUE);
ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
+
+ mono_gc_set_skip_thread (FALSE);
+
if (ready == -1) {
switch (errno) {
case EINTR:
ready = 0;
break;
default:
- g_warning ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
+ g_error ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
break;
}
}
- return ready;
-}
+ if (ready == -1)
+ return -1;
-static gint
-kqueue_event_get_fd_at (gint i, gint *events)
-{
- g_assert (events);
+ for (i = 0; i < ready; ++i) {
+ gint fd, events = 0;
- *events = ((kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0) ? MONO_POLLIN : 0)
- | ((kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0) ? MONO_POLLOUT : 0);
+ fd = kqueue_events [i].ident;
+ if (kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0)
+ events |= EVENT_IN;
+ if (kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0)
+ events |= EVENT_OUT;
- return kqueue_events [i].ident;
-}
+ callback (fd, events, user_data);
+ }
-static gint
-kqueue_event_get_fd_max (void)
-{
- return KQUEUE_NEVENTS;
+ return 0;
}
static ThreadPoolIOBackend backend_kqueue = {
.init = kqueue_init,
.cleanup = kqueue_cleanup,
.register_fd = kqueue_register_fd,
+ .remove_fd = kqueue_remove_fd,
.event_wait = kqueue_event_wait,
- .event_get_fd_max = kqueue_event_get_fd_max,
- .event_get_fd_at = kqueue_event_get_fd_at,
};
#endif
-#define POLL_NEVENTS 1024
+#if defined(HAVE_POLL)
+
+#if defined(HAVE_POLL_H)
+#include <poll.h>
+#elif defined(HAVE_SYS_POLL_H)
+#include <sys/poll.h>
+#endif
+
+typedef struct pollfd mono_pollfd;
+
+#elif defined(HOST_WIN32)
+
+#include "mswsock.h"
+
+typedef WSAPOLLFD mono_pollfd;
+
+#else
+/* poll is not defined */
+#error
+#endif
static mono_pollfd *poll_fds;
static guint poll_fds_capacity;
static gboolean
poll_init (gint wakeup_pipe_fd)
{
- guint i;
+ gint i;
+
+ poll_fds_size = wakeup_pipe_fd + 1;
+ poll_fds_capacity = 64;
+
+ while (wakeup_pipe_fd >= poll_fds_capacity)
+ poll_fds_capacity *= 4;
- poll_fds_size = 1;
- poll_fds_capacity = POLL_NEVENTS;
poll_fds = g_new0 (mono_pollfd, poll_fds_capacity);
- POLL_INIT_FD (poll_fds, wakeup_pipe_fd, MONO_POLLIN);
- for (i = 1; i < poll_fds_capacity; ++i)
- POLL_INIT_FD (poll_fds + i, -1, 0);
+ for (i = 0; i < wakeup_pipe_fd; ++i)
+ POLL_INIT_FD (&poll_fds [i], -1, 0);
+
+ POLL_INIT_FD (&poll_fds [wakeup_pipe_fd], wakeup_pipe_fd, POLLIN);
return TRUE;
}
g_free (poll_fds);
}
-static inline gint
-poll_mark_bad_fds (mono_pollfd *poll_fds, gint poll_fds_size)
+static void
+poll_register_fd (gint fd, gint events, gboolean is_new)
{
gint i;
- gint ret;
- gint ready = 0;
mono_pollfd *poll_fd;
- for (i = 0; i < poll_fds_size; i++) {
- poll_fd = poll_fds + i;
- if (poll_fd->fd == -1)
- continue;
+ g_assert (fd >= 0);
+ g_assert (poll_fds_size <= poll_fds_capacity);
- ret = mono_poll (poll_fd, 1, 0);
- if (ret == 1)
- ready++;
- if (ret == -1) {
-#if !defined(HOST_WIN32)
- if (errno == EBADF)
-#else
- if (WSAGetLastError () == WSAEBADF)
-#endif
- {
- poll_fd->revents |= MONO_POLLNVAL;
- ready++;
- }
- }
- }
+ if (fd >= poll_fds_capacity) {
+ do {
+ poll_fds_capacity *= 4;
+ } while (fd >= poll_fds_capacity);
- return ready;
-}
+ poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
+ }
-static void
-poll_register_fd (gint fd, gint events, gboolean is_new)
-{
- gboolean found = FALSE;
- gint j, k;
+ if (fd >= poll_fds_size) {
+ for (i = poll_fds_size; i <= fd; ++i)
+ POLL_INIT_FD (&poll_fds [i], -1, 0);
- for (j = 1; j < poll_fds_size; ++j) {
- mono_pollfd *poll_fd = poll_fds + j;
- if (poll_fd->fd == fd) {
- found = TRUE;
- break;
- }
+ poll_fds_size = fd + 1;
}
- if (events == 0) {
- if (found)
- POLL_INIT_FD (poll_fds + j, -1, 0);
- return;
- }
+ poll_fd = &poll_fds [fd];
- if (!found) {
- for (j = 1; j < poll_fds_capacity; ++j) {
- mono_pollfd *poll_fd = poll_fds + j;
- if (poll_fd->fd == -1)
- break;
- }
+ if (poll_fd->fd != -1) {
+ g_assert (poll_fd->fd == fd);
+ g_assert (!is_new);
}
- if (j == poll_fds_capacity) {
- poll_fds_capacity += POLL_NEVENTS;
- poll_fds = g_renew (mono_pollfd, poll_fds, poll_fds_capacity);
- for (k = j; k < poll_fds_capacity; ++k)
- POLL_INIT_FD (poll_fds + k, -1, 0);
- }
+ POLL_INIT_FD (poll_fd, fd, ((events & EVENT_IN) ? POLLIN : 0) | ((events & EVENT_OUT) ? POLLOUT : 0));
+}
+
+static void
+poll_remove_fd (gint fd)
+{
+ mono_pollfd *poll_fd;
- POLL_INIT_FD (poll_fds + j, fd, events);
+ g_assert (fd >= 0);
- if (j >= poll_fds_size)
- poll_fds_size = j + 1;
+ g_assert (fd < poll_fds_size);
+ poll_fd = &poll_fds [fd];
+
+ g_assert (poll_fd->fd == fd);
+ POLL_INIT_FD (poll_fd, -1, 0);
}
static gint
-poll_event_wait (void)
+poll_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
{
- gint ready;
+ gint i, ready;
+
+ for (i = 0; i < poll_fds_size; ++i)
+ poll_fds [i].revents = 0;
+
+ mono_gc_set_skip_thread (TRUE);
+
+#if !defined(HOST_WIN32)
+ ready = poll (poll_fds, poll_fds_size, -1);
+#else
+ ready = WSAPoll(poll_fds, poll_fds_size, -1);
+ if (ready == SOCKET_ERROR)
+ ready = -1;
+#endif
+
+ mono_gc_set_skip_thread (FALSE);
- ready = mono_poll (poll_fds, poll_fds_size, -1);
if (ready == -1) {
/*
* Apart from EINTR, we only check EBADF, for the rest:
* EINVAL: mono_poll() 'protects' us from descriptor
* numbers above the limit if using select() by marking
- * then as MONO_POLLERR. If a system poll() is being
+ * then as POLLERR. If a system poll() is being
* used, the number of descriptor we're passing will not
* be over sysconf(_SC_OPEN_MAX), as the error would have
* happened when opening.
#else
case WSAEINTR:
#endif
+ {
mono_thread_internal_check_for_interruption_critical (mono_thread_internal_current ());
ready = 0;
break;
-#if !defined(HOST_WIN32)
- case EBADF:
-#else
- case WSAEBADF:
-#endif
- ready = poll_mark_bad_fds (poll_fds, poll_fds_size);
- break;
+ }
default:
#if !defined(HOST_WIN32)
- g_warning ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
+ g_error ("poll_event_wait: mono_poll () failed, error (%d) %s", errno, g_strerror (errno));
#else
- g_warning ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
+ g_error ("poll_event_wait: mono_poll () failed, error (%d)\n", WSAGetLastError ());
#endif
break;
}
}
- return ready;
-}
+ if (ready == -1)
+ return -1;
-static gint
-poll_event_get_fd_at (gint i, gint *events)
-{
- g_assert (events);
+ for (i = 0; i < poll_fds_size; ++i) {
+ gint fd, events = 0;
+
+ if (poll_fds [i].fd == -1)
+ continue;
+ if (poll_fds [i].revents == 0)
+ continue;
- *events = ((poll_fds [i].revents & (MONO_POLLIN | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)) ? MONO_POLLIN : 0)
- | ((poll_fds [i].revents & (MONO_POLLOUT | MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)) ? MONO_POLLOUT : 0);
+ fd = poll_fds [i].fd;
+ if (poll_fds [i].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL))
+ events |= EVENT_IN;
+ if (poll_fds [i].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
+ events |= EVENT_OUT;
- /* if nothing happened on the fd, then just return
- * an invalid fd number so it is discarded */
- return poll_fds [i].revents == 0 ? -1 : poll_fds [i].fd;
-}
+ callback (fd, events, user_data);
-static gint
-poll_event_get_fd_max (void)
-{
- return poll_fds_size;
+ if (--ready == 0)
+ break;
+ }
+
+ return 0;
}
static ThreadPoolIOBackend backend_poll = {
.init = poll_init,
.cleanup = poll_cleanup,
.register_fd = poll_register_fd,
+ .remove_fd = poll_remove_fd,
.event_wait = poll_event_wait,
- .event_get_fd_max = poll_event_get_fd_max,
- .event_get_fd_at = poll_event_get_fd_at,
};
#include <mono/metadata/threadpool-ms.h>
#include <mono/metadata/threadpool-ms-io.h>
#include <mono/utils/atomic.h>
-#include <mono/utils/mono-poll.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/mono-lazy-init.h>
+#include <mono/utils/mono-logger-internal.h>
typedef struct {
gboolean (*init) (gint wakeup_pipe_fd);
void (*cleanup) (void);
void (*register_fd) (gint fd, gint events, gboolean is_new);
- gint (*event_wait) (void);
- gint (*event_get_fd_max) (void);
- gint (*event_get_fd_at) (gint i, gint *events);
+ void (*remove_fd) (gint fd);
+ gint (*event_wait) (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data);
} ThreadPoolIOBackend;
+enum {
+ EVENT_IN = 1 << 0,
+ EVENT_OUT = 1 << 1,
+} ThreadPoolIOEvent;
+
#include "threadpool-ms-io-epoll.c"
#include "threadpool-ms-io-kqueue.c"
#include "threadpool-ms-io-poll.c"
+#define UPDATES_CAPACITY 128
+
/* Keep in sync with System.Net.Sockets.Socket.SocketOperation */
enum {
AIO_OP_FIRST,
AIO_OP_LAST
};
+typedef enum {
+ UPDATE_EMPTY = 0,
+ UPDATE_ADD,
+ UPDATE_REMOVE_SOCKET,
+ UPDATE_REMOVE_DOMAIN,
+} ThreadPoolIOUpdateType;
+
typedef struct {
gint fd;
MonoSocketAsyncResult *sockares;
-} ThreadPoolIOUpdate;
+} ThreadPoolIOUpdate_Add;
typedef struct {
- ThreadPoolIOBackend backend;
+ gint fd;
+} ThreadPoolIOUpdate_RemoveSocket;
- mono_mutex_t lock;
+typedef struct {
+ MonoDomain *domain;
+} ThreadPoolIOUpdate_RemoveDomain;
- mono_cond_t updates_signal;
+typedef struct {
+ ThreadPoolIOUpdateType type;
+ union {
+ ThreadPoolIOUpdate_Add add;
+ ThreadPoolIOUpdate_RemoveSocket remove_socket;
+ ThreadPoolIOUpdate_RemoveDomain remove_domain;
+ } data;
+} ThreadPoolIOUpdate;
- MonoGHashTable *states;
+typedef struct {
+ ThreadPoolIOBackend backend;
- ThreadPoolIOUpdate *updates;
- guint updates_size;
- guint updates_capacity;
+ ThreadPoolIOUpdate updates [UPDATES_CAPACITY];
+ gint updates_size;
+ mono_mutex_t updates_lock;
+ mono_cond_t updates_cond;
#if !defined(HOST_WIN32)
gint wakeup_pipes [2];
case AIO_OP_READPIPE:
case AIO_OP_ACCEPTRECEIVE:
case AIO_OP_RECEIVE_BUFFERS:
- return MONO_POLLIN;
+ return EVENT_IN;
case AIO_OP_SEND:
case AIO_OP_SEND_JUST_CALLBACK:
case AIO_OP_SENDTO:
case AIO_OP_CONNECT:
case AIO_OP_SEND_BUFFERS:
case AIO_OP_DISCONNECT:
- return MONO_POLLOUT;
+ return EVENT_OUT;
default:
g_assert_not_reached ();
}
MonoMList *current;
gint events = 0;
- for (current = list; current; current = mono_mlist_next (current)) {
- MonoSocketAsyncResult *ares = (MonoSocketAsyncResult*) mono_mlist_get_data (current);
- if (ares)
- events |= get_events_from_sockares (ares);
- }
+ for (current = list; current; current = mono_mlist_next (current))
+ events |= get_events_from_sockares ((MonoSocketAsyncResult*) mono_mlist_get_data (current));
return events;
}
-static void
-selector_thread_wakeup (void);
-
-/*
- * If sockares is NULL, then it means we want to delete the corresponding fd
- */
-static void
-update_add (gint fd, MonoSocketAsyncResult *sockares)
-{
- ThreadPoolIOUpdate *update;
-
- mono_mutex_lock (&threadpool_io->lock);
-
- threadpool_io->updates_size += 1;
- if (threadpool_io->updates_size > threadpool_io->updates_capacity) {
- ThreadPoolIOUpdate *updates_new, *updates_old;
- gint updates_new_capacity, updates_old_capacity;
-
- updates_old_capacity = threadpool_io->updates_capacity;
- updates_new_capacity = updates_old_capacity + 16;
-
- updates_old = threadpool_io->updates;
- updates_new = mono_gc_alloc_fixed (sizeof (ThreadPoolIOUpdate) * updates_new_capacity, MONO_GC_DESCRIPTOR_NULL);
- g_assert (updates_new);
-
- if (updates_old)
- memcpy (updates_new, updates_old, sizeof (ThreadPoolIOUpdate) * updates_old_capacity);
-
- threadpool_io->updates = updates_new;
- threadpool_io->updates_capacity = updates_new_capacity;
-
- if (updates_old)
- mono_gc_free_fixed (updates_old);
- }
-
- update = &threadpool_io->updates [threadpool_io->updates_size - 1];
- update->fd = fd;
- update->sockares = sockares;
-
- selector_thread_wakeup ();
-
- mono_cond_wait (&threadpool_io->updates_signal, &threadpool_io->lock);
-
- mono_mutex_unlock (&threadpool_io->lock);
-}
-
-static void
-update_drain (void (*callback) (gint fd, gint events, gboolean is_new))
-{
- gint i;
-
- mono_mutex_lock (&threadpool_io->lock);
-
- for (i = 0; i < threadpool_io->updates_size; ++i) {
- ThreadPoolIOUpdate *update;
- MonoMList *list = NULL;
- gpointer k;
- gboolean is_new;
-
- update = &threadpool_io->updates [i];
-
- is_new = !mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (update->fd), &k, (gpointer*) &list);
-
- if (!update->sockares) {
- callback (update->fd, 0, is_new);
- } else {
- list = mono_mlist_append (list, (MonoObject*) update->sockares);
- mono_g_hash_table_replace (threadpool_io->states, update->sockares->handle, list);
-
- callback (update->fd, get_events (list), is_new);
- }
- }
-
- mono_cond_broadcast (&threadpool_io->updates_signal);
-
- if (threadpool_io->updates_size > 0) {
- ThreadPoolIOUpdate *updates_old;
-
- threadpool_io->updates_size = 0;
- threadpool_io->updates_capacity = 16;
-
- updates_old = threadpool_io->updates;
-
- threadpool_io->updates = mono_gc_alloc_fixed (sizeof (ThreadPoolIOUpdate) * threadpool_io->updates_capacity, MONO_GC_DESCRIPTOR_NULL);
- g_assert (threadpool_io->updates);
-
- mono_gc_free_fixed (updates_old);
- }
-
- mono_mutex_unlock (&threadpool_io->lock);
-}
-
-static void
-update_remove (gboolean (*predicate) (ThreadPoolIOUpdate *update, gpointer user_data), gpointer user_data)
-{
- gint i;
-
- mono_mutex_lock (&threadpool_io->lock);
-
- for (i = 0; i < threadpool_io->updates_size; ++i) {
- if (predicate (&threadpool_io->updates [i], user_data)) {
- if (i < threadpool_io->updates_size - 1)
- memmove (threadpool_io->updates + i, threadpool_io->updates + i + 1, sizeof (ThreadPoolIOUpdate) * threadpool_io->updates_size - i - 1);
- memset (threadpool_io->updates + threadpool_io->updates_size - 1, 0, sizeof (ThreadPoolIOUpdate));
-
- threadpool_io->updates_size --;
- i --;
- }
- }
-
- mono_mutex_unlock (&threadpool_io->lock);
-}
-
static void
selector_thread_wakeup (void)
{
}
}
+typedef struct {
+ MonoDomain *domain;
+ MonoGHashTable *states;
+} FilterSockaresForDomainData;
+
+static void
+filter_sockares_for_domain (gpointer key, gpointer value, gpointer user_data)
+{
+ FilterSockaresForDomainData *data;
+ MonoMList *list = value, *element;
+ MonoDomain *domain;
+ MonoGHashTable *states;
+
+ g_assert (user_data);
+ data = user_data;
+ domain = data->domain;
+ states = data->states;
+
+ for (element = list; element; element = mono_mlist_next (element)) {
+ MonoSocketAsyncResult *sockares = (MonoSocketAsyncResult*) mono_mlist_get_data (element);
+ if (mono_object_domain (sockares) == domain)
+ mono_mlist_set_data (element, NULL);
+ }
+
+ /* we skip all the first elements which are NULL */
+ for (; list; list = mono_mlist_next (list)) {
+ if (mono_mlist_get_data (list))
+ break;
+ }
+
+ if (list) {
+ g_assert (mono_mlist_get_data (list));
+
+ /* we delete all the NULL elements after the first one */
+ for (element = list; element;) {
+ MonoMList *next;
+ if (!(next = mono_mlist_next (element)))
+ break;
+ if (mono_mlist_get_data (next))
+ element = next;
+ else
+ mono_mlist_set_next (element, mono_mlist_next (next));
+ }
+ }
+
+ mono_g_hash_table_replace (states, key, list);
+}
+
+static void
+wait_callback (gint fd, gint events, gpointer user_data)
+{
+ if (mono_runtime_is_shutting_down ())
+ return;
+
+ if (fd == threadpool_io->wakeup_pipes [0]) {
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wke");
+ selector_thread_wakeup_drain_pipes ();
+ } else {
+ MonoGHashTable *states;
+ MonoMList *list = NULL;
+ gpointer k;
+
+ g_assert (user_data);
+ states = user_data;
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: cal fd %3d, events = %2s | %2s",
+ fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
+
+ if (!mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list))
+ g_error ("wait_callback: fd %d not found in states table", fd);
+
+ if (list && (events & EVENT_IN) != 0) {
+ MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, EVENT_IN);
+ if (sockares)
+ mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+ }
+ if (list && (events & EVENT_OUT) != 0) {
+ MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, EVENT_OUT);
+ if (sockares)
+ mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+ }
+
+ mono_g_hash_table_replace (states, GINT_TO_POINTER (fd), list);
+
+ events = get_events (list);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: res fd %3d, events = %2s | %2s",
+ fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
+
+ threadpool_io->backend.register_fd (fd, events, FALSE);
+ }
+}
+
static void
selector_thread (gpointer data)
{
+ MonoGHashTable *states;
+
io_selector_running = TRUE;
if (mono_runtime_is_shutting_down ()) {
return;
}
- mono_mutex_lock (&threadpool_io->lock);
+ states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC);
for (;;) {
- guint i;
- guint max;
- gint ready = 0;
-
- update_drain (threadpool_io->backend.register_fd);
+ gint i, j;
+ gint res;
- mono_mutex_unlock (&threadpool_io->lock);
+ mono_mutex_lock (&threadpool_io->updates_lock);
- mono_gc_set_skip_thread (TRUE);
+ for (i = 0; i < threadpool_io->updates_size; ++i) {
+ ThreadPoolIOUpdate *update = &threadpool_io->updates [i];
- ready = threadpool_io->backend.event_wait ();
+ switch (update->type) {
+ case UPDATE_EMPTY:
+ break;
+ case UPDATE_ADD: {
+ gint fd;
+ gint events;
+ gpointer k;
+ gboolean exists;
+ MonoMList *list = NULL;
+ MonoSocketAsyncResult *sockares;
- mono_gc_set_skip_thread (FALSE);
+ fd = update->data.add.fd;
+ g_assert (fd >= 0);
- mono_mutex_lock (&threadpool_io->lock);
+ sockares = update->data.add.sockares;
+ g_assert (sockares);
- if (ready == -1 || mono_runtime_is_shutting_down ())
- break;
+ exists = mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list);
+ list = mono_mlist_append (list, (MonoObject*) sockares);
+ mono_g_hash_table_replace (states, sockares->handle, list);
- max = threadpool_io->backend.event_get_fd_max ();
+ events = get_events (list);
- for (i = 0; i < max && ready > 0; ++i) {
- gint events;
- gint fd = threadpool_io->backend.event_get_fd_at (i, &events);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: %3s fd %3d, events = %2s | %2s",
+ exists ? "mod" : "add", fd, (events & EVENT_IN) ? "RD" : "..", (events & EVENT_OUT) ? "WR" : "..");
- if (fd == -1)
- continue;
+ threadpool_io->backend.register_fd (fd, events, !exists);
- if (fd == threadpool_io->wakeup_pipes [0]) {
- selector_thread_wakeup_drain_pipes ();
- } else {
- MonoMList *list = NULL;
+ break;
+ }
+ case UPDATE_REMOVE_SOCKET: {
+ gint fd;
gpointer k;
+ MonoMList *list = NULL;
- if (mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) {
- if (list && (events & MONO_POLLIN) != 0) {
- MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, MONO_POLLIN);
- if (sockares)
- mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
- }
- if (list && (events & MONO_POLLOUT) != 0) {
- MonoSocketAsyncResult *sockares = get_sockares_for_event (&list, MONO_POLLOUT);
- if (sockares)
- mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
+ fd = update->data.remove_socket.fd;
+ g_assert (fd >= 0);
+
+ if (mono_g_hash_table_lookup_extended (states, GINT_TO_POINTER (fd), &k, (gpointer*) &list)) {
+ mono_g_hash_table_remove (states, GINT_TO_POINTER (fd));
+
+ for (j = i + 1; j < threadpool_io->updates_size; ++j) {
+ ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
+ if (update->type == UPDATE_ADD && update->data.add.fd == fd)
+ memset (update, 0, sizeof (ThreadPoolIOUpdate));
}
- if (!list)
- mono_g_hash_table_remove (threadpool_io->states, GINT_TO_POINTER (fd));
- else
- mono_g_hash_table_replace (threadpool_io->states, GINT_TO_POINTER (fd), list);
+ for (; list; list = mono_mlist_remove_item (list, list))
+ mono_threadpool_ms_enqueue_work_item (mono_object_domain (mono_mlist_get_data (list)), mono_mlist_get_data (list));
- threadpool_io->backend.register_fd (fd, get_events (list), FALSE);
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: del fd %3d", fd);
+ threadpool_io->backend.remove_fd (fd);
}
+
+ break;
+ }
+ case UPDATE_REMOVE_DOMAIN: {
+ MonoDomain *domain;
+
+ domain = update->data.remove_domain.domain;
+ g_assert (domain);
+
+ FilterSockaresForDomainData user_data = { .domain = domain, .states = states };
+ mono_g_hash_table_foreach (states, filter_sockares_for_domain, &user_data);
+
+ for (j = i + 1; j < threadpool_io->updates_size; ++j) {
+ ThreadPoolIOUpdate *update = &threadpool_io->updates [j];
+ if (update->type == UPDATE_ADD && mono_object_domain (update->data.add.sockares) == domain)
+ memset (update, 0, sizeof (ThreadPoolIOUpdate));
+ }
+
+ break;
+ }
+ default:
+ g_assert_not_reached ();
}
+ }
- ready -= 1;
+ mono_cond_broadcast (&threadpool_io->updates_cond);
+
+ if (threadpool_io->updates_size > 0) {
+ threadpool_io->updates_size = 0;
+ memset (&threadpool_io->updates, 0, UPDATES_CAPACITY * sizeof (ThreadPoolIOUpdate));
}
+
+ mono_mutex_unlock (&threadpool_io->updates_lock);
+
+ mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_THREADPOOL, "io threadpool: wai");
+
+ res = threadpool_io->backend.event_wait (wait_callback, states);
+
+ if (res == -1 || mono_runtime_is_shutting_down ())
+ break;
}
- mono_mutex_unlock (&threadpool_io->lock);
+ mono_g_hash_table_destroy (states);
io_selector_running = FALSE;
}
+/* Locking: threadpool_io->updates_lock must be held */
+static ThreadPoolIOUpdate*
+update_get_new (void)
+{
+ ThreadPoolIOUpdate *update = NULL;
+ g_assert (threadpool_io->updates_size <= UPDATES_CAPACITY);
+
+ while (threadpool_io->updates_size == UPDATES_CAPACITY) {
+ /* we wait for updates to be applied in the selector_thread and we loop
+ * as long as none are available. if it happends too much, then we need
+ * to increase UPDATES_CAPACITY */
+ mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
+ }
+
+ g_assert (threadpool_io->updates_size < UPDATES_CAPACITY);
+
+ update = &threadpool_io->updates [threadpool_io->updates_size ++];
+
+ return update;
+}
+
static void
wakeup_pipes_init (void)
{
threadpool_io = g_new0 (ThreadPoolIO, 1);
g_assert (threadpool_io);
- mono_mutex_init_recursive (&threadpool_io->lock);
-
- mono_cond_init (&threadpool_io->updates_signal, NULL);
+ mono_mutex_init_recursive (&threadpool_io->updates_lock);
+ mono_cond_init (&threadpool_io->updates_cond, NULL);
+ mono_gc_register_root ((void*)&threadpool_io->updates [0], sizeof (threadpool_io->updates), MONO_GC_DESCRIPTOR_NULL);
- threadpool_io->states = mono_g_hash_table_new_type (g_direct_hash, g_direct_equal, MONO_HASH_VALUE_GC);
- MONO_GC_REGISTER_ROOT_FIXED (threadpool_io->states);
-
- threadpool_io->updates = NULL;
threadpool_io->updates_size = 0;
- threadpool_io->updates_capacity = 0;
+ threadpool_io->backend = backend_poll;
+ if (g_getenv ("MONO_ENABLE_AIO") != NULL) {
#if defined(HAVE_EPOLL)
- threadpool_io->backend = backend_epoll;
+ threadpool_io->backend = backend_epoll;
#elif defined(HAVE_KQUEUE)
- threadpool_io->backend = backend_kqueue;
-#else
- threadpool_io->backend = backend_poll;
+ threadpool_io->backend = backend_kqueue;
#endif
- if (g_getenv ("MONO_DISABLE_AIO") != NULL)
- threadpool_io->backend = backend_poll;
+ }
wakeup_pipes_init ();
while (io_selector_running)
g_usleep (1000);
- mono_mutex_destroy (&threadpool_io->lock);
-
- mono_cond_destroy (&threadpool_io->updates_signal);
-
- MONO_GC_UNREGISTER_ROOT (threadpool_io->states);
- mono_g_hash_table_destroy (threadpool_io->states);
-
- if (threadpool_io->updates)
- mono_gc_free_fixed (threadpool_io->updates);
+ mono_mutex_destroy (&threadpool_io->updates_lock);
+ mono_cond_destroy (&threadpool_io->updates_cond);
threadpool_io->backend.cleanup ();
MonoClass *socket_async_callback_class = NULL;
socket_async_callback_class = mono_class_from_name (system_image, "System.Net.Sockets", "SocketAsyncCallback");
- g_assert (socket_async_callback_class);
return class == socket_async_callback_class;
}
MonoClass *async_read_handler_class = NULL;
async_read_handler_class = mono_class_from_name (system_image, "System.Diagnostics", "Process/AsyncReadHandler");
- g_assert (async_read_handler_class);
return class == async_read_handler_class;
}
MonoAsyncResult *
mono_threadpool_ms_io_add (MonoAsyncResult *ares, MonoSocketAsyncResult *sockares)
{
+ ThreadPoolIOUpdate *update;
+
g_assert (ares);
g_assert (sockares);
if (mono_runtime_is_shutting_down ())
return NULL;
+ if (mono_domain_is_unloading (mono_object_domain (sockares)))
+ return NULL;
mono_lazy_initialize (&io_status, initialize);
MONO_OBJECT_SETREF (sockares, ares, ares);
- update_add (GPOINTER_TO_INT (sockares->handle), sockares);
+ mono_mutex_lock (&threadpool_io->updates_lock);
- return ares;
-}
+ update = update_get_new ();
+ update->type = UPDATE_ADD;
+ update->data.add.fd = GPOINTER_TO_INT (sockares->handle);
+ update->data.add.sockares = sockares;
+ mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
-static gboolean
-remove_update_for_socket (ThreadPoolIOUpdate *update, gpointer user_data)
-{
- if (!update->sockares)
- return FALSE;
+ selector_thread_wakeup ();
+
+ mono_mutex_unlock (&threadpool_io->updates_lock);
- return GPOINTER_TO_INT (update->sockares->handle) == GPOINTER_TO_INT (user_data);
+ return ares;
}
void
mono_threadpool_ms_io_remove_socket (int fd)
{
- MonoMList *list = NULL;
- gpointer k;
+ ThreadPoolIOUpdate *update;
if (!mono_lazy_is_initialized (&io_status))
return;
- mono_mutex_lock (&threadpool_io->lock);
-
- g_assert (threadpool_io->states);
-
- if (mono_g_hash_table_lookup_extended (threadpool_io->states, GINT_TO_POINTER (fd), &k, (gpointer*) &list))
- mono_g_hash_table_remove (threadpool_io->states, GINT_TO_POINTER (fd));
-
- update_remove (remove_update_for_socket, GINT_TO_POINTER (fd));
-
- mono_mutex_unlock (&threadpool_io->lock);
+ mono_mutex_lock (&threadpool_io->updates_lock);
- for (; list; list = mono_mlist_remove_item (list, list)) {
- MonoSocketAsyncResult *sockares = (MonoSocketAsyncResult*) mono_mlist_get_data (list);
+ update = update_get_new ();
+ update->type = UPDATE_REMOVE_SOCKET;
+ update->data.add.fd = fd;
+ mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
- if (!sockares)
- continue;
-
- switch (sockares->operation) {
- case AIO_OP_RECEIVE:
- sockares->operation = AIO_OP_RECV_JUST_CALLBACK;
- break;
- case AIO_OP_SEND:
- sockares->operation = AIO_OP_SEND_JUST_CALLBACK;
- break;
- }
-
- mono_threadpool_ms_enqueue_work_item (((MonoObject*) sockares)->vtable->domain, (MonoObject*) sockares);
- }
-
- update_add (fd, NULL);
-}
-
-static gboolean
-remove_sockstate_for_domain (gpointer key, gpointer value, gpointer user_data)
-{
- MonoMList *list;
- gboolean remove = FALSE;
-
- for (list = value; list; list = mono_mlist_next (list)) {
- MonoObject *data = mono_mlist_get_data (list);
- if (mono_object_domain (data) == user_data) {
- remove = TRUE;
- mono_mlist_set_data (list, NULL);
- }
- }
+ selector_thread_wakeup ();
- //FIXME is there some sort of additional unregistration we need to perform here?
- return remove;
-}
+ mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
-static gboolean
-remove_update_for_domain (ThreadPoolIOUpdate *update, gpointer user_data)
-{
- if (!update->sockares)
- return FALSE;
-
- return mono_object_domain (update->sockares) == (MonoDomain*) user_data;
+ mono_mutex_unlock (&threadpool_io->updates_lock);
}
void
mono_threadpool_ms_io_remove_domain_jobs (MonoDomain *domain)
{
+ ThreadPoolIOUpdate *update;
+
if (!mono_lazy_is_initialized (&io_status))
return;
- mono_mutex_lock (&threadpool_io->lock);
+ mono_mutex_lock (&threadpool_io->updates_lock);
- mono_g_hash_table_foreach_remove (threadpool_io->states, remove_sockstate_for_domain, domain);
+ update = update_get_new ();
+ update->type = UPDATE_REMOVE_DOMAIN;
+ update->data.remove_domain.domain = domain;
+ mono_memory_barrier (); /* Ensure this is safely published before we wake up the selector */
+
+ selector_thread_wakeup ();
- update_remove (remove_update_for_domain, domain);
+ mono_cond_wait (&threadpool_io->updates_cond, &threadpool_io->updates_lock);
- mono_mutex_unlock (&threadpool_io->lock);
+ mono_mutex_unlock (&threadpool_io->updates_lock);
}
void
* cleaning up only if the runtime is shutting down */
g_assert (mono_runtime_is_shutting_down ());
+ MONO_PREPARE_BLOCKING;
while (monitor_status != MONITOR_STATUS_NOT_RUNNING)
g_usleep (1000);
+ MONO_FINISH_BLOCKING;
+ MONO_PREPARE_BLOCKING;
mono_mutex_lock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
/* stop all threadpool->working_threads */
for (i = 0; i < threadpool->working_threads->len; ++i)
mono_gc_set_skip_thread (TRUE);
+ MONO_PREPARE_BLOCKING;
+
mono_mutex_lock (&threadpool->active_threads_lock);
if (!mono_runtime_is_shutting_down ()) {
mono_mutex_unlock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
+
mono_gc_set_skip_thread (FALSE);
mono_cond_destroy (&cond);
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try unpark worker", GetCurrentThreadId ());
+ MONO_PREPARE_BLOCKING;
+
mono_mutex_lock (&threadpool->active_threads_lock);
len = threadpool->parked_threads->len;
if (len > 0) {
}
mono_mutex_unlock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
+
mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try unpark worker, success? %s", GetCurrentThreadId (), res ? "yes" : "no");
return res;
mono_thread_set_name_internal (thread, mono_string_new (mono_domain_get (), "Threadpool worker"), FALSE);
+ MONO_PREPARE_BLOCKING;
mono_mutex_lock (&threadpool->active_threads_lock);
g_ptr_array_add (threadpool->working_threads, thread);
mono_mutex_unlock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
previous_tpdomain = NULL;
mono_mutex_unlock (&threadpool->domains_lock);
+ MONO_PREPARE_BLOCKING;
mono_mutex_lock (&threadpool->active_threads_lock);
g_ptr_array_remove_fast (threadpool->working_threads, thread);
mono_mutex_unlock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
COUNTER_ATOMIC (counter, {
counter._.working--;
if (mono_runtime_is_shutting_down () || !domain_any_has_request ())
continue;
+ MONO_PREPARE_BLOCKING;
mono_mutex_lock (&threadpool->active_threads_lock);
for (i = 0; i < threadpool->working_threads->len; ++i) {
thread = g_ptr_array_index (threadpool->working_threads, i);
}
}
mono_mutex_unlock (&threadpool->active_threads_lock);
+ MONO_FINISH_BLOCKING;
if (all_waitsleepjoin) {
ThreadPoolCounter counter;
return NULL;
}
- MONO_OBJECT_SETREF (ares, endinvoke_called, 1);
+ ares->endinvoke_called = 1;
/* wait until we are really finished */
if (ares->completed) {
MONO_OBJECT_SETREF (ares, handle, (MonoObject*) mono_wait_handle_new (mono_object_domain (ares), wait_event));
}
mono_monitor_exit ((MonoObject*) ares);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
ac = (MonoAsyncCall*) ares->object_data;
mono_memory_write_barrier ();
while (domain->threadpool_jobs) {
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
WaitForSingleObject (sem, timeout);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (timeout != -1) {
timeout -= mono_msec_ticks () - start;
if (timeout <= 0) {
static gint32 managed_thread_id_counter = 0;
-
static void
mono_threads_lock (void)
{
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_locks_acquire (&threads_mutex, ThreadsLock);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
}
static void
g_assert (thread->synch_cs);
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (thread->synch_cs);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
}
static inline void
}
/* This needs to be called even if handle_remove () fails */
if (mono_thread_cleanup_fn)
- mono_thread_cleanup_fn ((MonoNativeThreadId)thread->tid);
+ mono_thread_cleanup_fn (thread_get_tid (thread));
return;
}
mono_release_type_locks (thread);
thread->appdomain_refs = NULL;
if (mono_thread_cleanup_fn)
- mono_thread_cleanup_fn ((MonoNativeThreadId)thread->tid);
+ mono_thread_cleanup_fn (thread_get_tid (thread));
if (mono_gc_is_moving ()) {
MONO_GC_UNREGISTER_ROOT (thread->thread_pinning_ref);
internal->thread_info = info;
internal->small_id = info->small_id;
- tid=internal->tid;
+ tid = internal->tid;
SET_CURRENT_OBJECT (internal);
*/
if (thread_start_args == NULL) {
MONO_GC_REGISTER_ROOT_FIXED (thread_start_args);
- thread_start_args = mono_g_hash_table_new (NULL, NULL);
+ thread_start_args = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC);
}
mono_g_hash_table_insert (thread_start_args, thread, start_info->start_arg);
if (threads_starting_up == NULL) {
*/
create_flags = CREATE_SUSPENDED;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)start_wrapper, start_info,
stack_size, create_flags, &tid);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (thread_handle == NULL) {
/* The thread couldn't be created, so throw an exception */
if (!handle_store (thread, FALSE))
return FALSE;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
mono_thread_info_resume (tid);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (internal->start_notify) {
/*
*/
THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for thread %p (%"G_GSIZE_FORMAT") to start", __func__, GetCurrentThreadId (), internal, (gsize)internal->tid));
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
WaitForSingleObjectEx (internal->start_notify, INFINITE, FALSE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
CloseHandle (internal->start_notify);
internal->start_notify = NULL;
tid=GetCurrentThreadId ();
- thread->handle=thread_handle;
- thread->tid=tid;
+ thread->handle = thread_handle;
+ thread->tid = tid;
thread->stack_ptr = &tid;
THREAD_DEBUG (g_message ("%s: Attached thread ID %"G_GSIZE_FORMAT" (handle %p)", __func__, tid, thread_handle));
while (TRUE) {
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = SleepEx(ms,TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
mono_thread_set_state (cur_thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret=WaitForSingleObjectEx (handle, ms, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
mono_thread_clr_state (cur_thread, ThreadState_WaitSleepJoin);
start = (ms == -1) ? 0 : mono_100ns_ticks ();
do {
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
if (multiple)
ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
else
ret = WaitForSingleObjectEx (handles [0], ms, alertable);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (ret != WAIT_IO_COMPLETION)
break;
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
THREAD_DEBUG (g_message("%s: %d threads to wait for in this batch", __func__, wait->num));
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret=WaitForMultipleObjectsEx(wait->num, wait->handles, TRUE, timeout, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
count++;
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
ret=WaitForMultipleObjectsEx (count, wait->handles, FALSE, timeout, TRUE);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if(ret==WAIT_FAILED) {
/* See the comment in build_wait_tids() */
return;
}
- handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+ handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
if (handle == NULL) {
THREAD_DEBUG (g_message ("%s: ignoring unopenable thread %"G_GSIZE_FORMAT, __func__, (gsize)thread->tid));
return;
if (thread->tid != self && (thread->state & ThreadState_Background) != 0 &&
!(thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
- handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+ handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
if (handle == NULL)
return FALSE;
return;
if (wait->num<MAXIMUM_WAIT_OBJECTS) {
- handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+ handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
if (handle == NULL)
return;
{
GString *p = (GString*)data;
MonoMethod *method = NULL;
- if (frame->ji)
+ if (frame->type == FRAME_TYPE_MANAGED)
method = mono_jit_info_get_method (frame->ji);
if (method) {
We probably should loop a bit around trying to get it to either managed code
or WSJ state.
*/
- mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, FALSE, print_thread_dump, thread);
+ mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, print_thread_dump, thread);
}
void
/* printf ("ABORTING THREAD %p BECAUSE IT REFERENCES DOMAIN %s.\n", thread->tid, domain->friendly_name); */
if(data->wait.num<MAXIMUM_WAIT_OBJECTS) {
- HANDLE handle = mono_threads_open_thread_handle (thread->handle, (MonoNativeThreadId)thread->tid);
+ HANDLE handle = mono_threads_open_thread_handle (thread->handle, thread_get_tid (thread));
if (handle == NULL)
return;
data->wait.handles [data->wait.num] = handle;
WaitForSingleObjectEx (GetCurrentThread(), 0, TRUE);
#endif
InterlockedDecrement (&thread_interruption_requested);
+
/* Clear the interrupted flag of the thread so it can wait again */
- mono_thread_info_clear_interruption ();
+ mono_thread_info_clear_self_interrupt ();
}
if ((thread->state & ThreadState_AbortRequested) != 0) {
typedef struct {
MonoInternalThread *thread;
gboolean install_async_abort;
- gpointer interrupt_handle;
+ MonoThreadInfoInterruptToken *interrupt_token;
} AbortThreadData;
static SuspendThreadResult
InterlockedIncrement (&thread_interruption_requested);
ji = mono_thread_info_get_last_managed (info);
- protected_wrapper = ji && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
+ protected_wrapper = ji && !ji->is_trampoline && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
if (!protected_wrapper && running_managed) {
* functions in the io-layer until the signal handler calls QueueUserAPC which will
* make it return.
*/
- data->interrupt_handle = mono_thread_info_prepare_interrupt (thread->handle);
+ data->interrupt_token = mono_thread_info_prepare_interrupt (info);
+
return MonoResumeThread;
}
}
MonoException *exc = mono_thread_request_interruption (can_raise_exception);
if (exc)
mono_raise_exception (exc);
- mono_thread_info_interrupt (thread->handle);
+
+ mono_thread_info_self_interrupt ();
+
return;
}
- mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, TRUE, abort_thread_critical, &data);
- if (data.interrupt_handle)
- mono_thread_info_finish_interrupt (data.interrupt_handle);
+ mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), TRUE, abort_thread_critical, &data);
+ if (data.interrupt_token)
+ mono_thread_info_finish_interrupt (data.interrupt_token);
/*FIXME we need to wait for interruption to complete -- figure out how much into interruption we should wait for here*/
}
typedef struct{
MonoInternalThread *thread;
gboolean interrupt;
- gpointer interrupt_handle;
+ MonoThreadInfoInterruptToken *interrupt_token;
} SuspendThreadData;
static SuspendThreadResult
gboolean running_managed;
ji = mono_thread_info_get_last_managed (info);
- protected_wrapper = ji && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
+ protected_wrapper = ji && !ji->is_trampoline && !ji->async && mono_threads_is_critical_method (mono_jit_info_get_method (ji));
running_managed = mono_jit_info_match (ji, MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
if (running_managed && !protected_wrapper) {
if (InterlockedCompareExchange (&thread->interruption_requested, 1, 0) == 0)
InterlockedIncrement (&thread_interruption_requested);
if (data->interrupt)
- data->interrupt_handle = mono_thread_info_prepare_interrupt (thread->handle);
+ data->interrupt_token = mono_thread_info_prepare_interrupt (thread->thread_info);
if (mono_thread_notify_pending_exc_fn && !running_managed)
/* The JIT will notify the thread about the interruption */
data.thread = thread;
data.interrupt = interrupt;
- mono_thread_info_safe_suspend_and_run ((MonoNativeThreadId)(gsize)thread->tid, interrupt, suspend_thread_critical, &data);
- if (data.interrupt_handle)
- mono_thread_info_finish_interrupt (data.interrupt_handle);
+ mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), interrupt, suspend_thread_critical, &data);
+ if (data.interrupt_token)
+ mono_thread_info_finish_interrupt (data.interrupt_token);
UNLOCK_THREAD (thread);
}
}
{
UNLOCK_THREAD (thread);
/* Awake the thread */
- if (!mono_thread_info_resume ((MonoNativeThreadId)(gpointer)(gsize)thread->tid))
+ if (!mono_thread_info_resume (thread_get_tid (thread)))
return FALSE;
LOCK_THREAD (thread);
thread->state &= ~ThreadState_Suspended;
libgc_libs=$(monodir)/libgc/libmonogc.la
libgc_static_libs=$(monodir)/libgc/libmonogc-static.la
-libs= \
+boehm_libs= \
$(monodir)/mono/metadata/libmonoruntime.la \
$(monodir)/mono/io-layer/libwapi.la \
$(monodir)/mono/utils/libmonoutils.la \
$(monodir)/mono/utils/libmonoutils.la \
$(GLIB_LIBS) $(LIBICONV)
-static_libs= \
+boehm_static_libs= \
$(monodir)/mono/metadata/libmonoruntime-static.la \
$(monodir)/mono/io-layer/libwapi.la \
$(monodir)/mono/utils/libmonoutils.la \
$(GLIB_LIBS) $(LIBICONV) \
$(libgc_static_libs)
-sgenstatic_libs = \
+sgen_static_libs = \
$(monodir)/mono/metadata/libmonoruntimesgen-static.la \
$(monodir)/mono/sgen/libmonosgen-static.la \
$(monodir)/mono/io-layer/libwapi.la \
if SUPPORT_SGEN
sgen_binaries = mono-sgen
sgen_libraries = libmonosgen-2.0.la
-sgen_static_libraries = libmini-static.la $(sgenstatic_libs)
+sgen_static_libraries = libmini-static.la $(sgen_static_libs)
endif
if SUPPORT_BOEHM
boehm_libraries = libmonoboehm-2.0.la
-boehm_static_libraries = libmini-static.la $(static_libs)
+boehm_static_libraries = libmini-static.la $(boehm_static_libs)
boehm_binaries = mono-boehm
endif
-#The mono uses sgen, while libmono remains boehm
+# The mono executable uses sgen, while libmono remains boehm
if SUPPORT_SGEN
mono_bin_suffix = sgen
else
if PLATFORM_DARWIN
libmono_llvm_la_LDFLAGS=-Wl,-undefined -Wl,suppress -Wl,-flat_namespace
else
-libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $(libs)
+libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $(boehm_libs)
endif
endif
libmonoboehm_2_0_la_SOURCES =
libmonoboehm_2_0_la_CFLAGS = $(mono_boehm_CFLAGS)
-libmonoboehm_2_0_la_LIBADD = libmini.la $(libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
+libmonoboehm_2_0_la_LIBADD = libmini.la $(boehm_libs) $(LIBMONO_DTRACE_OBJECT) $(LLVMMONOF)
libmonoboehm_2_0_la_LDFLAGS = $(libmonoldflags)
libmonosgen_2_0_la_SOURCES =
rcheck: mono $(regtests)
if NACL_CODEGEN
for i in $(regtests); do echo "running test $$i"; $(MINI_RUNTIME) $$i --exclude 'NaClDisable' || exit 1; done
-else
+elif JENKINS_URL
-($(MINI_RUNTIME) --regression $(regtests); echo $$? > regressionexitcode.out) | $(srcdir)/emitnunit.pl
exit $$(cat regressionexitcode.out)
-endif
-
-rcheck2: mono $(regtests)
+else
$(MINI_RUNTIME) --regression $(regtests)
+endif
check-seq-points: mono $(regtests)
rm -f TestResults_op_il_seq_point.xml
fullaot_regtests = $(regtests) aot-tests.exe $(if $(GSHAREDVT),gshared.exe)
+FULLAOT_LIBS = \
+ mscorlib.dll \
+ System.Core.dll \
+ System.dll \
+ Mono.Posix.dll \
+ System.Configuration.dll \
+ System.Security.dll \
+ System.Xml.dll \
+ Mono.Security.dll \
+ Mono.Simd.dll
+
# This currently only works on amd64/arm
fullaotcheck: mono $(fullaot_regtests)
rm -rf fullaot-tmp
mkdir fullaot-tmp
- cp $(CLASS)/mscorlib.dll $(CLASS)/System.Core.dll $(CLASS)/System.dll $(CLASS)/Mono.Posix.dll $(CLASS)/System.Configuration.dll $(CLASS)/System.Security.dll $(CLASS)/System.Xml.dll $(CLASS)/Mono.Security.dll $(CLASS)/Mono.Simd.dll $(regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
- cp $(fullaot_regtests) fullaot-tmp/
- MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot=full fullaot-tmp/* || exit 1
+ $(MAKE) fullaot-libs AOT_FLAGS=full
+ cp $(regtests) $(fullaot_regtests) generics-variant-types.dll TestDriver.dll fullaot-tmp/
+ MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper $(LLVM_AOT_RUNTIME_OPTS) $(GSHAREDVT_RUNTIME_OPTS) --aot=full fullaot-tmp/{generics-variant-types.dll,TestDriver.dll,*.exe} || exit 1
ln -s $$PWD/mono fullaot-tmp/
for i in $(fullaot_regtests); do echo $$i; MONO_PATH=fullaot-tmp $(top_builddir)/runtime/mono-wrapper --full-aot fullaot-tmp/$$i --exclude '!FULLAOT' $(ARCH_FULLAOT_EXCLUDE) || exit 1; done
+# This can run in parallel
+fullaot-libs: $(patsubst %,fullaot-tmp/%.dylib,$(FULLAOT_LIBS))
+
+fullaot-tmp/%.dylib: $(CLASS)/%
+ cp $(CLASS)/$* fullaot-tmp/
+ mkdir fullaot-tmp/$*-tmp
+ MONO_PATH=fullaot-tmp/:$(CLASS) $(top_builddir)/runtime/mono-wrapper --aot=$(AOT_FLAGS),temp-path=fullaot-tmp/$*-tmp fullaot-tmp/$*
+ rm -rf fullaot-tmp/$*-tmp
+
llvmfullaotcheck:
$(MAKE) fullaotcheck LLVM=1
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internal.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/mempool-internals.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/threads-types.h>
#endif
+static guint32
+get_unwind_info_offset (MonoAotCompile *acfg, guint8 *encoded, guint32 encoded_len);
+
static char*
get_plt_entry_debug_sym (MonoAotCompile *acfg, MonoJumpInfo *ji, GHashTable *cache);
#endif
}
+/* Save unwind_info in the module and emit the offset to the information at symbol */
+static void save_unwind_info (MonoAotCompile *acfg, char *symbol, GSList *unwind_ops)
+{
+ guint32 uw_offset, encoded_len;
+ guint8 *encoded;
+
+ emit_section_change (acfg, RODATA_SECT, 0);
+ emit_global (acfg, symbol, FALSE);
+ emit_label (acfg, symbol);
+
+ encoded = mono_unwind_ops_encode (unwind_ops, &encoded_len);
+ uw_offset = get_unwind_info_offset (acfg, encoded, encoded_len);
+ g_free (encoded);
+ emit_int32 (acfg, uw_offset);
+}
+
/*
* arch_emit_specific_trampoline_pages:
*
guint8 *loop_start, *loop_branch_back, *loop_end_check, *imt_found_check;
int i;
int pagesize = MONO_AOT_TRAMP_PAGE_SIZE;
+ GSList *unwind_ops = NULL;
#define COMMON_TRAMP_SIZE 16
int count = (pagesize - COMMON_TRAMP_SIZE) / 8;
int imm8, rot_amount;
/* now the imt trampolines: each specific trampolines puts in the ip register
* the instruction pointer address, so the generic trampoline at the start of the page
* subtracts 4096 to get to the data page and loads the values
- * We again fit the generic trampiline in 16 bytes.
*/
#define IMT_TRAMP_SIZE 72
sprintf (symbol, "%simt_trampolines_page", acfg->user_symbol_prefix);
acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_STATIC_RGCTX] = 16;
acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_IMT_THUNK] = 72;
acfg->tramp_page_code_offsets [MONO_AOT_TRAMP_GSHAREDVT_ARG] = 16;
+
+ /* Unwind info for specifc trampolines */
+ sprintf (symbol, "%sspecific_trampolines_page_gen_p", acfg->user_symbol_prefix);
+ /* We unwind to the original caller, from the stack, since lr is clobbered */
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 14 * sizeof (mgreg_t));
+ mono_add_unwind_op_offset (unwind_ops, 0, 0, ARMREG_LR, -4);
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ sprintf (symbol, "%sspecific_trampolines_page_sp_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 14 * sizeof (mgreg_t));
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ /* Unwind info for rgctx trampolines */
+ sprintf (symbol, "%srgctx_trampolines_page_gen_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ save_unwind_info (acfg, symbol, unwind_ops);
+
+ sprintf (symbol, "%srgctx_trampolines_page_sp_p", acfg->user_symbol_prefix);
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ /* Unwind info for gsharedvt trampolines */
+ sprintf (symbol, "%sgsharedvt_trampolines_page_gen_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 4 * sizeof (mgreg_t));
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ sprintf (symbol, "%sgsharedvt_trampolines_page_sp_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ /* Unwind info for imt trampolines */
+ sprintf (symbol, "%simt_trampolines_page_gen_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, 4, 0, 3 * sizeof (mgreg_t));
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ sprintf (symbol, "%simt_trampolines_page_sp_p", acfg->user_symbol_prefix);
+ mono_add_unwind_op_def_cfa (unwind_ops, 0, 0, ARMREG_SP, 0);
+ save_unwind_info (acfg, symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
#elif defined(TARGET_ARM64)
arm64_emit_specific_trampoline_pages (acfg);
#endif
/* FIXME: Could this clobber the register needed by get_vcall_slot () ? */
- /* We clobber ECX, since EAX is used as MONO_ARCH_MONITOR_OBJECT_REG */
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
- g_assert (MONO_ARCH_MONITOR_OBJECT_REG != X86_ECX);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
- g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG != X86_ECX);
-#endif
-#endif
-
code = buf;
/* Load mscorlib got address */
x86_mov_reg_membase (code, X86_ECX, MONO_ARCH_GOT_REG, sizeof (gpointer), 4);
case MONO_PATCH_INFO_JIT_ICALL_ADDR:
case MONO_PATCH_INFO_ICALL_ADDR:
case MONO_PATCH_INFO_RGCTX_FETCH:
- case MONO_PATCH_INFO_MONITOR_ENTER:
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- case MONO_PATCH_INFO_MONITOR_EXIT:
case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
return TRUE;
default:
encode_patch (acfg, entry->data, p, &p);
break;
}
- case MONO_PATCH_INFO_MONITOR_ENTER:
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- case MONO_PATCH_INFO_MONITOR_EXIT:
case MONO_PATCH_INFO_SEQ_POINT_INFO:
break;
case MONO_PATCH_INFO_LLVM_IMT_TRAMPOLINE:
static G_GNUC_UNUSED void
emit_trampoline (MonoAotCompile *acfg, int got_offset, MonoTrampInfo *info)
{
- emit_trampoline_full (acfg, got_offset, info, FALSE);
+ emit_trampoline_full (acfg, got_offset, info, TRUE);
}
static void
emit_trampoline (acfg, acfg->got_offset, info);
}
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG)
- mono_arch_create_monitor_enter_trampoline (&info, FALSE, TRUE);
- emit_trampoline (acfg, acfg->got_offset, info);
-#if defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
- mono_arch_create_monitor_enter_trampoline (&info, TRUE, TRUE);
- emit_trampoline (acfg, acfg->got_offset, info);
-#endif
- mono_arch_create_monitor_exit_trampoline (&info, TRUE);
- emit_trampoline (acfg, acfg->got_offset, info);
-#endif
-
/* Emit the exception related code pieces */
mono_arch_get_restore_context (&info, TRUE);
emit_trampoline (acfg, acfg->got_offset, info);
emit_code (MonoAotCompile *acfg)
{
int oindex, i, prev_index;
+ gboolean saved_unbox_info = FALSE;
char symbol [256];
#if defined(TARGET_POWERPC64)
if (acfg->thumb_mixed && cfg->compile_llvm)
emit_set_arm_mode (acfg);
+
+ if (!saved_unbox_info) {
+ char user_symbol [128];
+ GSList *unwind_ops;
+ sprintf (user_symbol, "%sunbox_trampoline_p", acfg->user_symbol_prefix);
+
+ emit_label (acfg, "ut_end");
+
+ unwind_ops = mono_unwind_get_cie_program ();
+ save_unwind_info (acfg, user_symbol, unwind_ops);
+ mono_free_unwind_info (unwind_ops);
+
+ /* Save the unbox trampoline size */
+ emit_symbol_diff (acfg, "ut_end", symbol, 0);
+
+ saved_unbox_info = TRUE;
+ }
}
if (cfg->compile_llvm)
tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
if (acfg->llvm) {
- llvm_ofile = g_strdup (acfg->llvm_ofile);
+ llvm_ofile = g_strdup_printf ("\"%s\"", acfg->llvm_ofile);
} else {
llvm_ofile = g_strdup ("");
}
g_strdelimit (ld_flags, ";", ' ');
#ifdef LD_NAME
- command = g_strdup_printf ("%s -o %s %s %s.o %s", LD_NAME, tmp_outfile_name, llvm_ofile, acfg->tmpfname, ld_flags);
+ command = g_strdup_printf ("%s -o \"%s\" %s \"%s.o\" %s", LD_NAME, tmp_outfile_name, llvm_ofile, acfg->tmpfname, ld_flags);
#else
command = g_strdup_printf ("\"%sld\" %s -shared -o %s %s %s.o %s", tool_prefix, LD_OPTIONS, tmp_outfile_name, llvm_ofile,
acfg->tmpfname, ld_flags);
rename (tmp_outfile_name, outfile_name);
#if defined(TARGET_MACH)
- command = g_strdup_printf ("dsymutil %s", outfile_name);
+ command = g_strdup_printf ("dsymutil \"%s\"", outfile_name);
aot_printf (acfg, "Executing dsymutil: %s\n", command);
if (execute_system (command) != 0) {
return 1;
#include <mono/metadata/metadata-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internal.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/mono-endian.h>
#include <mono/utils/mono-logger-internal.h>
int atype = decode_value (p, &p);
ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
- if (!ref->method) {
- fprintf (stderr, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
- exit (1);
- }
+ if (!ref->method)
+ g_error ("Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
break;
}
case MONO_WRAPPER_WRITE_BARRIER:
}
if (!sofile && !globals) {
- if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows) {
- fprintf (stderr, "Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
- exit (1);
- }
+ if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows)
+ g_error ("Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
g_free (aot_name);
return;
}
if (!usable) {
if (mono_aot_only) {
- fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode: %s.\n", aot_name, msg);
- exit (1);
+ g_error ("Failed to load AOT module '%s' while running in aot-only mode: %s.\n", aot_name, msg);
} else {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable: %s.\n", aot_name, msg);
}
init_gots (amodule);
+ /*
+ * Register the plt region as a single trampoline so we can unwind from this code
+ */
+ mono_tramp_info_register (
+ mono_tramp_info_create (
+ NULL,
+ amodule->plt,
+ amodule->plt_end - amodule->plt,
+ NULL,
+ mono_unwind_get_cie_program ()
+ ),
+ NULL
+ );
+
/*
* Since we store methoddef and classdef tokens when referring to methods/classes in
* referenced assemblies, we depend on the exact versions of the referenced assemblies.
if (amodule->out_of_date) {
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: Module %s is unusable because a dependency is out-of-date.\n", assembly->image->name);
- if (mono_aot_only) {
- fprintf (stderr, "Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", aot_name);
- exit (1);
- }
+ if (mono_aot_only)
+ g_error ("Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", aot_name);
}
else
mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: loaded AOT Module for %s.\n", assembly->image->name);
p += 4;
table = (gint32*)p;
- if (fde_count > 1) {
- /* mono_aot_personality () */
- g_assert (table [0] == -1);
- *code_start = amodule->methods [table [2]];
+ if (fde_count > 0) {
+ *code_start = amodule->methods [table [0]];
*code_end = (guint8*)amodule->methods [table [(fde_count - 1) * 2]] + table [fde_count * 2];
} else {
*code_start = NULL;
ji->data.offset = decode_value (p, &p);
break;
case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG:
- case MONO_PATCH_INFO_MONITOR_ENTER:
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- case MONO_PATCH_INFO_MONITOR_EXIT:
case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
case MONO_PATCH_INFO_GC_NURSERY_START:
case MONO_PATCH_INFO_JIT_TLS_ID:
amodule_unlock (amodule);
if (!m) {
m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
- if (m) {
+ /*
+ * Can't catche runtime invoke wrappers since it would break
+ * the check in decode_method_ref_with_target ().
+ */
+ if (m && m->wrapper_type != MONO_WRAPPER_RUNTIME_INVOKE) {
amodule_lock (amodule);
g_hash_table_insert (amodule->method_ref_to_method, orig_p, m);
amodule_unlock (amodule);
g_assert (res == 1);
target = mono_create_specific_trampoline (GUINT_TO_POINTER (slot), MONO_TRAMPOLINE_RGCTX_LAZY_FETCH, mono_get_root_domain (), NULL);
target = mono_create_ftnptr_malloc (target);
- } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_enter")) {
- target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
- target = mono_create_ftnptr_malloc (target);
- } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_enter_v4")) {
- target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
- target = mono_create_ftnptr_malloc (target);
- } else if (!strcmp (ji->data.name, "specific_trampoline_monitor_exit")) {
- target = mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
- target = mono_create_ftnptr_malloc (target);
} else if (!strcmp (ji->data.name, "mono_thread_get_and_clear_pending_exception")) {
target = mono_thread_get_and_clear_pending_exception;
} else if (!strcmp (ji->data.name, "debugger_agent_single_step_from_context")) {
gpointer
mono_aot_get_trampoline (const char *name)
{
- return mono_aot_get_trampoline_full (name, NULL);
+ MonoTrampInfo *out_tinfo;
+ gpointer code;
+
+ code = mono_aot_get_trampoline_full (name, &out_tinfo);
+ mono_tramp_info_register (out_tinfo, NULL);
+
+ return code;
+}
+
+static gpointer
+read_unwind_info (MonoAotModule *amodule, MonoTrampInfo *info, const char *symbol_name)
+{
+ gpointer symbol_addr;
+ guint32 uw_offset, uw_info_len;
+ guint8 *uw_info;
+
+ find_symbol (amodule->sofile, amodule->globals, symbol_name, &symbol_addr);
+
+ if (!symbol_addr)
+ return NULL;
+
+ uw_offset = *(guint32*)symbol_addr;
+ uw_info = amodule->unwind_info + uw_offset;
+ uw_info_len = decode_value (uw_info, &uw_info);
+
+ info->uw_info = uw_info;
+ info->uw_info_len = uw_info_len;
+
+ /* If successful return the address of the following data */
+ return (guint32*)symbol_addr + 1;
}
#ifdef MONOTOUCH
static TrampolinePage* trampoline_pages [MONO_AOT_TRAMP_NUM];
+static void
+read_page_trampoline_uwinfo (MonoTrampInfo *info, int tramp_type, gboolean is_generic)
+{
+ char symbol_name [128];
+
+ if (tramp_type == MONO_AOT_TRAMP_SPECIFIC)
+ sprintf (symbol_name, "specific_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+ else if (tramp_type == MONO_AOT_TRAMP_STATIC_RGCTX)
+ sprintf (symbol_name, "rgctx_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+ else if (tramp_type == MONO_AOT_TRAMP_IMT_THUNK)
+ sprintf (symbol_name, "imt_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+ else if (tramp_type == MONO_AOT_TRAMP_GSHAREDVT_ARG)
+ sprintf (symbol_name, "gsharedvt_trampolines_page_%s_p", is_generic ? "gen" : "sp");
+ else
+ g_assert_not_reached ();
+
+ read_unwind_info (mono_defaults.corlib->aot_module, info, symbol_name);
+}
+
static unsigned char*
get_new_trampoline_from_page (int tramp_type)
{
count = 40;
page = NULL;
while (page == NULL && count-- > 0) {
+ MonoTrampInfo *gen_info, *sp_info;
+
addr = 0;
/* allocate two contiguous pages of memory: the first page will contain the data (like a local constant pool)
* while the second will contain the trampolines.
code = page->trampolines;
page->trampolines += specific_trampoline_size;
mono_aot_page_unlock ();
+
+ /* Register the generic part at the beggining of the trampoline page */
+ gen_info = mono_tramp_info_create (NULL, (guint8*)taddr, amodule->info.tramp_page_code_offsets [tramp_type], NULL, NULL);
+ read_page_trampoline_uwinfo (gen_info, tramp_type, TRUE);
+ mono_tramp_info_register (gen_info, NULL);
+ /*
+ * FIXME
+ * Registering each specific trampoline produces a lot of
+ * MonoJitInfo structures. Jump trampolines are also registered
+ * separately.
+ */
+ if (tramp_type != MONO_AOT_TRAMP_SPECIFIC) {
+ /* Register the rest of the page as a single trampoline */
+ sp_info = mono_tramp_info_create (NULL, code, page->trampolines_end - code, NULL, NULL);
+ read_page_trampoline_uwinfo (sp_info, tramp_type, FALSE);
+ mono_tramp_info_register (sp_info, NULL);
+ }
return code;
}
g_error ("Cannot allocate more trampoline pages: %d", ret);
}
/* Return a given kind of trampoline */
+/* FIXME set unwind info for these trampolines */
static gpointer
get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size)
{
gpointer code;
guint32 *ut, *ut_end, *entry;
int low, high, entry_index = 0;
+ gpointer symbol_addr;
+ MonoTrampInfo *tinfo;
if (method->is_inflated && !mono_method_is_generic_sharable_full (method, FALSE, FALSE, FALSE)) {
method_index = find_aot_method (method, &amodule);
code = get_call_table_entry (amodule->unbox_trampoline_addresses, entry_index);
g_assert (code);
+ tinfo = mono_tramp_info_create (NULL, code, 0, NULL, NULL);
+
+ symbol_addr = read_unwind_info (amodule, tinfo, "unbox_trampoline_p");
+ if (!symbol_addr) {
+ mono_tramp_info_free (tinfo);
+ return FALSE;
+ }
+
+ tinfo->code_size = *(guint32*)symbol_addr;
+ mono_tramp_info_register (tinfo, NULL);
+
/* The caller expects an ftnptr */
return mono_create_ftnptr (mono_domain_get (), code);
}
using System;
using System.Text;
+using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
return 0;
}
+ class Foo6 {
+ public T reg_stack_split_inner<T> (int i, int j, T l) {
+ return l;
+ }
+ }
+
+ [Category("DYNCALL")]
+ static int test_0_arm_dyncall_reg_stack_split () {
+ var m = typeof (Foo6).GetMethod ("reg_stack_split_inner").MakeGenericMethod (new Type[] { typeof (long) });
+ var o = new Foo6 ();
+ if ((long)m.Invoke (o, new object [] { 1, 2, 3 }) != 3)
+ return 1;
+ if ((long)m.Invoke (o, new object [] { 1, 2, Int64.MaxValue }) != Int64.MaxValue)
+ return 2;
+ return 0;
+ }
+
static int test_0_partial_sharing_regress_30204 () {
var t = typeof (System.Collections.Generic.Comparer<System.Collections.Generic.KeyValuePair<string, string>>);
var d = new SortedDictionary<string, string> ();
var c = Comparer<AnEnum>.Default;
return c.Compare (AnEnum.A, AnEnum.A);
}
+
+ private static Dictionary<long, TValue> ConvertDictionary<TValue>(Dictionary<long, IList<TValue>> source) {
+ return source.ToDictionary(pair => pair.Key, pair => pair.Value[0]);
+ }
+
+ [Category ("GSHAREDVT")]
+ public static int test_0_gsharedvt_non_variable_arg () {
+ Dictionary<long, IList<int>> data = new Dictionary<long, IList<int>>
+ {
+ {123L, new List<int> {2}}
+ };
+ Dictionary<long, int> newDict = ConvertDictionary(data);
+ if (newDict.Count != 1)
+ return 1;
+ return 0;
+ }
}
void
mono_optimize_branches (MonoCompile *cfg)
{
- int i, changed = FALSE;
+ int i, count = 0, changed = FALSE;
MonoBasicBlock *bb, *bbn;
guint32 niterations;
MonoInst *bbn_first_inst;
/* we skip the entry block (exit is handled specially instead ) */
for (previous_bb = cfg->bb_entry, bb = cfg->bb_entry->next_bb; bb; previous_bb = bb, bb = bb->next_bb) {
+ count ++;
+ if (count == 1000) {
+ MONO_SUSPEND_CHECK ();
+ count = 0;
+ }
/* dont touch code inside exception clauses */
if (bb->region != -1)
continue;
gc_liveness_use: len:0
gc_spill_slot_liveness_def: len:0
gc_param_slot_liveness_def: len:0
+gc_safe_point: clob:c src1:i len:40
atomic_add_i4: dest:i src1:i src2:i len:64
atomic_exchange_i4: dest:i src1:i src2:i len:64
atomic_store_r8: dest:b src1:f len:20
generic_class_init: src1:a len:44 clob:c
+gc_safe_point: src1:i len:12 clob:c
jump_table: dest:i len:8
-atomic_add_i4: src1:b src2:i dest:i len:20
+atomic_add_i4: src1:b src2:i dest:i len:28
atomic_cas_i4: src1:b src2:i src3:i dest:i len:38
call: dest:a clob:c len:17
tailcall: len:120 clob:c
br: len:5
-seq_point: len:17
+seq_point: len:24 clob:c
il_seq_point: len:0
int_beq: len:6
*/
MonoThreadUnwindState filter_state;
- /*
- * The callee address of the last mono_runtime_invoke call
- */
- gpointer invoke_addr;
-
gboolean abort_requested;
/*
#define HEADER_LENGTH 11
#define MAJOR_VERSION 2
-#define MINOR_VERSION 40
+#define MINOR_VERSION 41
typedef enum {
CMD_SET_VM = 1,
static gboolean vm_start_event_sent, vm_death_event_sent, disconnected;
/* Maps MonoInternalThread -> DebuggerTlsData */
+/* Protected by the loader lock */
static MonoGHashTable *thread_to_tls;
/* Maps tid -> MonoInternalThread */
+/* Protected by the loader lock */
static MonoGHashTable *tid_to_thread;
/* Maps tid -> MonoThread (not MonoInternalThread) */
+/* Protected by the loader lock */
static MonoGHashTable *tid_to_thread_obj;
static gsize debugger_thread_id;
/* The single step request instance */
static SingleStepReq *ss_req;
-static gpointer ss_invoke_addr;
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
/* Number of single stepping operations in progress */
static gboolean protocol_version_set;
/* A hash table containing all active domains */
+/* Protected by the loader lock */
static GHashTable *domains;
/* The number of times the runtime is suspended */
int nreply_packets;
#define dbg_lock() do { \
- MONO_TRY_BLOCKING \
+ MONO_TRY_BLOCKING; \
mono_mutex_lock (&debug_mutex); \
- MONO_FINISH_TRY_BLOCKING \
+ MONO_FINISH_TRY_BLOCKING; \
} while (0)
#define dbg_unlock() mono_mutex_unlock (&debug_mutex)
static void emit_type_load (gpointer key, gpointer type, gpointer user_data);
-static void start_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
-static void end_runtime_invoke (MonoProfiler *prof, MonoMethod *method);
-
static void jit_end (MonoProfiler *prof, MonoMethod *method, MonoJitInfo *jinfo, int result);
static void add_pending_breakpoints (MonoMethod *method, MonoJitInfo *jinfo);
mono_profiler_install_thread (thread_startup, thread_end);
mono_profiler_install_assembly (NULL, assembly_load, assembly_unload, NULL);
mono_profiler_install_jit_end (jit_end);
- mono_profiler_install_method_invoke (start_runtime_invoke, end_runtime_invoke);
mono_native_tls_alloc (&debugger_tls_id, NULL);
}
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
transport_connect (agent_config.address);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (!on_startup) {
/* Do some which is usually done after sending the VMStart () event */
}
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
conn_fd = socket_transport_accept (sfd);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (conn_fd == -1)
exit (1);
/* Write handshake message */
sprintf (handshake_msg, "DWP-Handshake");
/* Must use try blocking as this can nest into code that runs blocking */
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
do {
res = transport_send (handshake_msg, strlen (handshake_msg));
} while (res == -1 && get_last_sock_error () == MONO_EINTR);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
g_assert (res != -1);
/* Read answer */
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
res = transport_recv (buf, strlen (handshake_msg));
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
if ((res != strlen (handshake_msg)) || (memcmp (buf, handshake_msg, strlen (handshake_msg)) != 0)) {
fprintf (stderr, "debugger-agent: DWP handshake failed.\n");
return FALSE;
if (!inited)
return;
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
transport_close1 ();
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
/*
* Wait for the thread to exit.
*/
if (GetCurrentThreadId () != debugger_thread_id) {
do {
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&debugger_thread_exited_mutex);
if (!debugger_thread_exited)
mono_cond_wait (&debugger_thread_exited_cond, &debugger_thread_exited_mutex);
mono_mutex_unlock (&debugger_thread_exited_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
} while (!debugger_thread_exited);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
transport_close2 ();
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
}
static void
buffer_add_byte (&buf, command);
memcpy (buf.buf + 11, data->buf, data->p - data->buf);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = transport_send (buf.buf, len);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
buffer_free (&buf);
buffer_add_buffer (&buf, packets [i].data);
}
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = transport_send (buf.buf, len);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
buffer_free (&buf);
} ObjRef;
/* Maps objid -> ObjRef */
+/* Protected by the loader lock */
static GHashTable *objrefs;
+/* Protected by the loader lock */
static GHashTable *obj_to_objref;
/* Protected by the dbg lock */
static MonoGHashTable *suspended_objs;
typedef struct {
/* Maps runtime structure -> Id */
+ /* Protected by the dbg lock */
GHashTable *val_to_id [ID_NUM];
/* Classes whose class load event has been sent */
+ /* Protected by the loader lock */
GHashTable *loaded_classes;
/* Maps MonoClass->GPtrArray of file names */
GHashTable *source_files;
if (val == NULL)
return 0;
- mono_loader_lock ();
-
- mono_domain_lock (domain);
-
info = get_agent_domain_info (domain);
+ dbg_lock ();
+
if (info->val_to_id [type] == NULL)
info->val_to_id [type] = g_hash_table_new (mono_aligned_addr_hash, NULL);
id = g_hash_table_lookup (info->val_to_id [type], val);
if (id) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
+ dbg_unlock ();
return id->id;
}
- dbg_lock ();
-
id = g_new0 (Id, 1);
/* Reserve id 0 */
id->id = ids [type]->len + 1;
dbg_unlock ();
- mono_domain_unlock (domain);
-
- mono_loader_unlock ();
-
return id->id;
}
{
GetLastFrameUserData *data = user_data;
- if (info->type == FRAME_TYPE_MANAGED_TO_NATIVE)
+ if (info->type == FRAME_TYPE_MANAGED_TO_NATIVE || info->type == FRAME_TYPE_TRAMPOLINE)
return FALSE;
if (!data->last_frame_set) {
// FIXME: Races when the thread leaves managed code before hitting a single step
// event.
- if (ji) {
+ if (ji && !ji->is_trampoline) {
/* Running managed code, will be suspended by the single step code */
DEBUG_PRINTF (1, "[%p] Received interrupt while at %s(%p), continuing.\n", (gpointer)(gsize)tid, jinfo_get_method (ji)->name, ip);
} else {
MonoJitInfo *ji;
data->valid_info = TRUE;
- ji = mono_jit_info_table_find (mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN], MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx));
+ ji = mono_jit_info_table_find_internal (
+ mono_thread_info_get_suspend_state (info)->unwind_data [MONO_UNWIND_DATA_DOMAIN],
+ MONO_CONTEXT_GET_IP (&mono_thread_info_get_suspend_state (info)->ctx),
+ TRUE,
+ TRUE);
/* This is signal safe */
thread_interrupt (data->tls, info, ji);
{
mono_loader_lock ();
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&suspend_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
suspend_count ++;
mono_loader_lock ();
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&suspend_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
g_assert (suspend_count > 0);
suspend_count --;
tls = mono_g_hash_table_lookup (thread_to_tls, thread);
g_assert (tls);
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&suspend_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
g_assert (suspend_count > 0);
tls = mono_native_tls_get_value (debugger_tls_id);
g_assert (tls);
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&suspend_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
tls->suspending = FALSE;
tls->really_suspended = TRUE;
DEBUG_PRINTF (1, "[%p] Suspended.\n", (gpointer)GetCurrentThreadId ());
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
while (suspend_count - tls->resume_count > 0) {
err = mono_cond_wait (&suspend_cond, &suspend_mutex);
g_assert (err == 0);
}
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
tls->suspended = FALSE;
tls->really_suspended = FALSE;
info->il_offset = mono_debug_il_offset_from_address (method, info->domain, info->native_offset);
}
- DEBUG_PRINTF (1, "\tFrame: %s:%x(%x) %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed);
+ DEBUG_PRINTF (1, "\tFrame: %s:[il=0x%x, native=0x%x] %d\n", mono_method_full_name (method, TRUE), info->il_offset, info->native_offset, info->managed);
if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
if (!CHECK_PROTOCOL_VERSION (2, 17))
clear_types_for_assembly (assembly);
}
-static void
-start_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
-#if defined(HOST_WIN32) && !defined(__GNUC__)
- gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
- gpointer stackptr = __builtin_frame_address (1);
-#endif
- MonoInternalThread *thread = mono_thread_internal_current ();
- DebuggerTlsData *tls;
-
- mono_loader_lock ();
-
- tls = mono_g_hash_table_lookup (thread_to_tls, thread);
- /* Could be the debugger thread with assembly/type load hooks */
- if (tls)
- tls->invoke_addr = stackptr;
-
- mono_loader_unlock ();
-}
-
-static void
-end_runtime_invoke (MonoProfiler *prof, MonoMethod *method)
-{
- int i;
-#if defined(HOST_WIN32) && !defined(__GNUC__)
- gpointer stackptr = ((guint64)_AddressOfReturnAddress () - sizeof (void*));
-#else
- gpointer stackptr = __builtin_frame_address (1);
-#endif
-
- if (!embedding || ss_req == NULL || stackptr != ss_invoke_addr || ss_req->thread != mono_thread_internal_current ())
- return;
-
- /*
- * We need to stop single stepping when exiting a runtime invoke, since if it is
- * a step out, it may return to native code, and thus never end.
- */
- mono_loader_lock ();
- ss_invoke_addr = NULL;
-
- for (i = 0; i < event_requests->len; ++i) {
- EventRequest *req = g_ptr_array_index (event_requests, i);
-
- if (req->event_kind == EVENT_KIND_STEP) {
- ss_destroy (req->info);
- g_ptr_array_remove_index_fast (event_requests, i);
- g_free (req);
- break;
- }
- }
- mono_loader_unlock ();
-}
-
static void
send_type_load (MonoClass *klass)
{
MonoDomain *domain = mono_domain_get ();
AgentDomainInfo *info = NULL;
- mono_loader_lock ();
- mono_domain_lock (domain);
-
info = get_agent_domain_info (domain);
+ mono_loader_lock ();
+
if (!g_hash_table_lookup (info->loaded_classes, klass)) {
type_load = TRUE;
g_hash_table_insert (info->loaded_classes, klass, klass);
}
- mono_domain_unlock (domain);
mono_loader_unlock ();
+
if (type_load)
emit_type_load (klass, klass, NULL);
}
send_types_for_domain (MonoDomain *domain, void *user_data)
{
AgentDomainInfo *info = NULL;
+
+ info = get_agent_domain_info (domain);
+ g_assert (info);
mono_loader_lock ();
- mono_domain_lock (domain);
- info = get_agent_domain_info (domain);
- g_assert (info);
g_hash_table_foreach (info->loaded_classes, emit_type_load, NULL);
- mono_domain_unlock (domain);
mono_loader_unlock ();
}
} MonoBreakpoint;
/* List of breakpoints */
+/* Protected by the loader lock */
static GPtrArray *breakpoints;
/* Maps breakpoint locations to the number of breakpoints at that location */
static GHashTable *bp_locs;
#endif
}
- DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:0x%x [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, inst->ip, count);
+ DEBUG_PRINTF (1, "[dbg] Inserted breakpoint at %s:[il=0x%x,native=0x%x] [%p](%d).\n", mono_method_full_name (jinfo_get_method (ji), TRUE), (int)it.seq_point.il_offset, (int)it.seq_point.native_offset, inst->ip, count);
}
static void
#endif
}
+/*
+ * This doesn't take any locks.
+ */
static inline gboolean
bp_matches_method (MonoBreakpoint *bp, MonoMethod *method)
{
}
if (!found) {
+ MonoMethod *declaring = NULL;
+
jmethod = jinfo_get_method (ji);
+ if (jmethod->is_inflated)
+ declaring = mono_method_get_declaring_generic_method (jmethod);
+
mono_domain_lock (domain);
seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, jmethod);
- if (!seq_points && jmethod->is_inflated)
- seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, mono_method_get_declaring_generic_method (jmethod));
+ if (!seq_points && declaring)
+ seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, declaring);
mono_domain_unlock (domain);
if (!seq_points)
/* Could be AOT code */
MonoDomain *domain;
MonoMethod *m;
MonoSeqPointInfo *seq_points;
+ GPtrArray *methods;
+ GPtrArray *method_domains;
+ GPtrArray *method_seq_points;
+ int i;
if (error)
mono_error_init (error);
DEBUG_PRINTF (1, "[dbg] Setting %sbreakpoint at %s:0x%x.\n", (req->event_kind == EVENT_KIND_STEP) ? "single step " : "", method ? mono_method_full_name (method, TRUE) : "<all>", (int)il_offset);
- mono_loader_lock ();
+ methods = g_ptr_array_new ();
+ method_domains = g_ptr_array_new ();
+ method_seq_points = g_ptr_array_new ();
+ mono_loader_lock ();
g_hash_table_iter_init (&iter, domains);
while (g_hash_table_iter_next (&iter, (void**)&domain, NULL)) {
mono_domain_lock (domain);
-
g_hash_table_iter_init (&iter2, domain_jit_info (domain)->seq_points);
while (g_hash_table_iter_next (&iter2, (void**)&m, (void**)&seq_points)) {
- if (bp_matches_method (bp, m))
- set_bp_in_method (domain, m, seq_points, bp, error);
+ if (bp_matches_method (bp, m)) {
+ /* Save the info locally to simplify the code inside the domain lock */
+ g_ptr_array_add (methods, m);
+ g_ptr_array_add (method_domains, domain);
+ g_ptr_array_add (method_seq_points, seq_points);
+ }
}
-
mono_domain_unlock (domain);
}
- mono_loader_unlock ();
+ for (i = 0; i < methods->len; ++i) {
+ m = g_ptr_array_index (methods, i);
+ domain = g_ptr_array_index (method_domains, i);
+ seq_points = g_ptr_array_index (method_seq_points, i);
+ set_bp_in_method (domain, m, seq_points, bp, error);
+ }
- mono_loader_lock ();
g_ptr_array_add (breakpoints, bp);
mono_loader_unlock ();
+ g_ptr_array_free (methods, TRUE);
+ g_ptr_array_free (method_domains, TRUE);
+ g_ptr_array_free (method_seq_points, TRUE);
+
if (error && !mono_error_ok (error)) {
clear_breakpoint (bp);
return NULL;
ip = MONO_CONTEXT_GET_IP (ctx);
ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, NULL);
- g_assert (ji);
+ g_assert (ji && !ji->is_trampoline);
method = jinfo_get_method (ji);
/* Compute the native offset of the breakpoint from the ip */
g_assert (found_sp);
- DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, offset=0x%x, sp il offset=0x%x.\n", (gpointer)GetCurrentThreadId (), method->name, ip, native_offset, sp.il_offset);
+ DEBUG_PRINTF (1, "[%p] Breakpoint hit, method=%s, ip=%p, [il=0x%x,native=0x%x].\n", (gpointer)GetCurrentThreadId (), method->name, ip, sp.il_offset, native_offset);
bp = NULL;
for (i = 0; i < breakpoints->len; ++i) {
}
ji = mini_jit_info_table_find (mono_domain_get (), (char*)ip, &domain);
- g_assert (ji);
+ g_assert (ji && !ji->is_trampoline);
method = jinfo_get_method (ji);
g_assert (method);
if (val == 1)
mono_arch_start_single_stepping ();
-
- if (ss_req != NULL && ss_invoke_addr == NULL) {
- DebuggerTlsData *tls;
-
- mono_loader_lock ();
-
- tls = mono_g_hash_table_lookup (thread_to_tls, ss_req->thread);
- ss_invoke_addr = tls->invoke_addr;
-
- mono_loader_unlock ();
- }
#else
g_assert_not_reached ();
#endif
if (val == 0)
mono_arch_stop_single_stepping ();
- if (ss_req != NULL)
- ss_invoke_addr = NULL;
#else
g_assert_not_reached ();
#endif
/* Can happen during shutdown */
return;
- mono_loader_lock ();
info = get_agent_domain_info (domain);
+
+ mono_loader_lock ();
g_hash_table_foreach_remove (info->loaded_classes, type_comes_from_assembly, assembly);
mono_loader_unlock ();
}
* Store the invoke data into tls, the thread will execute it after it is
* resumed.
*/
- if (tls->pending_invoke)
+ if (tls->pending_invoke || tls->invoke)
return ERR_NOT_SUSPENDED;
tls->pending_invoke = g_new0 (InvokeData, 1);
tls->pending_invoke->id = id;
char *s;
int i, index, length;
gunichar2 *c;
+ gboolean use_utf16 = FALSE;
objid = decode_objid (p, &p, end);
err = get_object (objid, (MonoObject**)&str);
switch (command) {
case CMD_STRING_REF_GET_VALUE:
- s = mono_string_to_utf8 (str);
- buffer_add_string (buf, s);
- g_free (s);
+ if (CHECK_PROTOCOL_VERSION (2, 41)) {
+ for (i = 0; i < mono_string_length (str); ++i)
+ if (mono_string_chars (str)[i] == 0)
+ use_utf16 = TRUE;
+ buffer_add_byte (buf, use_utf16 ? 1 : 0);
+ }
+ if (use_utf16) {
+ buffer_add_int (buf, mono_string_length (str) * 2);
+ buffer_add_data (buf, (guint8*)mono_string_chars (str), mono_string_length (str) * 2);
+ } else {
+ s = mono_string_to_utf8 (str);
+ buffer_add_string (buf, s);
+ g_free (s);
+ }
break;
case CMD_STRING_REF_GET_LENGTH:
buffer_add_long (buf, mono_string_length (str));
}
/* Block and wait for client connection */
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
conn_fd = socket_transport_accept (listen_fd);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
DEBUG_PRINTF (1, "Accepted connection on %d\n", conn_fd);
if (conn_fd == -1) {
}
while (!attach_failed) {
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = transport_recv (header, HEADER_LENGTH);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
/* This will break if the socket is closed during shutdown too */
if (res != HEADER_LENGTH) {
data = g_malloc (len - HEADER_LENGTH);
if (len - HEADER_LENGTH > 0)
{
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
res = transport_recv (data, len - HEADER_LENGTH);
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
if (res != len - HEADER_LENGTH) {
DEBUG_PRINTF (1, "[dbg] transport_recv () returned %d, expected %d.\n", res, len - HEADER_LENGTH);
break;
mono_set_is_debugger_attached (FALSE);
- MONO_TRY_BLOCKING
+ MONO_TRY_BLOCKING;
mono_mutex_lock (&debugger_thread_exited_mutex);
debugger_thread_exited = TRUE;
mono_cond_signal (&debugger_thread_exited_cond);
mono_mutex_unlock (&debugger_thread_exited_mutex);
- MONO_FINISH_TRY_BLOCKING
+ MONO_FINISH_TRY_BLOCKING;
DEBUG_PRINTF (1, "[dbg] Debugger thread exited.\n");
}
/* Convert the list of MonoUnwindOps to the format used by DWARF */
- uw_info = mono_unwind_ops_encode (l, &uw_info_len);
+ uw_info = mono_unwind_ops_encode_full (l, &uw_info_len, FALSE);
emit_bytes (w, uw_info, uw_info_len);
g_free (uw_info);
guint8 *unwind_info;
guint8 *epilog = NULL;
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
MonoTrampInfo *info = l->data;
mono_register_jit_icall (info->code, g_strdup (info->name), NULL, TRUE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
}
g_slist_free (tramps);
}
MonoTrampInfo *info = l->data;
mono_register_jit_icall (info->code, g_strdup (info->name), NULL, TRUE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
}
g_slist_free (tramps);
}
guint32 unwind_info_len;
guint8 *unwind_info;
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
}
if (ji) {
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
frame->ji = ji;
//print_ctx (new_ctx);
guint32 unwind_info_len;
guint8 *unwind_info;
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
guint32 unwind_info_len;
guint8 *unwind_info;
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
sframe = (MonoPPCStackFrame*)MONO_CONTEXT_GET_SP (ctx);
MONO_CONTEXT_SET_BP (new_ctx, sframe->sp);
- if (jinfo_get_method (ji)->save_lmf) {
+ if (!ji->is_trampoline && jinfo_get_method (ji)->save_lmf) {
/* sframe->sp points just past the end of the LMF */
guint8 *lmf_addr = (guint8*)sframe->sp - sizeof (MonoLMF);
memcpy (&new_ctx->fregs, lmf_addr + G_STRUCT_OFFSET (MonoLMF, fregs), sizeof (double) * MONO_SAVED_FREGS);
const char *method;
/* we don't do much now, but we can warn the user with a useful message */
fprintf (stderr, "Stack overflow: IP: %p, SP: %p\n", mono_arch_ip_from_context (sigctx), (gpointer)UCONTEXT_REG_Rn(uc, 1));
- if (ji && jinfo_get_method (ji))
+ if (ji && !ji->is_trampoline && jinfo_get_method (ji))
method = mono_method_full_name (jinfo_get_method (ji), TRUE);
else
method = "Unmanaged";
return result;
#endif
}
+
+
+// FIX ME: This is not complete
+void
+mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data)
+{
+ uintptr_t sp = (uintptr_t) MONO_CONTEXT_GET_SP(ctx);
+ sp -= PPC_MINIMAL_STACK_SIZE;
+ *(unsigned long *)sp = MONO_CONTEXT_GET_SP(ctx);
+ MONO_CONTEXT_SET_BP(ctx, sp);
+ MONO_CONTEXT_SET_IP(ctx, (unsigned long) async_cb);
+}
+
guint8 *unwind_info;
mgreg_t regs[16];
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
*new_ctx = *ctx;
if (ji != NULL) {
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
/* Restore ip and sp from the saved register window */
window = MONO_SPARC_WINDOW_ADDR (ctx->sp);
* <return addr> <- esp (unaligned on apple)
*/
- mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
- mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+ unwind_ops = mono_arch_get_cie_program ();
/* Alloc frame */
x86_alu_reg_imm (code, X86_SUB, X86_ESP, stack_size);
mono_arch_exceptions_init (void)
{
guint8 *tramp;
+ MonoTrampInfo *tinfo;
/*
* If we're running WoW64, we need to set the usermode exception policy
}
/* LLVM needs different throw trampolines */
- tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, NULL, FALSE);
+ tramp = get_throw_trampoline ("llvm_throw_exception_trampoline", FALSE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE);
mono_register_jit_icall (tramp, "llvm_throw_exception_trampoline", NULL, TRUE);
+ mono_tramp_info_register (tinfo, NULL);
- tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, NULL, FALSE);
+ tramp = get_throw_trampoline ("llvm_rethrow_exception_trampoline", TRUE, TRUE, FALSE, FALSE, FALSE, &tinfo, FALSE);
mono_register_jit_icall (tramp, "llvm_rethrow_exception_trampoline", NULL, TRUE);
+ mono_tramp_info_register (tinfo, NULL);
- tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, NULL, FALSE);
+ tramp = get_throw_trampoline ("llvm_throw_corlib_exception_trampoline", FALSE, TRUE, TRUE, FALSE, FALSE, &tinfo, FALSE);
mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_trampoline", NULL, TRUE);
+ mono_tramp_info_register (tinfo, NULL);
- tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, NULL, FALSE);
+ tramp = get_throw_trampoline ("llvm_throw_corlib_exception_abs_trampoline", FALSE, TRUE, TRUE, TRUE, FALSE, &tinfo, FALSE);
mono_register_jit_icall (tramp, "llvm_throw_corlib_exception_abs_trampoline", NULL, TRUE);
+ mono_tramp_info_register (tinfo, NULL);
- tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, NULL, FALSE);
+ tramp = get_throw_trampoline ("llvm_resume_unwind_trampoline", FALSE, FALSE, FALSE, FALSE, TRUE, &tinfo, FALSE);
mono_register_jit_icall (tramp, "llvm_resume_unwind_trampoline", NULL, TRUE);
+ mono_tramp_info_register (tinfo, NULL);
- signal_exception_trampoline = mono_x86_get_signal_exception_trampoline (NULL, FALSE);
+ signal_exception_trampoline = mono_x86_get_signal_exception_trampoline (&tinfo, FALSE);
+ mono_tramp_info_register (tinfo, NULL);
}
/*
guint32 unwind_info_len;
guint8 *unwind_info;
- frame->type = FRAME_TYPE_MANAGED;
+ if (ji->is_trampoline)
+ frame->type = FRAME_TYPE_TRAMPOLINE;
+ else
+ frame->type = FRAME_TYPE_MANAGED;
unwind_info = mono_jinfo_get_unwind_info (ji, &unwind_info_len);
start = code = mono_global_codeman_reserve (128);
+ /* FIXME no unwind before we push ip */
/* Caller ip */
x86_push_reg (code, X86_ECX);
- mono_add_unwind_op_def_cfa (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_ESP, 4);
- mono_add_unwind_op_offset (unwind_ops, (guint8*)NULL, (guint8*)NULL, X86_NREG, -4);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, start, X86_ESP, 4);
+ mono_add_unwind_op_offset (unwind_ops, code, start, X86_NREG, -4);
/* Fix the alignment to be what apple expects */
stack_size = 12;
interface IFaceBox {
object box<T> (T t);
+ bool is_null<T> (T t);
}
class ClassBox : IFaceBox {
object o = t;
return o;
}
+
+ public bool is_null<T> (T t) {
+ if (!(default(T) == null))
+ return false;
+ return true;
+ }
}
public static int test_0_nullable_box () {
return 0;
}
+ public static int test_0_nullable_box_brtrue_opt () {
+ IFaceBox c = new ClassBox ();
+
+ if (c.is_null<double?> (null))
+ return 0;
+ else
+ return 1;
+ }
+
interface IFaceUnbox2 {
T unbox<T> (object o);
}
#include <mono/metadata/security-manager.h>
#include <mono/metadata/threads-types.h>
#include <mono/metadata/security-core-clr.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/debug-mono-symfile.h>
/* helper methods signatures */
static MonoMethodSignature *helper_sig_domain_get;
static MonoMethodSignature *helper_sig_rgctx_lazy_fetch_trampoline;
-static MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline;
-static MonoMethodSignature *helper_sig_monitor_enter_exit_trampoline_llvm;
-static MonoMethodSignature *helper_sig_monitor_enter_v4_trampoline_llvm;
/*
* Instruction metadata
{
helper_sig_domain_get = mono_create_icall_signature ("ptr");
helper_sig_rgctx_lazy_fetch_trampoline = mono_create_icall_signature ("ptr ptr");
- helper_sig_monitor_enter_exit_trampoline = mono_create_icall_signature ("void");
- helper_sig_monitor_enter_exit_trampoline_llvm = mono_create_icall_signature ("void object");
- helper_sig_monitor_enter_v4_trampoline_llvm = mono_create_icall_signature ("void object ptr");
}
static MONO_NEVER_INLINE void
g_hash_table_insert (h, (char*)"Decimal", GUINT_TO_POINTER (1));
g_hash_table_insert (h, (char*)"Number", GUINT_TO_POINTER (1));
g_hash_table_insert (h, (char*)"Buffer", GUINT_TO_POINTER (1));
+ g_hash_table_insert (h, (char*)"Monitor", GUINT_TO_POINTER (1));
mono_memory_barrier ();
direct_icall_type_hash = h;
}
return ins;
}
}
- } else if (cmethod->klass == mono_defaults.monitor_class) {
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG)
- if (strcmp (cmethod->name, "Enter") == 0 && fsig->param_count == 1) {
- MonoCallInst *call;
-
- if (COMPILE_LLVM (cfg)) {
- /*
- * Pass the argument normally, the LLVM backend will handle the
- * calling convention problems.
- */
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
- } else {
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER,
- NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
- mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
- MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
- }
-
- return (MonoInst*)call;
-#if defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
- } else if (strcmp (cmethod->name, "Enter") == 0 && fsig->param_count == 2) {
- MonoCallInst *call;
-
- if (COMPILE_LLVM (cfg)) {
- /*
- * Pass the argument normally, the LLVM backend will handle the
- * calling convention problems.
- */
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER_V4, NULL, helper_sig_monitor_enter_v4_trampoline_llvm, args);
- } else {
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_ENTER_V4,
- NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
- mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg, MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
- mono_call_inst_add_outarg_reg (cfg, call, args [1]->dreg, MONO_ARCH_MONITOR_LOCK_TAKEN_REG, FALSE);
- }
-
- return (MonoInst*)call;
-#endif
- } else if (strcmp (cmethod->name, "Exit") == 0 && fsig->param_count == 1) {
- MonoCallInst *call;
-
- if (COMPILE_LLVM (cfg)) {
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT, NULL, helper_sig_monitor_enter_exit_trampoline_llvm, args);
- } else {
- call = (MonoCallInst*)mono_emit_abs_call (cfg, MONO_PATCH_INFO_MONITOR_EXIT,
- NULL, helper_sig_monitor_enter_exit_trampoline, NULL);
- mono_call_inst_add_outarg_reg (cfg, call, args [0]->dreg,
- MONO_ARCH_MONITOR_OBJECT_REG, FALSE);
- }
-
- return (MonoInst*)call;
- }
-#endif
} else if (cmethod->klass->image == mono_defaults.corlib &&
(strcmp (cmethod->klass->name_space, "System.Threading") == 0) &&
(strcmp (cmethod->klass->name, "Interlocked") == 0)) {
cfg->disable_inline = prev_disable_inline;
cfg->inline_depth --;
- if ((costs >= 0 && costs < 60) || inline_always) {
+ if ((costs >= 0 && costs < 60) || inline_always || (costs >= 0 && (cmethod->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING))) {
if (cfg->verbose_level > 2)
printf ("INLINE END %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
MONO_INST_NEW (cfg, ins, OP_START_HANDLER);
MONO_ADD_INS (tblock, ins);
- if (seq_points && clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY) {
+ if (seq_points && clause->flags != MONO_EXCEPTION_CLAUSE_FINALLY && clause->flags != MONO_EXCEPTION_CLAUSE_FILTER) {
/* finally clauses already have a seq point */
+ /* seq points for filter clauses are emitted below */
NEW_SEQ_POINT (cfg, ins, clause->handler_offset, TRUE);
MONO_ADD_INS (tblock, ins);
}
*/
EMIT_NEW_DUMMY_USE (cfg, dummy_use, tblock->in_stack [0]);
#endif
+
+ if (seq_points && clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
+ NEW_SEQ_POINT (cfg, ins, clause->handler_offset, TRUE);
+ MONO_ADD_INS (tblock, ins);
+ }
if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) {
GET_BBLOCK (cfg, tblock, ip + clause->data.filter_offset);
CHECK_CFG_ERROR;
}
+ /* See code below */
+ if (cmethod->klass == mono_defaults.monitor_class && !strcmp (cmethod->name, "Enter") && mono_method_signature (cmethod)->param_count == 1) {
+ MonoBasicBlock *tbb;
+
+ GET_BBLOCK (cfg, tbb, ip + 5);
+ if (tbb->try_start && MONO_REGION_FLAGS(tbb->region) == MONO_EXCEPTION_CLAUSE_FINALLY) {
+ /*
+ * We want to extend the try block to cover the call, but we can't do it if the
+ * call is made directly since its followed by an exception check.
+ */
+ direct_icall = FALSE;
+ }
+ }
+
mono_save_token_info (cfg, image, token, cil_method);
if (!(seq_point_locs && mono_bitset_test_fast (seq_point_locs, ip + 5 - header->code)))
// FIXME: LLVM can't handle the inconsistent bb linking
if (!mono_class_is_nullable (klass) &&
+ !mini_is_gsharedvt_klass (klass) &&
ip + 5 < end && ip_in_bb (cfg, cfg->cbb, ip + 5) &&
(ip [5] == CEE_BRTRUE ||
ip [5] == CEE_BRTRUE_S ||
ensure_method_is_allowed_to_access_field (cfg, method, field);
*/
+ ftype = mono_field_get_type (field);
+
/*
* LDFLD etc. is usable on static fields as well, so convert those cases to
* the static case.
*/
- if (is_instance && field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+ if (is_instance && ftype->attrs & FIELD_ATTRIBUTE_STATIC) {
switch (op) {
case CEE_LDFLD:
op = CEE_LDSFLD;
/* STATIC CASE */
context_used = mini_class_check_context_used (cfg, klass);
- ftype = mono_field_get_type (field);
-
if (ftype->attrs & FIELD_ATTRIBUTE_LITERAL)
UNVERIFIED;
#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
static mono_mutex_t mini_arch_mutex;
-MonoBreakpointInfo
-mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
/*
* The code generated for sequence points reads from this location, which is
* made read-only when single stepping is enabled.
#define MAX_ARCH_DELEGATE_PARAMS 10
static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count)
{
guint8 *code, *start;
+ GSList *unwind_ops = NULL;
int i;
+ unwind_ops = mono_arch_get_cie_program ();
+
if (has_target) {
start = code = mono_global_codeman_reserve (64);
nacl_global_codeman_validate (&start, 64, &code);
mono_arch_flush_icache (start, code - start);
- if (code_len)
- *code_len = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+ g_free (name);
+ }
if (mono_jit_map_is_enabled ()) {
char *buff;
#define MAX_VIRTUAL_DELEGATE_OFFSET 32
static gpointer
-get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_len)
+get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, int offset)
{
guint8 *code, *start;
int size = 20;
+ char *tramp_name;
+ GSList *unwind_ops;
- if (offset / sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+ if (offset / (int)sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
return NULL;
start = code = mono_global_codeman_reserve (size);
+ unwind_ops = mono_arch_get_cie_program ();
+
/* Replace the this argument with the target */
amd64_mov_reg_reg (code, AMD64_RAX, AMD64_ARG_REG1, 8);
amd64_mov_reg_membase (code, AMD64_ARG_REG1, AMD64_RAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 8);
amd64_jump_membase (code, AMD64_RAX, offset);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (code_len)
- *code_len = code - start;
+ if (load_imt_reg)
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
+ else
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+ *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
+ g_free (tramp_name);
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0);
+ res = g_slist_prepend (res, info);
- for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+ get_delegate_invoke_impl (&info, FALSE, i);
+ res = g_slist_prepend (res, info);
}
- for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
- code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+ get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
+ res = g_slist_prepend (res, info);
- code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
+ res = g_slist_prepend (res, info);
}
return res;
if (cached)
return cached;
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0);
+ mono_tramp_info_register (info, NULL);
+ }
mono_memory_barrier ();
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+ mono_tramp_info_register (info, NULL);
}
mono_memory_barrier ();
gpointer
mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
{
- return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
+ MonoTrampInfo *info;
+ gpointer code;
+
+ code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
+ if (code)
+ mono_tramp_info_register (info, NULL);
+ return code;
}
void
int size = 0;
guint8 *code, *start;
gboolean vtable_is_32bit = ((gsize)(vtable) == (gsize)(int)(gsize)(vtable));
+ GSList *unwind_ops;
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
code = mono_domain_code_reserve (domain, size);
#endif
start = code;
+
+ unwind_ops = mono_arch_get_cie_program ();
+
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
item->code_target = code;
nacl_domain_code_validate(domain, &start, size, &code);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
#define MONO_ARCH_HAVE_LIVERANGE_OPS 1
#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
-#define MONO_ARCH_MONITOR_OBJECT_REG MONO_AMD64_ARG_REG1
-#define MONO_ARCH_MONITOR_LOCK_TAKEN_REG MONO_AMD64_ARG_REG2
#define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
#define MONO_ARCH_AOT_SUPPORTED 1
int
mono_amd64_get_tls_gs_offset (void) MONO_LLVM_INTERNAL;
-typedef struct {
- guint8 *address;
- guint8 saved_byte;
-} MonoBreakpointInfo;
-
-extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
#ifdef TARGET_WIN32
void mono_arch_unwindinfo_add_push_nonvol (gpointer* monoui, gpointer codebegin, gpointer nextip, guchar reg );
* within can be tracked. The tls value is returned in R0.
*/
+.macro DECLARE_GLOBAL_SYMBOL name
+#ifdef TARGET_MACH
+ .global _\name
+_\name:
+#else
+ .global \name
+\name:
+#endif
+.endm
+
.text
/* no .arch on clang. it only supports armv6+ anyway */
#ifndef TARGET_MACH
#endif
.arm
.align 4
-#ifdef TARGET_MACH
- .global _mono_fast_get_tls_key
-_mono_fast_get_tls_key :
-#else
- .global mono_fast_get_tls_key
-mono_fast_get_tls_key :
-#endif
+
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key
#if defined(__linux__)
mrc p15, 0, r1, c13, c0, 3
#if defined(HAVE_KW_THREAD)
ldr r0, [r1, r0, lsl #2]
bx lr
#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_get_tls_key_end
/*
* The following thunks fetch the value corresponding to the key/offset
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fallback_get_tls_key
-_mono_fallback_get_tls_key :
-#else
- .global mono_fallback_get_tls_key
-mono_fallback_get_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fallback_get_tls_key
#if defined(__linux__)
mov r1, r0
mvn r0, #0xf000
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fast_set_tls_key
-_mono_fast_set_tls_key :
-#else
- .global mono_fast_set_tls_key
-mono_fast_set_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key
#if defined(__linux__)
mrc p15, 0, r2, c13, c0, 3
#if defined(HAVE_KW_THREAD)
str r1, [r2, r0, lsl #2]
bx lr
#endif
+DECLARE_GLOBAL_SYMBOL mono_fast_set_tls_key_end
/*
* The following thunks set the value corresponding to the key/offset
*/
.align 4
-#ifdef TARGET_MACH
- .global _mono_fallback_set_tls_key
-_mono_fallback_set_tls_key :
-#else
- .global mono_fallback_set_tls_key
-mono_fallback_set_tls_key :
-#endif
+DECLARE_GLOBAL_SYMBOL mono_fallback_set_tls_key
#if defined(__linux__)
mov r2, r0
mvn r0, #0xf000
int mono_fallback_get_tls_key (int);
void mono_fallback_set_tls_key (int, int);
+/* End of thunks */
+
+void mono_fast_get_tls_key_end (void);
+void mono_fast_set_tls_key_end (void);
+
#endif
#define MAX_ARCH_DELEGATE_PARAMS 3
static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
{
guint8 *code, *start;
+ GSList *unwind_ops = mono_arch_get_cie_program ();
if (has_target) {
start = code = mono_global_codeman_reserve (12);
mono_arch_flush_icache (start, size);
}
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+ g_free (name);
+ }
+
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (code_size)
- *code_size = code - start;
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0);
+ res = g_slist_prepend (res, info);
for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ get_delegate_invoke_impl (&info, FALSE, i);
+ res = g_slist_prepend (res, info);
}
return res;
return cached;
}
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0);
+ mono_tramp_info_register (info, NULL);
+ }
cached = start;
mono_mini_arch_unlock ();
return cached;
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+ mono_tramp_info_register (info, NULL);
}
cache [sig->param_count] = start;
mono_mini_arch_unlock ();
cinfo->ret.reg = ARMREG_R0;
break;
}
- // FIXME: Only for variable types
- if (mini_is_gsharedvt_type (t)) {
+ if (mini_is_gsharedvt_variable_type (t)) {
cinfo->ret.storage = RegTypeStructByAddr;
break;
}
add_general (&gr, &stack_size, ainfo, TRUE);
break;
}
- if (mini_is_gsharedvt_type (t)) {
+ if (mini_is_gsharedvt_variable_type (t)) {
/* gsharedvt arguments are passed by ref */
g_assert (mini_is_gsharedvt_type (t));
add_general (&gr, &stack_size, ainfo, TRUE);
switch (ainfo->storage) {
case RegTypeGeneral:
- break;
case RegTypeIRegPair:
+ case RegTypeBaseGen:
break;
case RegTypeBase:
if (ainfo->offset >= (DYN_CALL_STACK_ARGS * sizeof (gpointer)))
ArgInfo *ainfo = &dinfo->cinfo->args [i + sig->hasthis];
int slot = -1;
- if (ainfo->storage == RegTypeGeneral || ainfo->storage == RegTypeIRegPair || ainfo->storage == RegTypeStructByVal)
+ if (ainfo->storage == RegTypeGeneral || ainfo->storage == RegTypeIRegPair || ainfo->storage == RegTypeStructByVal) {
slot = ainfo->reg;
- else if (ainfo->storage == RegTypeBase)
+ } else if (ainfo->storage == RegTypeBase) {
slot = PARAM_REGS + (ainfo->offset / 4);
- else
+ } else if (ainfo->storage == RegTypeBaseGen) {
+ /* slot + 1 is the first stack slot, so the code below will work */
+ slot = 3;
+ } else {
g_assert_not_reached ();
+ }
if (t->byref) {
p->regs [slot] = (mgreg_t)*arg;
/* Free entry */
target_thunk = p;
break;
+ } else if (((guint32*)p) [2] == (guint32)target) {
+ /* Thunk already points to target */
+ target_thunk = p;
+ break;
}
}
}
ins->backend.pc_offset = code - cfg->native_code;
bb->spill_slot_defs = g_slist_prepend_mempool (cfg->mempool, bb->spill_slot_defs, ins);
break;
+ case OP_GC_SAFE_POINT: {
+#if defined (USE_COOP_GC)
+ const char *polling_func = NULL;
+ guint8 *buf [1];
+
+ polling_func = "mono_threads_state_poll";
+ ARM_LDR_IMM (code, ARMREG_IP, ins->sreg1, 0);
+ ARM_CMP_REG_IMM (code, ARMREG_IP, 0, 0);
+ buf [0] = code;
+ ARM_B_COND (code, ARMCOND_EQ, 0);
+ mono_add_patch_info (cfg, code - cfg->native_code, MONO_PATCH_INFO_INTERNAL_METHOD, polling_func);
+ code = emit_call_seq (cfg, code);
+ arm_patch (buf [0], code);
+#endif
+ break;
+ }
default:
g_warning ("unknown opcode %s in %s()\n", mono_inst_name (ins->opcode), __FUNCTION__);
if (mono_arm_have_fast_tls ()) {
mono_register_jit_icall (mono_fast_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
mono_register_jit_icall (mono_fast_set_tls_key, "mono_set_tls_key", mono_create_icall_signature ("void ptr ptr"), TRUE);
+
+ mono_tramp_info_register (
+ mono_tramp_info_create (
+ "mono_get_tls_key",
+ (guint8*)mono_fast_get_tls_key,
+ (guint8*)mono_fast_get_tls_key_end - (guint8*)mono_fast_get_tls_key,
+ NULL,
+ mono_arch_get_cie_program ()
+ ),
+ NULL
+ );
+ mono_tramp_info_register (
+ mono_tramp_info_create (
+ "mono_set_tls_key",
+ (guint8*)mono_fast_set_tls_key,
+ (guint8*)mono_fast_set_tls_key_end - (guint8*)mono_fast_set_tls_key,
+ NULL,
+ mono_arch_get_cie_program ()
+ ),
+ NULL
+ );
} else {
g_warning ("No fast tls on device. Using fallbacks.");
mono_register_jit_icall (mono_fallback_get_tls_key, "mono_get_tls_key", mono_create_icall_signature ("ptr ptr"), TRUE);
* FIXME: Optimize this.
*/
ARM_PUSH (code, (1 << ARMREG_R7) | (1 << ARMREG_LR));
- ARM_MOV_REG_REG (code, ARMREG_R7, ARMREG_SP);
prev_sp_offset += 8; /* r7 and lr */
mono_emit_unwind_op_def_cfa_offset (cfg, code, prev_sp_offset);
mono_emit_unwind_op_offset (cfg, code, ARMREG_R7, (- prev_sp_offset) + 0);
+ ARM_MOV_REG_REG (code, ARMREG_R7, ARMREG_SP);
}
if (!method->save_lmf) {
*/
code = cfg->native_code + cfg->code_len;
+ /* Save the uwind state which is needed by the out-of-line code */
+ mono_emit_unwind_op_remember_state (cfg, code);
+
if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) {
code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
}
}
if (method->save_lmf) {
- int lmf_offset, reg, sp_adj, regmask;
+ int lmf_offset, reg, sp_adj, regmask, nused_int_regs = 0;
/* all but r0-r3, sp and pc */
pos += sizeof (MonoLMF) - (MONO_ARM_NUM_SAVED_REGS * sizeof (mgreg_t));
lmf_offset = pos;
regmask &= ~(1 << ARMREG_PC);
/* point sp at the registers to restore: 10 is 14 -4, because we skip r0-r3 */
code = emit_big_add (code, ARMREG_SP, cfg->frame_reg, cfg->stack_usage - lmf_offset + sp_adj);
+ for (i = 0; i < 16; i++) {
+ if (regmask & (1 << i))
+ nused_int_regs ++;
+ }
+ mono_emit_unwind_op_def_cfa (cfg, code, ARMREG_SP, ((iphone_abi ? 3 : 0) + nused_int_regs) * 4);
/* restore iregs */
ARM_POP (code, regmask);
if (iphone_abi) {
+ for (i = 0; i < 16; i++) {
+ if (regmask & (1 << i))
+ mono_emit_unwind_op_same_value (cfg, code, i);
+ }
/* Restore saved r7, restore LR to PC */
/* Skip lr from the lmf */
+ mono_emit_unwind_op_def_cfa_offset (cfg, code, 3 * 4);
ARM_ADD_REG_IMM (code, ARMREG_SP, ARMREG_SP, sizeof (gpointer), 0);
+ mono_emit_unwind_op_def_cfa_offset (cfg, code, 2 * 4);
ARM_POP (code, (1 << ARMREG_R7) | (1 << ARMREG_PC));
}
} else {
+ int i, nused_int_regs = 0;
+
+ for (i = 0; i < 16; i++) {
+ if (cfg->used_int_regs & (1 << i))
+ nused_int_regs ++;
+ }
+
if ((i = mono_arm_is_rotated_imm8 (cfg->stack_usage, &rot_amount)) >= 0) {
ARM_ADD_REG_IMM (code, ARMREG_SP, cfg->frame_reg, i, rot_amount);
} else {
ARM_ADD_REG_REG (code, ARMREG_SP, cfg->frame_reg, ARMREG_IP);
}
+ if (cfg->frame_reg != ARMREG_SP) {
+ mono_emit_unwind_op_def_cfa_reg (cfg, code, ARMREG_SP);
+ }
+
if (iphone_abi) {
/* Restore saved gregs */
- if (cfg->used_int_regs)
+ if (cfg->used_int_regs) {
+ mono_emit_unwind_op_def_cfa_offset (cfg, code, (2 + nused_int_regs) * 4);
ARM_POP (code, cfg->used_int_regs);
+ for (i = 0; i < 16; i++) {
+ if (cfg->used_int_regs & (1 << i))
+ mono_emit_unwind_op_same_value (cfg, code, i);
+ }
+ }
+ mono_emit_unwind_op_def_cfa_offset (cfg, code, 2 * 4);
/* Restore saved r7, restore LR to PC */
ARM_POP (code, (1 << ARMREG_R7) | (1 << ARMREG_PC));
} else {
+ mono_emit_unwind_op_def_cfa_offset (cfg, code, (nused_int_regs + 1) * 4);
ARM_POP (code, cfg->used_int_regs | (1 << ARMREG_PC));
}
}
+ /* Restore the unwind state to be the same as before the epilog */
+ mono_emit_unwind_op_restore_state (cfg, code);
+
cfg->code_len = code - cfg->native_code;
g_assert (cfg->code_len < cfg->code_size);
return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG];
}
+GSList*
+mono_arch_get_cie_program (void)
+{
+ GSList *l = NULL;
+
+ mono_add_unwind_op_def_cfa (l, (guint8*)NULL, (guint8*)NULL, ARMREG_SP, 0);
+
+ return l;
+}
+
/* #define ENABLE_WRONG_METHOD_CHECK 1 */
#define BASE_SIZE (6 * 4)
#define BSEARCH_ENTRY_SIZE (4 * 4)
#ifdef ENABLE_WRONG_METHOD_CHECK
char * cond;
#endif
+ GSList *unwind_ops;
size = BASE_SIZE;
#ifdef USE_JUMP_TABLES
code = mono_domain_code_reserve (domain, size);
start = code;
+ unwind_ops = mono_arch_get_cie_program ();
+
#ifdef DEBUG_IMT
g_print ("Building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p fail_tramp %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable, fail_tramp);
for (i = 0; i < count; ++i) {
#ifdef USE_JUMP_TABLES
ARM_PUSH3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 3 * sizeof (mgreg_t));
#define VTABLE_JTI 0
#define IMT_METHOD_OFFSET 0
#define TARGET_CODE_OFFSET 1
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_R2, VTABLE_JTI);
set_jumptable_element (jte, VTABLE_JTI, vtable);
#else
- if (large_offsets)
+ if (large_offsets) {
ARM_PUSH4 (code, ARMREG_R0, ARMREG_R1, ARMREG_IP, ARMREG_PC);
- else
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 4 * sizeof (mgreg_t));
+ } else {
ARM_PUSH2 (code, ARMREG_R0, ARMREG_R1);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 2 * sizeof (mgreg_t));
+ }
ARM_LDR_IMM (code, ARMREG_R0, ARMREG_LR, -4);
vtable_target = code;
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_PC, 0);
code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
/* Restore registers */
ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
/* And branch */
ARM_BX (code, ARMREG_R1);
set_jumptable_element (jte, target_code_jti, item->value.target_code);
ARM_LDR_REG_REG (code, ARMREG_IP, ARMREG_IP, ARMREG_R1);
/* Restore registers and branch */
ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
ARM_BX (code, ARMREG_IP);
#else
vtable_offset_ins = code;
#ifdef USE_JUMP_TABLES
ARM_LDR_IMM (code, ARMREG_IP, ARMREG_IP, vtable_offset);
ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
ARM_BX (code, ARMREG_IP);
#else
ARM_POP2 (code, ARMREG_R0, ARMREG_R1);
- if (large_offsets)
+ if (large_offsets) {
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 2 * sizeof (mgreg_t));
ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 2 * sizeof (gpointer));
+ }
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, vtable_offset);
#endif
}
code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, target_code_jti, ARMCOND_AL);
/* Restore registers */
ARM_POP3 (code, ARMREG_R0, ARMREG_R1, ARMREG_R2);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, 0);
/* And branch */
ARM_BX (code, ARMREG_R1);
set_jumptable_element (jte, target_code_jti, fail_tramp);
mono_stats.imt_thunks_size += code - start;
g_assert (DISTANCE (start, code) <= size);
+
+ mono_tramp_info_register (mono_tramp_info_create (NULL, (guint8*)start, DISTANCE (start, code), NULL, unwind_ops), domain);
+
return start;
}
pid_t
mono_runtime_syscall_fork ()
{
+#ifdef HAVE_FORK
return (pid_t) fork ();
+#else
+ g_assert_not_reached ();
+#endif
}
void
mono_gdb_render_native_backtraces (pid_t crashed_pid)
{
+#ifdef HAVE_EXECV
const char *argv [5];
char template [] = "/tmp/mono-gdb-commands.XXXXXX";
FILE *commands;
gboolean using_lldb = FALSE;
+ using_lldb = TRUE;
+
argv [0] = g_find_program_in_path ("gdb");
- if (!argv [0]) {
- // FIXME: LLDB doesn't quit when given the 'quit' command
- //argv [0] = g_find_program_in_path ("lldb");
- //using_lldb = TRUE;
- }
+ if (argv [0])
+ using_lldb = FALSE;
+
+ if (using_lldb)
+ argv [0] = g_find_program_in_path ("lldb");
if (argv [0] == NULL)
return;
} else {
fprintf (commands, "attach %ld\n", (long) crashed_pid);
fprintf (commands, "info threads\n");
+ fprintf (commands, " t a a info thread\n");
fprintf (commands, "thread apply all bt\n");
argv [1] = "-batch";
argv [2] = "-x";
fflush (commands);
fclose (commands);
+ fclose (stdin);
+
execv (argv [0], (char**)argv);
unlink (template);
+#else
+ fprintf (stderr, "mono_gdb_render_native_backtraces not supported on this platform\n");
+#endif // HAVE_EXECV
}
gboolean
#include <mono/metadata/profiler.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/environment.h>
+#include <mono/metadata/mono-mlist.h>
#include <mono/utils/mono-mmap.h>
#include <mono/utils/mono-logger-internal.h>
MonoTrampInfo *info;
restore_context_func = mono_arch_get_restore_context (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
call_filter_func = mono_arch_get_call_filter (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
throw_exception_func = mono_arch_get_throw_exception (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
rethrow_exception_func = mono_arch_get_rethrow_exception (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
}
#ifdef MONO_ARCH_HAVE_RESTORE_STACK_SUPPORT
try_more_restore_tramp = mono_create_specific_trampoline (try_more_restore, MONO_TRAMPOLINE_RESTORE_STACK_PROT, mono_domain_get (), NULL);
code = mono_aot_get_trampoline ("throw_corlib_exception");
else {
code = mono_arch_get_throw_corlib_exception (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
}
mono_memory_barrier ();
if (managed)
*managed = TRUE;
return frame.ji;
+ case FRAME_TYPE_TRAMPOLINE:
+ return frame.ji;
case FRAME_TYPE_MANAGED_TO_NATIVE:
if (frame.ji)
return frame.ji;
if (ji == (gpointer)-1)
return ji;
- if (ji)
+ if (ji && !ji->is_trampoline)
method = jinfo_get_method (ji);
- if (managed2 || (ji && method->wrapper_type)) {
+ if (managed2 || (method && method->wrapper_type)) {
const char *real_ip, *start;
gint32 offset;
*lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~(SIZEOF_VOID_P -1));
}
- if (frame->ji && !frame->ji->async)
+ if (frame->ji && !frame->ji->is_trampoline && !frame->ji->async)
method = jinfo_get_method (frame->ji);
if (frame->type == FRAME_TYPE_MANAGED && method) {
return TRUE;
}
+/*
+ * This function is async-safe.
+ */
static gpointer
get_generic_info_from_stack_frame (MonoJitInfo *ji, MonoContext *ctx)
{
return len > 0;
}
-MonoString *
-ves_icall_System_Exception_get_trace (MonoException *ex)
-{
- MonoDomain *domain = mono_domain_get ();
- MonoString *res;
- MonoArray *ta = ex->trace_ips;
- int i, len;
- GString *trace_str;
-
- if (ta == NULL)
- /* Exception is not thrown yet */
- return NULL;
-
- len = mono_array_length (ta) >> 1;
- trace_str = g_string_new ("");
- for (i = 0; i < len; i++) {
- MonoJitInfo *ji;
- gpointer ip = mono_array_get (ta, gpointer, i * 2 + 0);
- gpointer generic_info = mono_array_get (ta, gpointer, i * 2 + 1);
-
- ji = mono_jit_info_table_find (domain, ip);
- if (ji == NULL) {
- /* Unmanaged frame */
- g_string_append_printf (trace_str, "in (unmanaged) %p\n", ip);
- } else {
- gchar *location;
- gint32 address;
- MonoMethod *method = get_method_from_stack_frame (ji, generic_info);
-
- address = (char *)ip - (char *)ji->code_start;
- location = mono_debug_print_stack_frame (
- method, address, ex->object.vtable->domain);
-
- g_string_append_printf (trace_str, "%s\n", location);
- g_free (location);
- }
- }
-
- res = mono_string_new (ex->object.vtable->domain, trace_str->str);
- g_string_free (trace_str, TRUE);
-
- return res;
-}
-
MonoArray *
ves_icall_get_trace (MonoException *exc, gint32 skip, MonoBoolean need_file_info)
{
g_assert (state->valid);
+ if (!state->unwind_data [MONO_UNWIND_DATA_DOMAIN])
+ /* Not attached */
+ return;
+
mono_walk_stack_full (func,
&state->ctx,
state->unwind_data [MONO_UNWIND_DATA_DOMAIN],
if (!res)
return;
- if ((unwind_options & MONO_UNWIND_LOOKUP_IL_OFFSET) && frame.ji) {
+ if ((unwind_options & MONO_UNWIND_LOOKUP_IL_OFFSET) && frame.ji && !frame.ji->is_trampoline) {
MonoDebugSourceLocation *source;
source = mono_debug_lookup_source_location (jinfo_get_method (frame.ji), frame.native_offset, domain);
frame.il_offset = il_offset;
- if ((unwind_options & MONO_UNWIND_LOOKUP_ACTUAL_METHOD) && frame.ji) {
+ if ((unwind_options & MONO_UNWIND_LOOKUP_ACTUAL_METHOD) && frame.ji && !frame.ji->is_trampoline) {
frame.actual_method = get_method_from_stack_frame (frame.ji, get_generic_info_from_stack_frame (frame.ji, &ctx));
} else {
frame.actual_method = frame.method;
if (!res)
return FALSE;
- if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE || frame.type == FRAME_TYPE_DEBUGGER_INVOKE)
+ if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+ frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+ frame.type == FRAME_TYPE_TRAMPOLINE)
continue;
ji = frame.ji;
MonoJitInfo*
mini_jit_info_table_find (MonoDomain *domain, char *addr, MonoDomain **out_domain)
{
- return mini_jit_info_table_find_ext (domain, addr, FALSE, out_domain);
+ return mini_jit_info_table_find_ext (domain, addr, TRUE, out_domain);
}
/*
#endif
}
-#define setup_managed_stacktrace_information() do { \
- if (mono_ex && !initial_trace_ips) { \
- trace_ips = g_list_reverse (trace_ips); \
- MONO_OBJECT_SETREF (mono_ex, trace_ips, glist_to_array (trace_ips, mono_defaults.int_class)); \
- MONO_OBJECT_SETREF (mono_ex, native_trace_ips, build_native_trace ()); \
- if (has_dynamic_methods) \
- /* These methods could go away anytime, so compute the stack trace now */ \
- MONO_OBJECT_SETREF (mono_ex, stack_trace, ves_icall_System_Exception_get_trace (mono_ex)); \
- } \
- g_list_free (trace_ips); \
- trace_ips = NULL; \
-} while (0)
+static void
+setup_stack_trace (MonoException *mono_ex, GSList *dynamic_methods, MonoArray *initial_trace_ips, GList **trace_ips)
+{
+ if (mono_ex && !initial_trace_ips) {
+ *trace_ips = g_list_reverse (*trace_ips);
+ MONO_OBJECT_SETREF (mono_ex, trace_ips, glist_to_array (*trace_ips, mono_defaults.int_class));
+ MONO_OBJECT_SETREF (mono_ex, native_trace_ips, build_native_trace ());
+ if (dynamic_methods) {
+ /* These methods could go away anytime, so save a reference to them in the exception object */
+ GSList *l;
+ MonoMList *list = NULL;
+
+ for (l = dynamic_methods; l; l = l->next) {
+ gpointer *dis_link;
+ MonoDomain *domain = mono_domain_get ();
+
+ if (domain->method_to_dyn_method) {
+ mono_domain_lock (domain);
+ dis_link = g_hash_table_lookup (domain->method_to_dyn_method, l->data);
+ mono_domain_unlock (domain);
+ if (dis_link) {
+ MonoObject *o = mono_gc_weak_link_get (dis_link);
+ if (o) {
+ list = mono_mlist_prepend (list, o);
+ }
+ }
+ }
+ }
+
+ MONO_OBJECT_SETREF (mono_ex, dynamic_methods, list);
+ }
+ }
+ g_list_free (*trace_ips);
+ *trace_ips = NULL;
+}
+
/*
* mono_handle_exception_internal_first_pass:
*
MonoLMF *lmf = mono_get_lmf ();
MonoArray *initial_trace_ips = NULL;
GList *trace_ips = NULL;
+ GSList *dynamic_methods = NULL;
MonoException *mono_ex;
gboolean stack_overflow = FALSE;
MonoContext initial_ctx;
MonoMethod *method;
int frame_count = 0;
- gboolean has_dynamic_methods = FALSE;
gint32 filter_idx;
int i;
MonoObject *ex_obj;
unwind_res = mono_find_jit_info_ext (domain, jit_tls, NULL, ctx, &new_ctx, NULL, &lmf, NULL, &frame);
if (unwind_res) {
- if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE || frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
+ if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+ frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+ frame.type == FRAME_TYPE_TRAMPOLINE) {
*ctx = new_ctx;
continue;
}
}
if (!unwind_res) {
- setup_managed_stacktrace_information ();
+ setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+ g_slist_free (dynamic_methods);
return FALSE;
}
}
if (method->dynamic)
- has_dynamic_methods = TRUE;
+ dynamic_methods = g_slist_prepend (dynamic_methods, method);
if (stack_overflow) {
if (DOES_STACK_GROWS_UP)
FIXME Not 100% sure if it's a good idea even with user clauses.
*/
if (is_user_frame)
- setup_managed_stacktrace_information ();
+ setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
#ifdef MONO_CONTEXT_SET_LLVM_EXC_REG
if (ji->from_llvm)
if (filtered) {
if (!is_user_frame)
- setup_managed_stacktrace_information ();
+ setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+ g_slist_free (dynamic_methods);
/* mono_debugger_agent_handle_exception () needs this */
MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
return TRUE;
}
if (ei->flags == MONO_EXCEPTION_CLAUSE_NONE && mono_object_isinst (ex_obj, catch_class)) {
- setup_managed_stacktrace_information ();
+ setup_stack_trace (mono_ex, dynamic_methods, initial_trace_ips, &trace_ips);
+ g_slist_free (dynamic_methods);
if (out_ji)
*out_ji = ji;
unwind_res = mono_find_jit_info_ext (domain, jit_tls, NULL, ctx, &new_ctx, NULL, &lmf, NULL, &frame);
if (unwind_res) {
- if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE || frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
+ if (frame.type == FRAME_TYPE_DEBUGGER_INVOKE ||
+ frame.type == FRAME_TYPE_MANAGED_TO_NATIVE ||
+ frame.type == FRAME_TYPE_TRAMPOLINE) {
*ctx = new_ctx;
continue;
}
return 0;
}
- if (is_address_protected (ji, ei, MONO_CONTEXT_GET_IP (ctx)) &&
- (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT)) {
+ if (ei->flags == MONO_EXCEPTION_CLAUSE_FAULT) {
if (mono_trace_is_enabled () && mono_trace_eval (method))
g_print ("EXCEPTION: fault clause %d of %s\n", i, mono_method_full_name (method, TRUE));
jit_tls->orig_ex_ctx_set = TRUE;
jit_tls->orig_ex_ctx_set = FALSE;
call_filter (ctx, ei->handler_start);
}
- if (is_address_protected (ji, ei, MONO_CONTEXT_GET_IP (ctx)) &&
- (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) {
+ if (ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY) {
if (mono_trace_is_enabled () && mono_trace_eval (method))
g_print ("EXCEPTION: finally clause %d of %s\n", i, mono_method_full_name (method, TRUE));
jit_tls->orig_ex_ctx_set = TRUE;
PrintOverflowUserData *user_data = data;
gchar *location;
- if (frame->ji)
+ if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
method = jinfo_get_method (frame->ji);
if (method) {
mono_walk_stack_with_ctx (print_overflow_stack_frame, &mctx, MONO_UNWIND_LOOKUP_ACTUAL_METHOD, &ud);
#else
- if (ji && jinfo_get_method (ji))
+ if (ji && !ji->is_trampoline && jinfo_get_method (ji))
mono_runtime_printf_err ("At %s", mono_method_full_name (jinfo_get_method (ji), TRUE));
else
mono_runtime_printf_err ("At <unmanaged>.");
{
MonoMethod *method = NULL;
- if (frame->ji)
+ if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
method = jinfo_get_method (frame->ji);
if (method) {
GString *p = (GString*)data;
MonoMethod *method = NULL;
- if (frame->ji)
+ if (frame->ji && frame->type != FRAME_TYPE_TRAMPOLINE)
method = jinfo_get_method (frame->ji);
if (method && frame->domain) {
return FALSE;
}
- if (sigctx)
+ if (sigctx) {
mono_sigctx_to_monoctx (sigctx, &ctx->ctx);
- else
-#if defined(MONO_CROSS_COMPILE)
- ctx->valid = FALSE; //A cross compiler doesn't need to suspend.
-#elif MONO_ARCH_HAS_MONO_CONTEXT
- MONO_CONTEXT_GET_CURRENT (ctx->ctx);
-#else
- g_error ("Use a null sigctx requires a working mono-context");
-#endif
- ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
- ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
- ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread->jit_data;
+ ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
+ ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
+ ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread->jit_data;
+ }
+ else {
+ mono_thread_state_init (ctx);
+ }
if (!ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] || !ctx->unwind_data [MONO_UNWIND_DATA_LMF])
return FALSE;
#endif
}
+void
+mono_thread_state_init (MonoThreadUnwindState *ctx)
+{
+ MonoThreadInfo *thread = mono_thread_info_current_unchecked ();
+
+#if defined(MONO_CROSS_COMPILE)
+ ctx->valid = FALSE; //A cross compiler doesn't need to suspend.
+#elif MONO_ARCH_HAS_MONO_CONTEXT
+ MONO_CONTEXT_GET_CURRENT (ctx->ctx);
+#else
+ g_error ("Use a null sigctx requires a working mono-context");
+#endif
+
+ ctx->unwind_data [MONO_UNWIND_DATA_DOMAIN] = mono_domain_get ();
+ ctx->unwind_data [MONO_UNWIND_DATA_LMF] = mono_get_lmf ();
+ ctx->unwind_data [MONO_UNWIND_DATA_JIT_TLS] = thread ? thread->jit_data : NULL;
+ ctx->valid = TRUE;
+}
+
+
gboolean
mono_thread_state_init_from_monoctx (MonoThreadUnwindState *ctx, MonoContext *mctx)
{
ji = frame.ji;
// FIXME: For skipped frames, scan the param area of the parent frame conservatively ?
+ // FIXME: trampolines
if (frame.type == FRAME_TYPE_MANAGED_TO_NATIVE) {
/*
mono_stats.imt_thunks_size += size;
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, size, NULL, NULL), domain);
+
return start;
}
// EngineBuilder no longer has a copy assignment operator (?)
std::unique_ptr<Module> Owner(unwrap(MP));
EngineBuilder b (std::move(Owner));
-#ifdef TARGET_AMD64
- ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).setCodeModel (CodeModel::Large).create ();
-#else
ExecutionEngine *EE = b.setJITMemoryManager (mono_mm).setTargetOptions (opts).setAllocateGVsWithCode (true).setMCPU (cpu_name).create ();
-#endif
g_assert (EE);
mono_ee->EE = EE;
*/
typedef struct {
LLVMModuleRef module;
- LLVMValueRef throw, rethrow, throw_corlib_exception;
+ LLVMValueRef throw, rethrow, throw_corlib_exception, state_poll;
GHashTable *llvm_types;
LLVMValueRef got_var;
const char *got_symbol;
members [0] = IntPtrType ();
ret_type = LLVMStructType (members, 1, FALSE);
+ } else if (cinfo->ret.pair_storage [0] == LLVMArgNone && cinfo->ret.pair_storage [1] == LLVMArgNone) {
+ /* Empty struct */
+ ret_type = LLVMVoidType ();
} else {
g_assert_not_reached ();
}
;
}
-/* Have to export this for AOT */
-void
-mono_personality (void)
-{
- /* Not used */
- g_assert_not_reached ();
-}
-
static void
process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref, MonoInst *ins)
{
case LLVMArgVtypeInReg: {
LLVMValueRef regs [2];
+ if (LLVMTypeOf (lcall) == LLVMVoidType ())
+ /* Empty struct */
+ break;
+
if (!addresses [ins->dreg])
addresses [ins->dreg] = build_alloca (ctx, sig->ret);
if (cfg->compile_aot) {
/* Use a dummy personality function */
- personality = LLVMGetNamedFunction (module, "mono_aot_personality");
+ personality = LLVMGetNamedFunction (module, "mono_personality");
g_assert (personality);
} else {
personality = LLVMGetNamedFunction (module, "mono_personality");
if (bb->flags & BB_EXCEPTION_HANDLER) {
if (!bblocks [bb->block_num].invoke_target) {
- //LLVM_FAILURE (ctx, "handler without invokes");
+ LLVM_FAILURE (ctx, "handler without invokes");
}
emit_handler_start (ctx, bb, builder);
case OP_DUMMY_USE:
break;
+ case OP_GC_SAFE_POINT: {
+ LLVMValueRef callee, cmp, val;
+ LLVMTypeRef llvm_sig;
+ const char *icall_name;
+ LLVMBasicBlockRef poll_bb, cont_bb;
+
+ poll_bb = gen_bb (ctx, "POLL_BB");
+ cont_bb = gen_bb (ctx, "NOPOLL_BB");
+
+ val = LLVMBuildLoad (ctx->builder, convert (ctx, lhs, LLVMPointerType (LLVMInt8Type (), 0)), "");
+ cmp = LLVMBuildICmp (builder, LLVMIntEQ, val, LLVMConstInt (LLVMTypeOf (val), 0, FALSE), "");
+ LLVMBuildCondBr (ctx->builder, cmp, cont_bb, poll_bb);
+
+ builder = ctx->builder = create_builder (ctx);
+ LLVMPositionBuilderAtEnd (builder, poll_bb);
+
+ MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+ sig->ret = &mono_get_void_class ()->byval_arg;
+ icall_name = "mono_threads_state_poll";
+ llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+ if (ctx->cfg->compile_aot) {
+ callee = ctx->lmodule->state_poll;
+ if (!callee) {
+ MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+ sig->ret = &mono_get_void_class ()->byval_arg;
+ llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+ callee = get_plt_entry (ctx, llvm_sig, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name);
+ }
+ } else {
+ callee = ctx->lmodule->state_poll;
+ if (!callee) {
+ MonoMethodSignature *sig = mono_metadata_signature_alloc (mono_get_corlib (), 0);
+ sig->ret = &mono_get_void_class ()->byval_arg;
+ llvm_sig = sig_to_llvm_sig (ctx, sig);
+
+ callee = LLVMAddFunction (ctx->module, icall_name, llvm_sig);
+ LLVMAddGlobalMapping (ctx->lmodule->ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
+ ctx->lmodule->state_poll = callee;
+ }
+ }
+ //
+ // FIXME: This can use the PreserveAll cconv to avoid clobbering registers.
+ // It requires the wrapper to also use that calling convention.
+ //
+ val = emit_call (ctx, bb, &builder, callee, NULL, 0);
+ LLVMBuildBr (builder, cont_bb);
+
+ builder = ctx->builder = create_builder (ctx);
+ LLVMPositionBuilderAtEnd (builder, cont_bb);
+
+ bblocks [bb->block_num].end_bblock = cont_bb;
+ break;
+ }
/*
* EXCEPTION HANDLING
LLVMSetInitializer (lmodule->got_var, LLVMConstNull (got_type));
}
- /* Add a dummy personality function */
- {
- LLVMBasicBlockRef lbb;
- LLVMBuilderRef lbuilder;
- LLVMValueRef personality;
-
- personality = LLVMAddFunction (lmodule->module, "mono_aot_personality", LLVMFunctionType (LLVMVoidType (), NULL, 0, FALSE));
- LLVMSetLinkage (personality, LLVMInternalLinkage);
- lbb = LLVMAppendBasicBlock (personality, "BB0");
- lbuilder = LLVMCreateBuilder ();
- LLVMPositionBuilderAtEnd (lbuilder, lbb);
- LLVMBuildRetVoid (lbuilder);
- mark_as_used (lmodule, personality);
- }
-
lmodule->llvm_types = g_hash_table_new (NULL, NULL);
lmodule->plt_entries = g_hash_table_new (g_str_hash, g_str_equal);
lmodule->plt_entries_ji = g_hash_table_new (NULL, NULL);
#define MAX_ARCH_DELEGATE_PARAMS (4 - 1)
static gpointer
-get_delegate_invoke_impl (gboolean has_target, gboolean param_count, guint32 *code_size)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, gboolean param_count)
{
guint8 *code, *start;
mono_arch_flush_icache (start, size);
}
- if (code_size)
- *code_size = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+ g_free (name);
+ }
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0);
+ res = g_slist_prepend (res, info);
for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ get_delegate_invoke_impl (&info, FALSE, i);
+ res = g_slist_prepend (res, info);
}
return res;
return cached;
}
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0);
+ mono_tramp_info_register (info, NULL);
+ }
cached = start;
mono_mini_arch_unlock ();
return cached;
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+ mono_tramp_info_register (info, NULL);
}
cache [sig->param_count] = start;
mono_mini_arch_unlock ();
mono_stats.imt_thunks_size += code - start;
g_assert (code - start <= size);
mono_arch_flush_icache (start, size);
+
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
MINI_OP(OP_GENERIC_CLASS_INIT, "generic_class_init", NONE, IREG, NONE)
/* Arch specific opcodes */
-/* #if defined(__native_client_codegen__) || defined(__native_client__) */
-/* We have to define these in terms of the TARGET defines, not NaCl defines */
-/* because genmdesc.pl doesn't have multiple defines per platform. */
-#if defined(TARGET_AMD64) || defined(TARGET_X86)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_ARM) || defined(TARGET_ARM64)
MINI_OP(OP_GC_SAFE_POINT, "gc_safe_point", NONE, IREG, NONE)
#endif
}
#endif
+void
+mono_runtime_posix_install_handlers(void)
+{
+
+}
+
void
mono_runtime_shutdown_handlers (void)
{
MONO_SIG_HANDLER_GET_CONTEXT;
if (mono_thread_internal_current ())
- ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+ ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
if (!ji) {
if (mono_chain_signal (MONO_SIG_HANDLER_PARAMS))
return;
#define MAX_ARCH_DELEGATE_PARAMS 7
static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len, gboolean aot)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count, gboolean aot)
{
guint8 *code, *start;
mono_arch_flush_icache (start, size);
}
- if (code_len)
- *code_len = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+ g_free (name);
+ }
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0, TRUE);
+ res = g_slist_prepend (res, info);
- for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+ get_delegate_invoke_impl (&info, FALSE, i, TRUE);
+ res = g_slist_prepend (res, info);
}
return res;
if (cached)
return cached;
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL, FALSE);
-
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0, FALSE);
+ mono_tramp_info_register (info, NULL);
+ }
mono_memory_barrier ();
cached = start;
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL, FALSE);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count, FALSE);
+ mono_tramp_info_register (info, NULL);
}
mono_memory_barrier ();
cinfo->args [n].reg = fr;
fr ++;
FP_ALSO_IN_REG (gr ++);
+#if !defined(__mono_ppc64__)
if (size == 8)
FP_ALSO_IN_REG (gr ++);
+#endif
ALWAYS_ON_STACK (stack_size += size);
} else {
cinfo->args [n].offset = PPC_STACK_PARAM_OFFSET + stack_size;
cinfo->args [n].size = 4;
/* It was 7, now it is 8 in LinuxPPC */
- if (fr <= PPC_LAST_FPARG_REG) {
+ if (fr <= PPC_LAST_FPARG_REG
+ // For non-native vararg calls the parms must go in storage
+ && !(!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
+ ) {
cinfo->args [n].regtype = RegTypeFP;
cinfo->args [n].reg = fr;
fr ++;
case MONO_TYPE_R8:
cinfo->args [n].size = 8;
/* It was 7, now it is 8 in LinuxPPC */
- if (fr <= PPC_LAST_FPARG_REG) {
+ if (fr <= PPC_LAST_FPARG_REG
+ // For non-native vararg calls the parms must go in storage
+ && !(!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG))
+ ) {
cinfo->args [n].regtype = RegTypeFP;
cinfo->args [n].reg = fr;
fr ++;
m->ret->inst_c0 = m->ret->dreg = ppc_r3;
} else {
/* FIXME: handle long values? */
- switch (mini_get_underlying_type (m, sig->ret)->type) {
+ switch (mini_get_underlying_type (sig->ret)->type) {
case MONO_TYPE_VOID:
break;
case MONO_TYPE_R4:
else
ppc_mr (code, ins->dreg, ins->sreg1);
break;
+#else
+ case OP_ICONV_TO_R4:
+ case OP_ICONV_TO_R8: {
+ if (cpu_hw_caps & PPC_ISA_64) {
+ ppc_srawi(code, ppc_r0, ins->sreg1, 31);
+ ppc_stw (code, ppc_r0, -8, ppc_r1);
+ ppc_stw (code, ins->sreg1, -4, ppc_r1);
+ ppc_lfd (code, ins->dreg, -8, ppc_r1);
+ ppc_fcfid (code, ins->dreg, ins->dreg);
+ if (ins->opcode == OP_ICONV_TO_R4)
+ ppc_frsp (code, ins->dreg, ins->dreg);
+ }
+ break;
+ }
+#endif
+
case OP_ATOMIC_ADD_I4:
CASE_PPC64 (OP_ATOMIC_ADD_I8) {
int location = ins->inst_basereg;
ppc_mr (code, ins->dreg, ppc_r0);
break;
}
-#else
- case OP_ICONV_TO_R4:
- case OP_ICONV_TO_R8: {
- if (cpu_hw_caps & PPC_ISA_64) {
- ppc_srawi(code, ppc_r0, ins->sreg1, 31);
- ppc_stw (code, ppc_r0, -8, ppc_r1);
- ppc_stw (code, ins->sreg1, -4, ppc_r1);
- ppc_lfd (code, ins->dreg, -8, ppc_r1);
- ppc_fcfid (code, ins->dreg, ins->dreg);
- if (ins->opcode == OP_ICONV_TO_R4)
- ppc_frsp (code, ins->dreg, ins->dreg);
- }
- break;
- }
-#endif
case OP_ATOMIC_CAS_I4:
CASE_PPC64 (OP_ATOMIC_CAS_I8) {
int location = ins->sreg1;
mono_stats.imt_thunks_size += code - start;
g_assert (code - start <= size);
mono_arch_flush_icache (start, size);
+
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
/* Linux */
#ifdef __mono_ppc64__
#define PPC_RET_ADDR_OFFSET 16
-#define PPC_STACK_PARAM_OFFSET 48
-#define PPC_MINIMAL_STACK_SIZE 48
+ // Power LE abvi2
+ #if (_CALL_ELF == 2)
+ #define PPC_STACK_PARAM_OFFSET 32
+ #define PPC_MINIMAL_STACK_SIZE 32
+ #else
+ #define PPC_STACK_PARAM_OFFSET 48
+ #define PPC_MINIMAL_STACK_SIZE 48
+ #endif
+#define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
#define PPC_MINIMAL_PARAM_AREA_SIZE 64
#define PPC_LAST_FPARG_REG ppc_f13
#define PPC_PASS_STRUCTS_BY_VALUE 1
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-signal-handler.h>
#include <mono/utils/mono-threads.h>
+#include <mono/utils/checked-build.h>
#include <mono/io-layer/io-layer.h>
#include "mini.h"
gboolean
mono_running_on_valgrind (void)
{
+#ifndef HOST_WIN32
if (RUNNING_ON_VALGRIND){
#ifdef VALGRIND_JIT_REGISTER_MAP
valgrind_register = TRUE;
#endif
return TRUE;
} else
+#endif
return FALSE;
}
if (!domain)
domain = mono_get_root_domain ();
- ji = mono_jit_info_table_find (domain, ip);
+ ji = mono_jit_info_table_find_internal (domain, ip, TRUE, TRUE);
if (!ji) {
user_data.ip = ip;
user_data.method = NULL;
}
else
return NULL;
+ } else if (ji->is_trampoline) {
+ res = g_strdup_printf ("<%p - %s trampoline>", ip, ((MonoTrampInfo*)ji->d.tramp_info)->name);
+ return res;
}
+
method = mono_method_full_name (jinfo_get_method (ji), TRUE);
/* FIXME: unused ? */
location = mono_debug_lookup_source_location (jinfo_get_method (ji), (guint32)((guint8*)ip - (guint8*)ji->code_start), domain);
{
MonoMethod *cmethod;
- if (!caller || !callee)
+ if (!caller || caller->is_trampoline || !callee || callee->is_trampoline)
return FALSE;
/*
void
mono_tramp_info_free (MonoTrampInfo *info)
{
- GSList *l;
-
g_free (info->name);
// FIXME: ji
- for (l = info->unwind_ops; l; l = l->next)
- g_free (l->data);
- g_slist_free (info->unwind_ops);
+ mono_free_unwind_info (info->unwind_ops);
g_free (info);
}
mono_jit_info_init (ji, NULL, info->code, info->code_size, 0, 0, 0);
ji->d.tramp_info = info;
ji->is_trampoline = TRUE;
- // FIXME: Unwind info
+
+ ji->unwind_info = mono_cache_unwind_info (info->uw_info, info->uw_info_len);
mono_jit_info_table_add (domain, ji);
}
* Frees INFO.
*/
void
-mono_tramp_info_register (MonoTrampInfo *info)
+mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain)
{
MonoTrampInfo *copy;
if (!info)
return;
+ if (!domain)
+ domain = mono_get_root_domain ();
+
copy = g_new0 (MonoTrampInfo, 1);
copy->code = info->code;
copy->code_size = info->code_size;
copy->name = g_strdup (info->name);
+ if (info->unwind_ops) {
+ copy->uw_info = mono_unwind_ops_encode (info->unwind_ops, ©->uw_info_len);
+ } else {
+ /* Trampolines from aot have the unwind ops already encoded */
+ copy->uw_info = info->uw_info;
+ copy->uw_info_len = info->uw_info_len;
+ }
+
mono_jit_lock ();
tramp_infos = g_slist_prepend (tramp_infos, copy);
mono_jit_unlock ();
mono_save_trampoline_xdebug_info (info);
- if (mono_get_root_domain ())
- register_trampoline_jit_info (mono_get_root_domain (), copy);
+ /* Only register trampolines that have unwind infos */
+ if (mono_get_root_domain () && copy->uw_info)
+ register_trampoline_jit_info (domain, copy);
if (mono_jit_map_is_enabled ())
mono_emit_jit_tramp (info->code, info->code_size, info->name);
MonoDomain *domain = mono_get_root_domain ();
gboolean check_exc = TRUE;
- if (callinfo->wrapper) {
+ if (callinfo->wrapper)
return callinfo->wrapper;
- }
if (callinfo->trampoline)
return callinfo->trampoline;
- /*
- * We use the lock on the root domain instead of the JIT lock to protect
- * callinfo->trampoline, since we do a lot of stuff inside the critical section.
- */
- mono_loader_lock (); /*FIXME mono_compile_method requires the loader lock, by large.*/
- mono_domain_lock (domain);
-
- if (callinfo->trampoline) {
- mono_domain_unlock (domain);
- mono_loader_unlock ();
- return callinfo->trampoline;
- }
-
if (!strcmp (callinfo->name, "mono_thread_interruption_checkpoint"))
/* This icall is used to check for exceptions, so don't check in the wrapper */
check_exc = FALSE;
trampoline = mono_compile_method (wrapper);
else
trampoline = mono_create_ftnptr (domain, mono_create_jit_trampoline_in_domain (domain, wrapper));
- mono_register_jit_icall_wrapper (callinfo, trampoline);
- callinfo->trampoline = trampoline;
-
- mono_domain_unlock (domain);
+ mono_loader_lock ();
+ if (!callinfo->trampoline) {
+ mono_register_jit_icall_wrapper (callinfo, trampoline);
+ callinfo->trampoline = trampoline;
+ }
mono_loader_unlock ();
return callinfo->trampoline;
static void
register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, const char *symbol, gboolean no_throw)
{
+#ifndef DISABLE_JIT
mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw);
+#endif
}
/*
case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR:
case MONO_PATCH_INFO_GC_NURSERY_START:
case MONO_PATCH_INFO_JIT_TLS_ID:
- case MONO_PATCH_INFO_MONITOR_ENTER:
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- case MONO_PATCH_INFO_MONITOR_EXIT:
case MONO_PATCH_INFO_GOT_OFFSET:
case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG:
return (ji->type << 8);
target = mono_create_rgctx_lazy_fetch_trampoline (slot);
break;
}
- case MONO_PATCH_INFO_MONITOR_ENTER:
- target = mono_create_monitor_enter_trampoline ();
- break;
- case MONO_PATCH_INFO_MONITOR_ENTER_V4:
- target = mono_create_monitor_enter_v4_trampoline ();
- break;
- case MONO_PATCH_INFO_MONITOR_EXIT:
- target = mono_create_monitor_exit_trampoline ();
- break;
#ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED
case MONO_PATCH_INFO_SEQ_POINT_INFO:
if (!run_cctors)
mono_internal_hash_table_remove (&domain->jit_code_hash, method);
mono_domain_jit_code_hash_unlock (domain);
g_hash_table_remove (domain_jit_info (domain)->jump_trampoline_hash, method);
+
+ /* requires the domain lock - took above */
mono_conc_hashtable_remove (domain_jit_info (domain)->runtime_invoke_hash, method);
/* Remove jump targets in this method */
if (!info->dyn_call_info)
info->runtime_invoke = mono_jit_compile_method (invoke);
+ mono_domain_lock (domain);
info2 = mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info);
+ mono_domain_unlock (domain);
if (info2) {
g_free (info);
info = info2;
MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO ();
MONO_SIG_HANDLER_GET_CONTEXT;
- ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+ ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
#if defined(MONO_ARCH_HAVE_IS_INT_OVERFLOW)
if (mono_arch_is_int_overflow (ctx, info))
}
#endif
- ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx));
+ ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE);
#ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK
if (mono_handle_soft_stack_ovf (jit_tls, ji, ctx, info, (guint8*)info->si_addr))
/* FIXME Support more cases */
if (mono_aot_only) {
char tramp_name [256];
+ const char *imt = load_imt_reg ? "_imt" : "";
+ int ind = (load_imt_reg ? (-offset) : offset) / SIZEOF_VOID_P;
- sprintf (tramp_name, "delegate_virtual_invoke%s_%d", load_imt_reg ? "_imt" : "", offset / SIZEOF_VOID_P);
+ sprintf (tramp_name, "delegate_virtual_invoke%s_%d", imt, ind);
cache [idx] = mono_aot_get_trampoline (tramp_name);
g_assert (cache [idx]);
} else {
info->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
info->delegate_trampoline_hash = g_hash_table_new (class_method_pair_hash, class_method_pair_equal);
info->llvm_vcall_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL);
- info->runtime_invoke_hash = mono_conc_hashtable_new_full (&domain->lock, mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free);
+ info->runtime_invoke_hash = mono_conc_hashtable_new_full (mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free);
info->seq_points = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, mono_seq_point_info_free);
info->arch_seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL);
info->jump_target_hash = g_hash_table_new (NULL, NULL);
MONO_VES_INIT_BEGIN ();
+ CHECKED_MONO_INIT ();
+
#if defined(__linux__) && !defined(__native_client__)
if (access ("/proc/self/maps", F_OK) != 0) {
g_print ("Mono requires /proc to be mounted.\n");
ticallbacks.setup_async_callback = mono_setup_async_callback;
ticallbacks.thread_state_init_from_sigctx = mono_thread_state_init_from_sigctx;
ticallbacks.thread_state_init_from_handle = mono_thread_state_init_from_handle;
+ ticallbacks.thread_state_init = mono_thread_state_init;
mono_counters_init ();
ves_icall_get_frame_info);
mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace",
ves_icall_get_trace);
- mono_add_internal_call ("System.Exception::get_trace",
- ves_icall_System_Exception_get_trace);
mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers",
mono_runtime_install_handlers);
mono_mutex_destroy (&jit_mutex);
- mono_mutex_destroy (&mono_delegate_section);
-
mono_code_manager_cleanup ();
#ifdef USE_JUMP_TABLES
g_hash_table_destroy (assemblies);
}
+/*
+ * Used by LLVM.
+ * Have to export this for AOT.
+ */
+void
+mono_personality (void)
+{
+ /* Not used */
+ g_assert_not_reached ();
+}
+
#ifdef USE_JUMP_TABLES
#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
/*------------------------------------------------------------------*/
static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len, gboolean aot)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count, gboolean aot)
{
guint8 *code, *start;
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (code_len)
- *code_len = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, NULL);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, NULL);
+ g_free (name);
+ }
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len, TRUE);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0, TRUE);
+ res = g_slist_prepend (res, info);
- for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len, TRUE);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+ get_delegate_invoke_impl (&info, FALSE, i, TRUE);
+ res = g_slist_prepend (res, info);
}
return res;
if (cached)
return cached;
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL, FALSE);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0, FALSE);
+ mono_tramp_info_register (info, NULL);
+ }
mono_memory_barrier ();
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL, FALSE);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count, FALSE);
+ mono_tramp_info_register (info, NULL);
}
mono_memory_barrier ();
g_assert (code - start <= size);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return (start);
}
#define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
#define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
#define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
-#define MONO_ARCH_MONITOR_OBJECT_REG s390_r2
-#define MONO_ARCH_LOCK_TAKEN_REG s390_r1
#define S390_STACK_ALIGNMENT 8
#define S390_FIRST_ARG_REG s390_r2
mono_stats.imt_thunks_size += (code - start) * 4;
g_assert (code - start <= size);
+
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
}
}
- if (ji)
+ if (ji && !ji->is_trampoline)
jmethod = jinfo_get_method (ji);
if (callee_gsharedvt && mini_is_gsharedvt_variable_signature (mono_method_signature (jmethod))) {
MonoMethodSignature *sig, *gsig;
return mono_class_fill_runtime_generic_context (arg, index);
}
-void
-mono_monitor_enter_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
- mono_monitor_enter (obj);
-}
-
-void
-mono_monitor_enter_v4_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
- char *lock_taken = (char*)regs [MONO_ARCH_MONITOR_LOCK_TAKEN_REG];
- mono_monitor_enter_v4 (obj, lock_taken);
-#else
- g_assert_not_reached ();
-#endif
-}
-
-void
-mono_monitor_exit_trampoline (mgreg_t *regs, guint8 *code, MonoObject *obj, guint8 *tramp)
-{
- mono_monitor_exit (obj);
-}
-
/*
* Precompute data to speed up mono_delegate_trampoline ().
* METHOD might be NULL.
}
}
}
- } else {
+ // If "delegate->method_ptr" is null mono_get_addr_from_ftnptr will fail if
+ // ftnptrs are being used. "method" would end up null on archtitectures without
+ // ftnptrs so we can just skip this.
+ } else if (delegate->method_ptr) {
ji = mono_jit_info_table_find (domain, mono_get_addr_from_ftnptr (delegate->method_ptr));
if (ji)
method = jinfo_get_method (ji);
gpointer tmp;
tmp = mono_arch_create_handler_block_trampoline (&info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
mono_memory_barrier ();
code = tmp;
}
case MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING:
return mono_generic_virtual_remoting_trampoline;
#endif
- case MONO_TRAMPOLINE_MONITOR_ENTER:
- return mono_monitor_enter_trampoline;
- case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
- return mono_monitor_enter_v4_trampoline;
- case MONO_TRAMPOLINE_MONITOR_EXIT:
- return mono_monitor_exit_trampoline;
case MONO_TRAMPOLINE_VCALL:
return mono_vcall_trampoline;
#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
guchar *code;
code = mono_arch_create_generic_trampoline (tramp_type, &info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
return code;
}
#ifndef DISABLE_REMOTING
mono_trampoline_code [MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING] = create_trampoline_code (MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING);
#endif
- mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER);
- mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_ENTER_V4] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER_V4);
- mono_trampoline_code [MONO_TRAMPOLINE_MONITOR_EXIT] = create_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
mono_trampoline_code [MONO_TRAMPOLINE_VCALL] = create_trampoline_code (MONO_TRAMPOLINE_VCALL);
#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD
mono_trampoline_code [MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD] = create_trampoline_code (MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD);
ptr = mono_aot_get_lazy_fetch_trampoline (offset);
} else {
tramp = mono_arch_create_rgctx_lazy_fetch_trampoline (offset, &info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
ptr = mono_create_ftnptr (mono_get_root_domain (), tramp);
}
return ptr;
}
-
-gpointer
-mono_create_monitor_enter_trampoline (void)
-{
- static gpointer code;
-
- if (mono_aot_only) {
- if (!code)
- code = mono_aot_get_trampoline ("monitor_enter_trampoline");
- return code;
- }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
- mono_trampolines_lock ();
-
- if (!code) {
- MonoTrampInfo *info;
-
- code = mono_arch_create_monitor_enter_trampoline (&info, FALSE, FALSE);
- mono_tramp_info_register (info);
- }
-
- mono_trampolines_unlock ();
-#else
- code = NULL;
- g_assert_not_reached ();
-#endif
-
- return code;
-}
-
-gpointer
-mono_create_monitor_enter_v4_trampoline (void)
-{
- static gpointer code;
-
- if (mono_aot_only) {
- if (!code)
- code = mono_aot_get_trampoline ("monitor_enter_v4_trampoline");
- return code;
- }
-
-#if defined(MONO_ARCH_MONITOR_OBJECT_REG) && defined(MONO_ARCH_MONITOR_LOCK_TAKEN_REG)
- mono_trampolines_lock ();
-
- if (!code) {
- MonoTrampInfo *info;
-
- code = mono_arch_create_monitor_enter_trampoline (&info, TRUE, FALSE);
- mono_tramp_info_register (info);
- }
-
- mono_trampolines_unlock ();
-#else
- code = NULL;
- g_assert_not_reached ();
-#endif
-
- return code;
-}
-
-gpointer
-mono_create_monitor_exit_trampoline (void)
-{
- static gpointer code;
-
- if (mono_aot_only) {
- if (!code)
- code = mono_aot_get_trampoline ("monitor_exit_trampoline");
- return code;
- }
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
- mono_trampolines_lock ();
-
- if (!code) {
- MonoTrampInfo *info;
-
- code = mono_arch_create_monitor_exit_trampoline (&info, FALSE);
- mono_tramp_info_register (info);
- }
-
- mono_trampolines_unlock ();
-#else
- code = NULL;
- g_assert_not_reached ();
-#endif
- return code;
-}
#ifdef MONO_ARCH_LLVM_SUPPORTED
/*
"delegate",
"restore_stack_prot",
"generic_virtual_remoting",
- "monitor_enter",
- "monitor_enter_v4",
- "monitor_exit",
"vcall",
"handler_block_guard"
};
#ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
MonoTrampInfo *info;
tramp = mono_arch_create_sdb_trampoline (TRUE, &info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
#else
tramp = NULL;
g_assert_not_reached ();
#ifdef MONO_ARCH_HAVE_SDB_TRAMPOLINES
MonoTrampInfo *info;
tramp = mono_arch_create_sdb_trampoline (FALSE, &info, FALSE);
- mono_tramp_info_register (info);
+ mono_tramp_info_register (info, NULL);
#else
tramp = NULL;
g_assert_not_reached ();
#define mono_add_unwind_op_same_value(op_list,code,buf,reg) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_same_value, (reg), 0)); } while (0)
#define mono_add_unwind_op_offset(op_list,code,buf,reg,offset) do { (op_list) = g_slist_append ((op_list), mono_create_unwind_op ((code) - (buf), DW_CFA_offset, (reg), (offset))); } while (0)
+#define mono_free_unwind_info(op_list) do { GSList *l; for (l = op_list; l; l = l->next) g_free (l->data); g_slist_free (op_list); op_list = NULL; } while (0)
+
/* Pointer Encoding in the .eh_frame */
enum {
DW_EH_PE_absptr = 0x00,
int
mono_unwind_get_dwarf_pc_reg (void);
+guint8*
+mono_unwind_ops_encode_full (GSList *unwind_ops, guint32 *out_len, gboolean enable_extensions);
+
guint8*
mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len);
#endif
#endif
+/* The single step trampoline */
+static gpointer ss_trampoline;
+
+/* The breakpoint trampoline */
+static gpointer bp_trampoline;
+
/* This mutex protects architecture specific caches */
#define mono_mini_arch_lock() mono_mutex_lock (&mini_arch_mutex)
#define mono_mini_arch_unlock() mono_mutex_unlock (&mini_arch_mutex)
#define X86_IS_CALLEE_SAVED_REG(reg) (((reg) == X86_EBX) || ((reg) == X86_EDI) || ((reg) == X86_ESI))
-MonoBreakpointInfo
-mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
+#define OP_SEQ_POINT_BP_OFFSET 7
static guint8*
emit_load_aotconst (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji, int dreg, int tramp_type, gconstpointer target);
#endif /* __native_client_codegen__ */
-/*
- * The code generated for sequence points reads from this location, which is
- * made read-only when single stepping is enabled.
- */
-static gpointer ss_trigger_page;
-
-/* Enabled breakpoints read from this trigger page */
-static gpointer bp_trigger_page;
-
const char*
mono_arch_regname (int reg)
{
{
mono_mutex_init_recursive (&mini_arch_mutex);
- ss_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ);
- bp_trigger_page = mono_valloc (NULL, mono_pagesize (), MONO_MMAP_READ|MONO_MMAP_32BIT);
- mono_mprotect (bp_trigger_page, mono_pagesize (), 0);
+ if (!mono_aot_only)
+ bp_trampoline = mini_get_breakpoint_trampoline ();
mono_aot_register_jit_icall ("mono_x86_throw_exception", mono_x86_throw_exception);
mono_aot_register_jit_icall ("mono_x86_throw_corlib_exception", mono_x86_throw_corlib_exception);
void
mono_arch_cleanup (void)
{
- if (ss_trigger_page)
- mono_vfree (ss_trigger_page, mono_pagesize ());
- if (bp_trigger_page)
- mono_vfree (bp_trigger_page, mono_pagesize ());
mono_mutex_destroy (&mini_arch_mutex);
}
cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
}
+ if (cfg->gen_sdb_seq_points) {
+ MonoInst *ins;
+
+ ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+ ins->flags |= MONO_INST_VOLATILE;
+ cfg->arch.ss_tramp_var = ins;
+
+ ins = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+ ins->flags |= MONO_INST_VOLATILE;
+ cfg->arch.bp_tramp_var = ins;
+ }
+
if (cfg->method->save_lmf) {
cfg->create_lmf_var = TRUE;
cfg->lmf_ir = TRUE;
if (cfg->compile_aot)
NOT_IMPLEMENTED;
+ /* Have to use ecx as a temp reg since this can occur after OP_SETRET */
+
/*
* Read from the single stepping trigger page. This will cause a
* SIGSEGV when single stepping is enabled.
* We do this _before_ the breakpoint, so single stepping after
* a breakpoint is hit will step to the next IL offset.
*/
- if (ins->flags & MONO_INST_SINGLE_STEP_LOC)
- x86_alu_reg_mem (code, X86_CMP, X86_EAX, (guint32)ss_trigger_page);
+ if (ins->flags & MONO_INST_SINGLE_STEP_LOC) {
+ MonoInst *var = cfg->arch.ss_tramp_var;
+ guint8 *br [1];
+
+ g_assert (var);
+ g_assert (var->opcode == OP_REGOFFSET);
+ /* Load ss_tramp_var */
+ /* This is equal to &ss_trampoline */
+ x86_mov_reg_membase (code, X86_ECX, var->inst_basereg, var->inst_offset, sizeof (mgreg_t));
+ x86_alu_membase_imm (code, X86_CMP, X86_ECX, 0, 0);
+ br[0] = code; x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+ x86_call_membase (code, X86_ECX, 0);
+ x86_patch (br [0], code);
+ }
+
+ /*
+ * Many parts of sdb depend on the ip after the single step trampoline call to be equal to the seq point offset.
+ * This means we have to put the loading of bp_tramp_var after the offset.
+ */
mono_add_seq_point (cfg, bb, ins, code - cfg->native_code);
+ MonoInst *var = cfg->arch.bp_tramp_var;
+
+ g_assert (var);
+ g_assert (var->opcode == OP_REGOFFSET);
+ /* Load the address of the bp trampoline */
+ /* This needs to be constant size */
+ guint8 *start = code;
+ x86_mov_reg_membase (code, X86_ECX, var->inst_basereg, var->inst_offset, 4);
+ if (code < start + OP_SEQ_POINT_BP_OFFSET) {
+ int size = start + OP_SEQ_POINT_BP_OFFSET - code;
+ x86_padding (code, size);
+ }
/*
* A placeholder for a possible breakpoint inserted by
* mono_arch_set_breakpoint ().
*/
- for (i = 0; i < 6; ++i)
+ for (i = 0; i < 2; ++i)
x86_nop (code);
/*
* Add an additional nop so skipping the bp doesn't cause the ip to point
if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
+ {
+ MonoInst *ins;
+
+ if (cfg->arch.ss_tramp_var) {
+ /* Initialize ss_tramp_var */
+ ins = cfg->arch.ss_tramp_var;
+ g_assert (ins->opcode == OP_REGOFFSET);
+
+ g_assert (!cfg->compile_aot);
+ x86_mov_membase_imm (code, ins->inst_basereg, ins->inst_offset, (guint32)&ss_trampoline, 4);
+ }
+
+ if (cfg->arch.bp_tramp_var) {
+ /* Initialize bp_tramp_var */
+ ins = cfg->arch.bp_tramp_var;
+ g_assert (ins->opcode == OP_REGOFFSET);
+
+ g_assert (!cfg->compile_aot);
+ x86_mov_membase_imm (code, ins->inst_basereg, ins->inst_offset, (guint32)&bp_trampoline, 4);
+ }
+ }
+
/* load arguments allocated to register from the stack */
sig = mono_method_signature (method);
pos = 0;
int i;
int size = 0;
guint8 *code, *start;
+ GSList *unwind_ops;
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
code = mono_domain_code_reserve (domain, size);
#endif
start = code;
+
+ unwind_ops = mono_arch_get_cie_program ();
+
for (i = 0; i < count; ++i) {
MonoIMTCheckItem *item = imt_entries [i];
item->code_target = code;
nacl_domain_code_validate (domain, &start, size, &code);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_IMT_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
#define MAX_ARCH_DELEGATE_PARAMS 10
static gpointer
-get_delegate_invoke_impl (gboolean has_target, guint32 param_count, guint32 *code_len)
+get_delegate_invoke_impl (MonoTrampInfo **info, gboolean has_target, guint32 param_count)
{
guint8 *code, *start;
int code_reserve = 64;
+ GSList *unwind_ops;
+
+ unwind_ops = mono_arch_get_cie_program ();
/*
* The stack contains:
nacl_global_codeman_validate (&start, code_reserve, &code);
- if (code_len)
- *code_len = code - start;
+ if (has_target) {
+ *info = mono_tramp_info_create ("delegate_invoke_impl_has_target", start, code - start, NULL, unwind_ops);
+ } else {
+ char *name = g_strdup_printf ("delegate_invoke_impl_target_%d", param_count);
+ *info = mono_tramp_info_create (name, start, code - start, NULL, unwind_ops);
+ g_free (name);
+ }
if (mono_jit_map_is_enabled ()) {
char *buff;
#define MAX_VIRTUAL_DELEGATE_OFFSET 32
static gpointer
-get_delegate_virtual_invoke_impl (gboolean load_imt_reg, int offset, guint32 *code_size)
+get_delegate_virtual_invoke_impl (MonoTrampInfo **info, gboolean load_imt_reg, int offset)
{
guint8 *code, *start;
int size = 24;
+ char *tramp_name;
+ GSList *unwind_ops;
+
+ if (offset / (int)sizeof (gpointer) > MAX_VIRTUAL_DELEGATE_OFFSET)
+ return NULL;
/*
* The stack contains:
*/
start = code = mono_global_codeman_reserve (size);
+ unwind_ops = mono_arch_get_cie_program ();
+
/* Replace the this argument with the target */
x86_mov_reg_membase (code, X86_EAX, X86_ESP, 4, 4);
x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoDelegate, target), 4);
x86_jump_membase (code, X86_EAX, offset);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_DELEGATE_INVOKE, NULL);
- if (code_size)
- *code_size = code - start;
+ if (load_imt_reg)
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", - offset / sizeof (gpointer));
+ else
+ tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", offset / sizeof (gpointer));
+ *info = mono_tramp_info_create (tramp_name, start, code - start, NULL, unwind_ops);
+ g_free (tramp_name);
+
return start;
}
mono_arch_get_delegate_invoke_impls (void)
{
GSList *res = NULL;
- guint8 *code;
- guint32 code_len;
+ MonoTrampInfo *info;
int i;
- char *tramp_name;
- code = get_delegate_invoke_impl (TRUE, 0, &code_len);
- res = g_slist_prepend (res, mono_tramp_info_create ("delegate_invoke_impl_has_target", code, code_len, NULL, NULL));
+ get_delegate_invoke_impl (&info, TRUE, 0);
+ res = g_slist_prepend (res, info);
- for (i = 0; i < MAX_ARCH_DELEGATE_PARAMS; ++i) {
- code = get_delegate_invoke_impl (FALSE, i, &code_len);
- tramp_name = g_strdup_printf ("delegate_invoke_impl_target_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_ARCH_DELEGATE_PARAMS; ++i) {
+ get_delegate_invoke_impl (&info, FALSE, i);
+ res = g_slist_prepend (res, info);
}
- for (i = 0; i < MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
- code = get_delegate_virtual_invoke_impl (TRUE, i * SIZEOF_VOID_P, &code_len);
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_imt_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ for (i = 0; i <= MAX_VIRTUAL_DELEGATE_OFFSET; ++i) {
+ get_delegate_virtual_invoke_impl (&info, TRUE, - i * SIZEOF_VOID_P);
+ res = g_slist_prepend (res, info);
- code = get_delegate_virtual_invoke_impl (FALSE, i * SIZEOF_VOID_P, &code_len);
- tramp_name = g_strdup_printf ("delegate_virtual_invoke_%d", i);
- res = g_slist_prepend (res, mono_tramp_info_create (tramp_name, code, code_len, NULL, NULL));
- g_free (tramp_name);
+ get_delegate_virtual_invoke_impl (&info, FALSE, i * SIZEOF_VOID_P);
+ res = g_slist_prepend (res, info);
}
return res;
if (cached)
return cached;
- if (mono_aot_only)
+ if (mono_aot_only) {
start = mono_aot_get_trampoline ("delegate_invoke_impl_has_target");
- else
- start = get_delegate_invoke_impl (TRUE, 0, NULL);
+ } else {
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, TRUE, 0);
+ mono_tramp_info_register (info, NULL);
+ }
mono_memory_barrier ();
start = mono_aot_get_trampoline (name);
g_free (name);
} else {
- start = get_delegate_invoke_impl (FALSE, sig->param_count, NULL);
+ MonoTrampInfo *info;
+ start = get_delegate_invoke_impl (&info, FALSE, sig->param_count);
+ mono_tramp_info_register (info, NULL);
}
mono_memory_barrier ();
gpointer
mono_arch_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *method, int offset, gboolean load_imt_reg)
{
- return get_delegate_virtual_invoke_impl (load_imt_reg, offset, NULL);
+ MonoTrampInfo *info;
+ gpointer code;
+
+ code = get_delegate_virtual_invoke_impl (&info, load_imt_reg, offset);
+ if (code)
+ mono_tramp_info_register (info, NULL);
+ return code;
}
mgreg_t
void
mono_arch_set_breakpoint (MonoJitInfo *ji, guint8 *ip)
{
- guint8 *code = ip;
+ guint8 *code = ip + OP_SEQ_POINT_BP_OFFSET;
- /*
- * In production, we will use int3 (has to fix the size in the md
- * file). But that could confuse gdb, so during development, we emit a SIGSEGV
- * instead.
- */
g_assert (code [0] == 0x90);
- x86_alu_reg_mem (code, X86_CMP, X86_EAX, (guint32)bp_trigger_page);
+ x86_call_membase (code, X86_ECX, 0);
}
/*
void
mono_arch_clear_breakpoint (MonoJitInfo *ji, guint8 *ip)
{
- guint8 *code = ip;
+ guint8 *code = ip + OP_SEQ_POINT_BP_OFFSET;
int i;
- for (i = 0; i < 6; ++i)
+ for (i = 0; i < 2; ++i)
x86_nop (code);
}
void
mono_arch_start_single_stepping (void)
{
- mono_mprotect (ss_trigger_page, mono_pagesize (), 0);
+ ss_trampoline = mini_get_single_step_trampoline ();
}
/*
void
mono_arch_stop_single_stepping (void)
{
- mono_mprotect (ss_trigger_page, mono_pagesize (), MONO_MMAP_READ);
+ ss_trampoline = NULL;
}
/*
gboolean
mono_arch_is_single_step_event (void *info, void *sigctx)
{
-#ifdef TARGET_WIN32
- EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
-
- if (((gpointer)einfo->ExceptionInformation[1] >= ss_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)ss_trigger_page + 128))
- return TRUE;
- else
- return FALSE;
-#else
- siginfo_t* sinfo = (siginfo_t*) info;
- /* Sometimes the address is off by 4 */
- if (sinfo->si_signo == DBG_SIGNAL && (sinfo->si_addr >= ss_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)ss_trigger_page + 128))
- return TRUE;
- else
- return FALSE;
-#endif
+ /* We use soft breakpoints */
+ return FALSE;
}
gboolean
mono_arch_is_breakpoint_event (void *info, void *sigctx)
{
-#ifdef TARGET_WIN32
- EXCEPTION_RECORD* einfo = ((EXCEPTION_POINTERS*)info)->ExceptionRecord; /* Sometimes the address is off by 4 */
- if (((gpointer)einfo->ExceptionInformation[1] >= bp_trigger_page && (guint8*)einfo->ExceptionInformation[1] <= (guint8*)bp_trigger_page + 128))
- return TRUE;
- else
- return FALSE;
-#else
- siginfo_t* sinfo = (siginfo_t*)info;
- /* Sometimes the address is off by 4 */
- if (sinfo->si_signo == DBG_SIGNAL && (sinfo->si_addr >= bp_trigger_page && (guint8*)sinfo->si_addr <= (guint8*)bp_trigger_page + 128))
- return TRUE;
- else
- return FALSE;
-#endif
+ /* We use soft breakpoints */
+ return FALSE;
}
-#define BREAKPOINT_SIZE 6
+#define BREAKPOINT_SIZE 2
/*
* mono_arch_skip_breakpoint:
void
mono_arch_skip_breakpoint (MonoContext *ctx, MonoJitInfo *ji)
{
- MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + BREAKPOINT_SIZE);
+ g_assert_not_reached ();
}
/*
void
mono_arch_skip_single_step (MonoContext *ctx)
{
- MONO_CONTEXT_SET_IP (ctx, (guint8*)MONO_CONTEXT_GET_IP (ctx) + 6);
+ g_assert_not_reached ();
}
/*
gboolean need_stack_frame_inited;
gboolean need_stack_frame;
int sp_fp_offset, param_area_size;
+ gpointer ss_tramp_var;
+ gpointer bp_tramp_var;
} MonoCompileArch;
#define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->eax = (gsize)exc; } while (0)
#define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
#define MONO_ARCH_HAVE_LIVERANGE_OPS 1
#define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
-#if defined(__linux__) || defined (__APPLE__)
-#define MONO_ARCH_MONITOR_OBJECT_REG X86_EAX
-#define MONO_ARCH_MONITOR_LOCK_TAKEN_REG X86_EDX
-#endif
#if !defined(__native_client_codegen__)
#define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
#endif
#define MONO_ARCH_HAVE_LLVM_IMT_TRAMPOLINE 1
#define MONO_ARCH_LLVM_SUPPORTED 1
-#if defined(MONO_ARCH_USE_SIGACTION) || defined(TARGET_WIN32)
#define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
-#endif
#define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1
#define MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD 1
#define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1
#define MONO_ARCH_HAVE_TLS_GET_REG 1
#define MONO_ARCH_HAVE_DUMMY_INIT 1
+#define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
#define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
/* Used for optimization, not complete */
MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
} while (0)
-typedef struct {
- guint8 *address;
- guint8 saved_byte;
-} MonoBreakpointInfo;
-
-extern MonoBreakpointInfo mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
-
/* Return value marshalling for calls between gsharedvt and normal code */
typedef enum {
GSHAREDVT_RET_NONE = 0,
#define mono_jit_unlock() mono_mutex_unlock (&jit_mutex)
static mono_mutex_t jit_mutex;
+#ifndef DISABLE_JIT
+
gpointer
mono_realloc_native_code (MonoCompile *cfg)
{
}
#endif /* __native_client_codegen__ */
+#ifdef USE_JUMP_TABLES
+
+#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
+
+typedef struct MonoJumpTableChunk {
+ guint32 total;
+ guint32 active;
+ struct MonoJumpTableChunk *previous;
+ /* gpointer entries[total]; */
+} MonoJumpTableChunk;
+
+static MonoJumpTableChunk* g_jumptable;
+#define mono_jumptable_lock() mono_mutex_lock (&jumptable_mutex)
+#define mono_jumptable_unlock() mono_mutex_unlock (&jumptable_mutex)
+static mono_mutex_t jumptable_mutex;
+
+static MonoJumpTableChunk*
+mono_create_jumptable_chunk (guint32 max_entries)
+{
+ guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
+ MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
+ chunk->total = max_entries;
+ return chunk;
+}
+
+void
+mono_jumptable_init (void)
+{
+ if (g_jumptable == NULL) {
+ mono_mutex_init_recursive (&jumptable_mutex);
+ g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
+ }
+}
+
+gpointer*
+mono_jumptable_add_entry (void)
+{
+ return mono_jumptable_add_entries (1);
+}
+
+gpointer*
+mono_jumptable_add_entries (guint32 entries)
+{
+ guint32 index;
+ gpointer *result;
+
+ mono_jumptable_init ();
+ mono_jumptable_lock ();
+ index = g_jumptable->active;
+ if (index + entries >= g_jumptable->total) {
+ /*
+ * Grow jumptable, by adding one more chunk.
+ * We cannot realloc jumptable, as there could be pointers
+ * to existing jump table entries in the code, so instead
+ * we just add one more chunk.
+ */
+ guint32 max_entries = entries;
+ MonoJumpTableChunk *new_chunk;
+
+ if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
+ max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
+ new_chunk = mono_create_jumptable_chunk (max_entries);
+ /* Link old jumptable, so that we could free it up later. */
+ new_chunk->previous = g_jumptable;
+ g_jumptable = new_chunk;
+ index = 0;
+ }
+ g_jumptable->active = index + entries;
+ result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
+ mono_jumptable_unlock();
+
+ return result;
+}
+
+void
+mono_jumptable_cleanup (void)
+{
+ if (g_jumptable) {
+ MonoJumpTableChunk *current = g_jumptable, *prev;
+ while (current != NULL) {
+ prev = current->previous;
+ g_free (current);
+ current = prev;
+ }
+ g_jumptable = NULL;
+ mono_mutex_destroy (&jumptable_mutex);
+ }
+}
+
+gpointer*
+mono_jumptable_get_entry (guint8 *code_ptr)
+{
+ return mono_arch_jumptable_entry_from_code (code_ptr);
+}
+
+#endif /* USE_JUMP_TABLES */
+
typedef struct {
MonoExceptionClause *clause;
MonoBasicBlock *basic_block;
return -1;
}
-static guint
-mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
-{
- type = mini_get_underlying_type (type);
- if (cfg->gshared && !type->byref && (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR)) {
- g_assert (mini_type_var_is_vt (type));
- return CEE_LDOBJ;
- }
- return mono_type_to_ldind (type);
-}
-
-#ifndef DISABLE_JIT
-
guint
mini_type_to_stind (MonoCompile* cfg, MonoType *type)
{
bb->max_vreg = MAX (bb->max_vreg, cfg->next_vreg);
}
-#endif
-
static void
set_vreg_to_inst (MonoCompile *cfg, int vreg, MonoInst *inst)
{
#define mono_type_is_long(type) (!(type)->byref && ((mono_type_get_underlying_type (type)->type == MONO_TYPE_I8) || (mono_type_get_underlying_type (type)->type == MONO_TYPE_U8)))
#define mono_type_is_float(type) (!(type)->byref && (((type)->type == MONO_TYPE_R8) || ((type)->type == MONO_TYPE_R4)))
-#ifdef DISABLE_JIT
-
-MonoInst*
-mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
-{
- return NULL;
-}
-
-#else
-
MonoInst*
mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, int vreg)
{
return mono_compile_create_var_for_vreg (cfg, type, opcode, dreg);
}
-/*
- * Transform a MonoInst into a load from the variable of index var_index.
- */
-void
-mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index)
-{
- memset (dest, 0, sizeof (MonoInst));
- dest->inst_i0 = cfg->varinfo [var_index];
- dest->opcode = mini_type_to_ldind (cfg, dest->inst_i0->inst_vtype);
- type_to_eval_stack_type (cfg, dest->inst_i0->inst_vtype, dest);
- dest->klass = dest->inst_i0->klass;
-}
-
MonoInst*
mini_get_int_to_float_spill_area (MonoCompile *cfg)
{
#endif
}
-#endif
-
void
mono_mark_vreg_as_ref (MonoCompile *cfg, int vreg)
{
}
static MonoType*
-type_from_stack_type (MonoInst *ins) {
+type_from_stack_type (MonoInst *ins)
+{
switch (ins->type) {
case STACK_I4: return &mono_defaults.int32_class->byval_arg;
case STACK_I8: return &mono_defaults.int64_class->byval_arg;
}
MonoType*
-mono_type_from_stack_type (MonoInst *ins) {
+mono_type_from_stack_type (MonoInst *ins)
+{
return type_from_stack_type (ins);
}
return 1;
}
-#ifndef DISABLE_JIT
-
#if 0
#define LSCAN_DEBUG(a) do { a; } while (0)
#else
return offsets;
}
-#else
-
-gint32*
-mono_allocate_stack_slots (MonoCompile *cfg, gboolean backward, guint32 *stack_size, guint32 *stack_align)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-#endif /* DISABLE_JIT */
-
#define EMUL_HIT_SHIFT 3
#define EMUL_HIT_MASK ((1 << EMUL_HIT_SHIFT) - 1)
/* small hit bitmap cache */
}
static void
-print_dfn (MonoCompile *cfg) {
+print_dfn (MonoCompile *cfg)
+{
int i, j;
char *code;
MonoBasicBlock *bb;
void
mono_destroy_compile (MonoCompile *cfg)
{
-#ifndef DISABLE_JIT
GSList *l;
if (cfg->header)
g_free (cfg->vars);
g_free (cfg->exception_message);
g_free (cfg);
-#endif
}
-#ifndef DISABLE_JIT
-
static MonoInst*
mono_create_tls_get_offset (MonoCompile *cfg, int offset)
{
return mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
}
-#endif /* !DISABLE_JIT */
-
-
void
mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
{
cfg->rgctx_loclist = g_slist_append_mempool (cfg->mempool, cfg->rgctx_loclist, entry);
}
-#ifndef DISABLE_JIT
-
static void
mono_compile_create_vars (MonoCompile *cfg)
{
}
}
-#endif /* #ifndef DISABLE_JIT */
-
-static MonoJitInfo*
-create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
-{
- MonoDomain *domain = mono_get_root_domain ();
- MonoJitInfo *jinfo;
- guint8 *uw_info;
- guint32 info_len;
-
- if (info->uw_info) {
- uw_info = info->uw_info;
- info_len = info->uw_info_len;
- } else {
- uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
- }
-
- jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
- jinfo->d.method = wrapper;
- jinfo->code_start = info->code;
- jinfo->code_size = info->code_size;
- jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
-
- if (!info->uw_info)
- g_free (uw_info);
-
- return jinfo;
-}
-
-#ifndef DISABLE_JIT
-
static MonoJitInfo*
create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
{
return jinfo;
}
-#endif
/* Return whenever METHOD is a gsharedvt method */
static gboolean
return FALSE;
}
-#ifndef DISABLE_JIT
-
#if defined(__native_client_codegen__) || USE_COOP_GC
static void
mono_insert_safepoints (MonoCompile *cfg)
{
MonoBasicBlock *bb;
+ if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
+#if defined(__native_client__) || defined(__native_client_codegen__)
+ gpointer poll_func = &mono_nacl_gc;
+#elif defined(USE_COOP_GC)
+ gpointer poll_func = &mono_threads_state_poll;
+#else
+ gpointer poll_func = NULL;
+#endif
+
+ if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER && info->d.icall.func == poll_func) {
+ if (cfg->verbose_level > 1)
+ printf ("SKIPPING SAFEPOINTS for the polling function icall\n");
+ return;
+ }
+ }
+
+ if (cfg->method->wrapper_type == MONO_WRAPPER_NATIVE_TO_MANAGED) {
+ if (cfg->verbose_level > 1)
+ printf ("SKIPPING SAFEPOINTS for native-to-managed wrappers.\n");
+ return;
+ }
+
+ if (cfg->method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ WrapperInfo *info = mono_marshal_get_wrapper_info (cfg->method);
+
+ if (info && info->subtype == WRAPPER_SUBTYPE_ICALL_WRAPPER &&
+ (info->d.icall.func == mono_thread_interruption_checkpoint ||
+ info->d.icall.func == mono_threads_finish_blocking ||
+ info->d.icall.func == mono_threads_reset_blocking_start)) {
+ /* These wrappers are called from the wrapper for the polling function, leading to potential stack overflow */
+ if (cfg->verbose_level > 1)
+ printf ("SKIPPING SAFEPOINTS for wrapper %s\n", cfg->method->name);
+ return;
+ }
+ }
if (cfg->verbose_level > 1)
printf ("INSERTING SAFEPOINTS\n");
if (!COMPILE_LLVM (cfg))
mono_if_conversion (cfg);
+ MONO_SUSPEND_CHECK ();
+
/* Depth-first ordering on basic blocks */
cfg->bblocks = mono_mempool_alloc (cfg->mempool, sizeof (MonoBasicBlock*) * (cfg->num_bblocks + 1));
return cfg;
}
-#else
+void*
+mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
+{
+ return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
+}
-MonoCompile*
-mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
+void
+mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
{
- g_assert_not_reached ();
- return NULL;
+ TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
+ hole->clause = clause;
+ hole->start_offset = start - cfg->native_code;
+ hole->basic_block = bb;
+
+ cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
+}
+
+void
+mono_cfg_set_exception (MonoCompile *cfg, int type)
+{
+ cfg->exception_type = type;
}
#endif /* DISABLE_JIT */
+static MonoJitInfo*
+create_jit_info_for_trampoline (MonoMethod *wrapper, MonoTrampInfo *info)
+{
+ MonoDomain *domain = mono_get_root_domain ();
+ MonoJitInfo *jinfo;
+ guint8 *uw_info;
+ guint32 info_len;
+
+ if (info->uw_info) {
+ uw_info = info->uw_info;
+ info_len = info->uw_info_len;
+ } else {
+ uw_info = mono_unwind_ops_encode (info->unwind_ops, &info_len);
+ }
+
+ jinfo = mono_domain_alloc0 (domain, MONO_SIZEOF_JIT_INFO);
+ jinfo->d.method = wrapper;
+ jinfo->code_start = info->code;
+ jinfo->code_size = info->code_size;
+ jinfo->unwind_info = mono_cache_unwind_info (uw_info, info_len);
+
+ if (!info->uw_info)
+ g_free (uw_info);
+
+ return jinfo;
+}
+
+/*
+ * mono_jit_compile_method_inner:
+ *
+ * Main entry point for the JIT.
+ */
gpointer
mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, int opt, MonoException **jit_ex)
{
return code;
}
-#ifndef DISABLE_JIT
-
-void*
-mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments) {
- return mono_arch_instrument_epilog_full (cfg, func, p, enable_arguments, FALSE);
-}
-
-void
-mono_cfg_add_try_hole (MonoCompile *cfg, MonoExceptionClause *clause, guint8 *start, MonoBasicBlock *bb)
-{
- TryBlockHole *hole = mono_mempool_alloc (cfg->mempool, sizeof (TryBlockHole));
- hole->clause = clause;
- hole->start_offset = start - cfg->native_code;
- hole->basic_block = bb;
-
- cfg->try_block_holes = g_slist_append_mempool (cfg->mempool, cfg->try_block_holes, hole);
-}
-
-void
-mono_cfg_set_exception (MonoCompile *cfg, int type)
-{
- cfg->exception_type = type;
-}
-
-#endif
-
/* Dummy versions of some arch specific functions to avoid ifdefs at call sites */
#ifndef MONO_ARCH_GSHAREDVT_SUPPORTED
}
#endif
-#ifdef USE_JUMP_TABLES
-#define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128
-
-typedef struct MonoJumpTableChunk {
- guint32 total;
- guint32 active;
- struct MonoJumpTableChunk *previous;
- /* gpointer entries[total]; */
-} MonoJumpTableChunk;
-
-static MonoJumpTableChunk* g_jumptable;
-#define mono_jumptable_lock() mono_mutex_lock (&jumptable_mutex)
-#define mono_jumptable_unlock() mono_mutex_unlock (&jumptable_mutex)
-static mono_mutex_t jumptable_mutex;
-
-static MonoJumpTableChunk*
-mono_create_jumptable_chunk (guint32 max_entries)
-{
- guint32 size = sizeof (MonoJumpTableChunk) + max_entries * sizeof(gpointer);
- MonoJumpTableChunk *chunk = (MonoJumpTableChunk*) g_new0 (guchar, size);
- chunk->total = max_entries;
- return chunk;
-}
-
-void
-mono_jumptable_init (void)
-{
- if (g_jumptable == NULL) {
- mono_mutex_init_recursive (&jumptable_mutex);
- g_jumptable = mono_create_jumptable_chunk (DEFAULT_JUMPTABLE_CHUNK_ELEMENTS);
- }
-}
-
-gpointer*
-mono_jumptable_add_entry (void)
-{
- return mono_jumptable_add_entries (1);
-}
-
-gpointer*
-mono_jumptable_add_entries (guint32 entries)
-{
- guint32 index;
- gpointer *result;
-
- mono_jumptable_init ();
- mono_jumptable_lock ();
- index = g_jumptable->active;
- if (index + entries >= g_jumptable->total) {
- /*
- * Grow jumptable, by adding one more chunk.
- * We cannot realloc jumptable, as there could be pointers
- * to existing jump table entries in the code, so instead
- * we just add one more chunk.
- */
- guint32 max_entries = entries;
- MonoJumpTableChunk *new_chunk;
-
- if (max_entries < DEFAULT_JUMPTABLE_CHUNK_ELEMENTS)
- max_entries = DEFAULT_JUMPTABLE_CHUNK_ELEMENTS;
- new_chunk = mono_create_jumptable_chunk (max_entries);
- /* Link old jumptable, so that we could free it up later. */
- new_chunk->previous = g_jumptable;
- g_jumptable = new_chunk;
- index = 0;
- }
- g_jumptable->active = index + entries;
- result = (gpointer*)((guchar*)g_jumptable + sizeof(MonoJumpTableChunk)) + index;
- mono_jumptable_unlock();
-
- return result;
-}
-
-void
-mono_jumptable_cleanup (void)
-{
- if (g_jumptable) {
- MonoJumpTableChunk *current = g_jumptable, *prev;
- while (current != NULL) {
- prev = current->previous;
- g_free (current);
- current = prev;
- }
- g_jumptable = NULL;
- mono_mutex_destroy (&jumptable_mutex);
- }
-}
-
-gpointer*
-mono_jumptable_get_entry (guint8 *code_ptr)
-{
- return mono_arch_jumptable_entry_from_code (code_ptr);
-}
-#endif
-
/*
* mini_get_underlying_type:
*
void
mini_jit_cleanup (void)
{
+#ifndef DISABLE_JIT
g_free (emul_opcode_map);
g_free (emul_opcode_opcodes);
+#endif
+}
+
+#ifdef DISABLE_JIT
+
+MonoCompile*
+mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFlags flags, int parts, int aot_method_index)
+{
+ g_assert_not_reached ();
+ return NULL;
+}
+
+void
+mono_destroy_compile (MonoCompile *cfg)
+{
+ g_assert_not_reached ();
+}
+
+void
+mono_add_patch_info (MonoCompile *cfg, int ip, MonoJumpInfoType type, gconstpointer target)
+{
+ g_assert_not_reached ();
}
+
+#endif /* DISABLE_JIT */
#endif
/* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 120
+#define MONO_AOT_FILE_VERSION 121
//TODO: This is x86/amd64 specific.
#define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
/* maps MonoMethod -> MonoJitDynamicMethodInfo */
GHashTable *dynamic_code_hash;
GHashTable *method_code_hash;
- /* Maps methods to a RuntimeInvokeInfo structure */
+ /* Maps methods to a RuntimeInvokeInfo structure, protected by the associated MonoDomain lock */
MonoConcurrentHashTable *runtime_invoke_hash;
/* Maps MonoMethod to a GPtrArray containing sequence point locations */
+ /* Protected by the domain lock */
GHashTable *seq_points;
/* Debugger agent data */
gpointer agent_info;
MONO_TRAMPOLINE_DELEGATE,
MONO_TRAMPOLINE_RESTORE_STACK_PROT,
MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING,
- MONO_TRAMPOLINE_MONITOR_ENTER,
- MONO_TRAMPOLINE_MONITOR_ENTER_V4,
- MONO_TRAMPOLINE_MONITOR_EXIT,
MONO_TRAMPOLINE_VCALL,
MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD,
MONO_TRAMPOLINE_NUM
/* These trampolines return normally to their caller */
#define MONO_TRAMPOLINE_TYPE_MUST_RETURN(t) \
((t) == MONO_TRAMPOLINE_RESTORE_STACK_PROT || \
- (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH || \
- (t) == MONO_TRAMPOLINE_MONITOR_ENTER || \
- (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 || \
- (t) == MONO_TRAMPOLINE_MONITOR_EXIT)
+ (t) == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
/* These trampolines receive an argument directly in a register */
#define MONO_TRAMPOLINE_TYPE_HAS_ARG(t) \
- ((t) == MONO_TRAMPOLINE_MONITOR_ENTER || \
- (t) == MONO_TRAMPOLINE_MONITOR_ENTER_V4 || \
- (t) == MONO_TRAMPOLINE_MONITOR_EXIT || \
- (t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
+ ((t) == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD)
/* optimization flags */
#define OPTFLAG(id,shift,name,descr) MONO_OPT_ ## id = 1 << shift,
MonoInst* mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode);
MonoInst* mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, int vreg);
void mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index);
-MonoInst* mono_compile_create_var_load (MonoCompile *cfg, gssize var_index);
-MonoInst* mono_compile_create_var_store (MonoCompile *cfg, gssize var_index, MonoInst *value);
MonoInst* mini_get_int_to_float_spill_area (MonoCompile *cfg);
MonoType* mono_type_from_stack_type (MonoInst *ins);
guint32 mono_alloc_ireg (MonoCompile *cfg) MONO_LLVM_INTERNAL;
int val);
MonoTrampInfo* mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJumpInfo *ji, GSList *unwind_ops);
void mono_tramp_info_free (MonoTrampInfo *info);
-void mono_tramp_info_register (MonoTrampInfo *info);
+void mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain);
int mini_exception_id_by_name (const char *name);
gboolean mini_type_is_hfa (MonoType *t, int *out_nfields, int *out_esize) MONO_LLVM_INTERNAL;
void mono_walk_stack_with_state (MonoJitStackWalk func, MonoThreadUnwindState *state, MonoUnwindOptions unwind_options, void *user_data);
void mono_walk_stack (MonoJitStackWalk func, MonoUnwindOptions options, void *user_data);
gboolean mono_thread_state_init_from_sigctx (MonoThreadUnwindState *ctx, void *sigctx);
+void mono_thread_state_init (MonoThreadUnwindState *ctx);
gboolean mono_thread_state_init_from_current (MonoThreadUnwindState *ctx);
gboolean mono_thread_state_init_from_monoctx (MonoThreadUnwindState *ctx, MonoContext *mctx);
MonoReflectionMethod **method,
gint32 *iloffset, gint32 *native_offset,
MonoString **file, gint32 *line, gint32 *column);
-MonoString *ves_icall_System_Exception_get_trace (MonoException *exc);
void mono_set_cast_details (MonoClass *from, MonoClass *to);
/* Installs a function which is called when the runtime encounters an unhandled exception.
shared_method = mini_get_shared_method (method);
}
- mono_domain_lock (domain);
+ mono_loader_lock ();
seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, method);
if (!seq_points && method->is_inflated) {
/* generic sharing + aot */
if (!seq_points)
seq_points = g_hash_table_lookup (domain_jit_info (domain)->seq_points, shared_method);
}
- mono_domain_unlock (domain);
+ mono_loader_unlock ();
return seq_points;
}
if (keepalive_stacks)
return;
MONO_GC_REGISTER_ROOT_PINNING (keepalive_stacks);
- keepalive_stacks = mono_g_hash_table_new (NULL, NULL);
+ keepalive_stacks = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_CONSERVATIVE_GC);
}
static void*
ctx = new_ctx;
if (endloop)
break;
- if (strcmp (jinfo_get_method (ji)->name, "Mark") == 0)
+ if (!ji->is_trampoline && strcmp (jinfo_get_method (ji)->name, "Mark") == 0)
endloop = TRUE;
} while (1);
#include <mono/metadata/marshal.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/mono-debug-debugger.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/gc-internal.h>
#include <mono/arch/amd64/amd64-codegen.h>
mono_arch_get_unbox_trampoline (MonoMethod *m, gpointer addr)
{
guint8 *code, *start;
+ GSList *unwind_ops;
int this_reg, size = NACL_SIZE (20, 32);
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, size);
+ unwind_ops = mono_arch_get_cie_program ();
+
amd64_alu_reg_imm (code, X86_ADD, this_reg, sizeof (MonoObject));
/* FIXME: Optimize this */
amd64_mov_reg_imm (code, AMD64_RAX, addr);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
{
guint8 *code, *start;
+ GSList *unwind_ops;
int buf_len;
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, buf_len);
+ unwind_ops = mono_arch_get_cie_program ();
+
amd64_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
amd64_jump_code (code, addr);
g_assert ((code - start) < buf_len);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
return start;
}
+#ifdef _WIN64
+// Workaround lack of Valgrind support for 64-bit Windows
+#define VALGRIND_DISCARD_TRANSLATIONS(...)
+#endif
+
/*
* mono_arch_patch_callsite:
*
offset += sizeof (MonoLMFTramp);
lmf_offset = -offset;
- framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+#ifdef TARGET_WIN32
+ /* Reserve space where the callee can save the argument registers */
+ offset += 4 * sizeof (mgreg_t);
+#endif
- orig_rsp_to_rbp_offset = 0;
- r11_save_code = code;
- /* Reserve space for the mov_membase_reg to save R11 */
- code += 5;
- after_r11_save_code = code;
+ framesize = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
// CFA = sp + 16 (the trampoline address is on the stack)
cfa_offset = 16;
// IP saved at CFA - 8
mono_add_unwind_op_offset (unwind_ops, code, buf, AMD64_RIP, -8);
+ orig_rsp_to_rbp_offset = 0;
+ r11_save_code = code;
+ /* Reserve space for the mov_membase_reg to save R11 */
+ code += 5;
+ after_r11_save_code = code;
+
/* Pop the return address off the stack */
amd64_pop_reg (code, AMD64_R11);
orig_rsp_to_rbp_offset += sizeof(mgreg_t);
//amd64_breakpoint (code);
#endif
- if (tramp_type != MONO_TRAMPOLINE_MONITOR_ENTER &&
- tramp_type != MONO_TRAMPOLINE_MONITOR_ENTER_V4 &&
- tramp_type != MONO_TRAMPOLINE_MONITOR_EXIT &&
- tramp_type != MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
+ if (tramp_type != MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
/* Obtain the trampoline argument which is encoded in the instruction stream */
if (aot) {
/* Load the GOT offset */
/* Restore stack */
amd64_leave (code);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, AMD64_RSP, cfa_offset);
+
if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type)) {
/* Load result */
int i;
gboolean mrgctx;
MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
+ GSList *unwind_ops;
mrgctx = MONO_RGCTX_SLOT_IS_MRGCTX (slot);
index = MONO_RGCTX_SLOT_INDEX (slot);
return buf;
}
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
- guint8 *tramp;
- guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_sync_null, *jump_cmpxchg_failed, *jump_other_owner, *jump_tid, *jump_sync_thin_hash = NULL;
- guint8 *jump_lock_taken_true = NULL;
- int tramp_size;
- int status_offset, nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
- int obj_reg = MONO_AMD64_ARG_REG1;
- int lock_taken_reg = MONO_AMD64_ARG_REG2;
- int sync_reg = MONO_AMD64_ARG_REG3;
- int tid_reg = MONO_AMD64_ARG_REG4;
- int status_reg = AMD64_RAX;
-
- g_assert (MONO_ARCH_MONITOR_OBJECT_REG == obj_reg);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
- g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == lock_taken_reg);
-#else
- g_assert (!is_v4);
-#endif
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = 128;
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- unwind_ops = mono_arch_get_cie_program ();
-
- if (!aot && mono_thread_get_tls_offset () != -1) {
- /* MonoObject* obj is in obj_reg */
- /* is obj null? */
- amd64_test_reg_reg (code, obj_reg, obj_reg);
- /* if yes, jump to actual trampoline */
- jump_obj_null = code;
- amd64_branch8 (code, X86_CC_Z, -1, 1);
-
- if (is_v4) {
- amd64_test_membase_imm (code, lock_taken_reg, 0, 1);
- /* if *lock_taken is 1, jump to actual trampoline */
- jump_lock_taken_true = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
- }
-
- /* load obj->synchronization to sync_reg */
- amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- /*FIXME use testb encoding*/
- amd64_test_reg_imm (code, sync_reg, 0x01);
- jump_sync_thin_hash = code;
- amd64_branch8 (code, X86_CC_NE, -1, 1);
-
- /*clear bits used by the gc*/
- amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3);
- }
-
- /* is synchronization null? */
- amd64_test_reg_reg (code, sync_reg, sync_reg);
- /* if yes, jump to actual trampoline */
- jump_sync_null = code;
- amd64_branch8 (code, X86_CC_Z, -1, 1);
-
- /* load MonoInternalThread* into tid_reg */
- code = mono_amd64_emit_tls_get (code, tid_reg, mono_thread_get_tls_offset ());
- /* load TID into tid_reg */
- amd64_mov_reg_membase (code, tid_reg, tid_reg, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-
- /* is synchronization->owner free */
- amd64_mov_reg_membase (code, status_reg, sync_reg, status_offset, 4);
- amd64_test_reg_imm_size (code, status_reg, OWNER_MASK, 4);
- /* if not, jump to next case */
- jump_tid = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
-
- /* if yes, try a compare-exchange with the TID */
- g_assert (tid_reg != X86_EAX);
- /* Form new status in tid_reg */
- amd64_alu_reg_reg_size (code, X86_OR, tid_reg, status_reg, 4);
- /* compare and exchange */
- amd64_prefix (code, X86_LOCK_PREFIX);
- amd64_cmpxchg_membase_reg_size (code, sync_reg, status_offset, tid_reg, 4);
- /* if not successful, jump to actual trampoline */
- jump_cmpxchg_failed = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
- /* if successful, return */
- if (is_v4)
- amd64_mov_membase_imm (code, lock_taken_reg, 0, 1, 1);
- amd64_ret (code);
-
- /* next case: synchronization->owner is not null */
- x86_patch (jump_tid, code);
- /* is synchronization->owner == TID? */
- amd64_alu_reg_imm_size (code, X86_AND, status_reg, OWNER_MASK, 4);
- amd64_alu_reg_reg_size (code, X86_CMP, status_reg, tid_reg, 4);
- /* if not, jump to actual trampoline */
- jump_other_owner = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
- /* if yes, increment nest */
- amd64_inc_membase_size (code, sync_reg, nest_offset, 4);
- /* return */
- if (is_v4)
- amd64_mov_membase_imm (code, lock_taken_reg, 0, 1, 1);
- amd64_ret (code);
-
- x86_patch (jump_obj_null, code);
- if (jump_sync_thin_hash)
- x86_patch (jump_sync_thin_hash, code);
- x86_patch (jump_sync_null, code);
- x86_patch (jump_cmpxchg_failed, code);
- x86_patch (jump_other_owner, code);
- if (is_v4)
- x86_patch (jump_lock_taken_true, code);
- }
-
- /* jump to the actual trampoline */
- if (MONO_AMD64_ARG_REG1 != obj_reg)
- amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t));
-
- if (aot) {
- if (is_v4)
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_enter_v4");
- else
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_enter");
- amd64_jump_reg (code, AMD64_R11);
- } else {
- if (is_v4)
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
- else
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
-
- /* jump to the actual trampoline */
- amd64_jump_code (code, tramp);
- }
-
- nacl_global_codeman_validate (&buf, tramp_size, &code);
-
- mono_arch_flush_icache (code, code - buf);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
- g_assert (code - buf <= tramp_size);
-
- if (is_v4)
- *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
- else
- *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- guint8 *tramp;
- guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned, *jump_cmpxchg_failed;
- guint8 *jump_next, *jump_sync_thin_hash = NULL;
- int tramp_size;
- int status_offset, nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
- int obj_reg = MONO_AMD64_ARG_REG1;
- int sync_reg = MONO_AMD64_ARG_REG2;
- int status_reg = MONO_AMD64_ARG_REG3;
-
- g_assert (obj_reg == MONO_ARCH_MONITOR_OBJECT_REG);
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = 112;
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- unwind_ops = mono_arch_get_cie_program ();
-
- if (!aot && mono_thread_get_tls_offset () != -1) {
- /* MonoObject* obj is in obj_reg */
- /* is obj null? */
- amd64_test_reg_reg (code, obj_reg, obj_reg);
- /* if yes, jump to actual trampoline */
- jump_obj_null = code;
- amd64_branch8 (code, X86_CC_Z, -1, 1);
-
- /* load obj->synchronization to RCX */
- amd64_mov_reg_membase (code, sync_reg, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 8);
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- /*FIXME use testb encoding*/
- amd64_test_reg_imm (code, sync_reg, 0x01);
- jump_sync_thin_hash = code;
- amd64_branch8 (code, X86_CC_NE, -1, 1);
-
- /*clear bits used by the gc*/
- amd64_alu_reg_imm (code, X86_AND, sync_reg, ~0x3);
- }
-
- /* is synchronization null? */
- amd64_test_reg_reg (code, sync_reg, sync_reg);
- /* if yes, jump to actual trampoline */
- jump_sync_null = code;
- amd64_branch8 (code, X86_CC_Z, -1, 1);
-
- /* next case: synchronization is not null */
- /* load MonoInternalThread* into RAX */
- code = mono_amd64_emit_tls_get (code, AMD64_RAX, mono_thread_get_tls_offset ());
- /* load TID into RAX */
- amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RAX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
- /* is synchronization->owner == TID */
- amd64_mov_reg_membase (code, status_reg, sync_reg, status_offset, 4);
- amd64_alu_reg_reg_size (code, X86_XOR, AMD64_RAX, status_reg, 4);
- amd64_test_reg_imm_size (code, AMD64_RAX, OWNER_MASK, 4);
-
- /* if no, jump to actual trampoline */
- jump_not_owned = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
-
- /* next case: synchronization->owner == TID */
- /* is synchronization->nest == 1 */
- amd64_alu_membase_imm_size (code, X86_CMP, sync_reg, nest_offset, 1, 4);
- /* if not, jump to next case */
- jump_next = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
- /* if yes, is synchronization->entry_count greater than zero */
- amd64_test_reg_imm_size (code, status_reg, ENTRY_COUNT_WAITERS, 4);
- /* if not, jump to actual trampoline */
- jump_have_waiters = code;
- amd64_branch8 (code, X86_CC_NZ, -1 , 1);
- /* if yes, try to set synchronization->owner to null and return */
- g_assert (status_reg != AMD64_RAX);
- /* old status in RAX */
- amd64_mov_reg_reg (code, AMD64_RAX, status_reg, 4);
- /* form new status */
- amd64_alu_reg_imm_size (code, X86_AND, status_reg, ENTRY_COUNT_MASK, 4);
- /* compare and exchange */
- amd64_prefix (code, X86_LOCK_PREFIX);
- amd64_cmpxchg_membase_reg_size (code, sync_reg, status_offset, status_reg, 4);
- /* if not successful, jump to actual trampoline */
- jump_cmpxchg_failed = code;
- amd64_branch8 (code, X86_CC_NZ, -1, 1);
- amd64_ret (code);
-
- /* next case: synchronization->nest is not 1 */
- x86_patch (jump_next, code);
- /* decrease synchronization->nest and return */
- amd64_dec_membase_size (code, sync_reg, nest_offset, 4);
- amd64_ret (code);
-
- if (jump_sync_thin_hash)
- x86_patch (jump_sync_thin_hash, code);
- x86_patch (jump_obj_null, code);
- x86_patch (jump_have_waiters, code);
- x86_patch (jump_not_owned, code);
- x86_patch (jump_cmpxchg_failed, code);
- x86_patch (jump_sync_null, code);
- }
-
- /* jump to the actual trampoline */
- if (MONO_AMD64_ARG_REG1 != obj_reg)
- amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, obj_reg, sizeof (mgreg_t));
-
- if (aot) {
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "specific_trampoline_monitor_exit");
- amd64_jump_reg (code, AMD64_R11);
- } else {
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
- amd64_jump_code (code, tramp);
- }
-
- nacl_global_codeman_validate (&buf, tramp_size, &code);
-
- mono_arch_flush_icache (code, code - buf);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
- g_assert (code - buf <= tramp_size);
-
- *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-
-#else
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-#endif
-
void
mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
{
guint8 *code, *buf;
int tramp_size = 64;
MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
+ GSList *unwind_ops;
g_assert (!aot);
code = buf = mono_global_codeman_reserve (tramp_size);
+ unwind_ops = mono_arch_get_cie_program ();
+
/*
This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
*/
amd64_mov_reg_membase (code, MONO_AMD64_ARG_REG1, MONO_AMD64_ARG_REG1, MONO_STRUCT_OFFSET (MonoJitTlsData, handler_block_return_address), 8);
/* Simulate a call */
amd64_push_reg (code, AMD64_RAX);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
amd64_jump_code (code, tramp);
} else {
/*Slow path uses a c helper*/
amd64_mov_reg_reg (code, MONO_AMD64_ARG_REG1, AMD64_RSP, 8);
amd64_mov_reg_imm (code, AMD64_RAX, tramp);
amd64_push_reg (code, AMD64_RAX);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 16);
amd64_push_reg (code, AMD64_RAX);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, 24);
amd64_jump_code (code, handler_block_trampoline_helper);
}
code = buf = mono_global_codeman_reserve (tramp_size);
- framesize = sizeof (MonoContext);
+ framesize = 0;
+#ifdef TARGET_WIN32
+ /* Reserve space where the callee can save the argument registers */
+ framesize += 4 * sizeof (mgreg_t);
+#endif
+
+ ctx_offset = framesize;
+ framesize += sizeof (MonoContext);
+
framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
// CFA = sp + 8
mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, AMD64_RBP);
amd64_alu_reg_imm (code, X86_SUB, AMD64_RSP, framesize);
- ctx_offset = 0;
gregs_offset = ctx_offset + MONO_STRUCT_OFFSET (MonoContext, gregs);
/* Initialize a MonoContext structure on the stack */
amd64_mov_membase_reg (code, AMD64_RBP, sizeof (mgreg_t), AMD64_R11, sizeof (mgreg_t));
amd64_leave (code);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, AMD64_RSP, cfa_offset);
amd64_ret (code);
mono_arch_flush_icache (code, code - buf);
/* The offset where lr was saved inside the regsave area */
lr_offset = 13 * sizeof (mgreg_t);
- // FIXME: Finish the unwind info, the current info allows us to unwind
- // when the trampoline is not in the epilog
-
// CFA = SP + (num registers pushed) * 4
cfa_offset = 14 * sizeof (mgreg_t);
mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, cfa_offset);
* Note that IP has been conveniently set to the method addr.
*/
ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, STACK - regsave_size);
+ cfa_offset -= STACK - regsave_size;
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
ARM_POP_NWB (code, 0x5fff);
+ mono_add_unwind_op_same_value (unwind_ops, code, buf, ARMREG_LR);
if (tramp_type == MONO_TRAMPOLINE_RGCTX_LAZY_FETCH)
ARM_MOV_REG_REG (code, ARMREG_R0, ARMREG_IP);
ARM_ADD_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, regsave_size);
+ cfa_offset -= regsave_size;
+ g_assert (cfa_offset == 0);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type))
code = emit_bx (code, ARMREG_LR);
else
{
guint8 *code, *start;
MonoDomain *domain = mono_domain_get ();
+ GSList *unwind_ops;
#ifdef USE_JUMP_TABLES
gpointer *jte;
guint32 size = 20;
start = code = mono_domain_code_reserve (domain, size);
+ unwind_ops = mono_arch_get_cie_program ();
+
#ifdef USE_JUMP_TABLES
jte = mono_jumptable_add_entry ();
code = mono_arm_load_jumptable_entry (code, jte, ARMREG_IP);
/*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
g_print ("unbox code is at %p for method at %p\n", start, addr);*/
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
mono_arch_get_static_rgctx_trampoline (MonoMethod *m, MonoMethodRuntimeGenericContext *mrgctx, gpointer addr)
{
guint8 *code, *start;
+ GSList *unwind_ops;
#ifdef USE_JUMP_TABLES
int buf_len = 20;
gpointer *jte;
start = code = mono_domain_code_reserve (domain, buf_len);
+ unwind_ops = mono_arch_get_cie_program ();
+
#ifdef USE_JUMP_TABLES
jte = mono_jumptable_add_entries (2);
code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
code = buf = mono_global_codeman_reserve (tramp_size);
- mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
+ unwind_ops = mono_arch_get_cie_program ();
rgctx_null_jumps = g_malloc (sizeof (guint8*) * (depth + 2));
njumps = 0;
code = buf = mono_global_codeman_reserve (tramp_size);
- mono_add_unwind_op_def_cfa (unwind_ops, code, buf, ARMREG_SP, 0);
+ unwind_ops = mono_arch_get_cie_program ();
// FIXME: Currently, we always go to the slow path.
/* Load trampoline addr */
code = buf = mono_global_codeman_reserve (tramp_size);
+ unwind_ops = mono_arch_get_cie_program ();
+
tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD, NULL, NULL);
/*
mono_arch_flush_icache (buf, code - buf);
mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, buf, code - buf, NULL, NULL), domain);
+
return buf;
}
desc [0] = buf;
desc [1] = func_gp;
+ mono_tramp_info_register (mono_tramp_info_create (NULL, buf, code.buf - buf, NULL, NULL), domain);
+
return desc;
}
/*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
g_print ("unbox code is at %p for method at %p\n", start, addr);*/
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
mono_arch_flush_icache (start, code - start);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
/*g_print ("unbox trampoline at %d for %s:%s\n", this_pos, m->klass->name, m->name);
g_print ("unbox code is at %p for method at %p\n", start, addr);*/
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
mono_arch_flush_icache (start, code - start);
g_assert ((code - start) <= size);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
#include <mono/metadata/appdomain.h>
#include <mono/metadata/gc-internal.h>
#include <mono/metadata/marshal.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/tabledefs.h>
#include <mono/arch/s390x/s390x-codegen.h>
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, method);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return start;
}
/*----------------------------------------------------------*/
code = buf = mono_domain_code_reserve (domain, SPECIFIC_TRAMPOLINE_SIZE);
- switch (tramp_type) {
- /*
- * Monitor tramps have the object in r2
- */
- case MONO_TRAMPOLINE_MONITOR_ENTER:
- case MONO_TRAMPOLINE_MONITOR_ENTER_V4:
- case MONO_TRAMPOLINE_MONITOR_EXIT:
- s390_lgr (buf, s390_r1, s390_r2);
- break;
- default :
- S390_SET (buf, s390_r1, arg1);
- }
+ S390_SET (buf, s390_r1, arg1);
displace = (tramp - buf) / 2;
s390_jg (buf, displace);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_HELPER, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), domain);
+
return(start);
}
}
/*========================= End of Function ========================*/
-
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_monitor_enter_trampoline */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
- guint8 *tramp,
- *code, *buf;
- gint16 *jump_obj_null,
- *jump_sync_null,
- *jump_cs_failed,
- *jump_other_owner,
- *jump_tid,
- *jump_sync_thin_hash = NULL,
- *jump_lock_taken_true = NULL;
- int tramp_size,
- status_reg = s390_r0,
- lock_taken_reg = s390_r1,
- obj_reg = s390_r2,
- sync_reg = s390_r3,
- tid_reg = s390_r4,
- status_offset,
- nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
-
- g_assert (MONO_ARCH_MONITOR_OBJECT_REG == obj_reg);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
- g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == lock_taken_reg);
-#else
- g_assert (!is_v4);
-#endif
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = 160;
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- unwind_ops = mono_arch_get_cie_program ();
-
- if (mono_thread_get_tls_offset () != -1) {
- /* MonoObject* obj is in obj_reg */
- /* is obj null? */
- s390_ltgr (code, obj_reg, obj_reg);
- /* if yes, jump to actual trampoline */
- s390_jz (code, 0); CODEPTR(code, jump_obj_null);
-
- if (is_v4) {
- s390_cli (code, lock_taken_reg, 0, 1);
- /* if *lock_taken is 1, jump to actual trampoline */
- s390_je (code, 0); CODEPTR(code, jump_lock_taken_true);
- }
-
- /* load obj->synchronization to sync_reg */
- s390_lg (code, sync_reg, 0, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation));
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- s390_tmll (code, sync_reg, 1);
- s390_jo (code, 0); CODEPTR(code, jump_sync_thin_hash);
-
- /* Clear bits used by the gc */
- s390_nill (code, sync_reg, ~0x3);
- }
-
- /* is synchronization null? */
- s390_ltgr (code, sync_reg, sync_reg);
- /* if yes, jump to actual trampoline */
- s390_jz (code, 0); CODEPTR(code, jump_sync_null);
-
- /* load MonoInternalThread* into tid_reg */
- s390_ear (code, s390_r5, 0);
- s390_sllg(code, s390_r5, s390_r5, 0, 32);
- s390_ear (code, s390_r5, 1);
- /* load tid */
- s390_lg (code, tid_reg, 0, s390_r5, mono_thread_get_tls_offset ());
- s390_lgf (code, tid_reg, 0, tid_reg, MONO_STRUCT_OFFSET (MonoInternalThread, small_id));
-
- /* is synchronization->owner free */
- s390_lgf (code, status_reg, 0, sync_reg, status_offset);
- s390_nilf (code, status_reg, OWNER_MASK);
- /* if not, jump to next case */
- s390_jnz (code, 0); CODEPTR(code, jump_tid);
-
- /* if yes, try a compare-exchange with the TID */
- /* Form new status in tid_reg */
- s390_xr (code, tid_reg, status_reg);
- /* compare and exchange */
- s390_cs (code, status_reg, tid_reg, sync_reg, status_offset);
- s390_jnz (code, 0); CODEPTR(code, jump_cs_failed);
- /* if successful, return */
- if (is_v4)
- s390_mvi (code, lock_taken_reg, 0, 1);
- s390_br (code, s390_r14);
-
- /* next case: synchronization->owner is not null */
- PTRSLOT(code, jump_tid);
- /* is synchronization->owner == TID? */
- s390_nilf (code, status_reg, OWNER_MASK);
- s390_cr (code, status_reg, tid_reg);
- /* if not, jump to actual trampoline */
- s390_jnz (code, 0); CODEPTR(code, jump_other_owner);
- /* if yes, increment nest */
- s390_lgf (code, s390_r5, 0, sync_reg, nest_offset);
- s390_ahi (code, s390_r5, 1);
- s390_st (code, s390_r5, 0, sync_reg, nest_offset);
- /* return */
- if (is_v4)
- s390_mvi (code, lock_taken_reg, 0, 1);
- s390_br (code, s390_r14);
-
- PTRSLOT (code, jump_obj_null);
- if (jump_sync_thin_hash)
- PTRSLOT (code, jump_sync_thin_hash);
- PTRSLOT (code, jump_sync_null);
- PTRSLOT (code, jump_cs_failed);
- PTRSLOT (code, jump_other_owner);
- if (is_v4)
- PTRSLOT (code, jump_lock_taken_true);
- }
-
- /* jump to the actual trampoline */
- if (is_v4)
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER_V4, mono_get_root_domain (), NULL);
- else
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_ENTER, mono_get_root_domain (), NULL);
-
- /* jump to the actual trampoline */
- S390_SET (code, s390_r1, tramp);
- s390_br (code, s390_r1);
-
- mono_arch_flush_icache (code, code - buf);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
- g_assert (code - buf <= tramp_size);
-
- if (info) {
- if (is_v4)
- *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
- else
- *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
- }
-
- return buf;
-}
-
-/*========================= End of Function ========================*/
-
-/*------------------------------------------------------------------*/
-/* */
-/* Name - mono_arch_create_monitor_exit_trampoline */
-/* */
-/* Function - */
-/* */
-/*------------------------------------------------------------------*/
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- guint8 *tramp,
- *code, *buf;
- gint16 *jump_obj_null,
- *jump_have_waiters,
- *jump_sync_null,
- *jump_not_owned,
- *jump_cs_failed,
- *jump_next,
- *jump_sync_thin_hash = NULL;
- int tramp_size,
- status_offset, nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
- int obj_reg = s390_r2,
- sync_reg = s390_r3,
- status_reg = s390_r4;
-
- g_assert (obj_reg == MONO_ARCH_MONITOR_OBJECT_REG);
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = 160;
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- unwind_ops = mono_arch_get_cie_program ();
-
- if (mono_thread_get_tls_offset () != -1) {
- /* MonoObject* obj is in obj_reg */
- /* is obj null? */
- s390_ltgr (code, obj_reg, obj_reg);
- /* if yes, jump to actual trampoline */
- s390_jz (code, 0); CODEPTR(code, jump_obj_null);
-
- /* load obj->synchronization to RCX */
- s390_lg (code, sync_reg, 0, obj_reg, MONO_STRUCT_OFFSET (MonoObject, synchronisation));
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- s390_tmll (code, sync_reg, 1);
- s390_jo (code, 0); CODEPTR(code, jump_sync_thin_hash);
-
- /* Clear bits used by the gc */
- s390_nill (code, sync_reg, ~0x3);
- }
-
- /* is synchronization null? */
- s390_ltgr (code, sync_reg, sync_reg);
- /* if yes, jump to actual trampoline */
- s390_jz (code, 0); CODEPTR(code, jump_sync_null);
-
- /* next case: synchronization is not null */
- /* load MonoInternalThread* into r5 */
- s390_ear (code, s390_r5, 0);
- s390_sllg(code, s390_r5, s390_r5, 0, 32);
- s390_ear (code, s390_r5, 1);
- /* load TID into r1 */
- s390_lg (code, s390_r1, 0, s390_r5, mono_thread_get_tls_offset ());
- s390_lgf (code, s390_r1, 0, s390_r1, MONO_STRUCT_OFFSET (MonoInternalThread, small_id));
- /* is synchronization->owner == TID */
- s390_lgf (code, status_reg, 0, sync_reg, status_offset);
- s390_xr (code, s390_r1, status_reg);
- s390_tmlh (code, s390_r1, OWNER_MASK);
- /* if not, jump to actual trampoline */
- s390_jno (code, 0); CODEPTR(code, jump_not_owned);
-
- /* next case: synchronization->owner == TID */
- /* is synchronization->nest == 1 */
- s390_lgf (code, s390_r0, 0, sync_reg, nest_offset);
- s390_chi (code, s390_r0, 1);
- /* if not, jump to next case */
- s390_jne (code, 0); CODEPTR(code, jump_next);
- /* if yes, is synchronization->entry_count greater than zero */
- s390_cfi (code, status_reg, ENTRY_COUNT_WAITERS);
- /* if not, jump to actual trampoline */
- s390_jnz (code, 0); CODEPTR(code, jump_have_waiters);
- /* if yes, try to set synchronization->owner to null and return */
- /* old status in s390_r0 */
- s390_lgfr (code, s390_r0, status_reg);
- /* form new status */
- s390_nilf (code, status_reg, ENTRY_COUNT_MASK);
- /* compare and exchange */
- s390_cs (code, s390_r0, status_reg, sync_reg, status_offset);
- /* if not successful, jump to actual trampoline */
- s390_jnz (code, 0); CODEPTR(code, jump_cs_failed);
- s390_br (code, s390_r14);
-
- /* next case: synchronization->nest is not 1 */
- PTRSLOT (code, jump_next);
- /* decrease synchronization->nest and return */
- s390_lgf (code, s390_r0, 0, sync_reg, nest_offset);
- s390_ahi (code, s390_r0, -1);
- s390_st (code, s390_r0, 0, sync_reg, nest_offset);
- s390_br (code, s390_r14);
-
- PTRSLOT (code, jump_obj_null);
- if (jump_sync_thin_hash)
- PTRSLOT (code, jump_sync_thin_hash);
- PTRSLOT (code, jump_have_waiters);
- PTRSLOT (code, jump_not_owned);
- PTRSLOT (code, jump_cs_failed);
- PTRSLOT (code, jump_sync_null);
- }
-
- /* jump to the actual trampoline */
- tramp = mono_arch_create_specific_trampoline (NULL, MONO_TRAMPOLINE_MONITOR_EXIT, mono_get_root_domain (), NULL);
-
- S390_SET (code, s390_r1, tramp);
- s390_br (code, s390_r1);
-
- mono_arch_flush_icache (code, code - buf);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
- g_assert (code - buf <= tramp_size);
-
- if (info)
- *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-
-/*========================= End of Function ========================*/
-#endif
mono_arch_flush_icache (start, code - start);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, NULL), NULL);
+
return start;
}
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/mono-debug.h>
#include <mono/metadata/mono-debug-debugger.h>
-#include <mono/metadata/monitor.h>
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/gc-internal.h>
#include <mono/arch/x86/x86-codegen.h>
#include "mini.h"
#include "mini-x86.h"
+#include "debugger-agent.h"
#define ALIGN_TO(val,align) ((((guint64)val) + ((align) - 1)) & ~((align) - 1))
guint8 *code, *start;
int this_pos = 4, size = NACL_SIZE(16, 32);
MonoDomain *domain = mono_domain_get ();
+ GSList *unwind_ops;
start = code = mono_domain_code_reserve (domain, size);
+ unwind_ops = mono_arch_get_cie_program ();
+
x86_alu_membase_imm (code, X86_ADD, X86_ESP, this_pos, sizeof (MonoObject));
x86_jump_code (code, addr);
g_assert ((code - start) < size);
nacl_domain_code_validate (domain, &start, size, &code);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_UNBOX_TRAMPOLINE, m);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
{
guint8 *code, *start;
int buf_len;
+ GSList *unwind_ops;
MonoDomain *domain = mono_domain_get ();
start = code = mono_domain_code_reserve (domain, buf_len);
+ unwind_ops = mono_arch_get_cie_program ();
+
x86_mov_reg_imm (code, MONO_ARCH_RGCTX_REG, mrgctx);
x86_jump_code (code, addr);
g_assert ((code - start) <= buf_len);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
GSList *unwind_ops = NULL;
MonoJumpInfo *ji = NULL;
int i, offset, frame_size, regarray_offset, lmf_offset, caller_ip_offset, arg_offset;
-
- unwind_ops = mono_arch_get_cie_program ();
+ int cfa_offset; /* cfa = cfa_reg + cfa_offset */
code = buf = mono_global_codeman_reserve (256);
* the ret address is at: esp + (pushed_args + 1) * sizeof (gpointer)
*/
- // FIXME: Unwind info
-
/* Compute frame offsets relative to the frame pointer %ebp */
arg_offset = sizeof (mgreg_t);
caller_ip_offset = 2 * sizeof (mgreg_t);
offset += 4 * sizeof (mgreg_t);
frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT);
+ /* ret addr and arg are on the stack */
+ cfa_offset = 2 * sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+ // IP saved at CFA - 4
+ mono_add_unwind_op_offset (unwind_ops, code, buf, X86_NREG, -4);
+
/* Allocate frame */
x86_push_reg (code, X86_EBP);
+ cfa_offset += sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+ mono_add_unwind_op_offset (unwind_ops, code, buf, X86_EBP, -cfa_offset);
+
x86_mov_reg_reg (code, X86_EBP, X86_ESP, sizeof (mgreg_t));
+ mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, X86_EBP);
+
/* There are three words on the stack, adding + 4 aligns the stack to 16, which is needed on osx */
x86_alu_reg_imm (code, X86_SUB, X86_ESP, frame_size + sizeof (mgreg_t));
/* Restore frame */
x86_leave (code);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+ mono_add_unwind_op_same_value (unwind_ops, code, buf, X86_EBP);
if (MONO_TRAMPOLINE_TYPE_MUST_RETURN (tramp_type)) {
/* Load the value returned by the trampoline */
x86_mov_reg_membase (code, X86_EAX, X86_ESP, 0, 4);
/* The trampoline returns normally, pop the trampoline argument */
x86_alu_reg_imm (code, X86_ADD, X86_ESP, 4);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
x86_ret (code);
} else {
/* The trampoline argument is at the top of the stack, and it contains the address we need to branch to */
if (tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) {
x86_pop_reg (code, X86_EAX);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
x86_alu_reg_imm (code, X86_ADD, X86_ESP, 0x8);
x86_jump_reg (code, X86_EAX);
} else {
return buf;
}
-#ifdef MONO_ARCH_MONITOR_OBJECT_REG
-/*
- * The code produced by this trampoline is equivalent to this:
- *
- * if (obj) {
- * if (obj->synchronisation) {
- * if (obj->synchronisation->owner == 0) {
- * if (cmpxch (&obj->synchronisation->owner, TID, 0) == 0)
- * return;
- * }
- * if (obj->synchronisation->owner == TID) {
- * ++obj->synchronisation->nest;
- * return;
- * }
- * }
- * }
- * return full_monitor_enter ();
- *
- */
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
- guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_sync_null, *jump_other_owner, *jump_cmpxchg_failed, *jump_tid, *jump_sync_thin_hash = NULL;
- guint8 *jump_lock_taken_true = NULL;
- int tramp_size;
- int status_offset, nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
-
- g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
-#ifdef MONO_ARCH_MONITOR_LOCK_TAKEN_REG
- g_assert (MONO_ARCH_MONITOR_LOCK_TAKEN_REG == X86_EDX);
-#else
- g_assert (!is_v4);
-#endif
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = NACL_SIZE (128, 192);
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- x86_push_reg (code, X86_EAX);
- if (mono_thread_get_tls_offset () != -1) {
- if (is_v4) {
- x86_test_membase_imm (code, X86_EDX, 0, 1);
- /* if *lock_taken is 1, jump to actual trampoline */
- jump_lock_taken_true = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
- x86_push_reg (code, X86_EDX);
- }
- /* MonoObject* obj is in EAX */
- /* is obj null? */
- x86_test_reg_reg (code, X86_EAX, X86_EAX);
- /* if yes, jump to actual trampoline */
- jump_obj_null = code;
- x86_branch8 (code, X86_CC_Z, -1, 1);
-
- /* load obj->synchronization to ECX */
- x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 4);
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- /*FIXME use testb encoding*/
- x86_test_reg_imm (code, X86_ECX, 0x01);
- jump_sync_thin_hash = code;
- x86_branch8 (code, X86_CC_NE, -1, 1);
-
- /*clear bits used by the gc*/
- x86_alu_reg_imm (code, X86_AND, X86_ECX, ~0x3);
- }
-
- /* is synchronization null? */
- x86_test_reg_reg (code, X86_ECX, X86_ECX);
-
- /* if yes, jump to actual trampoline */
- jump_sync_null = code;
- x86_branch8 (code, X86_CC_Z, -1, 1);
-
- /* load MonoInternalThread* into EDX */
- if (aot) {
- /* load_aotconst () puts the result into EAX */
- x86_mov_reg_reg (code, X86_EDX, X86_EAX, sizeof (mgreg_t));
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_THREAD));
- code = mono_x86_emit_tls_get_reg (code, X86_EAX, X86_EAX);
- x86_xchg_reg_reg (code, X86_EAX, X86_EDX, sizeof (mgreg_t));
- } else {
- code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
- }
- /* load TID into EDX */
- x86_mov_reg_membase (code, X86_EDX, X86_EDX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
-
- /* is synchronization->owner free */
- x86_mov_reg_membase (code, X86_EAX, X86_ECX, status_offset, 4);
- x86_test_reg_imm (code, X86_EAX, OWNER_MASK);
- /* if not, jump to next case */
- jump_tid = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
-
- /* if yes, try a compare-exchange with the TID */
- /* Form new status */
- x86_alu_reg_reg (code, X86_OR, X86_EDX, X86_EAX);
- /* compare and exchange */
- x86_prefix (code, X86_LOCK_PREFIX);
- x86_cmpxchg_membase_reg (code, X86_ECX, status_offset, X86_EDX);
- /* if not successful, jump to actual trampoline */
- jump_cmpxchg_failed = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
- /* if successful, pop and return */
- if (is_v4) {
- x86_pop_reg (code, X86_EDX);
- x86_mov_membase_imm (code, X86_EDX, 0, 1, 1);
- }
- x86_pop_reg (code, X86_EAX);
- x86_ret (code);
-
- /* next case: synchronization->owner is not null */
- x86_patch (jump_tid, code);
- /* is synchronization->owner == TID? */
- x86_alu_reg_imm (code, X86_AND, X86_EAX, OWNER_MASK);
- x86_alu_reg_reg (code, X86_CMP, X86_EAX, X86_EDX);
- /* if not, jump to actual trampoline */
- jump_other_owner = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
- /* if yes, increment nest */
- x86_inc_membase (code, X86_ECX, nest_offset);
- if (is_v4) {
- x86_pop_reg (code, X86_EDX);
- x86_mov_membase_imm (code, X86_EDX, 0, 1, 1);
- }
- x86_pop_reg (code, X86_EAX);
- /* return */
- x86_ret (code);
-
- /* obj is pushed, jump to the actual trampoline */
- x86_patch (jump_obj_null, code);
- if (jump_sync_thin_hash)
- x86_patch (jump_sync_thin_hash, code);
- x86_patch (jump_sync_null, code);
- x86_patch (jump_other_owner, code);
- x86_patch (jump_cmpxchg_failed, code);
-
- if (is_v4) {
- x86_pop_reg (code, X86_EDX);
- x86_patch (jump_lock_taken_true, code);
- }
- }
-
- if (aot) {
- /* We are calling the generic trampoline directly, the argument is pushed
- * on the stack just like a specific trampoline.
- */
- if (is_v4)
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter_v4");
- else
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_enter");
- x86_jump_reg (code, X86_EAX);
- } else {
- if (is_v4)
- x86_jump_code (code, mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER_V4));
- else
- x86_jump_code (code, mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_ENTER));
- }
-
- mono_arch_flush_icache (buf, code - buf);
- g_assert (code - buf <= tramp_size);
-
- nacl_global_codeman_validate (&buf, tramp_size, &code);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-
- if (is_v4)
- *info = mono_tramp_info_create ("monitor_enter_v4_trampoline", buf, code - buf, ji, unwind_ops);
- else
- *info = mono_tramp_info_create ("monitor_enter_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- guint8 *tramp = mono_get_trampoline_code (MONO_TRAMPOLINE_MONITOR_EXIT);
- guint8 *code, *buf;
- guint8 *jump_obj_null, *jump_have_waiters, *jump_sync_null, *jump_not_owned, *jump_sync_thin_hash = NULL;
- guint8 *jump_next, *jump_cmpxchg_failed;
- int tramp_size;
- int status_offset, nest_offset;
- MonoJumpInfo *ji = NULL;
- GSList *unwind_ops = NULL;
-
- g_assert (MONO_ARCH_MONITOR_OBJECT_REG == X86_EAX);
-
- mono_monitor_threads_sync_members_offset (&status_offset, &nest_offset);
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (status_offset) == sizeof (guint32));
- g_assert (MONO_THREADS_SYNC_MEMBER_SIZE (nest_offset) == sizeof (guint32));
- status_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (status_offset);
- nest_offset = MONO_THREADS_SYNC_MEMBER_OFFSET (nest_offset);
-
- tramp_size = NACL_SIZE (128, 192);
-
- code = buf = mono_global_codeman_reserve (tramp_size);
-
- x86_push_reg (code, X86_EAX);
- if (mono_thread_get_tls_offset () != -1) {
- /* MonoObject* obj is in EAX */
- /* is obj null? */
- x86_test_reg_reg (code, X86_EAX, X86_EAX);
- /* if yes, jump to actual trampoline */
- jump_obj_null = code;
- x86_branch8 (code, X86_CC_Z, -1, 1);
-
- /* load obj->synchronization to ECX */
- x86_mov_reg_membase (code, X86_ECX, X86_EAX, MONO_STRUCT_OFFSET (MonoObject, synchronisation), 4);
-
- if (mono_gc_is_moving ()) {
- /*if bit zero is set it's a thin hash*/
- /*FIXME use testb encoding*/
- x86_test_reg_imm (code, X86_ECX, 0x01);
- jump_sync_thin_hash = code;
- x86_branch8 (code, X86_CC_NE, -1, 1);
-
- /*clear bits used by the gc*/
- x86_alu_reg_imm (code, X86_AND, X86_ECX, ~0x3);
- }
-
- /* is synchronization null? */
- x86_test_reg_reg (code, X86_ECX, X86_ECX);
- /* if yes, jump to actual trampoline */
- jump_sync_null = code;
- x86_branch8 (code, X86_CC_Z, -1, 1);
-
- /* next case: synchronization is not null */
- /* load MonoInternalThread* into EDX */
- if (aot) {
- /* load_aotconst () puts the result into EAX */
- x86_mov_reg_reg (code, X86_EDX, X86_EAX, sizeof (mgreg_t));
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_THREAD));
- code = mono_x86_emit_tls_get_reg (code, X86_EAX, X86_EAX);
- x86_xchg_reg_reg (code, X86_EAX, X86_EDX, sizeof (mgreg_t));
- } else {
- code = mono_x86_emit_tls_get (code, X86_EDX, mono_thread_get_tls_offset ());
- }
- /* load TID into EDX */
- x86_mov_reg_membase (code, X86_EDX, X86_EDX, MONO_STRUCT_OFFSET (MonoInternalThread, small_id), 4);
- /* is synchronization->owner == TID */
- x86_mov_reg_membase (code, X86_EAX, X86_ECX, status_offset, 4);
- x86_alu_reg_reg (code, X86_XOR, X86_EDX, X86_EAX);
- x86_test_reg_imm (code, X86_EDX, OWNER_MASK);
- /* if no, jump to actual trampoline */
- jump_not_owned = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
-
- /* next case: synchronization->owner == TID */
- /* is synchronization->nest == 1 */
- x86_alu_membase_imm (code, X86_CMP, X86_ECX, nest_offset, 1);
- /* if not, jump to next case */
- jump_next = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
- /* if yes, is synchronization->entry_count greater than zero? */
- x86_test_reg_imm (code, X86_EAX, ENTRY_COUNT_WAITERS);
- /* if yes, jump to actual trampoline */
- jump_have_waiters = code;
- x86_branch8 (code, X86_CC_NZ, -1 , 1);
- /* if not, try to set synchronization->owner to null and return */
- x86_mov_reg_reg (code, X86_EDX, X86_EAX, 4);
- x86_alu_reg_imm (code, X86_AND, X86_EDX, ENTRY_COUNT_MASK);
- /* compare and exchange */
- x86_prefix (code, X86_LOCK_PREFIX);
- /* EAX contains the previous status */
- x86_cmpxchg_membase_reg (code, X86_ECX, status_offset, X86_EDX);
- /* if not successful, jump to actual trampoline */
- jump_cmpxchg_failed = code;
- x86_branch8 (code, X86_CC_NZ, -1, 1);
-
- x86_pop_reg (code, X86_EAX);
- x86_ret (code);
-
- /* next case: synchronization->nest is not 1 */
- x86_patch (jump_next, code);
- /* decrease synchronization->nest and return */
- x86_dec_membase (code, X86_ECX, nest_offset);
- x86_pop_reg (code, X86_EAX);
- x86_ret (code);
-
- /* push obj and jump to the actual trampoline */
- x86_patch (jump_obj_null, code);
- if (jump_sync_thin_hash)
- x86_patch (jump_sync_thin_hash, code);
- x86_patch (jump_have_waiters, code);
- x86_patch (jump_cmpxchg_failed, code);
- x86_patch (jump_not_owned, code);
- x86_patch (jump_sync_null, code);
- }
-
- /* obj is pushed, jump to the actual trampoline */
- if (aot) {
- code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "generic_trampoline_monitor_exit");
- x86_jump_reg (code, X86_EAX);
- } else {
- x86_jump_code (code, tramp);
- }
-
- nacl_global_codeman_validate (&buf, tramp_size, &code);
-
- mono_arch_flush_icache (buf, code - buf);
- g_assert (code - buf <= tramp_size);
- mono_profiler_code_buffer_new (buf, code - buf, MONO_PROFILER_CODE_BUFFER_MONITOR, NULL);
-
- *info = mono_tramp_info_create ("monitor_exit_trampoline", buf, code - buf, ji, unwind_ops);
-
- return buf;
-}
-
-#else
-
-gpointer
-mono_arch_create_monitor_enter_trampoline (MonoTrampInfo **info, gboolean is_v4, gboolean aot)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-gpointer
-mono_arch_create_monitor_exit_trampoline (MonoTrampInfo **info, gboolean aot)
-{
- g_assert_not_reached ();
- return NULL;
-}
-
-#endif
-
void
mono_arch_invalidate_method (MonoJitInfo *ji, void *func, gpointer func_arg)
{
guint8 *code, *buf;
int tramp_size = 64;
MonoJumpInfo *ji = NULL;
+ int cfa_offset;
GSList *unwind_ops = NULL;
g_assert (!aot);
code = buf = mono_global_codeman_reserve (tramp_size);
+ unwind_ops = mono_arch_get_cie_program ();
+ cfa_offset = sizeof (mgreg_t);
/*
This trampoline restore the call chain of the handler block then jumps into the code that deals with it.
*/
/* Simulate a call */
/*Fix stack alignment*/
x86_alu_reg_imm (code, X86_SUB, X86_ESP, 0x4);
+ cfa_offset += sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+
/* This is the address the trampoline will return to */
x86_push_reg (code, X86_EAX);
+ cfa_offset += sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+
/* Dummy trampoline argument, since we call the generic trampoline directly */
x86_push_imm (code, 0);
+ cfa_offset += sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
x86_jump_code (code, tramp);
nacl_global_codeman_validate (&buf, tramp_size, &code);
{
guint8 *code, *start;
int buf_len;
+ GSList *unwind_ops;
+
buf_len = 10;
start = code = mono_domain_code_reserve (domain, buf_len);
+ unwind_ops = mono_arch_get_cie_program ();
+
x86_mov_reg_imm (code, X86_EAX, arg);
x86_jump_code (code, addr);
g_assert ((code - start) <= buf_len);
mono_arch_flush_icache (start, code - start);
mono_profiler_code_buffer_new (start, code - start, MONO_PROFILER_CODE_BUFFER_GENERICS_TRAMPOLINE, NULL);
+ mono_tramp_info_register (mono_tramp_info_create (NULL, start, code - start, NULL, unwind_ops), domain);
+
return start;
}
+/*
+ * mono_arch_create_sdb_trampoline:
+ *
+ * Return a trampoline which captures the current context, passes it to
+ * debugger_agent_single_step_from_context ()/debugger_agent_breakpoint_from_context (),
+ * then restores the (potentially changed) context.
+ */
+guint8*
+mono_arch_create_sdb_trampoline (gboolean single_step, MonoTrampInfo **info, gboolean aot)
+{
+ int tramp_size = 256;
+ int framesize, ctx_offset, cfa_offset;
+ guint8 *code, *buf;
+ GSList *unwind_ops = NULL;
+ MonoJumpInfo *ji = NULL;
+
+ code = buf = mono_global_codeman_reserve (tramp_size);
+
+ framesize = 0;
+
+ /* Argument area */
+ framesize += sizeof (mgreg_t);
+
+ ctx_offset = framesize;
+ framesize += sizeof (MonoContext);
+
+ framesize = ALIGN_TO (framesize, MONO_ARCH_FRAME_ALIGNMENT);
+
+ // CFA = sp + 4
+ cfa_offset = 4;
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, 4);
+ // IP saved at CFA - 4
+ mono_add_unwind_op_offset (unwind_ops, code, buf, X86_NREG, -cfa_offset);
+
+ x86_push_reg (code, X86_EBP);
+ cfa_offset += sizeof(mgreg_t);
+ mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
+ mono_add_unwind_op_offset (unwind_ops, code, buf, X86_EBP, - cfa_offset);
+
+ x86_mov_reg_reg (code, X86_EBP, X86_ESP, sizeof(mgreg_t));
+ mono_add_unwind_op_def_cfa_reg (unwind_ops, code, buf, X86_EBP);
+ /* The + 8 makes the stack aligned */
+ x86_alu_reg_imm (code, X86_SUB, X86_ESP, framesize + 8);
+
+ /* Initialize a MonoContext structure on the stack */
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eax), X86_EAX, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebx), X86_EBX, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ecx), X86_ECX, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edx), X86_EDX, sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EAX, X86_EBP, 0, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebp), X86_EAX, sizeof (mgreg_t));
+ x86_mov_reg_reg (code, X86_EAX, X86_EBP, sizeof (mgreg_t));
+ x86_alu_reg_imm (code, X86_ADD, X86_EAX, cfa_offset);
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esp), X86_ESP, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esi), X86_ESI, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edi), X86_EDI, sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EAX, X86_EBP, 4, sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eip), X86_EAX, sizeof (mgreg_t));
+
+ /* Call the single step/breakpoint function in sdb */
+ x86_lea_membase (code, X86_EAX, X86_ESP, ctx_offset);
+ x86_mov_membase_reg (code, X86_ESP, 0, X86_EAX, sizeof (mgreg_t));
+
+ if (aot) {
+ x86_breakpoint (code);
+ } else {
+ if (single_step)
+ x86_call_code (code, debugger_agent_single_step_from_context);
+ else
+ x86_call_code (code, debugger_agent_breakpoint_from_context);
+ }
+
+ /* Restore registers from ctx */
+ /* Overwrite the saved ebp */
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebp), sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_EBP, 0, X86_EAX, sizeof (mgreg_t));
+ /* Overwrite saved eip */
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eip), sizeof (mgreg_t));
+ x86_mov_membase_reg (code, X86_EBP, 4, X86_EAX, sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EAX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, eax), sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EBX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ebx), sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_ECX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, ecx), sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EDX, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edx), sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_ESI, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, esi), sizeof (mgreg_t));
+ x86_mov_reg_membase (code, X86_EDI, X86_ESP, ctx_offset + G_STRUCT_OFFSET (MonoContext, edi), sizeof (mgreg_t));
+
+ x86_leave (code);
+ cfa_offset -= sizeof (mgreg_t);
+ mono_add_unwind_op_def_cfa (unwind_ops, code, buf, X86_ESP, cfa_offset);
+ x86_ret (code);
+
+ mono_arch_flush_icache (code, code - buf);
+ g_assert (code - buf <= tramp_size);
+
+ const char *tramp_name = single_step ? "sdb_single_step_trampoline" : "sdb_breakpoint_trampoline";
+ *info = mono_tramp_info_create (tramp_name, buf, code - buf, ji, unwind_ops);
+
+ return buf;
+}
+
#if defined(ENABLE_GSHAREDVT)
#include "../../../mono-extensions/mono/mini/tramp-x86-gsharedvt.c"
}
/*
- * mono_unwind_ops_encode:
+ * mono_unwind_ops_encode_full:
*
* Encode the unwind ops in UNWIND_OPS into the compact DWARF encoding.
* Return a pointer to malloc'ed memory.
+ * If ENABLE_EXTENSIONS is FALSE, avoid encoding the mono extension
+ * opcode (DW_CFA_mono_advance_loc).
*/
guint8*
-mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
+mono_unwind_ops_encode_full (GSList *unwind_ops, guint32 *out_len, gboolean enable_extensions)
{
GSList *l;
MonoUnwindOp *op;
*p ++ = op->op;
break;
case DW_CFA_mono_advance_loc:
+ if (!enable_extensions)
+ break;
/* Only one location is supported */
g_assert (op->val == 0);
*p ++ = op->op;
return res;
}
+guint8*
+mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
+{
+ return mono_unwind_ops_encode_full (unwind_ops, out_len, TRUE);
+}
+
#if 0
#define UNW_DEBUG(stmt) do { stmt; } while (0)
#else
GSList*
mono_unwind_get_cie_program (void)
{
-#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_POWERPC)
+#if defined(TARGET_AMD64) || defined(TARGET_X86) || defined(TARGET_POWERPC) || defined(TARGET_ARM)
return mono_arch_get_cie_program ();
#else
return NULL;
uint64_t live;
uint64_t max_live;
TraceDesc traces;
+ TraceDesc destroy_traces;
} HandleInfo;
static HandleInfo handle_info [4];
}
static void
-track_handle (uintptr_t obj, int htype, uint32_t handle)
+track_handle (uintptr_t obj, int htype, uint32_t handle, BackTrace *bt, uint64_t timestamp)
{
int i;
for (i = 0; i < num_tracked_objects; ++i) {
- if (tracked_objects [i] == obj)
- fprintf (outfile, "Object %p referenced from handle %u\n", (void*)obj, handle);
+ if (tracked_objects [i] != obj)
+ continue;
+ fprintf (outfile, "Object %p referenced from handle %u at %.3f secs.\n", (void*)obj, handle, (timestamp - startup_time) / 1000000000.0);
+ if (bt && bt->count) {
+ int k;
+ for (k = 0; k < bt->count; ++k)
+ fprintf (outfile, "\t%s\n", bt->methods [k]->name);
+ }
}
}
fprintf (outfile, "moved obj %p to %p\n", (void*)OBJ_ADDR (obj1diff), (void*)OBJ_ADDR (obj2diff));
}
}
- } else if (subtype == TYPE_GC_HANDLE_CREATED) {
+ } else if (subtype == TYPE_GC_HANDLE_CREATED || subtype == TYPE_GC_HANDLE_CREATED_BT) {
+ int has_bt = subtype == TYPE_GC_HANDLE_CREATED_BT;
+ int num_bt = 0;
+ MethodDesc *sframes [8];
+ MethodDesc **frames = sframes;
int htype = decode_uleb128 (p, &p);
uint32_t handle = decode_uleb128 (p, &p);
intptr_t objdiff = decode_sleb128 (p, &p);
+ if (has_bt) {
+ num_bt = 8;
+ frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ if (!frames) {
+ fprintf (outfile, "Cannot load backtrace\n");
+ return 0;
+ }
+ }
if (htype > 3)
return 0;
- handle_info [htype].created++;
- handle_info [htype].live++;
- add_trace_thread (thread, &handle_info [htype].traces, 1);
- /* FIXME: we don't take into account timing here */
- if (handle_info [htype].live > handle_info [htype].max_live)
- handle_info [htype].max_live = handle_info [htype].live;
- if (num_tracked_objects)
- track_handle (OBJ_ADDR (objdiff), htype, handle);
+ if ((thread_filter && thread_filter == thread->thread_id) || (time_base >= time_from && time_base < time_to)) {
+ handle_info [htype].created++;
+ handle_info [htype].live++;
+ if (handle_info [htype].live > handle_info [htype].max_live)
+ handle_info [htype].max_live = handle_info [htype].live;
+ BackTrace *bt;
+ if (has_bt)
+ bt = add_trace_methods (frames, num_bt, &handle_info [htype].traces, 1);
+ else
+ bt = add_trace_thread (thread, &handle_info [htype].traces, 1);
+ if (num_tracked_objects)
+ track_handle (OBJ_ADDR (objdiff), htype, handle, bt, time_base);
+ }
if (debug)
fprintf (outfile, "handle (%s) %u created for object %p\n", get_handle_name (htype), handle, (void*)OBJ_ADDR (objdiff));
- } else if (subtype == TYPE_GC_HANDLE_DESTROYED) {
+ if (frames != sframes)
+ free (frames);
+ } else if (subtype == TYPE_GC_HANDLE_DESTROYED || subtype == TYPE_GC_HANDLE_DESTROYED_BT) {
+ int has_bt = subtype == TYPE_GC_HANDLE_DESTROYED_BT;
+ int num_bt = 0;
+ MethodDesc *sframes [8];
+ MethodDesc **frames = sframes;
int htype = decode_uleb128 (p, &p);
uint32_t handle = decode_uleb128 (p, &p);
+ if (has_bt) {
+ num_bt = 8;
+ frames = decode_bt (sframes, &num_bt, p, &p, ptr_base);
+ if (!frames) {
+ fprintf (outfile, "Cannot load backtrace\n");
+ return 0;
+ }
+ }
if (htype > 3)
return 0;
- handle_info [htype].destroyed ++;
- handle_info [htype].live--;
+ if ((thread_filter && thread_filter == thread->thread_id) || (time_base >= time_from && time_base < time_to)) {
+ handle_info [htype].destroyed ++;
+ handle_info [htype].live--;
+ BackTrace *bt;
+ if (has_bt)
+ bt = add_trace_methods (frames, num_bt, &handle_info [htype].destroy_traces, 1);
+ else
+ bt = add_trace_thread (thread, &handle_info [htype].destroy_traces, 1);
+ /* TODO: track_handle_free () - would need to record and keep track of the associated object address... */
+ }
if (debug)
fprintf (outfile, "handle (%s) %u destroyed\n", get_handle_name (htype), handle);
+ if (frames != sframes)
+ free (frames);
}
break;
}
(unsigned long long) (handle_info [i].destroyed),
(unsigned long long) (handle_info [i].max_live));
dump_traces (&handle_info [i].traces, "created");
+ dump_traces (&handle_info [i].destroy_traces, "destroyed");
}
}
+++ /dev/null
-/*
- * mono-codeanalyst.c: AMD CodeAnalyst profiler
- *
- * Author:
- * Jonathan Chambers (joncham@gmail.com)
- *
- * (C) 2011 Jonathan Chambers
- *
- * 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.
- */
-#include <mono/metadata/profiler.h>
-#include <mono/metadata/tokentype.h>
-#include <mono/metadata/tabledefs.h>
-#include <mono/metadata/debug-helpers.h>
-#include <mono/metadata/assembly.h>
-#include <string.h>
-#include <glib.h>
-
-#define bool char
-
-#include "CAJITNTFLib.h"
-
-/* called at the end of the program */
-static void
-codeanalyst_shutdown (MonoProfiler *prof)
-{
- CAJIT_CompleteJITLog ();
-}
-
-static void
-method_jit_result (MonoProfiler *prof, MonoMethod *method, MonoJitInfo* jinfo, int result) {
- if (result == MONO_PROFILE_OK) {
- gunichar2* name_utf16;
- MonoClass *klass = mono_method_get_class (method);
- char *signature = mono_signature_get_desc (mono_method_signature (method), TRUE);
- char *name = g_strdup_printf ("%s.%s.%s (%s)", mono_class_get_namespace (klass), mono_class_get_name (klass), mono_method_get_name (method), signature);
- gpointer code_start = mono_jit_info_get_code_start (jinfo);
- int code_size = mono_jit_info_get_code_size (jinfo);
-
- name_utf16 = g_utf8_to_utf16 (name, strlen (name), NULL, NULL, NULL);
-
- CAJIT_LogJITCode ((uintptr_t)code_start, code_size, (wchar_t*)name_utf16);
-
- g_free (signature);
- g_free (name);
- g_free (name_utf16);
- }
-}
-
-void
-mono_profiler_startup (const char *desc);
-
-/* the entry point */
-void
-mono_profiler_startup (const char *desc)
-{
- CAJIT_Initialize ();
-
- mono_profiler_install (NULL, codeanalyst_shutdown);
- mono_profiler_install_jit_end (method_jit_result);
- mono_profiler_set_events (MONO_PROFILE_JIT_COMPILATION);
-}
-
-
*
* type GC format:
* type: TYPE_GC
- * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED,
- * TYPE_GC_HANDLE_DESTROYED
+ * exinfo: one of TYPE_GC_EVENT, TYPE_GC_RESIZE, TYPE_GC_MOVE, TYPE_GC_HANDLE_CREATED[_BT],
+ * TYPE_GC_HANDLE_DESTROYED[_BT]
* [time diff: uleb128] nanoseconds since last timing
* if exinfo == TYPE_GC_RESIZE
* [heap_size: uleb128] new heap size
* [objaddr: sleb128]+ num_objects object pointer differences from obj_base
* num is always an even number: the even items are the old
* addresses, the odd numbers are the respective new object addresses
- * if exinfo == TYPE_GC_HANDLE_CREATED
+ * if exinfo == TYPE_GC_HANDLE_CREATED[_BT]
* [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
* upper bits reserved as flags
* [handle: uleb128] GC handle value
* [objaddr: sleb128] object pointer differences from obj_base
- * if exinfo == TYPE_GC_HANDLE_DESTROYED
+ * If exinfo == TYPE_GC_HANDLE_CREATED_BT, a backtrace follows.
+ * if exinfo == TYPE_GC_HANDLE_DESTROYED[_BT]
* [handle_type: uleb128] GC handle type (System.Runtime.InteropServices.GCHandleType)
* upper bits reserved as flags
* [handle: uleb128] GC handle value
+ * If exinfo == TYPE_GC_HANDLE_DESTROYED_BT, a backtrace follows.
*
* type metadata format:
* type: TYPE_METADATA
* [pointer: sleb128] pointer of the metadata type depending on mtype
* if mtype == TYPE_CLASS
* [image: sleb128] MonoImage* as a pointer difference from ptr_base
- * [flags: uleb128] must be 0
+ * [flags: uleb128] must be 0
* [name: string] full class name
* if mtype == TYPE_IMAGE
- * [flags: uleb128] must be 0
+ * [flags: uleb128] must be 0
* [name: string] image file name
* if mtype == TYPE_ASSEMBLY
- * [flags: uleb128] must be 0
+ * [flags: uleb128] must be 0
* [name: string] assembly name
* if mtype == TYPE_DOMAIN
- * [flags: uleb128] must be 0
+ * [flags: uleb128] must be 0
* if mtype == TYPE_DOMAIN && exinfo == 0
* [name: string] domain friendly name
* if mtype == TYPE_CONTEXT
+ * [flags: uleb128] must be 0
* [domain: sleb128] domain id as pointer
* if mtype == TYPE_THREAD && (format_version < 11 || (format_version > 10 && exinfo == 0))
+ * [flags: uleb128] must be 0
* [name: string] thread name
*
* type method format:
static void
gc_handle (MonoProfiler *prof, int op, int type, uintptr_t handle, MonoObject *obj)
{
+ int do_bt = nocalls && InterlockedRead (&runtime_inited) && !notraces;
uint64_t now;
+ FrameData data;
+
+ if (do_bt)
+ collect_bt (&data);
+
LogBuffer *logbuffer = ensure_logbuf (
EVENT_SIZE /* event */ +
LEB128_SIZE /* time */ +
LEB128_SIZE /* handle */ +
(op == MONO_PROFILER_GC_HANDLE_CREATED ? (
LEB128_SIZE /* obj */
+ ) : 0) +
+ (do_bt ? (
+ LEB128_SIZE /* flags */ +
+ LEB128_SIZE /* count */ +
+ data.count * (
+ LEB128_SIZE /* method */
+ )
) : 0)
);
+
now = current_time ();
ENTER_LOG (logbuffer, "gchandle");
+
if (op == MONO_PROFILER_GC_HANDLE_CREATED)
- emit_byte (logbuffer, TYPE_GC_HANDLE_CREATED | TYPE_GC);
+ emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_CREATED_BT : TYPE_GC_HANDLE_CREATED) | TYPE_GC);
else if (op == MONO_PROFILER_GC_HANDLE_DESTROYED)
- emit_byte (logbuffer, TYPE_GC_HANDLE_DESTROYED | TYPE_GC);
+ emit_byte (logbuffer, (do_bt ? TYPE_GC_HANDLE_DESTROYED_BT : TYPE_GC_HANDLE_DESTROYED) | TYPE_GC);
else
- return;
+ g_assert_not_reached ();
+
emit_time (logbuffer, now);
emit_value (logbuffer, type);
emit_value (logbuffer, handle);
+
if (op == MONO_PROFILER_GC_HANDLE_CREATED)
emit_obj (logbuffer, obj);
+
+ if (do_bt)
+ emit_bt (prof, logbuffer, &data);
+
EXIT_LOG (logbuffer);
process_requests (prof);
}
}
#define COVERAGE_DEBUG(x) if (debug_coverage) {x}
+static mono_mutex_t coverage_mutex;
static MonoConcurrentHashTable *coverage_methods = NULL;
-static mono_mutex_t coverage_methods_mutex;
static MonoConcurrentHashTable *coverage_assemblies = NULL;
-static mono_mutex_t coverage_assemblies_mutex;
static MonoConcurrentHashTable *coverage_classes = NULL;
-static mono_mutex_t coverage_classes_mutex;
+
static MonoConcurrentHashTable *filtered_classes = NULL;
-static mono_mutex_t filtered_classes_mutex;
static MonoConcurrentHashTable *entered_methods = NULL;
-static mono_mutex_t entered_methods_mutex;
static MonoConcurrentHashTable *image_to_methods = NULL;
-static mono_mutex_t image_to_methods_mutex;
static MonoConcurrentHashTable *suppressed_assemblies = NULL;
-static mono_mutex_t suppressed_assemblies_mutex;
static gboolean coverage_initialized = FALSE;
static GPtrArray *coverage_data = NULL;
COVERAGE_DEBUG(fprintf (stderr, "Coverage: Started dump\n");)
method_id = 0;
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_foreach (coverage_assemblies, build_assembly_buffer, prof);
mono_conc_hashtable_foreach (coverage_classes, build_class_buffer, prof);
mono_conc_hashtable_foreach (coverage_methods, build_method_buffer, prof);
+ mono_mutex_unlock (&coverage_mutex);
COVERAGE_DEBUG(fprintf (stderr, "Coverage: Finished dump\n");)
}
if (mono_conc_hashtable_lookup (suppressed_assemblies, (gpointer) mono_image_get_name (image)))
return;
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (entered_methods, method, method);
+ mono_mutex_unlock (&coverage_mutex);
}
static MonoLockFreeQueueNode *
if (has_positive && !found) {
COVERAGE_DEBUG(fprintf (stderr, " Positive match was not found\n");)
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (filtered_classes, klass, klass);
+ mono_mutex_unlock (&coverage_mutex);
g_free (fqn);
g_free (classname);
if (strstr (fqn, filter) != NULL) {
COVERAGE_DEBUG(fprintf (stderr, "matched\n");)
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (filtered_classes, klass, klass);
+ mono_mutex_unlock (&coverage_mutex);
g_free (fqn);
g_free (classname);
assembly = mono_image_get_assembly (image);
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (coverage_methods, method, method);
mono_conc_hashtable_insert (coverage_assemblies, assembly, assembly);
+ mono_mutex_unlock (&coverage_mutex);
image_methods = mono_conc_hashtable_lookup (image_to_methods, image);
if (image_methods == NULL) {
image_methods = g_malloc (sizeof (MonoLockFreeQueue));
mono_lock_free_queue_init (image_methods);
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (image_to_methods, image, image_methods);
+ mono_mutex_unlock (&coverage_mutex);
}
node = create_method_node (method);
if (class_methods == NULL) {
class_methods = g_malloc (sizeof (MonoLockFreeQueue));
mono_lock_free_queue_init (class_methods);
+ mono_mutex_lock (&coverage_mutex);
mono_conc_hashtable_insert (coverage_classes, klass, class_methods);
+ mono_mutex_unlock (&coverage_mutex);
}
node = create_method_node (method);
char *line;
FILE *sa_file;
- mono_mutex_init (&suppressed_assemblies_mutex);
- suppressed_assemblies = mono_conc_hashtable_new (&suppressed_assemblies_mutex, g_str_hash, g_str_equal);
+ suppressed_assemblies = mono_conc_hashtable_new (g_str_hash, g_str_equal);
sa_file = fopen (SUPPRESSION_DIR "/mono-profiler-log.suppression", "r");
if (sa_file == NULL)
return;
while ((line = get_next_line (content, &content))) {
line = g_strchomp (g_strchug (line));
+ /* No locking needed as we're doing initialization */
mono_conc_hashtable_insert (suppressed_assemblies, line, line);
}
fclose (sa_file);
}
-static MonoConcurrentHashTable *
-init_hashtable (mono_mutex_t *mutex)
-{
- mono_mutex_init (mutex);
- return mono_conc_hashtable_new (mutex, NULL, NULL);
-}
-
-static void
-destroy_hashtable (MonoConcurrentHashTable *hashtable, mono_mutex_t *mutex)
-{
- mono_conc_hashtable_destroy (hashtable);
- mono_mutex_destroy (mutex);
-}
-
#endif /* DISABLE_HELPER_THREAD */
static void
COVERAGE_DEBUG(fprintf (stderr, "Coverage initialized\n");)
- coverage_methods = init_hashtable (&coverage_methods_mutex);
- coverage_assemblies = init_hashtable (&coverage_assemblies_mutex);
- coverage_classes = init_hashtable (&coverage_classes_mutex);
- filtered_classes = init_hashtable (&filtered_classes_mutex);
- entered_methods = init_hashtable (&entered_methods_mutex);
- image_to_methods = init_hashtable (&image_to_methods_mutex);
+ mono_mutex_init (&coverage_mutex);
+ coverage_methods = mono_conc_hashtable_new (NULL, NULL);
+ coverage_assemblies = mono_conc_hashtable_new (NULL, NULL);
+ coverage_classes = mono_conc_hashtable_new (NULL, NULL);
+ filtered_classes = mono_conc_hashtable_new (NULL, NULL);
+ entered_methods = mono_conc_hashtable_new (NULL, NULL);
+ image_to_methods = mono_conc_hashtable_new (NULL, NULL);
init_suppressed_assemblies ();
coverage_initialized = TRUE;
else
fclose (prof->file);
- destroy_hashtable (prof->method_table, &prof->method_table_mutex);
+ mono_conc_hashtable_destroy (prof->method_table);
+ mono_mutex_destroy (&prof->method_table_mutex);
if (coverage_initialized) {
- destroy_hashtable (coverage_methods, &coverage_methods_mutex);
- destroy_hashtable (coverage_assemblies, &coverage_assemblies_mutex);
- destroy_hashtable (coverage_classes, &coverage_classes_mutex);
- destroy_hashtable (filtered_classes, &filtered_classes_mutex);
- destroy_hashtable (entered_methods, &entered_methods_mutex);
- destroy_hashtable (image_to_methods, &image_to_methods_mutex);
- destroy_hashtable (suppressed_assemblies, &suppressed_assemblies_mutex);
+ mono_conc_hashtable_destroy (coverage_methods);
+ mono_conc_hashtable_destroy (coverage_assemblies);
+ mono_conc_hashtable_destroy (coverage_classes);
+ mono_conc_hashtable_destroy (filtered_classes);
+
+ mono_conc_hashtable_destroy (entered_methods);
+ mono_conc_hashtable_destroy (image_to_methods);
+ mono_conc_hashtable_destroy (suppressed_assemblies);
+ mono_mutex_destroy (&coverage_mutex);
}
free (prof);
* method lists will just be empty for the rest of the
* app's lifetime.
*/
+ mono_mutex_lock (&prof->method_table_mutex);
mono_conc_hashtable_insert (prof->method_table, info->method, info->method);
+ mono_mutex_unlock (&prof->method_table_mutex);
char *name = mono_method_full_name (info->method, 1);
int nlen = strlen (name) + 1;
mono_lock_free_queue_init (&prof->writer_queue);
mono_mutex_init (&prof->method_table_mutex);
- prof->method_table = mono_conc_hashtable_new (&prof->method_table_mutex, NULL, NULL);
+ prof->method_table = mono_conc_hashtable_new (NULL, NULL);
if (do_coverage)
coverage_init (prof);
load/unload for contexts
load/unload/name for assemblies
removed TYPE_LOAD_ERR flag (profiler never generated it, now removed from the format itself)
+ added TYPE_GC_HANDLE_{CREATED,DESTROYED}_BT
*/
enum {
TYPE_GC_EVENT = 1 << 4,
TYPE_GC_RESIZE = 2 << 4,
TYPE_GC_MOVE = 3 << 4,
- TYPE_GC_HANDLE_CREATED = 4 << 4,
- TYPE_GC_HANDLE_DESTROYED = 5 << 4,
+ TYPE_GC_HANDLE_CREATED = 4 << 4,
+ TYPE_GC_HANDLE_DESTROYED = 5 << 4,
+ TYPE_GC_HANDLE_CREATED_BT = 6 << 4,
+ TYPE_GC_HANDLE_DESTROYED_BT = 7 << 4,
/* extended type for TYPE_METHOD */
TYPE_LEAVE = 1 << 4,
TYPE_ENTER = 2 << 4,
} while (0)
/* MS_BLOCK_SIZE must be a multiple of the system pagesize, which for some
- archs is 64k. */
-#if defined(TARGET_POWERPC64) && _CALL_ELF == 2
+ architectures is 64k. */
+#if defined(TARGET_POWERPC64)
#define ARCH_MIN_MS_BLOCK_SIZE (64*1024)
#define ARCH_MIN_MS_BLOCK_SIZE_SHIFT 16
#endif
{
int count = 0;
-#ifdef VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE
+#if defined(VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE) && !defined(_WIN64)
VALGRIND_MAKE_MEM_DEFINED_IF_ADDRESSABLE (start, (char*)end - (char*)start);
#endif
extern LOCK_DECLARE (sgen_interruption_mutex);
-#define LOCK_INTERRUPTION mono_mutex_lock (&sgen_interruption_mutex)
+#define LOCK_INTERRUPTION do { \
+ MONO_TRY_BLOCKING \
+ mono_mutex_lock (&sgen_interruption_mutex); \
+ MONO_FINISH_TRY_BLOCKING \
+} while (0)
+
#define UNLOCK_INTERRUPTION mono_mutex_unlock (&sgen_interruption_mutex)
/* FIXME: Use InterlockedAdd & InterlockedAdd64 to reduce the CAS cost. */
static int los_segment_index = 0;
#endif
+mword
+sgen_los_object_size (LOSObject *obj)
+{
+ return obj->size & ~1L;
+}
+
#ifdef LOS_CONSISTENCY_CHECK
static void
los_consistency_check (void)
mword memory_usage = 0;
for (obj = los_object_list; obj; obj = obj->next) {
- char *end = obj->data + obj->size;
+ mword obj_size = sgen_los_object_size (obj);
+ char *end = obj->data + obj_size;
int start_index, num_chunks;
- memory_usage += obj->size;
+ memory_usage += obj_size;
- if (obj->size > LOS_SECTION_OBJECT_LIMIT)
+ if (obj_size > LOS_SECTION_OBJECT_LIMIT)
continue;
section = LOS_SECTION_FOR_OBJ (obj);
g_assert (end <= (char*)section + LOS_SECTION_SIZE);
start_index = LOS_CHUNK_INDEX (obj, section);
- num_chunks = (obj->size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
+ num_chunks = (obj_size + sizeof (LOSObject) + LOS_CHUNK_SIZE - 1) >> LOS_CHUNK_BITS;
for (i = start_index; i < start_index + num_chunks; ++i)
g_assert (!section->free_chunk_map [i]);
}
SGEN_ASSERT (0, !obj->cardtable_mod_union, "We should never free a LOS object with a mod-union table.");
#ifndef LOS_DUMMY
- size_t size = obj->size;
- SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)obj->size);
- binary_protocol_empty (obj->data, obj->size);
+ mword size = sgen_los_object_size (obj);
+ SGEN_LOG (4, "Freed large object %p, size %lu", obj->data, (unsigned long)size);
+ binary_protocol_empty (obj->data, size);
los_memory_usage -= size;
los_num_objects--;
SGEN_ASSERT (0, !SGEN_OBJECT_IS_PINNED (bigobj->data), "Who pinned a LOS object?");
if (bigobj->cardtable_mod_union) {
- sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, bigobj->size);
+ sgen_card_table_free_mod_union (bigobj->cardtable_mod_union, (char*)bigobj->data, sgen_los_object_size (bigobj));
bigobj->cardtable_mod_union = NULL;
}
*start = NULL;
for (obj = los_object_list; obj; obj = obj->next) {
- char *end = (char*)obj->data + obj->size;
+ char *end = (char*)obj->data + sgen_los_object_size (obj);
if (ptr >= (char*)obj->data && ptr < end) {
*start = (char*)obj->data;
LOSObject *obj;
for (obj = los_object_list; obj; obj = obj->next)
- cb (obj->data, obj->size, user_data);
+ cb (obj->data, sgen_los_object_size (obj), user_data);
}
gboolean
mword size;
gboolean pinned;
- if ((char*)obj->data > ptr || (char*)obj->data + obj->size <= ptr)
+ if ((char*)obj->data > ptr || (char*)obj->data + sgen_los_object_size (obj) <= ptr)
continue;
size = sgen_los_object_size (obj);
for (obj = los_object_list; obj; obj = obj->next) {
GCVTable vt = SGEN_LOAD_VTABLE (obj->data);
if (SGEN_VTABLE_HAS_REFERENCES (vt))
- callback ((mword)obj->data, (mword)obj->size);
+ callback ((mword)obj->data, sgen_los_object_size (obj));
}
}
static guint8*
get_cardtable_mod_union_for_object (LOSObject *obj)
{
+ mword size = sgen_los_object_size (obj);
guint8 *mod_union = obj->cardtable_mod_union;
guint8 *other;
if (mod_union)
return mod_union;
- mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, obj->size);
+ mod_union = sgen_card_table_alloc_mod_union ((char*)obj->data, size);
other = SGEN_CAS_PTR ((gpointer*)&obj->cardtable_mod_union, mod_union, NULL);
if (!other) {
SGEN_ASSERT (0, obj->cardtable_mod_union == mod_union, "Why did CAS not replace?");
return mod_union;
}
- sgen_card_table_free_mod_union (mod_union, (char*)obj->data, obj->size);
+ sgen_card_table_free_mod_union (mod_union, (char*)obj->data, size);
return other;
}
cards = NULL;
}
- sgen_cardtable_scan_object (obj->data, obj->size, cards, mod_union, ctx);
+ sgen_cardtable_scan_object (obj->data, sgen_los_object_size (obj), cards, mod_union, ctx);
}
}
for (obj = los_object_list; obj; obj = obj->next) {
int i;
guint8 *cards = sgen_card_table_get_card_scan_address ((mword) obj->data);
- guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + obj->size - 1);
+ guint8 *cards_end = sgen_card_table_get_card_scan_address ((mword) obj->data + sgen_los_object_size (obj) - 1);
mword num_cards = (cards_end - cards) + 1;
if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
if (!SGEN_OBJECT_HAS_REFERENCES (obj->data))
continue;
sgen_card_table_update_mod_union (get_cardtable_mod_union_for_object (obj),
- (char*)obj->data, obj->size, NULL);
+ (char*)obj->data, sgen_los_object_size (obj), NULL);
}
}
-mword
-sgen_los_object_size (LOSObject *obj)
-{
- return obj->size & ~1L;
-}
-
LOSObject*
sgen_los_header_for_object (GCObject *data)
{
SUBDIRS = assemblyresolve gc-descriptors
-check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-messages rm-empty-logs
+check-local: assemblyresolve/test/asm.dll testjit test-generic-sharing test-type-load test-cattr-type-load test-reflection-load-with-context test_platform test-process-exit test-messages test-unhandled-exception-2 rm-empty-logs
check-full: test-sgen check-local
check-parallel: compile-tests check-full
bug-80392.2.cs \
dynamic-method-access.2.cs \
dynamic-method-finalize.2.cs \
+ dynamic-method-stack-traces.cs \
bug-82194.2.cs \
anonarray.2.cs \
ienumerator-interfaces.2.cs \
sgen-descriptors.exe \
sgen-gshared-vtype.exe \
sgen-domain-unload.exe \
+ sgen-domain-unload-2.exe \
sgen-weakref-stress.exe \
sgen-cementing-stress.exe \
sgen-case-23400.exe \
MONO_GC_PARAMS=max-heap-size=16m $(RUNTIME) $$fn > $$fn.stdout || exit 1; \
done
+if HOST_WIN32
+test-unhandled-exception-2:
+else
+test-unhandled-exception-2: unhandled-exception.exe
+ @echo "Testing unhandled-exception_1 ..."; $(RUNTIME) $+ 1 1> unhandled-exception_1.exe.stdout 2> unhandled-exception_1.exe.stderr; if test "x$$?" != "x1"; then exit 1; fi; \
+ echo "Testing unhandled-exception_2 ..."; $(RUNTIME) $+ 2 1> unhandled-exception_2.exe.stdout 2> unhandled-exception_2.exe.stderr; if test "x$$?" != "x0"; then exit 2; fi; \
+ echo "Testing unhandled-exception_3 ..."; $(RUNTIME) $+ 3 1> unhandled-exception_3.exe.stdout 2> unhandled-exception_3.exe.stderr; if test "x$$?" != "x0"; then exit 3; fi; \
+ echo "Testing unhandled-exception_4 ..."; $(RUNTIME) $+ 4 1> unhandled-exception_4.exe.stdout 2> unhandled-exception_4.exe.stderr; if test "x$$?" != "x0"; then exit 4; fi; \
+ echo "Testing unhandled-exception_5 ..."; $(RUNTIME) $+ 5 1> unhandled-exception_5.exe.stdout 2> unhandled-exception_5.exe.stderr; if test "x$$?" != "x255"; then exit 5; fi; \
+ echo "Testing unhandled-exception_6 ..."; $(RUNTIME) $+ 6 1> unhandled-exception_6.exe.stdout 2> unhandled-exception_6.exe.stderr; if test "x$$?" != "x0"; then exit 6; fi; \
+ echo "Testing unhandled-exception_7 ..."; $(RUNTIME) $+ 7 1> unhandled-exception_7.exe.stdout 2> unhandled-exception_7.exe.stderr; if test "x$$?" != "x0"; then exit 7; fi; \
+ echo "Testing unhandled-exception_8 ..."; $(RUNTIME) $+ 8 1> unhandled-exception_8.exe.stdout 2> unhandled-exception_8.exe.stderr; if test "x$$?" != "x3"; then exit 8; fi
+endif
noinst_LTLIBRARIES = libtest.la
-AM_CPPFLAGS = $(GLIB_CFLAGS) $(GMODULE_CFLAGS)
+AM_CPPFLAGS = $(GLIB_CFLAGS)
if HOST_WIN32
# gcc-3.4.4 emits incorrect code when making indirect calls to stdcall functions using a tail call
--- /dev/null
+using System;
+using System.Threading;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.ExceptionServices;
+using System.Diagnostics;
+
+public class A
+{
+ public static Exception Caught;
+
+ public static void ThrowMe()
+ {
+ Exception e;
+ try
+ {
+ throw new Exception("test");
+ }
+ catch (Exception e2)
+ {
+ e = e2;
+ }
+
+ var edi = ExceptionDispatchInfo.Capture(e);
+
+ edi.Throw();
+ }
+
+ public static void Handler(Exception e)
+ {
+ Caught = e;
+ }
+}
+
+public class Example
+{
+ public static int Main()
+ {
+ TT();
+ string expected = A.Caught.StackTrace.ToString ();
+
+ for (int i = 0; i < 1000; ++i) {
+ Thread t = new Thread (delegate () {
+ TT ();
+ });
+ t.Start ();
+ t.Join ();
+ GC.Collect ();
+ GC.WaitForPendingFinalizers ();
+ if (A.Caught.StackTrace != expected) {
+ Console.WriteLine ("FAILED");
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ static void TT()
+ {
+ DynamicMethod multiplyHidden = new DynamicMethod(
+ "",
+ typeof(void), new[] { typeof(int) }, typeof(Example));
+
+ ILGenerator ig = multiplyHidden.GetILGenerator();
+
+ ig.BeginExceptionBlock();
+
+ ig.Emit(OpCodes.Call, typeof(A).GetMethod("ThrowMe"));
+
+ ig.BeginCatchBlock(typeof(Exception));
+
+ ig.Emit(OpCodes.Call, typeof(A).GetMethod("Handler"));
+
+ ig.EndExceptionBlock();
+
+ ig.Emit(OpCodes.Ret);
+
+ var invoke = (Action<int>)
+ multiplyHidden.CreateDelegate(
+ typeof(Action<int>)
+
+ );
+
+ invoke(1);
+ }
+}
if (a1->A != 42)
return 8;
- if (!fabs (a1->B - 3.1415) < 0.001)
+ if (!(fabs (a1->B - 3.1415) < 0.001))
return 9;
break;
if (a1->A != 42)
return 5;
- if (!fabs (a1->B - 3.1415) < 0.001)
+ if (!(fabs (a1->B - 3.1415) < 0.001))
return 6;
break;
resurrect = this;
}
+ public static void EnterMonitor (object obj)
+ {
+ for (int i = 0; i < 257; i++)
+ Monitor.Enter (obj);
+ }
+
+ public static void ExitMonitor (object obj)
+ {
+ for (int i = 0; i < 257; i++)
+ Monitor.Exit (obj);
+ }
+
public static void CreateFoo (int level)
{
if (level == 0) {
reference = new Foo ();
/* Allocate a MonoThreadsSync for the object */
- Monitor.Enter (reference);
- Monitor.Exit (reference);
+ EnterMonitor (reference);
+ ExitMonitor (reference);
reference = null;
} else {
CreateFoo (level - 1);
/* Make sure these are not collected */
list.Add (foo);
- Monitor.Enter (foo);
+ EnterMonitor (foo);
}
}
}
b.test_exception ();
}
catch (SynchronizationLockException ex) {
- return 1;
+ // OK
}
catch (Exception ex) {
- // OK
+ // The other exception should be overwritten by the lock one
+ return 1;
}
Console.WriteLine ("Test4...");
d ();
}
catch (SynchronizationLockException ex) {
- return 2;
+ // OK
}
catch (Exception ex) {
- // OK
+ return 2;
}
return 0;
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Diagnostics;
+using System.IO;
+
+/*
+TODO
+ Some tests are much more expensive than others (on cycles and synchronization), add a calibration step to figure out duration.
+ Some tests are more disrruptive than others, add weights to tests so some are picked more frequently.
+ The workload is too static, add some background generation noise tests.
+ The workload is too stable, add perturbance on the number of available tasks.
+ Fuse threadpool with non threadpool workloads by firing some tasks as separate threads.
+ Add an external watchdog so we can run the stress test in a loop for very long times and get results out of it.
+ We don't have enough tests, add one per locking operation we got in the runtime.
+
+Missing tests:
+ Ephemerons
+ Dynamic methods
+ Regular SRE
+ Remoting / Transparent Proxies
+ Context locals
+ Thread locals
+ Finalizers
+ Async socket IO
+*/
+
+class Driver {
+ static bool stop_please;
+ const int TEST_DURATION = 1000;
+
+ static object very_contended_object = new object ();
+
+ static bool Ok (ref int loops) {
+ if (loops == -1)
+ return !stop_please;
+ if (loops == 0)
+ return false;
+ loops--;
+ return true;
+
+ }
+ static void MonitorEnterInALoop (int loops)
+ {
+ while (Ok (ref loops)) {
+ if (Monitor.TryEnter (very_contended_object, 100)) {
+ Thread.Sleep (30);
+ Monitor.Exit (very_contended_object);
+ }
+ }
+ }
+
+ static void AllocObjectInALoop (int loops) {
+ while (Ok (ref loops)) {
+ var a = new object ();
+ var b = new byte [100];
+ }
+ }
+
+ static void AllocDomainInALoop (int loops) {
+ int count = 0;
+ while (Ok (ref loops)) {
+ var a = AppDomain.CreateDomain ("test_domain_" + ++count);
+ AppDomain.Unload (a);
+ }
+ }
+
+ static void FileIO (int loops) {
+ while (Ok (ref loops)) {
+ var dir = Path.GetTempFileName () + "_" + Thread.CurrentThread.ManagedThreadId;
+ Directory.CreateDirectory (dir);
+ Directory.Delete (dir);
+
+ }
+ }
+
+ static void Timer_Elapsed(object sender, EventArgs e)
+ {
+ HashSet<string> h = new HashSet<string>();
+ for (int j = 0; j < 500; j++)
+ {
+ h.Add(""+j+""+j);
+ }
+ }
+
+ //From sgen-new-threads-dont-join-stw
+ static void TimerStress (int loops) {
+ while (Ok (ref loops)) {
+ System.Timers.Timer timer = new System.Timers.Timer();
+ timer.Elapsed += Timer_Elapsed;
+ timer.AutoReset = false;
+ timer.Interval = 500;
+ timer.Start ();
+ }
+ }
+
+ //from sgen-weakref-stress
+ static void WeakRefStress (int loops) {
+ while (Ok (ref loops)) {
+ for (int j = 0; j < 500; ++j) {
+ new WeakReference (new object ());
+ }
+ }
+ }
+ static Tuple<Action<int>,string>[] available_tests = new [] {
+ Tuple.Create (new Action<int> (MonitorEnterInALoop), "monitor"),
+ Tuple.Create (new Action<int> (AllocObjectInALoop), "alloc"),
+ Tuple.Create (new Action<int> (AllocDomainInALoop), "appdomain"),
+ Tuple.Create (new Action<int> (FileIO), "file-io"),
+ Tuple.Create (new Action<int> (TimerStress), "timers"),
+ Tuple.Create (new Action<int> (WeakRefStress), "weakref"),
+ };
+
+ static void GcPump (int timeInMillis)
+ {
+ var sw = Stopwatch.StartNew ();
+ do {
+ GC.Collect ();
+ Thread.Sleep (1);
+ } while (sw.ElapsedMilliseconds < timeInMillis);
+ stop_please = true;
+ }
+
+ const int minTpSteps = 1;
+ const int maxTpSteps = 30;
+
+ static void QueueStuffUsingTpl (int threadCount) {
+ int pendingJobs = 0;
+ int maxPending = threadCount * 2;
+ int generatorIdx = 0;
+ Random rand = new Random (0);
+
+ while (!stop_please) {
+ while (pendingJobs < maxPending) {
+ var task = available_tests [generatorIdx++ % available_tests.Length].Item1;
+ int steps = rand.Next(minTpSteps, maxTpSteps);
+ ThreadPool.QueueUserWorkItem (_ => {
+ task (steps);
+ Interlocked.Decrement (ref pendingJobs);
+ });
+ Interlocked.Increment (ref pendingJobs);
+ }
+ Thread.Sleep (1);
+ }
+ while (pendingJobs > 0)
+ Thread.Sleep (1);
+ }
+
+ static void DynamicLoadGenerator (int threadCount, int timeInMillis) {
+ var t = new Thread (() => QueueStuffUsingTpl (threadCount));
+ t.Start ();
+
+ GcPump (timeInMillis);
+
+ t.Join ();
+ }
+
+ static void StaticLoadGenerator (int threadCount, int testIndex, int timeInMillis) {
+ List<Thread> threads = new List<Thread> ();
+
+ for (int i = 0; i < threadCount; ++i) {
+ var dele = (testIndex >= 0 ? available_tests [testIndex] : available_tests [i % available_tests.Length]).Item1;
+ var t = new Thread (() => dele (-1));
+ t.Start ();
+ threads.Add (t);
+ }
+
+ GcPump (timeInMillis);
+
+ foreach (var t in threads)
+ t.Join ();
+ }
+
+ static int ParseTestName (string name) {
+ for (int i = 0; i < available_tests.Length; ++i) {
+ if (available_tests[i].Item2 == name)
+ return i;
+ }
+ Console.WriteLine ("Invalid test name {0}", name);
+ Environment.Exit (2);
+ return -1;
+ }
+
+ static int Main (string[] args) {
+ int threadCount = Environment.ProcessorCount - 1;
+ int timeInMillis = TEST_DURATION;
+ int testIndex = -1;
+ bool tpLoadGenerator = false;
+ string testName = "static";
+
+
+ for (int j = 0; j < args.Length;) {
+ if ((args [j] == "--duration") || (args [j] == "-d")) {
+ timeInMillis = Int32.Parse (args [j + 1]);
+ j += 2;
+ } else if ((args [j] == "--test") || (args [j] == "-t")) {
+ if (args [j + 1] == "static")
+ testIndex = -1;
+ else if (args [j + 1] == "tp")
+ tpLoadGenerator = true;
+ else
+ testIndex = ParseTestName (testName = args [j + 1]);
+ j += 2;
+ } else if ((args [j] == "--thread-count") || (args [j] == "-tc")) {
+ threadCount = Int32.Parse (args [j + 1]);
+ j += 2;
+ }else {
+ Console.WriteLine ("Unknown argument: " + args [j]);
+ return 1;
+ }
+ }
+
+ if (tpLoadGenerator) {
+ Console.WriteLine ("tp window {0} duration {1}", threadCount, timeInMillis);
+ DynamicLoadGenerator (threadCount, timeInMillis);
+ } else {
+ Console.WriteLine ("thread count {0} duration {1} test {2}", threadCount, timeInMillis, testName);
+ StaticLoadGenerator (threadCount, testIndex, timeInMillis);
+ }
+
+ return 0;
+ }
+}
\ No newline at end of file
b.test_exception ();
}
catch (SynchronizationLockException ex) {
- return 1;
+ // OK
}
catch (Exception ex) {
- // OK
+ // The other exception should be overwritten by the lock one
+ return 1;
}
if (is_synchronized (b))
return 1;
d ();
}
catch (SynchronizationLockException ex) {
- return 2;
+ // OK
}
catch (Exception ex) {
- // OK
+ return 2;
}
if (is_synchronized (b))
return 1;
--- /dev/null
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+
+class CustomException : Exception
+{
+}
+
+class CustomException2 : Exception
+{
+}
+
+
+class CrossDomain : MarshalByRefObject
+{
+ public Action NewDelegateWithTarget ()
+ {
+ return new Action (Bar);
+ }
+
+ public Action NewDelegateWithoutTarget ()
+ {
+ return () => { throw new CustomException (); };
+ }
+
+ public void Bar ()
+ {
+ throw new CustomException ();
+ }
+}
+
+class Driver {
+ static ManualResetEvent mre = new ManualResetEvent (false);
+
+ static void DoTest1 ()
+ {
+ mre.Reset ();
+
+ var t = new Thread (new ThreadStart (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+ t.Start ();
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+
+ t.Join ();
+ }
+
+ static void DoTest2 ()
+ {
+ mre.Reset ();
+
+ var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+ var ares = a.BeginInvoke (null, null);
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+
+ try {
+ a.EndInvoke (ares);
+ throw new Exception ();
+ } catch (CustomException) {
+ } catch (Exception) {
+ Environment.Exit (3);
+ }
+ }
+
+ static void DoTest3 ()
+ {
+ mre.Reset ();
+
+ ThreadPool.QueueUserWorkItem (_ => { try { throw new CustomException (); } finally { mre.Set (); } });
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+ }
+
+ static void DoTest4 ()
+ {
+ mre.Reset ();
+
+ var t = Task.Factory.StartNew (new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } }));
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+
+ try {
+ t.Wait ();
+ throw new Exception ();
+ } catch (AggregateException ae) {
+ if (!(ae.InnerExceptions [0] is CustomException))
+ Environment.Exit (4);
+ } catch (Exception) {
+ Environment.Exit (3);
+ }
+ }
+
+ class FinalizedClass
+ {
+ ~FinalizedClass ()
+ {
+ try {
+ throw new CustomException ();
+ } finally {
+ mre.Set ();
+ }
+ }
+ }
+
+ static void DoTest5 ()
+ {
+ mre.Reset ();
+
+ new FinalizedClass();
+
+ GC.Collect ();
+ GC.WaitForPendingFinalizers ();
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+ }
+
+ static void DoTest6 ()
+ {
+ ManualResetEvent mre2 = new ManualResetEvent (false);
+
+ mre.Reset ();
+
+ var a = new Action (() => { try { throw new CustomException (); } finally { mre.Set (); } });
+ var ares = a.BeginInvoke (_ => { mre2.Set (); throw new CustomException2 (); }, null);
+
+ if (!mre.WaitOne (5000))
+ Environment.Exit (2);
+ if (!mre2.WaitOne (5000))
+ Environment.Exit (22);
+
+ try {
+ a.EndInvoke (ares);
+ throw new Exception ();
+ } catch (CustomException) {
+ } catch (Exception) {
+ Environment.Exit (3);
+ }
+ }
+
+ static void DoTest7 ()
+ {
+ var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+ var a = cd.NewDelegateWithoutTarget ();
+ var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+ try {
+ a.EndInvoke (ares);
+ throw new Exception ();
+ } catch (CustomException) {
+ } catch (Exception) {
+ Environment.Exit (3);
+ }
+ }
+
+ static void DoTest8 ()
+ {
+ var cd = (CrossDomain) AppDomain.CreateDomain ("ad").CreateInstanceAndUnwrap (typeof(CrossDomain).Assembly.FullName, "CrossDomain");
+
+ var a = cd.NewDelegateWithTarget ();
+ var ares = a.BeginInvoke (delegate { throw new CustomException2 (); }, null);
+
+ try {
+ a.EndInvoke (ares);
+ throw new Exception ();
+ } catch (CustomException) {
+ } catch (Exception) {
+ Environment.Exit (3);
+ }
+ }
+
+ static void Main (string[] args)
+ {
+ switch (int.Parse (args [0])) {
+ case 1: DoTest1 (); break;
+ case 2: DoTest2 (); break;
+ case 3: DoTest3 (); break;
+ case 4: DoTest4 (); break;
+ case 5: DoTest5 (); break;
+ case 6: DoTest6 (); break;
+ case 7: DoTest7 (); break;
+ case 8: DoTest8 (); break;
+ default: throw new ArgumentOutOfRangeException ();
+ }
+ Environment.Exit (0);
+ }
+}
#include "utils/mono-threads.h"
#include "utils/mono-conc-hashtable.h"
+#include "utils/checked-build.h"
#include <stdlib.h>
#include <string.h>
int res = 0;
mono_mutex_init (&mutex);
- h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+ h = mono_conc_hashtable_new (NULL, NULL);
+
+ mono_mutex_lock (&mutex);
mono_conc_hashtable_insert (h, GUINT_TO_POINTER (10), GUINT_TO_POINTER (20));
+ mono_mutex_unlock (&mutex);
+
+ mono_mutex_lock (&mutex);
mono_conc_hashtable_insert (h, GUINT_TO_POINTER (30), GUINT_TO_POINTER (40));
+ mono_mutex_unlock (&mutex);
+
+ mono_mutex_lock (&mutex);
mono_conc_hashtable_insert (h, GUINT_TO_POINTER (50), GUINT_TO_POINTER (60));
+ mono_mutex_unlock (&mutex);
+
+ mono_mutex_lock (&mutex);
mono_conc_hashtable_insert (h, GUINT_TO_POINTER (2), GUINT_TO_POINTER (3));
+ mono_mutex_unlock (&mutex);
if (mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (30)) != GUINT_TO_POINTER (40))
res = 1;
}
static MonoConcurrentHashTable *hash;
+static mono_mutex_t global_mutex;
static void*
pw_sr_thread (void *arg)
int i, idx = 1000 * GPOINTER_TO_INT (arg);
mono_thread_info_attach ((gpointer)&arg);
- for (i = 0; i < 1000; ++i)
+ for (i = 0; i < 1000; ++i) {
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + idx), GINT_TO_POINTER (i + 1));
+ mono_mutex_unlock (&global_mutex);
+ }
return NULL;
}
parallel_writer_single_reader (void)
{
pthread_t a,b,c;
- mono_mutex_t mutex;
int i, j, res = 0;
- mono_mutex_init (&mutex);
- hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+ mono_mutex_init (&global_mutex);
+ hash = mono_conc_hashtable_new (NULL, NULL);
pthread_create (&a, NULL, pw_sr_thread, GINT_TO_POINTER (1));
pthread_create (&b, NULL, pw_sr_thread, GINT_TO_POINTER (2));
done:
mono_conc_hashtable_destroy (hash);
- mono_mutex_destroy (&mutex);
+ mono_mutex_destroy (&global_mutex);
if (res)
printf ("PAR_WRITER_SINGLE_READER TEST FAILED %d\n", res);
return res;
single_writer_parallel_reader (void)
{
pthread_t a,b,c;
- mono_mutex_t mutex;
gpointer ra, rb, rc;
int i, res = 0;
ra = rb = rc = GINT_TO_POINTER (1);
- mono_mutex_init (&mutex);
- hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+ mono_mutex_init (&global_mutex);
+ hash = mono_conc_hashtable_new (NULL, NULL);
pthread_create (&a, NULL, pr_sw_thread, GINT_TO_POINTER (0));
pthread_create (&b, NULL, pr_sw_thread, GINT_TO_POINTER (1));
pthread_create (&c, NULL, pr_sw_thread, GINT_TO_POINTER (2));
for (i = 0; i < 100; ++i) {
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 0 + 1), GINT_TO_POINTER ((i + 0) * 2 + 1));
+ mono_mutex_unlock (&global_mutex);
+
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 100 + 1), GINT_TO_POINTER ((i + 100) * 2 + 1));
+ mono_mutex_unlock (&global_mutex);
+
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 200 + 1), GINT_TO_POINTER ((i + 200) * 2 + 1));
+ mono_mutex_unlock (&global_mutex);
}
pthread_join (a, &ra);
res = GPOINTER_TO_INT (ra) + GPOINTER_TO_INT (rb) + GPOINTER_TO_INT (rc);
mono_conc_hashtable_destroy (hash);
- mono_mutex_destroy (&mutex);
+ mono_mutex_destroy (&global_mutex);
if (res)
printf ("SINGLE_WRITER_PAR_READER TEST FAILED %d\n", res);
return res;
mono_thread_info_attach ((gpointer)&arg);
- for (i = idx; i < idx + 1000; i++)
+ for (i = idx; i < idx + 1000; i++) {
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_insert (hash, GINT_TO_POINTER (i + 1), GINT_TO_POINTER (i + 1));
+ mono_mutex_unlock (&global_mutex);
+ }
return NULL;
}
mono_thread_info_attach ((gpointer)&arg);
- for (i = idx; i < idx + 1000; i++)
+ for (i = idx; i < idx + 1000; i++) {
+ mono_mutex_lock (&global_mutex);
mono_conc_hashtable_remove (hash, GINT_TO_POINTER (i + 1));
+ mono_mutex_unlock (&global_mutex);
+ }
return NULL;
}
parallel_writer_parallel_reader (void)
{
pthread_t wa, wb, wc, ra, rb, rc;
- mono_mutex_t mutex;
gpointer a, b, c;
int res = 0, i;
srand(time(NULL));
- mono_mutex_init (&mutex);
- hash = mono_conc_hashtable_new (&mutex, NULL, NULL);
+ mono_mutex_init (&global_mutex);
+ hash = mono_conc_hashtable_new (NULL, NULL);
for (i = 0; i < 2; i++) {
running = 1;
printf ("PAR_WRITER_PAR_READER TEST FAILED %d %d %d\n", GPOINTER_TO_INT (a), GPOINTER_TO_INT (b), GPOINTER_TO_INT (c));
mono_conc_hashtable_destroy (hash);
- mono_mutex_destroy (&mutex);
+ mono_mutex_destroy (&global_mutex);
return res;
}
static void G_GNUC_UNUSED
benchmark_conc (void)
{
- mono_mutex_t mutex;
MonoConcurrentHashTable *h;
int i, j;
- mono_mutex_init (&mutex);
- h = mono_conc_hashtable_new (&mutex, NULL, NULL);
+ h = mono_conc_hashtable_new (NULL, NULL);
- for (i = 1; i < 10 * 1000; ++i)
+ for (i = 1; i < 10 * 1000; ++i) {
mono_conc_hashtable_insert (h, GUINT_TO_POINTER (i), GUINT_TO_POINTER (i));
+ }
for (j = 0; j < 100000; ++j)
mono_conc_hashtable_lookup (h, GUINT_TO_POINTER (i));
mono_conc_hashtable_destroy (h);
- mono_mutex_destroy (&mutex);
-
}
static void G_GNUC_UNUSED
MonoThreadInfoCallbacks cb = { NULL };
int res = 0;
+ CHECKED_MONO_INIT ();
mono_threads_init (&cb, sizeof (MonoThreadInfo));
mono_thread_info_attach ((gpointer)&cb);
mono-threads-openbsd.c \
mono-threads-android.c \
mono-threads.h \
+ mono-threads-api.h \
mono-threads-coop.c \
mono-threads-coop.h \
mono-tls.h \
memfuncs.c \
memfuncs.h \
parse.c \
- parse.h
+ parse.h \
+ checked-build.c \
+ checked-build.h
arch_sources =
--- /dev/null
+/*
+ * checked-build.c: Expensive asserts used when mono is built with --with-checked-build=yes
+ *
+ * Author:
+ * Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+#include <config.h>
+#ifdef CHECKED_BUILD
+
+#include <mono/utils/checked-build.h>
+#include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-tls.h>
+#include <glib.h>
+
+#define MAX_NATIVE_BT 6
+#define MAX_NATIVE_BT_PROBE (MAX_NATIVE_BT + 5)
+#define MAX_TRANSITIONS 3
+
+
+#ifdef HAVE_BACKTRACE_SYMBOLS
+#include <execinfo.h>
+
+//XXX We should collect just the IPs and lazily symbolificate them.
+static int
+collect_backtrace (gpointer out_data[])
+{
+ return backtrace (out_data, MAX_NATIVE_BT_PROBE);
+}
+
+static char*
+translate_backtrace (gpointer native_trace[], int size)
+{
+ char **names = backtrace_symbols (native_trace, size);
+ GString* bt = g_string_sized_new (100);
+
+ int i, j = -1;
+
+ //Figure out the cut point of useless backtraces
+ //We'll skip up to the caller of checked_build_thread_transition
+ for (i = 0; i < size; ++i) {
+ if (strstr (names [i], "checked_build_thread_transition")) {
+ j = i + 1;
+ break;
+ }
+ }
+
+ if (j == -1)
+ j = 0;
+ for (i = j; i < size; ++i) {
+ if (i - j <= MAX_NATIVE_BT)
+ g_string_append_printf (bt, "\tat %s\n", names [i]);
+ }
+
+ free (names);
+ return g_string_free (bt, FALSE);
+}
+
+#else
+
+static int
+collect_backtrace (gpointer out_data[])
+{
+ return 0;
+}
+
+static char*
+translate_backtrace (gpointer native_trace[], int size)
+{
+ return g_strdup ("\tno backtrace available\n");
+}
+
+#endif
+
+
+typedef struct {
+ GPtrArray *transitions;
+} CheckState;
+
+typedef struct {
+ const char *name;
+ int from_state, next_state, suspend_count, suspend_count_delta, size;
+ gpointer backtrace [MAX_NATIVE_BT_PROBE];
+} ThreadTransition;
+
+static MonoNativeTlsKey thread_status;
+
+void
+checked_build_init (void)
+{
+ mono_native_tls_alloc (&thread_status, NULL);
+}
+
+static CheckState*
+get_state (void)
+{
+ CheckState *state = mono_native_tls_get_value (thread_status);
+ if (!state) {
+ state = g_new0 (CheckState, 1);
+ state->transitions = g_ptr_array_new ();
+ mono_native_tls_set_value (thread_status, state);
+ }
+
+ return state;
+}
+
+static void
+free_transition (ThreadTransition *t)
+{
+ g_free (t);
+}
+
+void
+checked_build_thread_transition (const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta)
+{
+ MonoThreadInfo *cur = mono_thread_info_current_unchecked ();
+ CheckState *state = get_state ();
+ /* We currently don't record external changes as those are hard to reason about. */
+ if (cur != info)
+ return;
+
+ if (state->transitions->len >= MAX_TRANSITIONS)
+ free_transition (g_ptr_array_remove_index (state->transitions, 0));
+
+ ThreadTransition *t = g_new0 (ThreadTransition, 1);
+ t->name = transition;
+ t->from_state = from_state;
+ t->next_state = next_state;
+ t->suspend_count = suspend_count;
+ t->suspend_count_delta = suspend_count_delta;
+ t->size = collect_backtrace (t->backtrace);
+ g_ptr_array_add (state->transitions, t);
+}
+
+static void
+assertion_fail (const char *msg, ...)
+{
+ int i;
+ GString* err = g_string_sized_new (100);
+ CheckState *state = get_state ();
+
+ g_string_append_printf (err, "Assertion failure in thread %p due to: ", mono_native_thread_id_get ());
+
+ va_list args;
+ va_start (args, msg);
+ g_string_append_vprintf (err, msg, args);
+ va_end (args);
+
+ g_string_append_printf (err, "\nLast %d state transitions: (most recent first)\n", state->transitions->len);
+
+ for (i = state->transitions->len - 1; i >= 0; --i) {
+ ThreadTransition *t = state->transitions->pdata [i];
+ char *bt = translate_backtrace (t->backtrace, t->size);
+ g_string_append_printf (err, "[%s] %s -> %s (%d) %s%d at:\n%s",
+ t->name,
+ mono_thread_state_name (t->from_state),
+ mono_thread_state_name (t->next_state),
+ t->suspend_count,
+ t->suspend_count_delta > 0 ? "+" : "", //I'd like to see this sort of values: -1, 0, +1
+ t->suspend_count_delta,
+ bt);
+ g_free (bt);
+ }
+
+ g_error (err->str);
+ g_string_free (err, TRUE);
+}
+
+void
+assert_gc_safe_mode (void)
+{
+ MonoThreadInfo *cur = mono_thread_info_current ();
+ int state;
+
+ if (!cur)
+ assertion_fail ("Expected GC Safe mode but thread is not attached");
+
+ switch (state = mono_thread_info_current_state (cur)) {
+ case STATE_BLOCKING:
+ case STATE_BLOCKING_AND_SUSPENDED:
+ break;
+ default:
+ assertion_fail ("Expected GC Safe mode but was in %s state", mono_thread_state_name (state));
+ }
+}
+
+void
+assert_gc_unsafe_mode (void)
+{
+ MonoThreadInfo *cur = mono_thread_info_current ();
+ int state;
+
+ if (!cur)
+ assertion_fail ("Expected GC Unsafe mode but thread is not attached");
+
+ switch (state = mono_thread_info_current_state (cur)) {
+ case STATE_RUNNING:
+ case STATE_ASYNC_SUSPEND_REQUESTED:
+ case STATE_SELF_SUSPEND_REQUESTED:
+ break;
+ default:
+ assertion_fail ("Expected GC Unsafe mode but was in %s state", mono_thread_state_name (state));
+ }
+}
+
+void
+assert_gc_neutral_mode (void)
+{
+ MonoThreadInfo *cur = mono_thread_info_current ();
+ int state;
+
+ if (!cur)
+ assertion_fail ("Expected GC Neutral mode but thread is not attached");
+
+ switch (state = mono_thread_info_current_state (cur)) {
+ case STATE_RUNNING:
+ case STATE_ASYNC_SUSPEND_REQUESTED:
+ case STATE_SELF_SUSPEND_REQUESTED:
+ case STATE_BLOCKING:
+ case STATE_BLOCKING_AND_SUSPENDED:
+ break;
+ default:
+ assertion_fail ("Expected GC Neutral mode but was in %s state", mono_thread_state_name (state));
+ }
+}
+
+#endif /* CHECKED_BUILD */
--- /dev/null
+/*
+ * checked-build.h: Expensive asserts used when mono is built with --with-checked-build=yes
+ *
+ * Author:
+ * Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+
+#ifndef __CHECKED_BUILD_H__
+#define __CHECKED_BUILD_H__
+
+#include <config.h>
+
+#ifdef CHECKED_BUILD
+
+/*
+GC runtime modes rules:
+
+- GC Safe
+Can:
+Call into foreigh functions.
+Call GC Safe or Neutral modes functions.
+Read from pinned managed memory.
+
+Cannot:
+Touch managed memory (read/write).
+Be dettached.
+
+What's good for?
+Doing blocking calls.
+
+- GC Unsafe
+Can:
+Touch managed memory (read/write).
+Call GC Unsafe or Neutral modes functions.
+
+Cannot:
+Call foreign native code (embedder callbacks, pinvokes, etc)
+Call into any Blocking functions/syscalls (mutexes, IO, etc)
+Be dettached.
+
+What's good for?
+Poking into managed memory.
+
+-- GC Neutral
+Can:
+Call other GC Neutral mode functions.
+
+Cannot:
+Touch managed memory.
+Call foreign native code (embedder callbacks, pinvokes, etc)
+Call into any Blocking functions/syscalls (mutexes, IO, etc)
+Be dettached.
+
+What's good for?
+Functions that can be called from both coop or preept modes.
+
+*/
+
+#define MONO_REQ_GC_SAFE_MODE do { \
+ assert_gc_safe_mode (); \
+} while (0);
+
+#define MONO_REQ_GC_UNSAFE_MODE do { \
+ assert_gc_unsafe_mode (); \
+} while (0);
+
+#define MONO_REQ_GC_NEUTRAL_MODE do { \
+ assert_gc_neutral_mode (); \
+} while (0);
+
+/*
+This can be called by embedders
+*/
+#define MONO_REQ_API_ENTRYPOINT
+
+/*
+The JIT will generate code that will land on this function
+*/
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT() do { checked_build_init (); } while (0)
+
+#define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta) do { \
+ checked_build_thread_transition (transition, info, from_state, suspend_count, next_state, suspend_count_delta); \
+} while (0)
+
+void assert_gc_safe_mode (void);
+void assert_gc_unsafe_mode (void);
+void assert_gc_neutral_mode (void);
+
+void checked_build_init (void);
+void checked_build_thread_transition(const char *transition, void *info, int from_state, int suspend_count, int next_state, int suspend_count_delta);
+
+#else
+
+#define MONO_REQ_GC_SAFE_MODE
+#define MONO_REQ_GC_UNSAFE_MODE
+#define MONO_REQ_GC_NEUTRAL_MODE
+#define MONO_REQ_API_ENTRYPOINT
+#define MONO_REQ_RUNTIME_ENTRYPOINT
+
+#define CHECKED_MONO_INIT()
+#define CHECKED_BUILD_THREAD_TRANSITION(transition, info, from_state, suspend_count, next_state, suspend_count_delta)
+
+#endif /* CHECKED_BUILD */
+
+#endif
#define MONO_THREAD_VAR_OFFSET(var,offset) (offset) = -1
#endif
-#elif defined(TARGET_MACH) && 0
+#elif defined(TARGET_MACH) && (defined(__i386__) || defined(__x86_64__))
-#define MONO_HAVE_FAST_TLS
+#define MONO_HAVE_FAST_TLS 1
#define MONO_FAST_TLS_SET(x,y) pthread_setspecific(x, y)
#define MONO_FAST_TLS_GET(x) pthread_getspecific(x)
#define MONO_FAST_TLS_ADDR(x) (mono_mach_get_tls_address_from_thread (pthread_self (), x))
volatile conc_table *table; /* goes to HP0 */
GHashFunc hash_func;
GEqualFunc equal_func;
- mono_mutex_t *mutex;
int element_count;
int overflow_count;
GDestroyNotify key_destroy_func;
MonoConcurrentHashTable*
-mono_conc_hashtable_new (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func)
+mono_conc_hashtable_new (GHashFunc hash_func, GEqualFunc key_equal_func)
{
MonoConcurrentHashTable *res = g_new0 (MonoConcurrentHashTable, 1);
- res->mutex = mutex;
res->hash_func = hash_func ? hash_func : g_direct_hash;
res->equal_func = key_equal_func ? key_equal_func : g_direct_equal;
// res->equal_func = g_direct_equal;
}
MonoConcurrentHashTable*
-mono_conc_hashtable_new_full (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
+mono_conc_hashtable_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
{
- MonoConcurrentHashTable *res = mono_conc_hashtable_new (mutex, hash_func, key_equal_func);
+ MonoConcurrentHashTable *res = mono_conc_hashtable_new (hash_func, key_equal_func);
res->key_destroy_func = key_destroy_func;
res->value_destroy_func = value_destroy_func;
return res;
}
/**
- * mono_conc_hashtable_remove
+ * mono_conc_hashtable_remove:
+ *
+ * Remove a value from the hashtable. Requires external locking
*
* @Returns the old value if key is already present or null
*/
g_assert (key != NULL && key != TOMBSTONE);
hash = mix_hash (hash_table->hash_func (key));
- mono_mutex_lock (hash_table->mutex);
table = (conc_table*)hash_table->table;
kvs = table->kvs;
if (!hash_table->equal_func) {
for (;;) {
if (!kvs [i].key) {
- mono_mutex_unlock (hash_table->mutex);
return NULL; /*key not found*/
}
mono_memory_barrier ();
kvs [i].key = TOMBSTONE;
- mono_mutex_unlock (hash_table->mutex);
if (hash_table->key_destroy_func != NULL)
(*hash_table->key_destroy_func) (key);
if (hash_table->value_destroy_func != NULL)
GEqualFunc equal = hash_table->equal_func;
for (;;) {
if (!kvs [i].key) {
- mono_mutex_unlock (hash_table->mutex);
return NULL; /*key not found*/
}
mono_memory_barrier ();
kvs [i].key = TOMBSTONE;
- mono_mutex_unlock (hash_table->mutex);
if (hash_table->key_destroy_func != NULL)
(*hash_table->key_destroy_func) (old_key);
if (hash_table->value_destroy_func != NULL)
}
}
/**
- * mono_conc_hashtable_insert
- *
+ * mono_conc_hashtable_insert:
+ *
+ * Insert a value into the hashtable. Requires external locking.
* @Returns the old value if key is already present or null
*/
gpointer
g_assert (value != NULL);
hash = mix_hash (hash_table->hash_func (key));
- mono_mutex_lock (hash_table->mutex);
if (hash_table->element_count >= hash_table->overflow_count)
expand_table (hash_table);
mono_memory_barrier ();
kvs [i].key = key;
++hash_table->element_count;
- mono_mutex_unlock (hash_table->mutex);
return NULL;
}
if (key == kvs [i].key) {
gpointer value = kvs [i].value;
- mono_mutex_unlock (hash_table->mutex);
return value;
}
i = (i + 1) & table_mask;
mono_memory_barrier ();
kvs [i].key = key;
++hash_table->element_count;
- mono_mutex_unlock (hash_table->mutex);
return NULL;
}
if (equal (key, kvs [i].key)) {
gpointer value = kvs [i].value;
- mono_mutex_unlock (hash_table->mutex);
return value;
}
i = (i + 1) & table_mask;
}
}
+/**
+ * mono_conc_hashtable_foreach:
+ *
+ * Calls @func for each value in the hashtable. Requires external locking.
+ */
void
mono_conc_hashtable_foreach (MonoConcurrentHashTable *hash_table, GHFunc func, gpointer userdata)
{
conc_table *table = (conc_table*)hash_table->table;
key_value_pair *kvs = table->kvs;
- mono_mutex_lock (hash_table->mutex);
for (i = 0; i < table->table_size; ++i) {
if (kvs [i].key && kvs [i].key != TOMBSTONE) {
func (kvs [i].key, kvs [i].value, userdata);
}
}
- mono_mutex_unlock (hash_table->mutex);
}
typedef struct _MonoConcurrentHashTable MonoConcurrentHashTable;
-MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func);
-MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new_full (mono_mutex_t *mutex, GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
+MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new (GHashFunc hash_func, GEqualFunc key_equal_func);
+MONO_API MonoConcurrentHashTable* mono_conc_hashtable_new_full (GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func);
MONO_API void mono_conc_hashtable_destroy (MonoConcurrentHashTable *hash_table);
MONO_API gpointer mono_conc_hashtable_lookup (MonoConcurrentHashTable *hash_table, gpointer key);
MONO_API gpointer mono_conc_hashtable_insert (MonoConcurrentHashTable *hash_table, gpointer key, gpointer value);
: "x30", "memory" \
); \
__asm__ __volatile__( \
- "adr %0, L0\n" \
- "L0:\n" \
+ "adr %0, L0%=\n" \
+ "L0%=:\n" \
: "=r" (ctx.pc) \
: \
: "memory" \
* We might also want to add an additional field to propagate
* the original context from the signal handler.
*/
+#ifdef __mono_ppc64__
+
+typedef struct {
+ gulong sc_ir; // pc
+ gulong sc_sp; // r1
+ mgreg_t regs [32];
+ double fregs [32];
+} MonoContext;
+
+/* we have the stack pointer, not the base pointer in sigcontext */
+#define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->sc_ir = (gulong)ip; } while (0);
+#define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->sc_sp = (gulong)bp; } while (0);
+#define MONO_CONTEXT_SET_SP(ctx,sp) do { (ctx)->sc_sp = (gulong)sp; } while (0);
+
+#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
+#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
+#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+
+#define MONO_CONTEXT_GET_CURRENT(ctx) \
+ __asm__ __volatile__( \
+ "std 0, 0(%0)\n" \
+ "std 1, 8(%0)\n" \
+ "std 0, 8*0+16(%0)\n" \
+ "std 1, 8*1+16(%0)\n" \
+ "std 2, 8*2+16(%0)\n" \
+ "std 3, 8*3+16(%0)\n" \
+ "std 4, 8*4+16(%0)\n" \
+ "std 5, 8*5+16(%0)\n" \
+ "std 6, 8*6+16(%0)\n" \
+ "std 7, 8*7+16(%0)\n" \
+ "std 8, 8*8+16(%0)\n" \
+ "std 9, 8*9+16(%0)\n" \
+ "std 10, 8*10+16(%0)\n" \
+ "std 11, 8*11+16(%0)\n" \
+ "std 12, 8*12+16(%0)\n" \
+ "std 13, 8*13+16(%0)\n" \
+ "std 14, 8*14+16(%0)\n" \
+ "std 15, 8*15+16(%0)\n" \
+ "std 16, 8*16+16(%0)\n" \
+ "std 17, 8*17+16(%0)\n" \
+ "std 18, 8*18+16(%0)\n" \
+ "std 19, 8*19+16(%0)\n" \
+ "std 20, 8*20+16(%0)\n" \
+ "std 21, 8*21+16(%0)\n" \
+ "std 22, 8*22+16(%0)\n" \
+ "std 23, 8*23+16(%0)\n" \
+ "std 24, 8*24+16(%0)\n" \
+ "std 25, 8*25+16(%0)\n" \
+ "std 26, 8*26+16(%0)\n" \
+ "std 27, 8*27+16(%0)\n" \
+ "std 28, 8*28+16(%0)\n" \
+ "std 29, 8*29+16(%0)\n" \
+ "std 30, 8*30+16(%0)\n" \
+ "std 31, 8*31+16(%0)\n" \
+ "stfd 0, 8*0+8*32+16(%0)\n" \
+ "stfd 1, 8*1+8*32+16(%0)\n" \
+ "stfd 2, 8*2+8*32+16(%0)\n" \
+ "stfd 3, 8*3+8*32+16(%0)\n" \
+ "stfd 4, 8*4+8*32+16(%0)\n" \
+ "stfd 5, 8*5+8*32+16(%0)\n" \
+ "stfd 6, 8*6+8*32+16(%0)\n" \
+ "stfd 7, 8*7+8*32+16(%0)\n" \
+ "stfd 8, 8*8+8*32+16(%0)\n" \
+ "stfd 9, 8*9+8*32+16(%0)\n" \
+ "stfd 10, 8*10+8*32+16(%0)\n" \
+ "stfd 11, 8*11+8*32+16(%0)\n" \
+ "stfd 12, 8*12+8*32+16(%0)\n" \
+ "stfd 13, 8*13+8*32+16(%0)\n" \
+ "stfd 14, 8*14+8*32+16(%0)\n" \
+ "stfd 15, 8*15+8*32+16(%0)\n" \
+ "stfd 16, 8*16+8*32+16(%0)\n" \
+ "stfd 17, 8*17+8*32+16(%0)\n" \
+ "stfd 18, 8*18+8*32+16(%0)\n" \
+ "stfd 19, 8*19+8*32+16(%0)\n" \
+ "stfd 20, 8*20+8*32+16(%0)\n" \
+ "stfd 21, 8*21+8*32+16(%0)\n" \
+ "stfd 22, 8*22+8*32+16(%0)\n" \
+ "stfd 23, 8*23+8*32+16(%0)\n" \
+ "stfd 24, 8*24+8*32+16(%0)\n" \
+ "stfd 25, 8*25+8*32+16(%0)\n" \
+ "stfd 26, 8*26+8*32+16(%0)\n" \
+ "stfd 27, 8*27+8*32+16(%0)\n" \
+ "stfd 28, 8*28+8*32+16(%0)\n" \
+ "stfd 29, 8*29+8*32+16(%0)\n" \
+ "stfd 30, 8*30+8*32+16(%0)\n" \
+ "stfd 31, 8*31+8*32+16(%0)\n" \
+ : : "r" (&(ctx)) \
+ : "memory" \
+ )
+
+#define MONO_ARCH_HAS_MONO_CONTEXT 1
+
+#else
+
typedef struct {
gulong sc_ir; // pc
gulong sc_sp; // r1
#define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->sc_ir))
#define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->regs [ppc_r31-13]))
#define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sc_sp))
+#endif
#elif defined(__sparc__) || defined(sparc) /* defined(__mono_ppc__) */
MONO_TRACE_AOT = (1<<5),
MONO_TRACE_SECURITY = (1<<6),
MONO_TRACE_THREADPOOL = (1<<7),
+ MONO_TRACE_IO_THREADPOOL = (1<<8),
MONO_TRACE_ALL = MONO_TRACE_ASSEMBLY |
MONO_TRACE_TYPE |
MONO_TRACE_DLLIMPORT |
MONO_TRACE_CONFIG |
MONO_TRACE_AOT |
MONO_TRACE_SECURITY |
- MONO_TRACE_THREADPOOL
+ MONO_TRACE_THREADPOOL |
+ MONO_TRACE_IO_THREADPOOL
} MonoTraceMask;
void
const char *tok;
guint32 flags = 0;
- const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "all", NULL};
+ const char *valid_flags[] = {"asm", "type", "dll", "gc", "cfg", "aot", "security", "threadpool", "io-threadpool", "all", NULL};
const MonoTraceMask valid_masks[] = {MONO_TRACE_ASSEMBLY, MONO_TRACE_TYPE, MONO_TRACE_DLLIMPORT,
MONO_TRACE_GC, MONO_TRACE_CONFIG, MONO_TRACE_AOT, MONO_TRACE_SECURITY,
- MONO_TRACE_THREADPOOL, MONO_TRACE_ALL };
+ MONO_TRACE_THREADPOOL, MONO_TRACE_IO_THREADPOOL, MONO_TRACE_ALL };
if(!value)
return;
FRAME_TYPE_DEBUGGER_INVOKE = 1,
/* Frame for transitioning to native code */
FRAME_TYPE_MANAGED_TO_NATIVE = 2,
- FRAME_TYPE_SENTINEL = 3
+ FRAME_TYPE_TRAMPOLINE = 3,
+ FRAME_TYPE_NUM = 4
} MonoStackFrameType;
typedef enum {
--- /dev/null
+/*
+ * mono-threads-api.h: Low level access to thread state.
+ *
+ * Author:
+ * Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2015 Xamarin
+ */
+
+#ifndef __MONO_THREADS_API_H__
+#define __MONO_THREADS_API_H__
+
+#include <mono/utils/mono-publib.h>
+MONO_BEGIN_DECLS
+
+/*
+>>>> WARNING WARNING WARNING <<<<
+
+This API is experimental. It will eventually be required to properly use the rest of the raw-omp embedding API.
+*/
+
+/* Don't use those directly, use the MONO_(BEGIN|END)_EFRAME */
+MONO_API void* mono_threads_enter_gc_unsafe_region (void);
+MONO_API void mono_threads_exit_gc_unsafe_region (void *region_cookie);
+
+/*
+Use those macros to limit regions of code that interact with managed memory or use the embedding API.
+This will put the current thread in GC Unsafe mode.
+
+For further explanation of what can and can't be done in GC unsafe mode:
+http://www.mono-project.com/docs/advanced/runtime/docs/coop-suspend/#gc-unsafe-mode
+
+*/
+#define MONO_BEGIN_EFRAME { void *__region_cookie = mono_threads_enter_gc_unsafe_region ();
+#define MONO_END_EFRAME mono_threads_exit_gc_unsafe_region (__region_cookie); }
+
+
+MONO_END_DECLS
+
+#endif /* __MONO_LOGGER_H__ */
-/*
+ /*
* mono-threads.c: Coop threading
*
* Author:
#include <mono/utils/mono-mmap.h>
#include <mono/utils/atomic.h>
#include <mono/utils/mono-time.h>
+#include <mono/utils/mono-counters.h>
+
+#ifdef TARGET_OSX
+#include <mono/utils/mach-support.h>
+#endif
#ifdef USE_COOP_BACKEND
volatile size_t mono_polling_required;
+static int coop_reset_blocking_count, coop_try_blocking_count, coop_do_blocking_count, coop_do_polling_count, coop_save_count;
+
void
mono_threads_state_poll (void)
{
MonoThreadInfo *info;
+ ++coop_do_polling_count;
info = mono_thread_info_current_unchecked ();
if (!info)
if (!(info->thread_state & (STATE_ASYNC_SUSPEND_REQUESTED | STATE_SELF_SUSPEND_REQUESTED)))
return;
- g_assert (mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL));
+ ++coop_save_count;
+ mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
/* commit the saved state and notify others if needed */
switch (mono_threads_transition_state_poll (info)) {
mono_threads_prepare_blocking (void)
{
MonoThreadInfo *info;
+ ++coop_do_blocking_count;
info = mono_thread_info_current_unchecked ();
/* If the thread is not attached, it doesn't make sense prepare for suspend. */
}
retry:
- /*The JIT might not be able to save*/
- if (!mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL)) {
- THREADS_SUSPEND_DEBUG ("PREPARE-BLOCKING failed %p to save thread state\n", mono_thread_info_get_tid (info));
- return NULL;
- }
+ ++coop_save_count;
+ mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
switch (mono_threads_transition_do_blocking (info)) {
case DoBlockingContinue:
mono_threads_reset_blocking_start (void)
{
MonoThreadInfo *info = mono_thread_info_current_unchecked ();
+ ++coop_reset_blocking_count;
/* If the thread is not attached, it doesn't make sense prepare for suspend. */
if (!info || !mono_thread_info_is_live (info))
mono_threads_try_prepare_blocking (void)
{
MonoThreadInfo *info;
+ ++coop_try_blocking_count;
info = mono_thread_info_current_unchecked ();
/* If the thread is not attached, it doesn't make sense prepare for suspend. */
}
retry:
- /*The JIT might not be able to save*/
- if (!mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL)) {
- THREADS_SUSPEND_DEBUG ("PREPARE-TRY-BLOCKING failed %p to save thread state\n", mono_thread_info_get_tid (info));
- return NULL;
- }
+ ++coop_save_count;
+ mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
switch (mono_threads_transition_do_blocking (info)) {
case DoBlockingContinue:
void
mono_threads_init_platform (void)
{
+ mono_counters_register ("Coop Reset Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_reset_blocking_count);
+ mono_counters_register ("Coop Try Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_try_blocking_count);
+ mono_counters_register ("Coop Do Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_do_blocking_count);
+ mono_counters_register ("Coop Do Polling", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_do_polling_count);
+ mono_counters_register ("Coop Save Count", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_save_count);
//See the above for what's wrong here.
}
void
mono_threads_platform_free (MonoThreadInfo *info)
{
+#ifdef TARGET_OSX
+ mach_port_deallocate (current_task (), info->native_handle);
+#endif
+
//See the above for what's wrong here.
}
void
mono_threads_platform_register (MonoThreadInfo *info)
{
+#ifdef TARGET_OSX
+ info->native_handle = mach_thread_self ();
+#endif
+
//See the above for what's wrong here.
}
mono_polling_required = 0;
}
+void*
+mono_threads_enter_gc_unsafe_region (void)
+{
+ return mono_threads_reset_blocking_start ();
+}
+
+void
+mono_threads_exit_gc_unsafe_region (void *regions_cookie)
+{
+ mono_threads_reset_blocking_end (regions_cookie);
+}
+
+#else
+
+void*
+mono_threads_enter_gc_unsafe_region (void)
+{
+ return NULL;
+}
+
+void
+mono_threads_exit_gc_unsafe_region (void *regions_cookie)
+{
+}
#endif
\ No newline at end of file
/* Runtime consumable API */
#define MONO_SUSPEND_CHECK() do { \
- if (G_UNLIKELY (mono_threads_polling_required)) mono_threads_state_poll (); \
+ if (G_UNLIKELY (mono_polling_required)) mono_threads_state_poll (); \
} while (0);
#define MONO_PREPARE_BLOCKING \
/* Internal API */
-extern volatile size_t mono_threads_polling_required;
-
void mono_threads_state_poll (void);
void* mono_threads_prepare_blocking (void);
void mono_threads_finish_blocking (void* cookie);
void mono_threads_finish_try_blocking (void* cookie);
/* JIT specific interface */
-extern volatile size_t mono_polling_required ;
+extern volatile size_t mono_polling_required;
#else
-#define MONO_SUSPEND_CHECK do { } while (0);
+#define MONO_SUSPEND_CHECK() do { } while (0);
#define MONO_PREPARE_BLOCKING {
#define MONO_FINISH_BLOCKING }
#define MONO_PREPARE_RESET_BLOCKING {
mono_threads_init_dead_letter ();
}
-void
-mono_threads_core_interrupt (MonoThreadInfo *info)
-{
- thread_abort (info->native_handle);
-}
-
void
mono_threads_core_abort_syscall (MonoThreadInfo *info)
{
start_info->handle = handle;
info = mono_thread_info_attach (&result);
- MONO_PREPARE_BLOCKING
+ MONO_PREPARE_BLOCKING;
info->runtime_thread = TRUE;
info->handle = handle;
MONO_SEM_DESTROY (&info->create_suspended_sem);
}
- MONO_FINISH_BLOCKING
+ MONO_FINISH_BLOCKING;
/* Run the actual main function of the thread */
result = start_func (t_arg);
return NULL;
}
+ MONO_TRY_BLOCKING;
/* Wait until the thread register itself in various places */
while (MONO_SEM_WAIT (&(start_info.registered)) != 0) {
/*if (EINTR != errno) ABORT("sem_wait failed"); */
}
+ MONO_FINISH_TRY_BLOCKING;
+
MONO_SEM_DESTROY (&(start_info.registered));
if (out_tid)
return handle;
}
-gpointer
-mono_threads_core_prepare_interrupt (HANDLE thread_handle)
-{
- return wapi_prepare_interrupt_thread (thread_handle);
-}
-
-void
-mono_threads_core_finish_interrupt (gpointer wait_handle)
-{
- wapi_finish_interrupt_thread (wait_handle);
-}
-
-void
-mono_threads_core_self_interrupt (void)
-{
- wapi_self_interrupt ();
-}
-
-void
-mono_threads_core_clear_interruption (void)
-{
- wapi_clear_interruption ();
-}
-
int
mono_threads_pthread_kill (MonoThreadInfo *info, int signum)
{
#include <mono/utils/mono-tls.h>
#include <mono/utils/mono-memory-model.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/checked-build.h>
#include <errno.h>
state_name (next_state),
get_thread_suspend_count (cur_raw_state),
get_thread_suspend_count (cur_raw_state) + suspend_count_delta);
+
+ CHECKED_BUILD_THREAD_TRANSITION (transition, info, get_thread_state (cur_raw_state), get_thread_suspend_count (cur_raw_state), next_state, suspend_count_delta);
}
/*
If this turns to be an issue we can introduce a new suspend request state for when both have been requested.
*/
default:
- g_error ("Cannot transition thread %p from %s with SUSPEND_REQUEST", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with SUSPEND_REQUEST", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_ASYNC_SUSPEND_REQUESTED: Since there can only be one async suspend in progress and it must finish, it should not be possible to witness this.
*/
default:
- g_error ("Cannot transition thread %p from %s with ASYNC_SUSPEND_REQUESTED", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with ASYNC_SUSPEND_REQUESTED", mono_thread_info_get_tid (info), state_name (cur_state));
}
return (MonoRequestAsyncSuspendResult) FALSE;
}
STATE_BLOCKING_AND_SUSPENDED: Pool is a local state transition. No VM activities are allowed while in blocking mode.
*/
default:
- g_error ("Cannot transition thread %p from %s with STATE_POLL", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with STATE_POLL", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
*/
default:
- g_error ("Cannot transition thread %p from %s with REQUEST_RESUME", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with REQUEST_RESUME", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_BLOCKING: Async suspend only begins if a transition to async suspend requested happened. Blocking would have put us into blocking with positive suspend count if it raced with async finish.
*/
default:
- g_error ("Cannot transition thread %p from %s with FINISH_ASYNC_SUSPEND", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with FINISH_ASYNC_SUSPEND", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_SELF_SUSPEND_REQUESTED: All those are invalid end states of a sucessfull finish async suspend
*/
default:
- g_error ("Cannot transition thread %p from %s with COMPENSATE_FINISH_ASYNC_SUSPEND", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with COMPENSATE_FINISH_ASYNC_SUSPEND", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_BLOCKING_AND_SUSPENDED: Blocking is not nestabled
*/
default:
- g_error ("Cannot transition thread %p from %s with DO_BLOCKING", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with DO_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_BLOCKING_AND_SUSPENDED: This an exit state of done blocking
*/
default:
- g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
STATE_BLOCKING_AND_SUSPENDED: This is an exit state of done blocking, can't happen here.
*/
default:
- g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", info, state_name (cur_state));
+ g_error ("Cannot transition thread %p from %s with DONE_BLOCKING", mono_thread_info_get_tid (info), state_name (cur_state));
}
}
{
return get_thread_state (info->thread_state);
}
+
+const char*
+mono_thread_state_name (int state)
+{
+ return state_name (state);
+}
#endif
}
-
-gpointer
-mono_threads_core_prepare_interrupt (HANDLE thread_handle)
-{
- return NULL;
-}
-
-void
-mono_threads_core_finish_interrupt (gpointer wait_handle)
-{
-}
-
-void
-mono_threads_core_self_interrupt (void)
-{
-}
-
-void
-mono_threads_core_clear_interruption (void)
-{
-}
-
#endif
MonoThreadInfo *info;
MonoThreadInfo *cur = mono_thread_info_current ();
- MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2)\n");
+ MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2, * means any number)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x0\t- starting (GOOD, unless the thread is running managed code)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x1\t- running (BAD, unless it's the gc thread)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x2\t- detached (GOOD, unless the thread is running managed code)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?04\t- self suspended (GOOD)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?05\t- async suspend requested (BAD)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?06\t- self suspend requested (BAD)\n");
- MOSTLY_ASYNC_SAFE_PRINTF ("\t0x07\t- blocking (GOOD)\n");
+ MOSTLY_ASYNC_SAFE_PRINTF ("\t0x*07\t- blocking (GOOD)\n");
MOSTLY_ASYNC_SAFE_PRINTF ("\t0x?08\t- blocking with pending suspend (GOOD)\n");
FOREACH_THREAD_SAFE (info) {
if (threads_callbacks.thread_detach)
threads_callbacks.thread_detach (info);
- /*
- Since the thread info lock is taken from within blocking sections, we can't check from there, so it must be done here.
- This ensures that we won't lose any suspend requests as a suspend initiator must hold the lock.
- Once we're holding the suspend lock, no threads can suspend us and once we unregister, no thread can find us.
- */
- MONO_PREPARE_BLOCKING
mono_thread_info_suspend_lock ();
- MONO_FINISH_BLOCKING
/*
Now perform the callback that must be done under locks.
return;
THREADS_SUSPEND_DEBUG ("FINISH SELF SUSPEND OF %p\n", info);
- g_assert (mono_threads_get_runtime_callbacks ()->thread_state_init_from_sigctx (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX], NULL));
+ mono_threads_get_runtime_callbacks ()->thread_state_init (&info->thread_saved_state [SELF_SUSPEND_STATE_INDEX]);
/* commit the saved state and notify others if needed */
switch (mono_threads_transition_state_poll (info)) {
/*FIXME: unify this with self-suspend*/
g_assert (id != mono_native_thread_id_get ());
+ /* This can block during stw */
mono_thread_info_suspend_lock ();
mono_threads_begin_global_suspend ();
void
mono_thread_info_suspend_lock (void)
{
+ MONO_TRY_BLOCKING;
MONO_SEM_WAIT_UNITERRUPTIBLE (&global_suspend_semaphore);
+ MONO_FINISH_TRY_BLOCKING;
}
void
mono_threads_core_set_name (tid, name);
}
+#define INTERRUPT_STATE ((MonoThreadInfoInterruptToken*) (size_t) -1)
+
+struct _MonoThreadInfoInterruptToken {
+ void (*callback) (gpointer data);
+ gpointer data;
+};
+
/*
- * mono_thread_info_prepare_interrupt:
+ * mono_thread_info_install_interrupt: install an interruption token for the current thread.
*
- * See wapi_prepare_interrupt ().
+ * - @callback: must be able to be called from another thread and always cancel the wait
+ * - @data: passed to the callback
+ * - @interrupted: will be set to TRUE if a token is already installed, FALSE otherwise
+ * if set to TRUE, it must mean that the thread is in interrupted state
*/
-gpointer
-mono_thread_info_prepare_interrupt (HANDLE thread_handle)
+void
+mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted)
{
- return mono_threads_core_prepare_interrupt (thread_handle);
+ MonoThreadInfo *info;
+ MonoThreadInfoInterruptToken *previous_token, *token;
+
+ g_assert (callback);
+
+ g_assert (interrupted);
+ *interrupted = FALSE;
+
+ info = mono_thread_info_current ();
+ g_assert (info);
+
+ /* The memory of this token can be freed at 2 places:
+ * - if the token is not interrupted: it will be freed in uninstall, as info->interrupt_token has not been replaced
+ * by the INTERRUPT_STATE flag value, and it still contains the pointer to the memory location
+ * - if the token is interrupted: it will be freed in finish, as the token is now owned by the prepare/finish
+ * functions, and info->interrupt_token does not contains a pointer to the memory anymore */
+ token = g_new0 (MonoThreadInfoInterruptToken, 1);
+ token->callback = callback;
+ token->data = data;
+
+ previous_token = InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, token, NULL);
+
+ if (previous_token) {
+ if (previous_token != INTERRUPT_STATE)
+ g_error ("mono_thread_info_install_interrupt: previous_token should be INTERRUPT_STATE (%p), but it was %p", INTERRUPT_STATE, previous_token);
+
+ g_free (token);
+
+ *interrupted = TRUE;
+ }
+
+ THREADS_INTERRUPT_DEBUG ("interrupt install tid %p token %p previous_token %p interrupted %s\n",
+ mono_thread_info_get_tid (info), token, previous_token, *interrupted ? "TRUE" : "FALSE");
}
void
-mono_thread_info_finish_interrupt (gpointer wait_handle)
+mono_thread_info_uninstall_interrupt (gboolean *interrupted)
+{
+ MonoThreadInfo *info;
+ MonoThreadInfoInterruptToken *previous_token;
+
+ g_assert (interrupted);
+ *interrupted = FALSE;
+
+ info = mono_thread_info_current ();
+ g_assert (info);
+
+ previous_token = InterlockedExchangePointer ((gpointer*) &info->interrupt_token, NULL);
+
+ /* only the installer can uninstall the token */
+ g_assert (previous_token);
+
+ if (previous_token == INTERRUPT_STATE) {
+ /* if it is interrupted, then it is going to be freed in finish interrupt */
+ *interrupted = TRUE;
+ } else {
+ g_free (previous_token);
+ }
+
+ THREADS_INTERRUPT_DEBUG ("interrupt uninstall tid %p previous_token %p interrupted %s\n",
+ mono_thread_info_get_tid (info), previous_token, *interrupted ? "TRUE" : "FALSE");
+}
+
+static MonoThreadInfoInterruptToken*
+set_interrupt_state (MonoThreadInfo *info)
+{
+ MonoThreadInfoInterruptToken *token, *previous_token;
+
+ g_assert (info);
+
+ /* Atomically obtain the token the thread is
+ * waiting on, and change it to a flag value. */
+
+ do {
+ previous_token = info->interrupt_token;
+
+ /* Already interrupted */
+ if (previous_token == INTERRUPT_STATE) {
+ token = NULL;
+ break;
+ }
+
+ token = previous_token;
+ } while (InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, INTERRUPT_STATE, previous_token) != previous_token);
+
+ return token;
+}
+
+/*
+ * mono_thread_info_prepare_interrupt:
+ *
+ * The state of the thread info interrupt token is set to 'interrupted' which means that :
+ * - if the thread calls one of the WaitFor functions, the function will return with
+ * WAIT_IO_COMPLETION instead of waiting
+ * - if the thread was waiting when this function was called, the wait will be broken
+ *
+ * It is possible that the wait functions return WAIT_IO_COMPLETION, but the target thread
+ * didn't receive the interrupt signal yet, in this case it should call the wait function
+ * again. This essentially means that the target thread will busy wait until it is ready to
+ * process the interruption.
+ */
+MonoThreadInfoInterruptToken*
+mono_thread_info_prepare_interrupt (MonoThreadInfo *info)
{
- mono_threads_core_finish_interrupt (wait_handle);
+ MonoThreadInfoInterruptToken *token;
+
+ token = set_interrupt_state (info);
+
+ THREADS_INTERRUPT_DEBUG ("interrupt prepare tid %p token %p\n",
+ mono_thread_info_get_tid (info), token);
+
+ return token;
}
void
-mono_thread_info_interrupt (HANDLE thread_handle)
+mono_thread_info_finish_interrupt (MonoThreadInfoInterruptToken *token)
{
- gpointer wait_handle;
+ THREADS_INTERRUPT_DEBUG ("interrupt finish token %p\n", token);
+
+ if (token == NULL)
+ return;
+
+ g_assert (token->callback);
+
+ token->callback (token->data);
- wait_handle = mono_thread_info_prepare_interrupt (thread_handle);
- mono_thread_info_finish_interrupt (wait_handle);
+ g_free (token);
}
-
+
void
mono_thread_info_self_interrupt (void)
{
- mono_threads_core_self_interrupt ();
+ MonoThreadInfo *info;
+ MonoThreadInfoInterruptToken *token;
+
+ info = mono_thread_info_current ();
+ g_assert (info);
+
+ token = set_interrupt_state (info);
+ g_assert (!token);
+
+ THREADS_INTERRUPT_DEBUG ("interrupt self tid %p\n",
+ mono_thread_info_get_tid (info));
+}
+
+/* Clear the interrupted flag of the current thread, set with
+ * mono_thread_info_self_interrupt, so it can wait again */
+void
+mono_thread_info_clear_self_interrupt ()
+{
+ MonoThreadInfo *info;
+ MonoThreadInfoInterruptToken *previous_token;
+
+ info = mono_thread_info_current ();
+ g_assert (info);
+
+ previous_token = InterlockedCompareExchangePointer ((gpointer*) &info->interrupt_token, NULL, INTERRUPT_STATE);
+ g_assert (previous_token == NULL || previous_token == INTERRUPT_STATE);
+
+ THREADS_INTERRUPT_DEBUG ("interrupt clear self tid %p previous_token %p\n", mono_thread_info_get_tid (info), previous_token);
+}
+
+gboolean
+mono_thread_info_is_interrupt_state (MonoThreadInfo *info)
+{
+ g_assert (info);
+ return InterlockedReadPointer ((gpointer*) &info->interrupt_token) == INTERRUPT_STATE;
}
void
-mono_thread_info_clear_interruption (void)
+mono_thread_info_describe_interrupt_token (MonoThreadInfo *info, GString *text)
{
- mono_threads_core_clear_interruption ();
+ g_assert (info);
+
+ if (!InterlockedReadPointer ((gpointer*) &info->interrupt_token))
+ g_string_append_printf (text, "not waiting");
+ else if (InterlockedReadPointer ((gpointer*) &info->interrupt_token) == INTERRUPT_STATE)
+ g_string_append_printf (text, "interrupted state");
+ else
+ g_string_append_printf (text, "waiting");
}
/* info must be self or be held in a hazard pointer. */
#include <mono/utils/mono-mutex.h>
#include <mono/utils/mono-tls.h>
#include <mono/utils/mono-threads-coop.h>
+#include <mono/utils/mono-threads-api.h>
#include <glib.h>
#include <config.h>
#define THREADS_STATE_MACHINE_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
#endif
+#if 1
+#define THREADS_INTERRUPT_DEBUG(...)
+#else
+#define THREADS_INTERRUPT_DEBUG MOSTLY_ASYNC_SAFE_PRINTF
+#endif
+
/* If this is defined, use the signals backed on Mach. Debug only as signals can't be made usable on OSX. */
// #define USE_SIGNALS_ON_MACH
MONO_SERVICE_REQUEST_SAMPLE = 1,
} MonoAsyncJob;
+typedef struct _MonoThreadInfoInterruptToken MonoThreadInfoInterruptToken;
+
typedef struct {
MonoLinkedListSetNode node;
guint32 small_id; /*Used by hazard pointers */
volatile gint32 service_requests;
void *jit_data;
+
+ MonoThreadInfoInterruptToken *interrupt_token;
} MonoThreadInfo;
typedef struct {
void (*setup_async_callback) (MonoContext *ctx, void (*async_cb)(void *fun), gpointer user_data);
gboolean (*thread_state_init_from_sigctx) (MonoThreadUnwindState *state, void *sigctx);
gboolean (*thread_state_init_from_handle) (MonoThreadUnwindState *tctx, MonoThreadInfo *info);
+ void (*thread_state_init) (MonoThreadUnwindState *tctx);
} MonoThreadInfoRuntimeCallbacks;
//Not using 0 and 1 to ensure callbacks are not returning bad data
HANDLE
mono_thread_info_open_handle (void);
-gpointer
-mono_thread_info_prepare_interrupt (HANDLE thread_handle);
+void
+mono_thread_info_install_interrupt (void (*callback) (gpointer data), gpointer data, gboolean *interrupted);
void
-mono_thread_info_finish_interrupt (gpointer wait_handle);
+mono_thread_info_uninstall_interrupt (gboolean *interrupted);
+
+MonoThreadInfoInterruptToken*
+mono_thread_info_prepare_interrupt (THREAD_INFO_TYPE *info);
void
-mono_thread_info_interrupt (HANDLE thread_handle);
+mono_thread_info_finish_interrupt (MonoThreadInfoInterruptToken *token);
void
mono_thread_info_self_interrupt (void);
void
-mono_thread_info_clear_interruption (void);
+mono_thread_info_clear_self_interrupt (void);
+
+gboolean
+mono_thread_info_is_interrupt_state (THREAD_INFO_TYPE *info);
+
+void
+mono_thread_info_describe_interrupt_token (THREAD_INFO_TYPE *info, GString *text);
gboolean
mono_thread_info_is_live (THREAD_INFO_TYPE *info);
gboolean mono_threads_core_resume (THREAD_INFO_TYPE *info);
void mono_threads_platform_register (THREAD_INFO_TYPE *info); //ok
void mono_threads_platform_free (THREAD_INFO_TYPE *info);
-void mono_threads_core_interrupt (THREAD_INFO_TYPE *info);
void mono_threads_core_abort_syscall (THREAD_INFO_TYPE *info);
gboolean mono_threads_core_needs_abort_syscall (void);
HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid);
HANDLE mono_threads_core_open_handle (void);
HANDLE mono_threads_core_open_thread_handle (HANDLE handle, MonoNativeThreadId tid);
void mono_threads_core_set_name (MonoNativeThreadId tid, const char *name);
-gpointer mono_threads_core_prepare_interrupt (HANDLE thread_handle);
-void mono_threads_core_finish_interrupt (gpointer wait_handle);
-void mono_threads_core_self_interrupt (void);
-void mono_threads_core_clear_interruption (void);
MonoNativeThreadId mono_native_thread_id_get (void);
gboolean mono_thread_info_is_live (THREAD_INFO_TYPE *info);
int mono_thread_info_suspend_count (THREAD_INFO_TYPE *info);
int mono_thread_info_current_state (THREAD_INFO_TYPE *info);
+const char* mono_thread_state_name (int state);
gboolean mono_thread_info_in_critical_location (THREAD_INFO_TYPE *info);
gboolean mono_thread_info_begin_suspend (THREAD_INFO_TYPE *info, gboolean interrupt_kernel);
#if defined(PLAT_amd64_win64) && !defined(__GNUC__)
-#error Unsupported compiler.
+//#error Unsupported compiler.
#endif /* PLAT_amd64_win64 */
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
</PropertyGroup>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<SuppressStartupBanner>true</SuppressStartupBanner>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<SuppressStartupBanner>true</SuppressStartupBanner>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<SuppressStartupBanner>true</SuppressStartupBanner>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<SubSystem>Console</SubSystem>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;libmonoutils.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<SuppressStartupBanner>true</SuppressStartupBanner>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<SubSystem>Console</SubSystem>\r
<ItemGroup>\r
<ProjectReference Include="eglib.vcxproj">\r
<Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\lib\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">monosgen-2.0</TargetName>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">mono-2.0</TargetName>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">monosgen-2.0</TargetName>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">\r
<PreBuildEvent>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
<PreBuildEvent>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">\r
<PreBuildEvent>\r
<Link>\r
<AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <ModuleDefinitionFile>monosgen64.def</ModuleDefinitionFile>\r
+ <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
<PreBuildEvent>\r
<FunctionLevelLinking>true</FunctionLevelLinking>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
- <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+ <PrecompiledHeaderOutputFile>\r
+ </PrecompiledHeaderOutputFile>\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<ResourceCompile>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">\r
<PreBuildEvent>\r
<FunctionLevelLinking>true</FunctionLevelLinking>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
- <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+ <PrecompiledHeaderOutputFile>\r
+ </PrecompiledHeaderOutputFile>\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<ResourceCompile>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<ProgramDatabaseFile>$(TargetDir)$(TargetName).pdb</ProgramDatabaseFile>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
<PreBuildEvent>\r
<FunctionLevelLinking>true</FunctionLevelLinking>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
- <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+ <PrecompiledHeaderOutputFile>\r
+ </PrecompiledHeaderOutputFile>\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<ResourceCompile>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntime.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<ModuleDefinitionFile>mono.def</ModuleDefinitionFile>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">\r
<PreBuildEvent>\r
<FunctionLevelLinking>true</FunctionLevelLinking>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
- <PrecompiledHeaderOutputFile>.\Release/libmono.pch</PrecompiledHeaderOutputFile>\r
+ <PrecompiledHeaderOutputFile>\r
+ </PrecompiledHeaderOutputFile>\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<ResourceCompile>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>libgc.lib;libmonoruntimesgen.lib;libmonoutils.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <ModuleDefinitionFile>monosgen64.def</ModuleDefinitionFile>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ModuleDefinitionFile>monosgen.def</ModuleDefinitionFile>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
</Link>\r
+ <PostBuildEvent>\r
+ <Command>xcopy /F /Y "$(SolutionDir)..\mono\cil\opcode.def" "$(SolutionDir)include\mono\cil\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\mini\jit.h" "$(SolutionDir)include\mono\jit\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\metadata\*.h" "$(SolutionDir)include\mono\metadata\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-counters.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-dl-fallback.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-error.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-logger.h" "$(SolutionDir)include\mono\utils\"\r
+xcopy /F /Y "$(SolutionDir)..\mono\utils\mono-publib.h" "$(SolutionDir)include\mono\utils\"</Command>\r
+ </PostBuildEvent>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
<CustomBuildStep Include="..\mono\mini\mini-x86.h">\r
<ItemGroup>\r
<ProjectReference Include="eglib.vcxproj">\r
<Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
- </ProjectReference>\r
- <ProjectReference Include="genmdesc.vcxproj">\r
- <Project>{b7098dfa-31e6-4006-8a15-1c9a4e925149}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
<ProjectReference Include="libgc.vcxproj">\r
<Project>{eb56000b-c80b-4e8b-908d-d84d31b517d3}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
+ <ProjectReference Include="libmonoruntime.vcxproj">\r
+ <Project>{c36612bd-22d3-4b95-85e2-7fdc4fc5d739}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
+ <ProjectReference Include="libmonoutils.vcxproj">\r
+ <Project>{8fc2b0c8-51ad-49df-851f-5d01a77a75e4}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
</ImportGroup>\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<TargetName>$(ProjectName)sgen</TargetName>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<TargetName>$(ProjectName)sgen</TargetName>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<TargetName>$(ProjectName)sgen</TargetName>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<TargetName>$(ProjectName)sgen</TargetName>\r
</PropertyGroup>\r
<Optimization>Disabled</Optimization>\r
<PreprocessorDefinitions>WIN32;$(BOEHM_DEFINES);_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<AdditionalIncludeDirectories>$(top_srcdir);$(top_srcdir)/mono;$(LIBGC_CPPFLAGS_INCLUDE);$(GLIB_CFLAGS_INCLUDE)</AdditionalIncludeDirectories>\r
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
</ClCompile>\r
<Link>\r
<SubSystem>Windows</SubSystem>\r
</ImportGroup>\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
- <OutDir>$(Platform)\lib\</OutDir>\r
+ <OutDir>$(Platform)\lib\$(Configuration)\</OutDir>\r
<IntDir>$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Windows</SubSystem>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX86</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Windows</SubSystem>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Windows</SubSystem>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX86</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>eglib.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Windows</SubSystem>\r
<OptimizeReferences>true</OptimizeReferences>\r
<EnableCOMDATFolding>true</EnableCOMDATFolding>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
<ProjectReference Include="eglib.vcxproj">\r
<Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
mono_g_hash_table_insert
mono_g_hash_table_lookup
mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
mono_g_hash_table_new_type
mono_g_hash_table_print_stats
mono_g_hash_table_remove
mono_thread_exit
mono_thread_get_main
mono_thread_get_undeniable_exception
-mono_thread_info_clear_interruption
mono_thread_info_exit
mono_thread_info_finish_interrupt
mono_thread_info_get_stack_bounds
-mono_thread_info_interrupt
mono_thread_info_open_handle
mono_thread_info_prepare_interrupt
mono_thread_info_self_interrupt
mono_thread_set_manage_callback
mono_thread_stop
mono_threads_attach_tools_thread
-mono_threads_core_clear_interruption
-mono_threads_core_finish_interrupt
-mono_threads_core_prepare_interrupt
-mono_threads_core_self_interrupt
mono_threads_create_thread
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\bin\$(Configuration)</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)</IntDir>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|Win32'">$(ProjectName)-sgen</TargetName>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">$(ProjectName)-sgen</TargetName>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release_SGen|x64'">$(ProjectName)-sgen</TargetName>\r
</ClCompile>\r
<ProjectReference />\r
<Link>\r
- <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</ClCompile>\r
<ProjectReference />\r
<Link>\r
- <AdditionalDependencies>monosgen-2.0.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<SubSystem>Console</SubSystem>\r
<OptimizeReferences>true</OptimizeReferences>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>monosgen-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>mono-2.0.lib;libgc.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<ItemGroup>\r
<ProjectReference Include="eglib.vcxproj">\r
<Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<PreprocessorDefinitions>_DEBUG;WIN32;_WINDOWS;__WIN32__;HAVE_CONFIG_H;__i386__;TARGET_X86;HOST_WIN32;TARGET_WIN32;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
<DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r
</ClCompile>\r
<ProjectReference>\r
- <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>\r
+ </AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
<ClCompile>\r
<Optimization>MinSpace</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
</ClCompile>\r
<ProjectReference>\r
- <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
<TargetMachine>MachineX86</TargetMachine>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<DisableSpecificWarnings>4996;4018;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>\r
</ClCompile>\r
<ProjectReference>\r
- <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>\r
+ </AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</Midl>\r
<ClCompile>\r
<Optimization>MinSpace</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
</ClCompile>\r
<ProjectReference>\r
- <LinkLibraryDependencies>false</LinkLibraryDependencies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<OptimizeReferences>true</OptimizeReferences>\r
<EnableCOMDATFolding>true</EnableCOMDATFolding>\r
<TargetMachine>MachineX64</TargetMachine>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
<ClInclude Include="..\mono\dis\util.h" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ProjectReference Include="eglib.vcxproj">\r
+ <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>\r
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
<PrecompiledHeader>\r
</PrecompiledHeader>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
<ClCompile>\r
<Optimization>MinSpace</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>ws2_32.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</Midl>\r
<ClCompile>\r
<Optimization>MinSpace</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\VSDependancies\include\glib-2.0;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\VSDependancies\lib\glib-2.0\include;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>..\;..\eglib\src;..\mono\;..\mono\jit;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
<BufferSecurityCheck>true</BufferSecurityCheck>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
- <ClCompile Include="..\mono\monograph\monograph.c" />\r
<ClCompile Include="..\mono\metadata\opcodes.c" />\r
+ <ClCompile Include="..\tools\monograph\monograph.c" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ProjectReference Include="eglib.vcxproj">\r
+ <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MonoPosixHelper</TargetName>\r
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MonoPosixHelper</TargetName>\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<Link>\r
- <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\r
<ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX86</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Windows</SubSystem>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
- <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
<CompileAs>CompileAsC</CompileAs>\r
</ClCompile>\r
<Link>\r
- <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>\r
<ModuleDefinitionFile>monoposixhelper.def</ModuleDefinitionFile>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
</DataExecutionPrevention>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX86</TargetMachine>\r
</Link>\r
</ItemDefinitionGroup>\r
<SubSystem>Windows</SubSystem>\r
<OptimizeReferences>true</OptimizeReferences>\r
<EnableCOMDATFolding>true</EnableCOMDATFolding>\r
- <ImportLibrary>$(Platform)\lib\$(TargetName).lib</ImportLibrary>\r
+ <ImportLibrary>$(Platform)\lib\$(Configuration)\$(TargetName).lib</ImportLibrary>\r
<TargetMachine>MachineX64</TargetMachine>\r
- <AdditionalDependencies>$(TargetDir)..\lib\eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
<None Include="monoposixhelper.def" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ProjectReference Include="eglib.vcxproj">\r
+ <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+ </ProjectReference>\r
<ProjectReference Include="genmdesc.vcxproj">\r
<Project>{b7098dfa-31e6-4006-8a15-1c9a4e925149}</Project>\r
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
mono_g_hash_table_insert
mono_g_hash_table_lookup
mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
mono_g_hash_table_new_type
mono_g_hash_table_print_stats
mono_g_hash_table_remove
mono_install_assembly_refonly_search_hook
mono_install_assembly_search_hook
mono_install_runtime_cleanup
-mono_install_threadpool_item_hooks
-mono_install_threadpool_thread_hooks
mono_install_unhandled_exception_hook
mono_invoke_unhandled_exception_hook
mono_is_debugger_attached
mono_thread_exit
mono_thread_get_main
mono_thread_get_undeniable_exception
-mono_thread_info_clear_interruption
mono_thread_info_exit
-mono_thread_info_finish_interrupt
mono_thread_info_get_stack_bounds
-mono_thread_info_interrupt
mono_thread_info_open_handle
mono_thread_info_prepare_interrupt
mono_thread_info_self_interrupt
mono_thread_set_manage_callback
mono_thread_stop
mono_threads_attach_tools_thread
-mono_threads_core_clear_interruption
-mono_threads_core_finish_interrupt
-mono_threads_core_prepare_interrupt
-mono_threads_core_self_interrupt
mono_threads_create_thread
mono_threads_get_default_stacksize
mono_threads_request_thread_dump
mono_win32_compat_FillMemory
mono_win32_compat_MoveMemory
mono_win32_compat_ZeroMemory
-mono_xdebug_flush
+++ /dev/null
-; file generated by create-windef.pl
-LIBRARY monosgen-2.0.dll
-EXPORTS
-MonoFixupCorEE
-mono_add_internal_call
-mono_aot_register_globals
-mono_aot_register_module
-mono_array_addr_with_size
-mono_array_class_get
-mono_array_clone
-mono_array_element_size
-mono_array_length
-mono_array_new
-mono_array_new_full
-mono_array_new_specific
-mono_assemblies_cleanup
-mono_assemblies_init
-mono_assembly_close
-mono_assembly_fill_assembly_name
-mono_assembly_foreach
-mono_assembly_get_assemblyref
-mono_assembly_get_image
-mono_assembly_get_main
-mono_assembly_get_object
-mono_assembly_getrootdir
-mono_assembly_invoke_load_hook
-mono_assembly_invoke_search_hook
-mono_assembly_load
-mono_assembly_load_from
-mono_assembly_load_from_full
-mono_assembly_load_full
-mono_assembly_load_module
-mono_assembly_load_reference
-mono_assembly_load_references
-mono_assembly_load_with_partial_name
-mono_assembly_loaded
-mono_assembly_loaded_full
-mono_assembly_name_free
-mono_assembly_name_get_culture
-mono_assembly_name_get_name
-mono_assembly_name_get_pubkeytoken
-mono_assembly_name_get_version
-mono_assembly_name_new
-mono_assembly_names_equal
-mono_assembly_open
-mono_assembly_open_full
-mono_assembly_set_main
-mono_assembly_setrootdir
-mono_binary_search
-mono_bitset_alloc_size
-mono_bitset_clear
-mono_bitset_clear_all
-mono_bitset_clone
-mono_bitset_copyto
-mono_bitset_count
-mono_bitset_equal
-mono_bitset_find_first
-mono_bitset_find_first_unset
-mono_bitset_find_last
-mono_bitset_find_start
-mono_bitset_foreach
-mono_bitset_free
-mono_bitset_intersection
-mono_bitset_intersection_2
-mono_bitset_invert
-mono_bitset_mem_new
-mono_bitset_new
-mono_bitset_set
-mono_bitset_set_all
-mono_bitset_size
-mono_bitset_sub
-mono_bitset_test
-mono_bitset_test_bulk
-mono_bitset_union
-mono_bounded_array_class_get
-mono_breakpoint_clean_code
-mono_check_corlib_version
-mono_class_array_element_size
-mono_class_data_size
-mono_class_describe_statics
-mono_class_enum_basetype
-mono_class_from_generic_parameter
-mono_class_from_mono_type
-mono_class_from_name
-mono_class_from_name_case
-mono_class_from_typeref
-mono_class_get
-mono_class_get_byref_type
-mono_class_get_com_object_class
-mono_class_get_element_class
-mono_class_get_event_token
-mono_class_get_events
-mono_class_get_field
-mono_class_get_field_from_name
-mono_class_get_field_token
-mono_class_get_fields
-mono_class_get_flags
-mono_class_get_full
-mono_class_get_idispatch_class
-mono_class_get_image
-mono_class_get_interfaces
-mono_class_get_interop_proxy_class
-mono_class_get_iunknown_class
-mono_class_get_method_from_name
-mono_class_get_method_from_name_flags
-mono_class_get_methods
-mono_class_get_name
-mono_class_get_namespace
-mono_class_get_nested_types
-mono_class_get_nesting_type
-mono_class_get_parent
-mono_class_get_properties
-mono_class_get_property_from_name
-mono_class_get_property_token
-mono_class_get_rank
-mono_class_get_type
-mono_class_get_type_token
-mono_class_get_variant_class
-mono_class_implements_interface
-mono_class_inflate_generic_method
-mono_class_inflate_generic_type
-mono_class_init
-mono_class_instance_size
-mono_class_interface_offset
-mono_class_is_assignable_from
-mono_class_is_delegate
-mono_class_is_enum
-mono_class_is_subclass_of
-mono_class_is_valid_enum
-mono_class_is_valuetype
-mono_class_min_align
-mono_class_name_from_token
-mono_class_num_events
-mono_class_num_fields
-mono_class_num_methods
-mono_class_num_properties
-mono_class_value_size
-mono_class_vtable
-mono_cli_rva_image_map
-mono_code_manager_cleanup
-mono_code_manager_commit
-mono_code_manager_destroy
-mono_code_manager_foreach
-mono_code_manager_init
-mono_code_manager_invalidate
-mono_code_manager_new
-mono_code_manager_new_dynamic
-mono_code_manager_reserve
-mono_code_manager_reserve_align
-mono_code_manager_set_read_only
-mono_code_manager_size
-mono_compile_method
-mono_config_cleanup
-mono_config_for_assembly
-mono_config_is_server_mode
-mono_config_parse
-mono_config_parse_memory
-mono_config_set_server_mode
-mono_config_string_for_assembly_file
-mono_context_get
-mono_context_get_desc
-mono_context_init
-mono_context_set
-mono_counters_cleanup
-mono_counters_dump
-mono_counters_enable
-mono_counters_register
-mono_custom_attrs_construct
-mono_custom_attrs_free
-mono_custom_attrs_from_assembly
-mono_custom_attrs_from_class
-mono_custom_attrs_from_event
-mono_custom_attrs_from_field
-mono_custom_attrs_from_index
-mono_custom_attrs_from_method
-mono_custom_attrs_from_param
-mono_custom_attrs_from_property
-mono_custom_attrs_get_attr
-mono_custom_attrs_has_attr
-mono_debug_add_delegate_trampoline
-mono_debug_add_method
-mono_debug_cleanup
-mono_debug_close_image
-mono_debug_close_mono_symbol_file
-mono_debug_domain_create
-mono_debug_domain_unload
-mono_debug_enabled
-mono_debug_find_method
-mono_debug_free_method_jit_info
-mono_debug_free_source_location
-mono_debug_il_offset_from_address
-mono_debug_init
-mono_debug_list_add
-mono_debug_list_remove
-mono_debug_lookup_locals
-mono_debug_lookup_method
-mono_debug_lookup_method_addresses
-mono_debug_lookup_source_location
-mono_debug_open_image_from_memory
-mono_debug_open_mono_symbols
-mono_debug_print_stack_frame
-mono_debug_print_vars
-mono_debug_remove_method
-mono_debug_symfile_free_locals
-mono_debug_symfile_free_location
-mono_debug_symfile_get_line_numbers
-mono_debug_symfile_get_line_numbers_full
-mono_debug_symfile_is_loaded
-mono_debug_symfile_lookup_locals
-mono_debug_symfile_lookup_location
-mono_debug_symfile_lookup_method
-mono_debugger_insert_breakpoint
-mono_debugger_method_has_breakpoint
-mono_debugger_run_finally
-mono_declsec_flags_from_assembly
-mono_declsec_flags_from_class
-mono_declsec_flags_from_method
-mono_declsec_get_assembly_action
-mono_declsec_get_class_action
-mono_declsec_get_demands
-mono_declsec_get_inheritdemands_class
-mono_declsec_get_inheritdemands_method
-mono_declsec_get_linkdemands
-mono_declsec_get_method_action
-mono_digest_get_public_token
-mono_disasm_code
-mono_disasm_code_one
-mono_dl_fallback_register
-mono_dl_fallback_unregister
-mono_dllmap_insert
-mono_domain_add_class_static_data
-mono_domain_assembly_open
-mono_domain_create
-mono_domain_create_appdomain
-mono_domain_finalize
-mono_domain_foreach
-mono_domain_free
-mono_domain_from_appdomain
-mono_domain_get
-mono_domain_get_by_id
-mono_domain_get_id
-mono_domain_has_type_resolve
-mono_domain_is_unloading
-mono_domain_owns_vtable_slot
-mono_domain_set
-mono_domain_set_config
-mono_domain_set_internal
-mono_domain_try_type_resolve
-mono_domain_try_unload
-mono_domain_unload
-mono_dwarf_escape_path
-mono_emit_native_call
-mono_environment_exitcode_get
-mono_environment_exitcode_set
-mono_error_cleanup
-mono_error_get_error_code
-mono_error_get_message
-mono_error_init
-mono_error_init_flags
-mono_error_ok
-mono_escape_uri_string
-mono_event_get_add_method
-mono_event_get_flags
-mono_event_get_name
-mono_event_get_object
-mono_event_get_parent
-mono_event_get_raise_method
-mono_event_get_remove_method
-mono_exception_from_name
-mono_exception_from_name_domain
-mono_exception_from_name_msg
-mono_exception_from_name_two_strings
-mono_exception_from_token
-mono_exception_from_token_two_strings
-mono_exception_walk_trace
-mono_field_from_token
-mono_field_full_name
-mono_field_get_data
-mono_field_get_flags
-mono_field_get_name
-mono_field_get_object
-mono_field_get_offset
-mono_field_get_parent
-mono_field_get_type
-mono_field_get_value
-mono_field_get_value_object
-mono_field_set_value
-mono_field_static_get_value
-mono_field_static_set_value
-mono_file_map
-mono_file_map_close
-mono_file_map_fd
-mono_file_map_open
-mono_file_map_size
-mono_file_unmap
-mono_free
-mono_free_bstr
-mono_free_method
-mono_free_verify_list
-mono_g_hash_table_destroy
-mono_g_hash_table_find
-mono_g_hash_table_foreach
-mono_g_hash_table_foreach_remove
-mono_g_hash_table_insert
-mono_g_hash_table_lookup
-mono_g_hash_table_lookup_extended
-mono_g_hash_table_new
-mono_g_hash_table_new_full
-mono_g_hash_table_new_type
-mono_g_hash_table_print_stats
-mono_g_hash_table_remove
-mono_g_hash_table_replace
-mono_g_hash_table_size
-mono_gc_collect
-mono_gc_collection_count
-mono_gc_get_generation
-mono_gc_get_heap_size
-mono_gc_get_used_size
-mono_gc_invoke_finalizers
-mono_gc_max_generation
-mono_gc_reference_queue_add
-mono_gc_reference_queue_free
-mono_gc_reference_queue_new
-mono_gc_toggleref_add
-mono_gc_toggleref_register_callback
-mono_gc_walk_heap
-mono_gc_wbarrier_arrayref_copy
-mono_gc_wbarrier_generic_nostore
-mono_gc_wbarrier_generic_store
-mono_gc_wbarrier_generic_store_atomic
-mono_gc_wbarrier_object_copy
-mono_gc_wbarrier_set_arrayref
-mono_gc_wbarrier_set_field
-mono_gc_wbarrier_value_copy
-mono_gchandle_free
-mono_gchandle_get_target
-mono_gchandle_new
-mono_gchandle_new_weakref
-mono_get_array_class
-mono_get_boolean_class
-mono_get_byte_class
-mono_get_char_class
-mono_get_config_dir
-mono_get_corlib
-mono_get_dbnull_object
-mono_get_delegate_begin_invoke
-mono_get_delegate_end_invoke
-mono_get_delegate_invoke
-mono_get_double_class
-mono_get_enum_class
-mono_get_exception_appdomain_unloaded
-mono_get_exception_argument
-mono_get_exception_argument_null
-mono_get_exception_argument_out_of_range
-mono_get_exception_arithmetic
-mono_get_exception_array_type_mismatch
-mono_get_exception_bad_image_format
-mono_get_exception_bad_image_format2
-mono_get_exception_cannot_unload_appdomain
-mono_get_exception_class
-mono_get_exception_divide_by_zero
-mono_get_exception_execution_engine
-mono_get_exception_field_access
-mono_get_exception_file_not_found
-mono_get_exception_file_not_found2
-mono_get_exception_index_out_of_range
-mono_get_exception_invalid_cast
-mono_get_exception_invalid_operation
-mono_get_exception_io
-mono_get_exception_method_access
-mono_get_exception_missing_field
-mono_get_exception_missing_method
-mono_get_exception_not_implemented
-mono_get_exception_not_supported
-mono_get_exception_null_reference
-mono_get_exception_out_of_memory
-mono_get_exception_overflow
-mono_get_exception_reflection_type_load
-mono_get_exception_runtime_wrapped
-mono_get_exception_security
-mono_get_exception_serialization
-mono_get_exception_stack_overflow
-mono_get_exception_synchronization_lock
-mono_get_exception_thread_abort
-mono_get_exception_thread_interrupted
-mono_get_exception_thread_state
-mono_get_exception_type_initialization
-mono_get_exception_type_load
-mono_get_inflated_method
-mono_get_int16_class
-mono_get_int32_class
-mono_get_int64_class
-mono_get_intptr_class
-mono_get_machine_config
-mono_get_method
-mono_get_method_constrained
-mono_get_method_full
-mono_get_object_class
-mono_get_root_domain
-mono_get_runtime_build_info
-mono_get_sbyte_class
-mono_get_single_class
-mono_get_string_class
-mono_get_thread_class
-mono_get_trampoline_func
-mono_get_uint16_class
-mono_get_uint32_class
-mono_get_uint64_class
-mono_get_uintptr_class
-mono_get_void_class
-mono_guid_to_string
-mono_image_add_to_name_cache
-mono_image_addref
-mono_image_close
-mono_image_ensure_section
-mono_image_ensure_section_idx
-mono_image_fixup_vtable
-mono_image_get_assembly
-mono_image_get_entry_point
-mono_image_get_filename
-mono_image_get_guid
-mono_image_get_name
-mono_image_get_public_key
-mono_image_get_resource
-mono_image_get_strong_name
-mono_image_get_table_info
-mono_image_get_table_rows
-mono_image_has_authenticode_entry
-mono_image_init
-mono_image_init_name_cache
-mono_image_is_dynamic
-mono_image_load_file_for_image
-mono_image_load_module
-mono_image_loaded
-mono_image_loaded_by_guid
-mono_image_loaded_by_guid_full
-mono_image_loaded_full
-mono_image_lookup_resource
-mono_image_open
-mono_image_open_from_data
-mono_image_open_from_data_full
-mono_image_open_from_data_with_name
-mono_image_open_full
-mono_image_rva_map
-mono_image_strerror
-mono_image_strong_name_position
-mono_images_cleanup
-mono_images_init
-mono_init
-mono_init_from_assembly
-mono_init_version
-mono_inst_name
-mono_install_assembly_load_hook
-mono_install_assembly_postload_refonly_search_hook
-mono_install_assembly_postload_search_hook
-mono_install_assembly_preload_hook
-mono_install_assembly_refonly_preload_hook
-mono_install_assembly_refonly_search_hook
-mono_install_assembly_search_hook
-mono_install_runtime_cleanup
-mono_install_threadpool_item_hooks
-mono_install_threadpool_thread_hooks
-mono_install_unhandled_exception_hook
-mono_invoke_unhandled_exception_hook
-mono_is_debugger_attached
-mono_jit_cleanup
-mono_jit_exec
-mono_jit_info_get_code_size
-mono_jit_info_get_code_start
-mono_jit_info_get_method
-mono_jit_info_table_find
-mono_jit_init
-mono_jit_init_version
-mono_jit_parse_options
-mono_jit_set_aot_only
-mono_jit_set_domain
-mono_jit_set_trace_options
-mono_jit_thread_attach
-mono_ldstr
-mono_ldtoken
-mono_lls_init
-mono_load_remote_field
-mono_load_remote_field_new
-mono_local_deadce
-mono_locks_dump
-mono_lookup_icall_symbol
-mono_lookup_internal_call
-mono_lookup_pinvoke_call
-mono_main
-mono_marshal_string_to_utf16
-mono_md5_final
-mono_md5_get_digest
-mono_md5_get_digest_from_file
-mono_md5_init
-mono_md5_update
-mono_mempool_alloc
-mono_mempool_alloc0
-mono_mempool_contains_addr
-mono_mempool_destroy
-mono_mempool_empty
-mono_mempool_get_allocated
-mono_mempool_invalidate
-mono_mempool_new
-mono_mempool_new_size
-mono_mempool_stats
-mono_mempool_strdup
-mono_metadata_blob_heap
-mono_metadata_cleanup
-mono_metadata_compute_size
-mono_metadata_custom_attrs_from_index
-mono_metadata_declsec_from_index
-mono_metadata_decode_blob_size
-mono_metadata_decode_row
-mono_metadata_decode_row_col
-mono_metadata_decode_signed_value
-mono_metadata_decode_table_row
-mono_metadata_decode_table_row_col
-mono_metadata_decode_value
-mono_metadata_encode_value
-mono_metadata_events_from_typedef
-mono_metadata_field_info
-mono_metadata_field_info_with_mempool
-mono_metadata_free_array
-mono_metadata_free_inflated_signature
-mono_metadata_free_marshal_spec
-mono_metadata_free_method_signature
-mono_metadata_free_mh
-mono_metadata_free_type
-mono_metadata_generic_class_is_valuetype
-mono_metadata_get_constant_index
-mono_metadata_get_generic_param_row
-mono_metadata_get_inflated_signature
-mono_metadata_get_marshal_info
-mono_metadata_guid_heap
-mono_metadata_implmap_from_method
-mono_metadata_init
-mono_metadata_interfaces_from_typedef
-mono_metadata_load_generic_param_constraints
-mono_metadata_load_generic_params
-mono_metadata_locate
-mono_metadata_locate_token
-mono_metadata_methods_from_event
-mono_metadata_methods_from_property
-mono_metadata_nested_in_typedef
-mono_metadata_nesting_typedef
-mono_metadata_packing_from_typedef
-mono_metadata_parse_array
-mono_metadata_parse_custom_mod
-mono_metadata_parse_field_type
-mono_metadata_parse_marshal_spec
-mono_metadata_parse_method_signature
-mono_metadata_parse_method_signature_full
-mono_metadata_parse_mh
-mono_metadata_parse_mh_full
-mono_metadata_parse_param
-mono_metadata_parse_signature
-mono_metadata_parse_type
-mono_metadata_parse_type_full
-mono_metadata_parse_typedef_or_ref
-mono_metadata_properties_from_typedef
-mono_metadata_signature_alloc
-mono_metadata_signature_dup
-mono_metadata_signature_equal
-mono_metadata_string_heap
-mono_metadata_token_from_dor
-mono_metadata_translate_token_index
-mono_metadata_type_equal
-mono_metadata_type_hash
-mono_metadata_typedef_from_field
-mono_metadata_typedef_from_method
-mono_metadata_user_string
-mono_method_body_get_object
-mono_method_can_access_field
-mono_method_can_access_method
-mono_method_desc_free
-mono_method_desc_from_method
-mono_method_desc_full_match
-mono_method_desc_match
-mono_method_desc_new
-mono_method_desc_search_in_class
-mono_method_desc_search_in_image
-mono_method_full_name
-mono_method_get_class
-mono_method_get_flags
-mono_method_get_generic_container
-mono_method_get_header
-mono_method_get_index
-mono_method_get_last_managed
-mono_method_get_marshal_info
-mono_method_get_name
-mono_method_get_object
-mono_method_get_param_names
-mono_method_get_param_token
-mono_method_get_signature
-mono_method_get_signature_full
-mono_method_get_token
-mono_method_get_unmanaged_thunk
-mono_method_has_marshal_info
-mono_method_header_get_clauses
-mono_method_header_get_code
-mono_method_header_get_locals
-mono_method_header_get_num_clauses
-mono_method_signature
-mono_method_verify
-mono_mlist_alloc
-mono_mlist_append
-mono_mlist_get_data
-mono_mlist_last
-mono_mlist_length
-mono_mlist_next
-mono_mlist_prepend
-mono_mlist_remove_item
-mono_mlist_set_data
-mono_mlist_set_next
-mono_module_file_get_object
-mono_module_get_object
-mono_monitor_enter
-mono_monitor_exit
-mono_monitor_try_enter
-mono_mprotect
-mono_mutex_init_suspend_safe
-mono_object_castclass_mbyref
-mono_object_castclass_with_cache
-mono_object_clone
-mono_object_describe
-mono_object_describe_fields
-mono_object_get_class
-mono_object_get_domain
-mono_object_get_size
-mono_object_get_virtual_method
-mono_object_hash
-mono_object_isinst
-mono_object_isinst_mbyref
-mono_object_isinst_with_cache
-mono_object_new
-mono_object_new_alloc_specific
-mono_object_new_fast
-mono_object_new_from_token
-mono_object_new_specific
-mono_object_to_string
-mono_object_unbox
-mono_op_to_op_imm_noemul
-mono_opcode_name
-mono_opcode_value
-mono_pagesize
-mono_param_get_objects
-mono_parse_default_optimizations
-mono_path_canonicalize
-mono_path_resolve_symlinks
-mono_pe_file_open
-mono_perfcounters_init
-mono_pmip
-mono_poll
-mono_print_method_from_ip
-mono_print_thread_dump
-mono_print_thread_dump_from_ctx
-mono_print_unhandled_exception
-mono_profiler_coverage_get
-mono_profiler_get_events
-mono_profiler_install
-mono_profiler_install_allocation
-mono_profiler_install_appdomain
-mono_profiler_install_assembly
-mono_profiler_install_class
-mono_profiler_install_code_buffer_new
-mono_profiler_install_code_chunk_destroy
-mono_profiler_install_code_chunk_new
-mono_profiler_install_coverage_filter
-mono_profiler_install_enter_leave
-mono_profiler_install_exception
-mono_profiler_install_gc
-mono_profiler_install_gc_moves
-mono_profiler_install_gc_roots
-mono_profiler_install_iomap
-mono_profiler_install_jit_compile
-mono_profiler_install_jit_end
-mono_profiler_install_method_free
-mono_profiler_install_method_invoke
-mono_profiler_install_module
-mono_profiler_install_monitor
-mono_profiler_install_runtime_initialized
-mono_profiler_install_statistical
-mono_profiler_install_statistical_call_chain
-mono_profiler_install_thread
-mono_profiler_install_thread_name
-mono_profiler_install_transition
-mono_profiler_load
-mono_profiler_set_events
-mono_property_get_flags
-mono_property_get_get_method
-mono_property_get_name
-mono_property_get_object
-mono_property_get_parent
-mono_property_get_set_method
-mono_property_get_value
-mono_property_hash_destroy
-mono_property_hash_insert
-mono_property_hash_lookup
-mono_property_hash_new
-mono_property_hash_remove_object
-mono_property_set_value
-mono_ptr_class_get
-mono_raise_exception
-mono_realloc_native_code
-mono_reflection_free_type_info
-mono_reflection_get_custom_attrs
-mono_reflection_get_custom_attrs_blob
-mono_reflection_get_custom_attrs_by_type
-mono_reflection_get_custom_attrs_data
-mono_reflection_get_custom_attrs_info
-mono_reflection_get_token
-mono_reflection_get_type
-mono_reflection_parse_type
-mono_reflection_type_from_name
-mono_reflection_type_get_type
-mono_register_bundled_assemblies
-mono_register_config_for_assembly
-mono_register_machine_config
-mono_register_symfile_for_assembly
-mono_replace_ins
-mono_runtime_class_init
-mono_runtime_cleanup
-mono_runtime_delegate_invoke
-mono_runtime_exec_main
-mono_runtime_exec_managed_code
-mono_runtime_get_main_args
-mono_runtime_init
-mono_runtime_invoke
-mono_runtime_invoke_array
-mono_runtime_is_shutting_down
-mono_runtime_object_init
-mono_runtime_quit
-mono_runtime_resource_check_limit
-mono_runtime_resource_limit
-mono_runtime_resource_set_callback
-mono_runtime_run_main
-mono_runtime_set_shutting_down
-mono_security_core_clr_get_options
-mono_security_core_clr_require_elevated_permissions
-mono_security_core_clr_set_options
-mono_security_enable_core_clr
-mono_security_set_core_clr_platform_callback
-mono_sem_post
-mono_sem_timedwait
-mono_sem_wait
-mono_set_assemblies_path
-mono_set_break_policy
-mono_set_config_dir
-mono_set_defaults
-mono_set_dirs
-mono_set_is_debugger_attached
-mono_set_rootdir
-mono_set_signal_chaining
-mono_sha1_final
-mono_sha1_get_digest
-mono_sha1_get_digest_from_file
-mono_sha1_init
-mono_sha1_update
-mono_shared_area
-mono_shared_area_for_pid
-mono_shared_area_instances
-mono_shared_area_remove
-mono_shared_area_unload
-mono_signature_explicit_this
-mono_signature_get_call_conv
-mono_signature_get_desc
-mono_signature_get_param_count
-mono_signature_get_params
-mono_signature_get_return_type
-mono_signature_hash
-mono_signature_is_instance
-mono_signature_param_is_out
-mono_signature_vararg_start
-mono_signbit_double
-mono_signbit_float
-mono_stack_walk
-mono_stack_walk_no_il
-mono_store_remote_field
-mono_store_remote_field_new
-mono_string_chars
-mono_string_equal
-mono_string_from_bstr
-mono_string_from_utf16
-mono_string_hash
-mono_string_intern
-mono_string_is_interned
-mono_string_length
-mono_string_new
-mono_string_new_len
-mono_string_new_size
-mono_string_new_utf16
-mono_string_new_wrapper
-mono_string_to_utf16
-mono_string_to_utf8
-mono_string_to_utf8_checked
-mono_stringify_assembly_name
-mono_table_info_get_rows
-mono_thread_attach
-mono_thread_cleanup
-mono_thread_create
-mono_thread_current
-mono_thread_detach
-mono_thread_exit
-mono_thread_get_main
-mono_thread_get_undeniable_exception
-mono_thread_init
-mono_thread_is_foreign
-mono_thread_manage
-mono_thread_new_init
-mono_thread_set_main
-mono_thread_set_manage_callback
-mono_thread_stop
-mono_threads_get_default_stacksize
-mono_threads_request_thread_dump
-mono_threads_set_default_stacksize
-mono_tls_key_get_offset
-mono_tls_key_set_offset
-mono_trace_set_level_string
-mono_trace_set_mask_string
-mono_type_create_from_typespec
-mono_type_full_name
-mono_type_generic_inst_is_valuetype
-mono_type_get_array_type
-mono_type_get_class
-mono_type_get_desc
-mono_type_get_modifiers
-mono_type_get_name
-mono_type_get_object
-mono_type_get_ptr_type
-mono_type_get_signature
-mono_type_get_type
-mono_type_get_underlying_type
-mono_type_is_byref
-mono_type_is_pointer
-mono_type_is_reference
-mono_type_is_struct
-mono_type_is_valid_enum_basetype
-mono_type_is_void
-mono_type_size
-mono_type_stack_size
-mono_type_to_unmanaged
-mono_unhandled_exception
-mono_unicode_from_external
-mono_unicode_to_external
-mono_upgrade_remote_class_wrapper
-mono_utf8_from_external
-mono_utf8_validate_and_len
-mono_utf8_validate_and_len_with_bounds
-mono_valloc
-mono_valloc_aligned
-mono_value_box
-mono_value_copy
-mono_value_copy_array
-mono_value_describe_fields
-mono_verify_corlib
-mono_vfree
-mono_vtable_get_static_field_data
-mono_win32_compat_CopyMemory
-mono_win32_compat_FillMemory
-mono_win32_compat_MoveMemory
-mono_win32_compat_ZeroMemory
-mono_xdebug_flush
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\libgc\include;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;GC_NOT_DLL;GC_GCJ_SUPPORT;GC_WIN32_THREADS;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libgc.lib;mono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\;..\libgc\include;..\VSDependancies\include\glib-2.0\glib;..\VSDependancies\include;..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WINDOWS;__WIN32__;HOST_WIN32;TARGET_WIN32;__i386__;TARGET_X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src\;$(SolutionDir)..\;$(SolutionDir)..\mono\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;ws2_32.lib;gthread-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Psapi.lib;Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</Link>\r
</ItemDefinitionGroup>\r
<ItemGroup>\r
- <ClCompile Include="..\mono\utils\strtod.c" />\r
<ClCompile Include="..\mono\metadata\appdomain.c" />\r
<ClCompile Include="..\mono\metadata\assembly.c" />\r
<ClCompile Include="..\mono\metadata\boehm-gc.c" />\r
<ClCompile Include="..\mono\metadata\class.c" />\r
<ClCompile Include="..\mono\metadata\console-win32.c" />\r
- <ClCompile Include="..\mono\metadata\decimal.c" />\r
<ClCompile Include="..\mono\metadata\domain.c" />\r
<ClCompile Include="..\mono\metadata\environment.c" />\r
<ClCompile Include="..\mono\metadata\file-io.c" />\r
<ClCompile Include="..\mono\metadata\process.c" />\r
<ClCompile Include="..\mono\metadata\profiler.c" />\r
<ClCompile Include="..\mono\metadata\rand.c" />\r
- <ClCompile Include="..\mono\metadata\rawbuffer.c" />\r
<ClCompile Include="..\mono\metadata\reflection.c" />\r
<ClCompile Include="..\mono\metadata\security-manager.c" />\r
- <ClCompile Include="..\mono\metadata\security.c" />\r
<ClCompile Include="..\mono\metadata\socket-io.c" />\r
<ClCompile Include="..\mono\metadata\string-icalls.c" />\r
<ClCompile Include="..\mono\metadata\sysmath.c" />\r
- <ClCompile Include="..\mono\metadata\threadpool.c" />\r
<ClCompile Include="..\mono\metadata\threads.c" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <ProjectReference Include="eglib.vcxproj">\r
+ <Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
+ <ProjectReference Include="libgc.vcxproj">\r
+ <Project>{eb56000b-c80b-4e8b-908d-d84d31b517d3}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
- <ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
+ <ProjectReference Include="libmonoruntime.vcxproj">\r
+ <Project>{c36612bd-22d3-4b95-85e2-7fdc4fc5d739}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
+ </ProjectReference>\r
+ <ProjectReference Include="libmonoutils.vcxproj">\r
+ <Project>{8fc2b0c8-51ad-49df-851f-5d01a77a75e4}</Project>\r
+ <Private>false</Private>\r
+ <ReferenceOutputAssembly>true</ReferenceOutputAssembly>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\include;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\include;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\eglib\src;$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<OptimizeReferences>false</OptimizeReferences>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<RandomizedBaseAddress>false</RandomizedBaseAddress>\r
<DataExecutionPrevention>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<OptimizeReferences>false</OptimizeReferences>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>Ws2_32.lib;Psapi.lib;eglib.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>Ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<TargetMachine>MachineX64</TargetMachine>\r
</Link>\r
<ProjectReference Include="eglib.vcxproj">\r
<Project>{158073ed-99ae-4196-9edc-ddb2344f8466}</Project>\r
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
<PropertyGroup Label="UserMacros" />\r
<PropertyGroup>\r
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/bin\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)_$(Configuration)/obj/$(ProjectName)\</IntDir>\r
+ <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\bin\$(Configuration)\</OutDir>\r
+ <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Platform)\obj\$(ProjectName)\$(Configuration)\</IntDir>\r
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
</PropertyGroup>\r
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</ProjectReference>\r
<Link>\r
- <AdditionalDependencies>glib-2.0.lib;gmodule-2.0.lib;ws2_32.lib;gthread-2.0.lib;gobject-2.0.lib;libmono.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ <AdditionalDependencies>ws2_32.lib;Psapi.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
<AdditionalLibraryDirectories>$(Platform)_$(Configuration)/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
<GenerateDebugInformation>true</GenerateDebugInformation>\r
<SubSystem>Console</SubSystem>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
</Midl>\r
<ClCompile>\r
<Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>..\..\..\libgc\include;..\..\VSDependancies\include\glib-2.0;..\..\VSDependancies\include\glib-2.0\glib;..\..\VSDependancies\lib\glib-2.0\include;..\..\VSDependancies\include;..\..\;C:\cygwin\opt\mono\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
<MinimalRebuild>true</MinimalRebuild>\r
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
</PrecompiledHeader>\r
<WarningLevel>Level3</WarningLevel>\r
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
</ClCompile>\r
<ProjectReference>\r
<LinkLibraryDependencies>false</LinkLibraryDependencies>\r
<ProjectReference Include="libmono.vcxproj">\r
<Project>{cb0d9e92-293c-439c-9ac7-c5f59b6e0771}</Project>\r
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>\r
+ <Private>false</Private>\r
+ <CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>\r
+ <LinkLibraryDependencies>true</LinkLibraryDependencies>\r
+ <UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>\r
</ProjectReference>\r
</ItemGroup>\r
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
endif
if INSTALL_MONOTOUCH
-build_profiles += monotouch monotouch_runtime monotouch_watch
+build_profiles += monotouch monotouch_runtime
+endif
+
+if INSTALL_MONOTOUCH_WATCH
+build_profiles += monotouch_watch
endif
if INSTALL_XAMMAC
# Only include files with /gac/ in path
# (Allows packages to contain private assemblies that don't conflict with other packages)
-#monolist=($(printf "%s\n" "${monolist[@]}" | egrep "/gac/"))
+monolist=($(printf "%s\n" "${monolist[@]}" | egrep "/gac/"))
# Disabled... see ChangeLog
# Set the prefix, unless it is overriden (used when building mono rpms)
serial.c \
sys-mman.c \
sys-sendfile.c \
+ sys-socket.c \
sys-stat.c \
sys-statvfs.c \
sys-time.c \
--impl-macro=_GNU_SOURCE --impl-macro=_XOPEN_SOURCE \
--impl-header="<sys/types.h>" \
--impl-header="<sys/stat.h>" \
+ --autoconf-header="<netinet/in.h>" \
--autoconf-header="<sys/time.h>" \
--autoconf-header="<sys/poll.h>" \
--autoconf-header="<sys/wait.h>" \
--autoconf-header="<sys/statvfs.h>" \
--autoconf-header="<sys/xattr.h>" \
--autoconf-header="<sys/mman.h>" \
+ --autoconf-header="<sys/socket.h>" \
--autoconf-header="<sys/uio.h>" \
--autoconf-header="<unistd.h>" \
--impl-header="<fcntl.h>" \
--rename-member=st_mtime=st_mtime_ \
--rename-namespace=Mono.Unix.Native=Mono.Posix \
--library=MonoPosixHelper \
- $(mcs_topdir)/class/lib/net_4_5/Mono.Posix.dll map
+ $(mcs_topdir)/class/lib/net_4_x/Mono.Posix.dll map
# Useful if mono is compiled with --enable-shared=no
patch-libtool:
* we assume that the XPG version is present.
*/
-#ifdef _GNU_SOURCE
+#ifdef _GNU_SOURCE && !PLATFORM_ANDROID
#define mph_min(x,y) ((x) <= (y) ? (x) : (y))
/* If you pass an invalid errno value to glibc 2.3.2's strerror_r, you get
mph_return_if_size_t_overflow (n);
/* first, check for valid errnum */
+#if PLATFORM_ANDROID
+ /* Android NDK defines _GNU_SOURCE but strerror_r follows the XSI semantics
+ * not the GNU one. XSI version returns an integer, as opposed to the GNU one
+ * which returns pointer to the buffer.
+ */
+ if (strerror_r (errnum, ebuf, sizeof(ebuf)) == -1) {
+ /* XSI strerror_r will return -1 if errno is set, but if we leave the value
+ * alone it breaks Mono.Posix StdioFileStream tests, so we'll ignore the value
+ * and set errno as below
+ */
+ errno = EINVAL;
+ return -1;
+ }
+ r = ebuf;
+#else
r = strerror_r (errnum, ebuf, sizeof(ebuf));
+#endif
+ if (!r) {
+ errno = EINVAL;
+ return -1;
+ }
len = strlen (r);
if (r == ebuf ||
/*
- * This file was automatically generated by create-native-map from /cvs/mono/mcs/class/lib/net_4_5/Mono.Posix.dll.
+ * This file was automatically generated by create-native-map from /home/kiesssn/prog/mono/mono/mcs/class/lib/net_4_x/Mono.Posix.dll.
*
* DO NOT MODIFY.
*/
*/
#include <sys/types.h>
#include <sys/stat.h>
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif /* ndef HAVE_NETINET_IN_H */
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#endif /* ndef HAVE_SYS_TIME_H */
#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#endif /* ndef HAVE_SYS_MMAN_H */
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif /* ndef HAVE_SYS_SOCKET_H */
#ifdef HAVE_SYS_UIO_H
#include <sys/uio.h>
#endif /* ndef HAVE_SYS_UIO_H */
#endif /* ndef HAVE_STRUCT_IOVEC */
+#ifdef HAVE_STRUCT_LINGER
+int
+Mono_Posix_FromLinger (struct Mono_Posix_Linger *from, struct linger *to)
+{
+ _cnm_return_val_if_overflow (int, from->l_onoff, -1);
+ _cnm_return_val_if_overflow (int, from->l_linger, -1);
+
+ memset (to, 0, sizeof(*to));
+
+ to->l_onoff = from->l_onoff;
+ to->l_linger = from->l_linger;
+
+ return 0;
+}
+#endif /* ndef HAVE_STRUCT_LINGER */
+
+
+#ifdef HAVE_STRUCT_LINGER
+int
+Mono_Posix_ToLinger (struct linger *from, struct Mono_Posix_Linger *to)
+{
+ _cnm_return_val_if_overflow (int, from->l_onoff, -1);
+ _cnm_return_val_if_overflow (int, from->l_linger, -1);
+
+ memset (to, 0, sizeof(*to));
+
+ to->l_onoff = from->l_onoff;
+ to->l_linger = from->l_linger;
+
+ return 0;
+}
+#endif /* ndef HAVE_STRUCT_LINGER */
+
+
int Mono_Posix_FromLockType (short x, short *r)
{
*r = 0;
errno = EINVAL; return -1;
}
+int Mono_Posix_FromMessageFlags (int x, int *r)
+{
+ *r = 0;
+ if ((x & Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC) == Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC)
+#ifdef MSG_CMSG_CLOEXEC
+ *r |= MSG_CMSG_CLOEXEC;
+#else /* def MSG_CMSG_CLOEXEC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CMSG_CLOEXEC */
+ if ((x & Mono_Posix_MessageFlags_MSG_CONFIRM) == Mono_Posix_MessageFlags_MSG_CONFIRM)
+#ifdef MSG_CONFIRM
+ *r |= MSG_CONFIRM;
+#else /* def MSG_CONFIRM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CONFIRM */
+ if ((x & Mono_Posix_MessageFlags_MSG_CTRUNC) == Mono_Posix_MessageFlags_MSG_CTRUNC)
+#ifdef MSG_CTRUNC
+ *r |= MSG_CTRUNC;
+#else /* def MSG_CTRUNC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_CTRUNC */
+ if ((x & Mono_Posix_MessageFlags_MSG_DONTROUTE) == Mono_Posix_MessageFlags_MSG_DONTROUTE)
+#ifdef MSG_DONTROUTE
+ *r |= MSG_DONTROUTE;
+#else /* def MSG_DONTROUTE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_DONTROUTE */
+ if ((x & Mono_Posix_MessageFlags_MSG_DONTWAIT) == Mono_Posix_MessageFlags_MSG_DONTWAIT)
+#ifdef MSG_DONTWAIT
+ *r |= MSG_DONTWAIT;
+#else /* def MSG_DONTWAIT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_DONTWAIT */
+ if ((x & Mono_Posix_MessageFlags_MSG_EOR) == Mono_Posix_MessageFlags_MSG_EOR)
+#ifdef MSG_EOR
+ *r |= MSG_EOR;
+#else /* def MSG_EOR */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_EOR */
+ if ((x & Mono_Posix_MessageFlags_MSG_ERRQUEUE) == Mono_Posix_MessageFlags_MSG_ERRQUEUE)
+#ifdef MSG_ERRQUEUE
+ *r |= MSG_ERRQUEUE;
+#else /* def MSG_ERRQUEUE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_ERRQUEUE */
+ if ((x & Mono_Posix_MessageFlags_MSG_FASTOPEN) == Mono_Posix_MessageFlags_MSG_FASTOPEN)
+#ifdef MSG_FASTOPEN
+ *r |= MSG_FASTOPEN;
+#else /* def MSG_FASTOPEN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_FASTOPEN */
+ if ((x & Mono_Posix_MessageFlags_MSG_FIN) == Mono_Posix_MessageFlags_MSG_FIN)
+#ifdef MSG_FIN
+ *r |= MSG_FIN;
+#else /* def MSG_FIN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_FIN */
+ if ((x & Mono_Posix_MessageFlags_MSG_MORE) == Mono_Posix_MessageFlags_MSG_MORE)
+#ifdef MSG_MORE
+ *r |= MSG_MORE;
+#else /* def MSG_MORE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_MORE */
+ if ((x & Mono_Posix_MessageFlags_MSG_NOSIGNAL) == Mono_Posix_MessageFlags_MSG_NOSIGNAL)
+#ifdef MSG_NOSIGNAL
+ *r |= MSG_NOSIGNAL;
+#else /* def MSG_NOSIGNAL */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_NOSIGNAL */
+ if ((x & Mono_Posix_MessageFlags_MSG_OOB) == Mono_Posix_MessageFlags_MSG_OOB)
+#ifdef MSG_OOB
+ *r |= MSG_OOB;
+#else /* def MSG_OOB */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_OOB */
+ if ((x & Mono_Posix_MessageFlags_MSG_PEEK) == Mono_Posix_MessageFlags_MSG_PEEK)
+#ifdef MSG_PEEK
+ *r |= MSG_PEEK;
+#else /* def MSG_PEEK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_PEEK */
+ if ((x & Mono_Posix_MessageFlags_MSG_PROXY) == Mono_Posix_MessageFlags_MSG_PROXY)
+#ifdef MSG_PROXY
+ *r |= MSG_PROXY;
+#else /* def MSG_PROXY */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_PROXY */
+ if ((x & Mono_Posix_MessageFlags_MSG_RST) == Mono_Posix_MessageFlags_MSG_RST)
+#ifdef MSG_RST
+ *r |= MSG_RST;
+#else /* def MSG_RST */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_RST */
+ if ((x & Mono_Posix_MessageFlags_MSG_SYN) == Mono_Posix_MessageFlags_MSG_SYN)
+#ifdef MSG_SYN
+ *r |= MSG_SYN;
+#else /* def MSG_SYN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_SYN */
+ if ((x & Mono_Posix_MessageFlags_MSG_TRUNC) == Mono_Posix_MessageFlags_MSG_TRUNC)
+#ifdef MSG_TRUNC
+ *r |= MSG_TRUNC;
+#else /* def MSG_TRUNC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_TRUNC */
+ if ((x & Mono_Posix_MessageFlags_MSG_WAITALL) == Mono_Posix_MessageFlags_MSG_WAITALL)
+#ifdef MSG_WAITALL
+ *r |= MSG_WAITALL;
+#else /* def MSG_WAITALL */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_WAITALL */
+ if ((x & Mono_Posix_MessageFlags_MSG_WAITFORONE) == Mono_Posix_MessageFlags_MSG_WAITFORONE)
+#ifdef MSG_WAITFORONE
+ *r |= MSG_WAITFORONE;
+#else /* def MSG_WAITFORONE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef MSG_WAITFORONE */
+ if (x == 0)
+ return 0;
+ return 0;
+}
+
+int Mono_Posix_ToMessageFlags (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef MSG_CMSG_CLOEXEC
+ if ((x & MSG_CMSG_CLOEXEC) == MSG_CMSG_CLOEXEC)
+ *r |= Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC;
+#endif /* ndef MSG_CMSG_CLOEXEC */
+#ifdef MSG_CONFIRM
+ if ((x & MSG_CONFIRM) == MSG_CONFIRM)
+ *r |= Mono_Posix_MessageFlags_MSG_CONFIRM;
+#endif /* ndef MSG_CONFIRM */
+#ifdef MSG_CTRUNC
+ if ((x & MSG_CTRUNC) == MSG_CTRUNC)
+ *r |= Mono_Posix_MessageFlags_MSG_CTRUNC;
+#endif /* ndef MSG_CTRUNC */
+#ifdef MSG_DONTROUTE
+ if ((x & MSG_DONTROUTE) == MSG_DONTROUTE)
+ *r |= Mono_Posix_MessageFlags_MSG_DONTROUTE;
+#endif /* ndef MSG_DONTROUTE */
+#ifdef MSG_DONTWAIT
+ if ((x & MSG_DONTWAIT) == MSG_DONTWAIT)
+ *r |= Mono_Posix_MessageFlags_MSG_DONTWAIT;
+#endif /* ndef MSG_DONTWAIT */
+#ifdef MSG_EOR
+ if ((x & MSG_EOR) == MSG_EOR)
+ *r |= Mono_Posix_MessageFlags_MSG_EOR;
+#endif /* ndef MSG_EOR */
+#ifdef MSG_ERRQUEUE
+ if ((x & MSG_ERRQUEUE) == MSG_ERRQUEUE)
+ *r |= Mono_Posix_MessageFlags_MSG_ERRQUEUE;
+#endif /* ndef MSG_ERRQUEUE */
+#ifdef MSG_FASTOPEN
+ if ((x & MSG_FASTOPEN) == MSG_FASTOPEN)
+ *r |= Mono_Posix_MessageFlags_MSG_FASTOPEN;
+#endif /* ndef MSG_FASTOPEN */
+#ifdef MSG_FIN
+ if ((x & MSG_FIN) == MSG_FIN)
+ *r |= Mono_Posix_MessageFlags_MSG_FIN;
+#endif /* ndef MSG_FIN */
+#ifdef MSG_MORE
+ if ((x & MSG_MORE) == MSG_MORE)
+ *r |= Mono_Posix_MessageFlags_MSG_MORE;
+#endif /* ndef MSG_MORE */
+#ifdef MSG_NOSIGNAL
+ if ((x & MSG_NOSIGNAL) == MSG_NOSIGNAL)
+ *r |= Mono_Posix_MessageFlags_MSG_NOSIGNAL;
+#endif /* ndef MSG_NOSIGNAL */
+#ifdef MSG_OOB
+ if ((x & MSG_OOB) == MSG_OOB)
+ *r |= Mono_Posix_MessageFlags_MSG_OOB;
+#endif /* ndef MSG_OOB */
+#ifdef MSG_PEEK
+ if ((x & MSG_PEEK) == MSG_PEEK)
+ *r |= Mono_Posix_MessageFlags_MSG_PEEK;
+#endif /* ndef MSG_PEEK */
+#ifdef MSG_PROXY
+ if ((x & MSG_PROXY) == MSG_PROXY)
+ *r |= Mono_Posix_MessageFlags_MSG_PROXY;
+#endif /* ndef MSG_PROXY */
+#ifdef MSG_RST
+ if ((x & MSG_RST) == MSG_RST)
+ *r |= Mono_Posix_MessageFlags_MSG_RST;
+#endif /* ndef MSG_RST */
+#ifdef MSG_SYN
+ if ((x & MSG_SYN) == MSG_SYN)
+ *r |= Mono_Posix_MessageFlags_MSG_SYN;
+#endif /* ndef MSG_SYN */
+#ifdef MSG_TRUNC
+ if ((x & MSG_TRUNC) == MSG_TRUNC)
+ *r |= Mono_Posix_MessageFlags_MSG_TRUNC;
+#endif /* ndef MSG_TRUNC */
+#ifdef MSG_WAITALL
+ if ((x & MSG_WAITALL) == MSG_WAITALL)
+ *r |= Mono_Posix_MessageFlags_MSG_WAITALL;
+#endif /* ndef MSG_WAITALL */
+#ifdef MSG_WAITFORONE
+ if ((x & MSG_WAITFORONE) == MSG_WAITFORONE)
+ *r |= Mono_Posix_MessageFlags_MSG_WAITFORONE;
+#endif /* ndef MSG_WAITFORONE */
+ return 0;
+}
+
int Mono_Posix_FromMlockallFlags (int x, int *r)
{
*r = 0;
errno = EINVAL; return -1;
}
+int Mono_Posix_FromShutdownOption (int x, int *r)
+{
+ *r = 0;
+ if (x == Mono_Posix_ShutdownOption_SHUT_RD)
+#ifdef SHUT_RD
+ {*r = SHUT_RD; return 0;}
+#else /* def SHUT_RD */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_RD */
+ if (x == Mono_Posix_ShutdownOption_SHUT_RDWR)
+#ifdef SHUT_RDWR
+ {*r = SHUT_RDWR; return 0;}
+#else /* def SHUT_RDWR */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_RDWR */
+ if (x == Mono_Posix_ShutdownOption_SHUT_WR)
+#ifdef SHUT_WR
+ {*r = SHUT_WR; return 0;}
+#else /* def SHUT_WR */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SHUT_WR */
+ if (x == 0)
+ return 0;
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToShutdownOption (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef SHUT_RD
+ if (x == SHUT_RD)
+ {*r = Mono_Posix_ShutdownOption_SHUT_RD; return 0;}
+#endif /* ndef SHUT_RD */
+#ifdef SHUT_RDWR
+ if (x == SHUT_RDWR)
+ {*r = Mono_Posix_ShutdownOption_SHUT_RDWR; return 0;}
+#endif /* ndef SHUT_RDWR */
+#ifdef SHUT_WR
+ if (x == SHUT_WR)
+ {*r = Mono_Posix_ShutdownOption_SHUT_WR; return 0;}
+#endif /* ndef SHUT_WR */
+ errno = EINVAL; return -1;
+}
+
int Mono_Posix_FromSignum (int x, int *r)
{
*r = 0;
#endif /* ndef HAVE_STRUCT_TIMEZONE */
+int Mono_Posix_FromUnixAddressFamily (int x, int *r)
+{
+ *r = 0;
+ if (x == Mono_Posix_UnixAddressFamily_AF_ALG)
+#ifdef AF_ALG
+ {*r = AF_ALG; return 0;}
+#else /* def AF_ALG */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ALG */
+ if (x == Mono_Posix_UnixAddressFamily_AF_APPLETALK)
+#ifdef AF_APPLETALK
+ {*r = AF_APPLETALK; return 0;}
+#else /* def AF_APPLETALK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_APPLETALK */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ASH)
+#ifdef AF_ASH
+ {*r = AF_ASH; return 0;}
+#else /* def AF_ASH */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ASH */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ATMPVC)
+#ifdef AF_ATMPVC
+ {*r = AF_ATMPVC; return 0;}
+#else /* def AF_ATMPVC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ATMPVC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ATMSVC)
+#ifdef AF_ATMSVC
+ {*r = AF_ATMSVC; return 0;}
+#else /* def AF_ATMSVC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ATMSVC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_AX25)
+#ifdef AF_AX25
+ {*r = AF_AX25; return 0;}
+#else /* def AF_AX25 */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_AX25 */
+ if (x == Mono_Posix_UnixAddressFamily_AF_BLUETOOTH)
+#ifdef AF_BLUETOOTH
+ {*r = AF_BLUETOOTH; return 0;}
+#else /* def AF_BLUETOOTH */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_BLUETOOTH */
+ if (x == Mono_Posix_UnixAddressFamily_AF_BRIDGE)
+#ifdef AF_BRIDGE
+ {*r = AF_BRIDGE; return 0;}
+#else /* def AF_BRIDGE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_BRIDGE */
+ if (x == Mono_Posix_UnixAddressFamily_AF_CAIF)
+#ifdef AF_CAIF
+ {*r = AF_CAIF; return 0;}
+#else /* def AF_CAIF */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_CAIF */
+ if (x == Mono_Posix_UnixAddressFamily_AF_CAN)
+#ifdef AF_CAN
+ {*r = AF_CAN; return 0;}
+#else /* def AF_CAN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_CAN */
+ if (x == Mono_Posix_UnixAddressFamily_AF_DECnet)
+#ifdef AF_DECnet
+ {*r = AF_DECnet; return 0;}
+#else /* def AF_DECnet */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_DECnet */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ECONET)
+#ifdef AF_ECONET
+ {*r = AF_ECONET; return 0;}
+#else /* def AF_ECONET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ECONET */
+ if (x == Mono_Posix_UnixAddressFamily_AF_IEEE802154)
+#ifdef AF_IEEE802154
+ {*r = AF_IEEE802154; return 0;}
+#else /* def AF_IEEE802154 */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_IEEE802154 */
+ if (x == Mono_Posix_UnixAddressFamily_AF_INET)
+#ifdef AF_INET
+ {*r = AF_INET; return 0;}
+#else /* def AF_INET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_INET */
+ if (x == Mono_Posix_UnixAddressFamily_AF_INET6)
+#ifdef AF_INET6
+ {*r = AF_INET6; return 0;}
+#else /* def AF_INET6 */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_INET6 */
+ if (x == Mono_Posix_UnixAddressFamily_AF_IPX)
+#ifdef AF_IPX
+ {*r = AF_IPX; return 0;}
+#else /* def AF_IPX */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_IPX */
+ if (x == Mono_Posix_UnixAddressFamily_AF_IRDA)
+#ifdef AF_IRDA
+ {*r = AF_IRDA; return 0;}
+#else /* def AF_IRDA */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_IRDA */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ISDN)
+#ifdef AF_ISDN
+ {*r = AF_ISDN; return 0;}
+#else /* def AF_ISDN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ISDN */
+ if (x == Mono_Posix_UnixAddressFamily_AF_IUCV)
+#ifdef AF_IUCV
+ {*r = AF_IUCV; return 0;}
+#else /* def AF_IUCV */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_IUCV */
+ if (x == Mono_Posix_UnixAddressFamily_AF_KEY)
+#ifdef AF_KEY
+ {*r = AF_KEY; return 0;}
+#else /* def AF_KEY */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_KEY */
+ if (x == Mono_Posix_UnixAddressFamily_AF_LLC)
+#ifdef AF_LLC
+ {*r = AF_LLC; return 0;}
+#else /* def AF_LLC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_LLC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_NETBEUI)
+#ifdef AF_NETBEUI
+ {*r = AF_NETBEUI; return 0;}
+#else /* def AF_NETBEUI */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETBEUI */
+ if (x == Mono_Posix_UnixAddressFamily_AF_NETLINK)
+#ifdef AF_NETLINK
+ {*r = AF_NETLINK; return 0;}
+#else /* def AF_NETLINK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETLINK */
+ if (x == Mono_Posix_UnixAddressFamily_AF_NETROM)
+#ifdef AF_NETROM
+ {*r = AF_NETROM; return 0;}
+#else /* def AF_NETROM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_NETROM */
+ if (x == Mono_Posix_UnixAddressFamily_AF_NFC)
+#ifdef AF_NFC
+ {*r = AF_NFC; return 0;}
+#else /* def AF_NFC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_NFC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_PACKET)
+#ifdef AF_PACKET
+ {*r = AF_PACKET; return 0;}
+#else /* def AF_PACKET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_PACKET */
+ if (x == Mono_Posix_UnixAddressFamily_AF_PHONET)
+#ifdef AF_PHONET
+ {*r = AF_PHONET; return 0;}
+#else /* def AF_PHONET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_PHONET */
+ if (x == Mono_Posix_UnixAddressFamily_AF_PPPOX)
+#ifdef AF_PPPOX
+ {*r = AF_PPPOX; return 0;}
+#else /* def AF_PPPOX */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_PPPOX */
+ if (x == Mono_Posix_UnixAddressFamily_AF_RDS)
+#ifdef AF_RDS
+ {*r = AF_RDS; return 0;}
+#else /* def AF_RDS */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_RDS */
+ if (x == Mono_Posix_UnixAddressFamily_AF_ROSE)
+#ifdef AF_ROSE
+ {*r = AF_ROSE; return 0;}
+#else /* def AF_ROSE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_ROSE */
+ if (x == Mono_Posix_UnixAddressFamily_AF_RXRPC)
+#ifdef AF_RXRPC
+ {*r = AF_RXRPC; return 0;}
+#else /* def AF_RXRPC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_RXRPC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_SECURITY)
+#ifdef AF_SECURITY
+ {*r = AF_SECURITY; return 0;}
+#else /* def AF_SECURITY */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_SECURITY */
+ if (x == Mono_Posix_UnixAddressFamily_AF_SNA)
+#ifdef AF_SNA
+ {*r = AF_SNA; return 0;}
+#else /* def AF_SNA */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_SNA */
+ if (x == Mono_Posix_UnixAddressFamily_AF_TIPC)
+#ifdef AF_TIPC
+ {*r = AF_TIPC; return 0;}
+#else /* def AF_TIPC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_TIPC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_UNIX)
+#ifdef AF_UNIX
+ {*r = AF_UNIX; return 0;}
+#else /* def AF_UNIX */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_UNIX */
+ if (x == Mono_Posix_UnixAddressFamily_AF_UNSPEC)
+#ifdef AF_UNSPEC
+ {*r = AF_UNSPEC; return 0;}
+#else /* def AF_UNSPEC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_UNSPEC */
+ if (x == Mono_Posix_UnixAddressFamily_AF_VSOCK)
+#ifdef AF_VSOCK
+ {*r = AF_VSOCK; return 0;}
+#else /* def AF_VSOCK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_VSOCK */
+ if (x == Mono_Posix_UnixAddressFamily_AF_WANPIPE)
+#ifdef AF_WANPIPE
+ {*r = AF_WANPIPE; return 0;}
+#else /* def AF_WANPIPE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_WANPIPE */
+ if (x == Mono_Posix_UnixAddressFamily_AF_X25)
+#ifdef AF_X25
+ {*r = AF_X25; return 0;}
+#else /* def AF_X25 */
+ {errno = EINVAL; return -1;}
+#endif /* ndef AF_X25 */
+ if (x == 0)
+ return 0;
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixAddressFamily (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef AF_ALG
+ if (x == AF_ALG)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ALG; return 0;}
+#endif /* ndef AF_ALG */
+#ifdef AF_APPLETALK
+ if (x == AF_APPLETALK)
+ {*r = Mono_Posix_UnixAddressFamily_AF_APPLETALK; return 0;}
+#endif /* ndef AF_APPLETALK */
+#ifdef AF_ASH
+ if (x == AF_ASH)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ASH; return 0;}
+#endif /* ndef AF_ASH */
+#ifdef AF_ATMPVC
+ if (x == AF_ATMPVC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ATMPVC; return 0;}
+#endif /* ndef AF_ATMPVC */
+#ifdef AF_ATMSVC
+ if (x == AF_ATMSVC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ATMSVC; return 0;}
+#endif /* ndef AF_ATMSVC */
+#ifdef AF_AX25
+ if (x == AF_AX25)
+ {*r = Mono_Posix_UnixAddressFamily_AF_AX25; return 0;}
+#endif /* ndef AF_AX25 */
+#ifdef AF_BLUETOOTH
+ if (x == AF_BLUETOOTH)
+ {*r = Mono_Posix_UnixAddressFamily_AF_BLUETOOTH; return 0;}
+#endif /* ndef AF_BLUETOOTH */
+#ifdef AF_BRIDGE
+ if (x == AF_BRIDGE)
+ {*r = Mono_Posix_UnixAddressFamily_AF_BRIDGE; return 0;}
+#endif /* ndef AF_BRIDGE */
+#ifdef AF_CAIF
+ if (x == AF_CAIF)
+ {*r = Mono_Posix_UnixAddressFamily_AF_CAIF; return 0;}
+#endif /* ndef AF_CAIF */
+#ifdef AF_CAN
+ if (x == AF_CAN)
+ {*r = Mono_Posix_UnixAddressFamily_AF_CAN; return 0;}
+#endif /* ndef AF_CAN */
+#ifdef AF_DECnet
+ if (x == AF_DECnet)
+ {*r = Mono_Posix_UnixAddressFamily_AF_DECnet; return 0;}
+#endif /* ndef AF_DECnet */
+#ifdef AF_ECONET
+ if (x == AF_ECONET)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ECONET; return 0;}
+#endif /* ndef AF_ECONET */
+#ifdef AF_IEEE802154
+ if (x == AF_IEEE802154)
+ {*r = Mono_Posix_UnixAddressFamily_AF_IEEE802154; return 0;}
+#endif /* ndef AF_IEEE802154 */
+#ifdef AF_INET
+ if (x == AF_INET)
+ {*r = Mono_Posix_UnixAddressFamily_AF_INET; return 0;}
+#endif /* ndef AF_INET */
+#ifdef AF_INET6
+ if (x == AF_INET6)
+ {*r = Mono_Posix_UnixAddressFamily_AF_INET6; return 0;}
+#endif /* ndef AF_INET6 */
+#ifdef AF_IPX
+ if (x == AF_IPX)
+ {*r = Mono_Posix_UnixAddressFamily_AF_IPX; return 0;}
+#endif /* ndef AF_IPX */
+#ifdef AF_IRDA
+ if (x == AF_IRDA)
+ {*r = Mono_Posix_UnixAddressFamily_AF_IRDA; return 0;}
+#endif /* ndef AF_IRDA */
+#ifdef AF_ISDN
+ if (x == AF_ISDN)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ISDN; return 0;}
+#endif /* ndef AF_ISDN */
+#ifdef AF_IUCV
+ if (x == AF_IUCV)
+ {*r = Mono_Posix_UnixAddressFamily_AF_IUCV; return 0;}
+#endif /* ndef AF_IUCV */
+#ifdef AF_KEY
+ if (x == AF_KEY)
+ {*r = Mono_Posix_UnixAddressFamily_AF_KEY; return 0;}
+#endif /* ndef AF_KEY */
+#ifdef AF_LLC
+ if (x == AF_LLC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_LLC; return 0;}
+#endif /* ndef AF_LLC */
+#ifdef AF_NETBEUI
+ if (x == AF_NETBEUI)
+ {*r = Mono_Posix_UnixAddressFamily_AF_NETBEUI; return 0;}
+#endif /* ndef AF_NETBEUI */
+#ifdef AF_NETLINK
+ if (x == AF_NETLINK)
+ {*r = Mono_Posix_UnixAddressFamily_AF_NETLINK; return 0;}
+#endif /* ndef AF_NETLINK */
+#ifdef AF_NETROM
+ if (x == AF_NETROM)
+ {*r = Mono_Posix_UnixAddressFamily_AF_NETROM; return 0;}
+#endif /* ndef AF_NETROM */
+#ifdef AF_NFC
+ if (x == AF_NFC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_NFC; return 0;}
+#endif /* ndef AF_NFC */
+#ifdef AF_PACKET
+ if (x == AF_PACKET)
+ {*r = Mono_Posix_UnixAddressFamily_AF_PACKET; return 0;}
+#endif /* ndef AF_PACKET */
+#ifdef AF_PHONET
+ if (x == AF_PHONET)
+ {*r = Mono_Posix_UnixAddressFamily_AF_PHONET; return 0;}
+#endif /* ndef AF_PHONET */
+#ifdef AF_PPPOX
+ if (x == AF_PPPOX)
+ {*r = Mono_Posix_UnixAddressFamily_AF_PPPOX; return 0;}
+#endif /* ndef AF_PPPOX */
+#ifdef AF_RDS
+ if (x == AF_RDS)
+ {*r = Mono_Posix_UnixAddressFamily_AF_RDS; return 0;}
+#endif /* ndef AF_RDS */
+#ifdef AF_ROSE
+ if (x == AF_ROSE)
+ {*r = Mono_Posix_UnixAddressFamily_AF_ROSE; return 0;}
+#endif /* ndef AF_ROSE */
+#ifdef AF_RXRPC
+ if (x == AF_RXRPC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_RXRPC; return 0;}
+#endif /* ndef AF_RXRPC */
+#ifdef AF_SECURITY
+ if (x == AF_SECURITY)
+ {*r = Mono_Posix_UnixAddressFamily_AF_SECURITY; return 0;}
+#endif /* ndef AF_SECURITY */
+#ifdef AF_SNA
+ if (x == AF_SNA)
+ {*r = Mono_Posix_UnixAddressFamily_AF_SNA; return 0;}
+#endif /* ndef AF_SNA */
+#ifdef AF_TIPC
+ if (x == AF_TIPC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_TIPC; return 0;}
+#endif /* ndef AF_TIPC */
+#ifdef AF_UNIX
+ if (x == AF_UNIX)
+ {*r = Mono_Posix_UnixAddressFamily_AF_UNIX; return 0;}
+#endif /* ndef AF_UNIX */
+#ifdef AF_UNSPEC
+ if (x == AF_UNSPEC)
+ {*r = Mono_Posix_UnixAddressFamily_AF_UNSPEC; return 0;}
+#endif /* ndef AF_UNSPEC */
+#ifdef AF_VSOCK
+ if (x == AF_VSOCK)
+ {*r = Mono_Posix_UnixAddressFamily_AF_VSOCK; return 0;}
+#endif /* ndef AF_VSOCK */
+#ifdef AF_WANPIPE
+ if (x == AF_WANPIPE)
+ {*r = Mono_Posix_UnixAddressFamily_AF_WANPIPE; return 0;}
+#endif /* ndef AF_WANPIPE */
+#ifdef AF_X25
+ if (x == AF_X25)
+ {*r = Mono_Posix_UnixAddressFamily_AF_X25; return 0;}
+#endif /* ndef AF_X25 */
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketFlags (int x, int *r)
+{
+ *r = 0;
+ if ((x & Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC) == Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC)
+#ifdef SOCK_CLOEXEC
+ *r |= SOCK_CLOEXEC;
+#else /* def SOCK_CLOEXEC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_CLOEXEC */
+ if ((x & Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK) == Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK)
+#ifdef SOCK_NONBLOCK
+ *r |= SOCK_NONBLOCK;
+#else /* def SOCK_NONBLOCK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_NONBLOCK */
+ if (x == 0)
+ return 0;
+ return 0;
+}
+
+int Mono_Posix_ToUnixSocketFlags (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef SOCK_CLOEXEC
+ if ((x & SOCK_CLOEXEC) == SOCK_CLOEXEC)
+ *r |= Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC;
+#endif /* ndef SOCK_CLOEXEC */
+#ifdef SOCK_NONBLOCK
+ if ((x & SOCK_NONBLOCK) == SOCK_NONBLOCK)
+ *r |= Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK;
+#endif /* ndef SOCK_NONBLOCK */
+ return 0;
+}
+
+int Mono_Posix_FromUnixSocketOptionName (int x, int *r)
+{
+ *r = 0;
+ if (x == Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN)
+#ifdef SO_ACCEPTCONN
+ {*r = SO_ACCEPTCONN; return 0;}
+#else /* def SO_ACCEPTCONN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_ACCEPTCONN */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER)
+#ifdef SO_ATTACH_FILTER
+ {*r = SO_ATTACH_FILTER; return 0;}
+#else /* def SO_ATTACH_FILTER */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_ATTACH_FILTER */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE)
+#ifdef SO_BINDTODEVICE
+ {*r = SO_BINDTODEVICE; return 0;}
+#else /* def SO_BINDTODEVICE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_BINDTODEVICE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_BROADCAST)
+#ifdef SO_BROADCAST
+ {*r = SO_BROADCAST; return 0;}
+#else /* def SO_BROADCAST */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_BROADCAST */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT)
+#ifdef SO_BSDCOMPAT
+ {*r = SO_BSDCOMPAT; return 0;}
+#else /* def SO_BSDCOMPAT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_BSDCOMPAT */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL)
+#ifdef SO_BUSY_POLL
+ {*r = SO_BUSY_POLL; return 0;}
+#else /* def SO_BUSY_POLL */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_BUSY_POLL */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_DEBUG)
+#ifdef SO_DEBUG
+ {*r = SO_DEBUG; return 0;}
+#else /* def SO_DEBUG */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_DEBUG */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER)
+#ifdef SO_DETACH_FILTER
+ {*r = SO_DETACH_FILTER; return 0;}
+#else /* def SO_DETACH_FILTER */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_DETACH_FILTER */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_DOMAIN)
+#ifdef SO_DOMAIN
+ {*r = SO_DOMAIN; return 0;}
+#else /* def SO_DOMAIN */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_DOMAIN */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_DONTROUTE)
+#ifdef SO_DONTROUTE
+ {*r = SO_DONTROUTE; return 0;}
+#else /* def SO_DONTROUTE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_DONTROUTE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_ERROR)
+#ifdef SO_ERROR
+ {*r = SO_ERROR; return 0;}
+#else /* def SO_ERROR */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_ERROR */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE)
+#ifdef SO_KEEPALIVE
+ {*r = SO_KEEPALIVE; return 0;}
+#else /* def SO_KEEPALIVE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_KEEPALIVE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_LINGER)
+#ifdef SO_LINGER
+ {*r = SO_LINGER; return 0;}
+#else /* def SO_LINGER */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_LINGER */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER)
+#ifdef SO_LOCK_FILTER
+ {*r = SO_LOCK_FILTER; return 0;}
+#else /* def SO_LOCK_FILTER */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_LOCK_FILTER */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_MARK)
+#ifdef SO_MARK
+ {*r = SO_MARK; return 0;}
+#else /* def SO_MARK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_MARK */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE)
+#ifdef SO_MAX_PACING_RATE
+ {*r = SO_MAX_PACING_RATE; return 0;}
+#else /* def SO_MAX_PACING_RATE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_MAX_PACING_RATE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_NOFCS)
+#ifdef SO_NOFCS
+ {*r = SO_NOFCS; return 0;}
+#else /* def SO_NOFCS */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_NOFCS */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_NO_CHECK)
+#ifdef SO_NO_CHECK
+ {*r = SO_NO_CHECK; return 0;}
+#else /* def SO_NO_CHECK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_NO_CHECK */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_OOBINLINE)
+#ifdef SO_OOBINLINE
+ {*r = SO_OOBINLINE; return 0;}
+#else /* def SO_OOBINLINE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_OOBINLINE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PASSCRED)
+#ifdef SO_PASSCRED
+ {*r = SO_PASSCRED; return 0;}
+#else /* def SO_PASSCRED */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PASSCRED */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PASSSEC)
+#ifdef SO_PASSSEC
+ {*r = SO_PASSSEC; return 0;}
+#else /* def SO_PASSSEC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PASSSEC */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF)
+#ifdef SO_PEEK_OFF
+ {*r = SO_PEEK_OFF; return 0;}
+#else /* def SO_PEEK_OFF */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEEK_OFF */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PEERCRED)
+#ifdef SO_PEERCRED
+ {*r = SO_PEERCRED; return 0;}
+#else /* def SO_PEERCRED */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERCRED */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PEERNAME)
+#ifdef SO_PEERNAME
+ {*r = SO_PEERNAME; return 0;}
+#else /* def SO_PEERNAME */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERNAME */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PEERSEC)
+#ifdef SO_PEERSEC
+ {*r = SO_PEERSEC; return 0;}
+#else /* def SO_PEERSEC */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PEERSEC */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PRIORITY)
+#ifdef SO_PRIORITY
+ {*r = SO_PRIORITY; return 0;}
+#else /* def SO_PRIORITY */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PRIORITY */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_PROTOCOL)
+#ifdef SO_PROTOCOL
+ {*r = SO_PROTOCOL; return 0;}
+#else /* def SO_PROTOCOL */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_PROTOCOL */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_RCVBUF)
+#ifdef SO_RCVBUF
+ {*r = SO_RCVBUF; return 0;}
+#else /* def SO_RCVBUF */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVBUF */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE)
+#ifdef SO_RCVBUFFORCE
+ {*r = SO_RCVBUFFORCE; return 0;}
+#else /* def SO_RCVBUFFORCE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVBUFFORCE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT)
+#ifdef SO_RCVLOWAT
+ {*r = SO_RCVLOWAT; return 0;}
+#else /* def SO_RCVLOWAT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVLOWAT */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO)
+#ifdef SO_RCVTIMEO
+ {*r = SO_RCVTIMEO; return 0;}
+#else /* def SO_RCVTIMEO */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_RCVTIMEO */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_REUSEADDR)
+#ifdef SO_REUSEADDR
+ {*r = SO_REUSEADDR; return 0;}
+#else /* def SO_REUSEADDR */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_REUSEADDR */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_REUSEPORT)
+#ifdef SO_REUSEPORT
+ {*r = SO_REUSEPORT; return 0;}
+#else /* def SO_REUSEPORT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_REUSEPORT */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL)
+#ifdef SO_RXQ_OVFL
+ {*r = SO_RXQ_OVFL; return 0;}
+#else /* def SO_RXQ_OVFL */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_RXQ_OVFL */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION)
+#ifdef SO_SECURITY_AUTHENTICATION
+ {*r = SO_SECURITY_AUTHENTICATION; return 0;}
+#else /* def SO_SECURITY_AUTHENTICATION */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_AUTHENTICATION */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK)
+#ifdef SO_SECURITY_ENCRYPTION_NETWORK
+ {*r = SO_SECURITY_ENCRYPTION_NETWORK; return 0;}
+#else /* def SO_SECURITY_ENCRYPTION_NETWORK */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_NETWORK */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT)
+#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
+ {*r = SO_SECURITY_ENCRYPTION_TRANSPORT; return 0;}
+#else /* def SO_SECURITY_ENCRYPTION_TRANSPORT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_TRANSPORT */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE)
+#ifdef SO_SELECT_ERR_QUEUE
+ {*r = SO_SELECT_ERR_QUEUE; return 0;}
+#else /* def SO_SELECT_ERR_QUEUE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SELECT_ERR_QUEUE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SNDBUF)
+#ifdef SO_SNDBUF
+ {*r = SO_SNDBUF; return 0;}
+#else /* def SO_SNDBUF */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDBUF */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE)
+#ifdef SO_SNDBUFFORCE
+ {*r = SO_SNDBUFFORCE; return 0;}
+#else /* def SO_SNDBUFFORCE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDBUFFORCE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT)
+#ifdef SO_SNDLOWAT
+ {*r = SO_SNDLOWAT; return 0;}
+#else /* def SO_SNDLOWAT */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDLOWAT */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO)
+#ifdef SO_SNDTIMEO
+ {*r = SO_SNDTIMEO; return 0;}
+#else /* def SO_SNDTIMEO */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_SNDTIMEO */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP)
+#ifdef SO_TIMESTAMP
+ {*r = SO_TIMESTAMP; return 0;}
+#else /* def SO_TIMESTAMP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMP */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING)
+#ifdef SO_TIMESTAMPING
+ {*r = SO_TIMESTAMPING; return 0;}
+#else /* def SO_TIMESTAMPING */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMPING */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS)
+#ifdef SO_TIMESTAMPNS
+ {*r = SO_TIMESTAMPNS; return 0;}
+#else /* def SO_TIMESTAMPNS */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_TIMESTAMPNS */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_TYPE)
+#ifdef SO_TYPE
+ {*r = SO_TYPE; return 0;}
+#else /* def SO_TYPE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_TYPE */
+ if (x == Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS)
+#ifdef SO_WIFI_STATUS
+ {*r = SO_WIFI_STATUS; return 0;}
+#else /* def SO_WIFI_STATUS */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SO_WIFI_STATUS */
+ if (x == 0)
+ return 0;
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketOptionName (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef SO_ACCEPTCONN
+ if (x == SO_ACCEPTCONN)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN; return 0;}
+#endif /* ndef SO_ACCEPTCONN */
+#ifdef SO_ATTACH_FILTER
+ if (x == SO_ATTACH_FILTER)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER; return 0;}
+#endif /* ndef SO_ATTACH_FILTER */
+#ifdef SO_BINDTODEVICE
+ if (x == SO_BINDTODEVICE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE; return 0;}
+#endif /* ndef SO_BINDTODEVICE */
+#ifdef SO_BROADCAST
+ if (x == SO_BROADCAST)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_BROADCAST; return 0;}
+#endif /* ndef SO_BROADCAST */
+#ifdef SO_BSDCOMPAT
+ if (x == SO_BSDCOMPAT)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT; return 0;}
+#endif /* ndef SO_BSDCOMPAT */
+#ifdef SO_BUSY_POLL
+ if (x == SO_BUSY_POLL)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL; return 0;}
+#endif /* ndef SO_BUSY_POLL */
+#ifdef SO_DEBUG
+ if (x == SO_DEBUG)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_DEBUG; return 0;}
+#endif /* ndef SO_DEBUG */
+#ifdef SO_DETACH_FILTER
+ if (x == SO_DETACH_FILTER)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER; return 0;}
+#endif /* ndef SO_DETACH_FILTER */
+#ifdef SO_DOMAIN
+ if (x == SO_DOMAIN)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_DOMAIN; return 0;}
+#endif /* ndef SO_DOMAIN */
+#ifdef SO_DONTROUTE
+ if (x == SO_DONTROUTE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_DONTROUTE; return 0;}
+#endif /* ndef SO_DONTROUTE */
+#ifdef SO_ERROR
+ if (x == SO_ERROR)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_ERROR; return 0;}
+#endif /* ndef SO_ERROR */
+#ifdef SO_KEEPALIVE
+ if (x == SO_KEEPALIVE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE; return 0;}
+#endif /* ndef SO_KEEPALIVE */
+#ifdef SO_LINGER
+ if (x == SO_LINGER)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_LINGER; return 0;}
+#endif /* ndef SO_LINGER */
+#ifdef SO_LOCK_FILTER
+ if (x == SO_LOCK_FILTER)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER; return 0;}
+#endif /* ndef SO_LOCK_FILTER */
+#ifdef SO_MARK
+ if (x == SO_MARK)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_MARK; return 0;}
+#endif /* ndef SO_MARK */
+#ifdef SO_MAX_PACING_RATE
+ if (x == SO_MAX_PACING_RATE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE; return 0;}
+#endif /* ndef SO_MAX_PACING_RATE */
+#ifdef SO_NOFCS
+ if (x == SO_NOFCS)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_NOFCS; return 0;}
+#endif /* ndef SO_NOFCS */
+#ifdef SO_NO_CHECK
+ if (x == SO_NO_CHECK)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_NO_CHECK; return 0;}
+#endif /* ndef SO_NO_CHECK */
+#ifdef SO_OOBINLINE
+ if (x == SO_OOBINLINE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_OOBINLINE; return 0;}
+#endif /* ndef SO_OOBINLINE */
+#ifdef SO_PASSCRED
+ if (x == SO_PASSCRED)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PASSCRED; return 0;}
+#endif /* ndef SO_PASSCRED */
+#ifdef SO_PASSSEC
+ if (x == SO_PASSSEC)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PASSSEC; return 0;}
+#endif /* ndef SO_PASSSEC */
+#ifdef SO_PEEK_OFF
+ if (x == SO_PEEK_OFF)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF; return 0;}
+#endif /* ndef SO_PEEK_OFF */
+#ifdef SO_PEERCRED
+ if (x == SO_PEERCRED)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PEERCRED; return 0;}
+#endif /* ndef SO_PEERCRED */
+#ifdef SO_PEERNAME
+ if (x == SO_PEERNAME)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PEERNAME; return 0;}
+#endif /* ndef SO_PEERNAME */
+#ifdef SO_PEERSEC
+ if (x == SO_PEERSEC)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PEERSEC; return 0;}
+#endif /* ndef SO_PEERSEC */
+#ifdef SO_PRIORITY
+ if (x == SO_PRIORITY)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PRIORITY; return 0;}
+#endif /* ndef SO_PRIORITY */
+#ifdef SO_PROTOCOL
+ if (x == SO_PROTOCOL)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_PROTOCOL; return 0;}
+#endif /* ndef SO_PROTOCOL */
+#ifdef SO_RCVBUF
+ if (x == SO_RCVBUF)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_RCVBUF; return 0;}
+#endif /* ndef SO_RCVBUF */
+#ifdef SO_RCVBUFFORCE
+ if (x == SO_RCVBUFFORCE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE; return 0;}
+#endif /* ndef SO_RCVBUFFORCE */
+#ifdef SO_RCVLOWAT
+ if (x == SO_RCVLOWAT)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT; return 0;}
+#endif /* ndef SO_RCVLOWAT */
+#ifdef SO_RCVTIMEO
+ if (x == SO_RCVTIMEO)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO; return 0;}
+#endif /* ndef SO_RCVTIMEO */
+#ifdef SO_REUSEADDR
+ if (x == SO_REUSEADDR)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_REUSEADDR; return 0;}
+#endif /* ndef SO_REUSEADDR */
+#ifdef SO_REUSEPORT
+ if (x == SO_REUSEPORT)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_REUSEPORT; return 0;}
+#endif /* ndef SO_REUSEPORT */
+#ifdef SO_RXQ_OVFL
+ if (x == SO_RXQ_OVFL)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL; return 0;}
+#endif /* ndef SO_RXQ_OVFL */
+#ifdef SO_SECURITY_AUTHENTICATION
+ if (x == SO_SECURITY_AUTHENTICATION)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION; return 0;}
+#endif /* ndef SO_SECURITY_AUTHENTICATION */
+#ifdef SO_SECURITY_ENCRYPTION_NETWORK
+ if (x == SO_SECURITY_ENCRYPTION_NETWORK)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK; return 0;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_NETWORK */
+#ifdef SO_SECURITY_ENCRYPTION_TRANSPORT
+ if (x == SO_SECURITY_ENCRYPTION_TRANSPORT)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT; return 0;}
+#endif /* ndef SO_SECURITY_ENCRYPTION_TRANSPORT */
+#ifdef SO_SELECT_ERR_QUEUE
+ if (x == SO_SELECT_ERR_QUEUE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE; return 0;}
+#endif /* ndef SO_SELECT_ERR_QUEUE */
+#ifdef SO_SNDBUF
+ if (x == SO_SNDBUF)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SNDBUF; return 0;}
+#endif /* ndef SO_SNDBUF */
+#ifdef SO_SNDBUFFORCE
+ if (x == SO_SNDBUFFORCE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE; return 0;}
+#endif /* ndef SO_SNDBUFFORCE */
+#ifdef SO_SNDLOWAT
+ if (x == SO_SNDLOWAT)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT; return 0;}
+#endif /* ndef SO_SNDLOWAT */
+#ifdef SO_SNDTIMEO
+ if (x == SO_SNDTIMEO)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO; return 0;}
+#endif /* ndef SO_SNDTIMEO */
+#ifdef SO_TIMESTAMP
+ if (x == SO_TIMESTAMP)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP; return 0;}
+#endif /* ndef SO_TIMESTAMP */
+#ifdef SO_TIMESTAMPING
+ if (x == SO_TIMESTAMPING)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING; return 0;}
+#endif /* ndef SO_TIMESTAMPING */
+#ifdef SO_TIMESTAMPNS
+ if (x == SO_TIMESTAMPNS)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS; return 0;}
+#endif /* ndef SO_TIMESTAMPNS */
+#ifdef SO_TYPE
+ if (x == SO_TYPE)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_TYPE; return 0;}
+#endif /* ndef SO_TYPE */
+#ifdef SO_WIFI_STATUS
+ if (x == SO_WIFI_STATUS)
+ {*r = Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS; return 0;}
+#endif /* ndef SO_WIFI_STATUS */
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketProtocol (int x, int *r)
+{
+ *r = 0;
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_AH)
+#ifdef IPPROTO_AH
+ {*r = IPPROTO_AH; return 0;}
+#else /* def IPPROTO_AH */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_AH */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH)
+#ifdef IPPROTO_BEETPH
+ {*r = IPPROTO_BEETPH; return 0;}
+#else /* def IPPROTO_BEETPH */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_BEETPH */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_COMP)
+#ifdef IPPROTO_COMP
+ {*r = IPPROTO_COMP; return 0;}
+#else /* def IPPROTO_COMP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_COMP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP)
+#ifdef IPPROTO_DCCP
+ {*r = IPPROTO_DCCP; return 0;}
+#else /* def IPPROTO_DCCP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_DCCP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_EGP)
+#ifdef IPPROTO_EGP
+ {*r = IPPROTO_EGP; return 0;}
+#else /* def IPPROTO_EGP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_EGP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP)
+#ifdef IPPROTO_ENCAP
+ {*r = IPPROTO_ENCAP; return 0;}
+#else /* def IPPROTO_ENCAP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ENCAP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ESP)
+#ifdef IPPROTO_ESP
+ {*r = IPPROTO_ESP; return 0;}
+#else /* def IPPROTO_ESP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ESP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_GRE)
+#ifdef IPPROTO_GRE
+ {*r = IPPROTO_GRE; return 0;}
+#else /* def IPPROTO_GRE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_GRE */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP)
+#ifdef IPPROTO_ICMP
+ {*r = IPPROTO_ICMP; return 0;}
+#else /* def IPPROTO_ICMP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_ICMP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IDP)
+#ifdef IPPROTO_IDP
+ {*r = IPPROTO_IDP; return 0;}
+#else /* def IPPROTO_IDP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IDP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP)
+#ifdef IPPROTO_IGMP
+ {*r = IPPROTO_IGMP; return 0;}
+#else /* def IPPROTO_IGMP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IGMP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IP)
+#ifdef IPPROTO_IP
+ {*r = IPPROTO_IP; return 0;}
+#else /* def IPPROTO_IP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP)
+#ifdef IPPROTO_IPIP
+ {*r = IPPROTO_IPIP; return 0;}
+#else /* def IPPROTO_IPIP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IPIP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6)
+#ifdef IPPROTO_IPV6
+ {*r = IPPROTO_IPV6; return 0;}
+#else /* def IPPROTO_IPV6 */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_IPV6 */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_MTP)
+#ifdef IPPROTO_MTP
+ {*r = IPPROTO_MTP; return 0;}
+#else /* def IPPROTO_MTP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_MTP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_PIM)
+#ifdef IPPROTO_PIM
+ {*r = IPPROTO_PIM; return 0;}
+#else /* def IPPROTO_PIM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_PIM */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_PUP)
+#ifdef IPPROTO_PUP
+ {*r = IPPROTO_PUP; return 0;}
+#else /* def IPPROTO_PUP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_PUP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_RAW)
+#ifdef IPPROTO_RAW
+ {*r = IPPROTO_RAW; return 0;}
+#else /* def IPPROTO_RAW */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_RAW */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP)
+#ifdef IPPROTO_RSVP
+ {*r = IPPROTO_RSVP; return 0;}
+#else /* def IPPROTO_RSVP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_RSVP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP)
+#ifdef IPPROTO_SCTP
+ {*r = IPPROTO_SCTP; return 0;}
+#else /* def IPPROTO_SCTP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_SCTP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_TCP)
+#ifdef IPPROTO_TCP
+ {*r = IPPROTO_TCP; return 0;}
+#else /* def IPPROTO_TCP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_TCP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_TP)
+#ifdef IPPROTO_TP
+ {*r = IPPROTO_TP; return 0;}
+#else /* def IPPROTO_TP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_TP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_UDP)
+#ifdef IPPROTO_UDP
+ {*r = IPPROTO_UDP; return 0;}
+#else /* def IPPROTO_UDP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_UDP */
+ if (x == Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE)
+#ifdef IPPROTO_UDPLITE
+ {*r = IPPROTO_UDPLITE; return 0;}
+#else /* def IPPROTO_UDPLITE */
+ {errno = EINVAL; return -1;}
+#endif /* ndef IPPROTO_UDPLITE */
+ if (x == Mono_Posix_UnixSocketProtocol_SOL_SOCKET)
+#ifdef SOL_SOCKET
+ {*r = SOL_SOCKET; return 0;}
+#else /* def SOL_SOCKET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOL_SOCKET */
+ if (x == 0)
+ return 0;
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketProtocol (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef IPPROTO_AH
+ if (x == IPPROTO_AH)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_AH; return 0;}
+#endif /* ndef IPPROTO_AH */
+#ifdef IPPROTO_BEETPH
+ if (x == IPPROTO_BEETPH)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH; return 0;}
+#endif /* ndef IPPROTO_BEETPH */
+#ifdef IPPROTO_COMP
+ if (x == IPPROTO_COMP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_COMP; return 0;}
+#endif /* ndef IPPROTO_COMP */
+#ifdef IPPROTO_DCCP
+ if (x == IPPROTO_DCCP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP; return 0;}
+#endif /* ndef IPPROTO_DCCP */
+#ifdef IPPROTO_EGP
+ if (x == IPPROTO_EGP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_EGP; return 0;}
+#endif /* ndef IPPROTO_EGP */
+#ifdef IPPROTO_ENCAP
+ if (x == IPPROTO_ENCAP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP; return 0;}
+#endif /* ndef IPPROTO_ENCAP */
+#ifdef IPPROTO_ESP
+ if (x == IPPROTO_ESP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ESP; return 0;}
+#endif /* ndef IPPROTO_ESP */
+#ifdef IPPROTO_GRE
+ if (x == IPPROTO_GRE)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_GRE; return 0;}
+#endif /* ndef IPPROTO_GRE */
+#ifdef IPPROTO_ICMP
+ if (x == IPPROTO_ICMP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP; return 0;}
+#endif /* ndef IPPROTO_ICMP */
+#ifdef IPPROTO_IDP
+ if (x == IPPROTO_IDP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IDP; return 0;}
+#endif /* ndef IPPROTO_IDP */
+#ifdef IPPROTO_IGMP
+ if (x == IPPROTO_IGMP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP; return 0;}
+#endif /* ndef IPPROTO_IGMP */
+#ifdef IPPROTO_IP
+ if (x == IPPROTO_IP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IP; return 0;}
+#endif /* ndef IPPROTO_IP */
+#ifdef IPPROTO_IPIP
+ if (x == IPPROTO_IPIP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP; return 0;}
+#endif /* ndef IPPROTO_IPIP */
+#ifdef IPPROTO_IPV6
+ if (x == IPPROTO_IPV6)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6; return 0;}
+#endif /* ndef IPPROTO_IPV6 */
+#ifdef IPPROTO_MTP
+ if (x == IPPROTO_MTP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_MTP; return 0;}
+#endif /* ndef IPPROTO_MTP */
+#ifdef IPPROTO_PIM
+ if (x == IPPROTO_PIM)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_PIM; return 0;}
+#endif /* ndef IPPROTO_PIM */
+#ifdef IPPROTO_PUP
+ if (x == IPPROTO_PUP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_PUP; return 0;}
+#endif /* ndef IPPROTO_PUP */
+#ifdef IPPROTO_RAW
+ if (x == IPPROTO_RAW)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_RAW; return 0;}
+#endif /* ndef IPPROTO_RAW */
+#ifdef IPPROTO_RSVP
+ if (x == IPPROTO_RSVP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP; return 0;}
+#endif /* ndef IPPROTO_RSVP */
+#ifdef IPPROTO_SCTP
+ if (x == IPPROTO_SCTP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP; return 0;}
+#endif /* ndef IPPROTO_SCTP */
+#ifdef IPPROTO_TCP
+ if (x == IPPROTO_TCP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_TCP; return 0;}
+#endif /* ndef IPPROTO_TCP */
+#ifdef IPPROTO_TP
+ if (x == IPPROTO_TP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_TP; return 0;}
+#endif /* ndef IPPROTO_TP */
+#ifdef IPPROTO_UDP
+ if (x == IPPROTO_UDP)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_UDP; return 0;}
+#endif /* ndef IPPROTO_UDP */
+#ifdef IPPROTO_UDPLITE
+ if (x == IPPROTO_UDPLITE)
+ {*r = Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE; return 0;}
+#endif /* ndef IPPROTO_UDPLITE */
+#ifdef SOL_SOCKET
+ if (x == SOL_SOCKET)
+ {*r = Mono_Posix_UnixSocketProtocol_SOL_SOCKET; return 0;}
+#endif /* ndef SOL_SOCKET */
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_FromUnixSocketType (int x, int *r)
+{
+ *r = 0;
+ if (x == Mono_Posix_UnixSocketType_SOCK_DCCP)
+#ifdef SOCK_DCCP
+ {*r = SOCK_DCCP; return 0;}
+#else /* def SOCK_DCCP */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_DCCP */
+ if (x == Mono_Posix_UnixSocketType_SOCK_DGRAM)
+#ifdef SOCK_DGRAM
+ {*r = SOCK_DGRAM; return 0;}
+#else /* def SOCK_DGRAM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_DGRAM */
+ if (x == Mono_Posix_UnixSocketType_SOCK_PACKET)
+#ifdef SOCK_PACKET
+ {*r = SOCK_PACKET; return 0;}
+#else /* def SOCK_PACKET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_PACKET */
+ if (x == Mono_Posix_UnixSocketType_SOCK_RAW)
+#ifdef SOCK_RAW
+ {*r = SOCK_RAW; return 0;}
+#else /* def SOCK_RAW */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_RAW */
+ if (x == Mono_Posix_UnixSocketType_SOCK_RDM)
+#ifdef SOCK_RDM
+ {*r = SOCK_RDM; return 0;}
+#else /* def SOCK_RDM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_RDM */
+ if (x == Mono_Posix_UnixSocketType_SOCK_SEQPACKET)
+#ifdef SOCK_SEQPACKET
+ {*r = SOCK_SEQPACKET; return 0;}
+#else /* def SOCK_SEQPACKET */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_SEQPACKET */
+ if (x == Mono_Posix_UnixSocketType_SOCK_STREAM)
+#ifdef SOCK_STREAM
+ {*r = SOCK_STREAM; return 0;}
+#else /* def SOCK_STREAM */
+ {errno = EINVAL; return -1;}
+#endif /* ndef SOCK_STREAM */
+ if (x == 0)
+ return 0;
+ errno = EINVAL; return -1;
+}
+
+int Mono_Posix_ToUnixSocketType (int x, int *r)
+{
+ *r = 0;
+ if (x == 0)
+ return 0;
+#ifdef SOCK_DCCP
+ if (x == SOCK_DCCP)
+ {*r = Mono_Posix_UnixSocketType_SOCK_DCCP; return 0;}
+#endif /* ndef SOCK_DCCP */
+#ifdef SOCK_DGRAM
+ if (x == SOCK_DGRAM)
+ {*r = Mono_Posix_UnixSocketType_SOCK_DGRAM; return 0;}
+#endif /* ndef SOCK_DGRAM */
+#ifdef SOCK_PACKET
+ if (x == SOCK_PACKET)
+ {*r = Mono_Posix_UnixSocketType_SOCK_PACKET; return 0;}
+#endif /* ndef SOCK_PACKET */
+#ifdef SOCK_RAW
+ if (x == SOCK_RAW)
+ {*r = Mono_Posix_UnixSocketType_SOCK_RAW; return 0;}
+#endif /* ndef SOCK_RAW */
+#ifdef SOCK_RDM
+ if (x == SOCK_RDM)
+ {*r = Mono_Posix_UnixSocketType_SOCK_RDM; return 0;}
+#endif /* ndef SOCK_RDM */
+#ifdef SOCK_SEQPACKET
+ if (x == SOCK_SEQPACKET)
+ {*r = Mono_Posix_UnixSocketType_SOCK_SEQPACKET; return 0;}
+#endif /* ndef SOCK_SEQPACKET */
+#ifdef SOCK_STREAM
+ if (x == SOCK_STREAM)
+ {*r = Mono_Posix_UnixSocketType_SOCK_STREAM; return 0;}
+#endif /* ndef SOCK_STREAM */
+ errno = EINVAL; return -1;
+}
+
#ifdef HAVE_STRUCT_UTIMBUF
int
Mono_Posix_FromUtimbuf (struct Mono_Posix_Utimbuf *from, struct utimbuf *to)
int Mono_Posix_FromLockfCommand (int x, int *r);
int Mono_Posix_ToLockfCommand (int x, int *r);
+enum Mono_Posix_MessageFlags {
+ Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC = 0x40000000,
+ #define Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC Mono_Posix_MessageFlags_MSG_CMSG_CLOEXEC
+ Mono_Posix_MessageFlags_MSG_CONFIRM = 0x00000800,
+ #define Mono_Posix_MessageFlags_MSG_CONFIRM Mono_Posix_MessageFlags_MSG_CONFIRM
+ Mono_Posix_MessageFlags_MSG_CTRUNC = 0x00000008,
+ #define Mono_Posix_MessageFlags_MSG_CTRUNC Mono_Posix_MessageFlags_MSG_CTRUNC
+ Mono_Posix_MessageFlags_MSG_DONTROUTE = 0x00000004,
+ #define Mono_Posix_MessageFlags_MSG_DONTROUTE Mono_Posix_MessageFlags_MSG_DONTROUTE
+ Mono_Posix_MessageFlags_MSG_DONTWAIT = 0x00000040,
+ #define Mono_Posix_MessageFlags_MSG_DONTWAIT Mono_Posix_MessageFlags_MSG_DONTWAIT
+ Mono_Posix_MessageFlags_MSG_EOR = 0x00000080,
+ #define Mono_Posix_MessageFlags_MSG_EOR Mono_Posix_MessageFlags_MSG_EOR
+ Mono_Posix_MessageFlags_MSG_ERRQUEUE = 0x00002000,
+ #define Mono_Posix_MessageFlags_MSG_ERRQUEUE Mono_Posix_MessageFlags_MSG_ERRQUEUE
+ Mono_Posix_MessageFlags_MSG_FASTOPEN = 0x20000000,
+ #define Mono_Posix_MessageFlags_MSG_FASTOPEN Mono_Posix_MessageFlags_MSG_FASTOPEN
+ Mono_Posix_MessageFlags_MSG_FIN = 0x00000200,
+ #define Mono_Posix_MessageFlags_MSG_FIN Mono_Posix_MessageFlags_MSG_FIN
+ Mono_Posix_MessageFlags_MSG_MORE = 0x00008000,
+ #define Mono_Posix_MessageFlags_MSG_MORE Mono_Posix_MessageFlags_MSG_MORE
+ Mono_Posix_MessageFlags_MSG_NOSIGNAL = 0x00004000,
+ #define Mono_Posix_MessageFlags_MSG_NOSIGNAL Mono_Posix_MessageFlags_MSG_NOSIGNAL
+ Mono_Posix_MessageFlags_MSG_OOB = 0x00000001,
+ #define Mono_Posix_MessageFlags_MSG_OOB Mono_Posix_MessageFlags_MSG_OOB
+ Mono_Posix_MessageFlags_MSG_PEEK = 0x00000002,
+ #define Mono_Posix_MessageFlags_MSG_PEEK Mono_Posix_MessageFlags_MSG_PEEK
+ Mono_Posix_MessageFlags_MSG_PROXY = 0x00000010,
+ #define Mono_Posix_MessageFlags_MSG_PROXY Mono_Posix_MessageFlags_MSG_PROXY
+ Mono_Posix_MessageFlags_MSG_RST = 0x00001000,
+ #define Mono_Posix_MessageFlags_MSG_RST Mono_Posix_MessageFlags_MSG_RST
+ Mono_Posix_MessageFlags_MSG_SYN = 0x00000400,
+ #define Mono_Posix_MessageFlags_MSG_SYN Mono_Posix_MessageFlags_MSG_SYN
+ Mono_Posix_MessageFlags_MSG_TRUNC = 0x00000020,
+ #define Mono_Posix_MessageFlags_MSG_TRUNC Mono_Posix_MessageFlags_MSG_TRUNC
+ Mono_Posix_MessageFlags_MSG_WAITALL = 0x00000100,
+ #define Mono_Posix_MessageFlags_MSG_WAITALL Mono_Posix_MessageFlags_MSG_WAITALL
+ Mono_Posix_MessageFlags_MSG_WAITFORONE = 0x00010000,
+ #define Mono_Posix_MessageFlags_MSG_WAITFORONE Mono_Posix_MessageFlags_MSG_WAITFORONE
+};
+int Mono_Posix_FromMessageFlags (int x, int *r);
+int Mono_Posix_ToMessageFlags (int x, int *r);
+
enum Mono_Posix_MlockallFlags {
Mono_Posix_MlockallFlags_MCL_CURRENT = 0x00000001,
#define Mono_Posix_MlockallFlags_MCL_CURRENT Mono_Posix_MlockallFlags_MCL_CURRENT
int Mono_Posix_FromSeekFlags (short x, short *r);
int Mono_Posix_ToSeekFlags (short x, short *r);
+enum Mono_Posix_ShutdownOption {
+ Mono_Posix_ShutdownOption_SHUT_RD = 0x00000001,
+ #define Mono_Posix_ShutdownOption_SHUT_RD Mono_Posix_ShutdownOption_SHUT_RD
+ Mono_Posix_ShutdownOption_SHUT_RDWR = 0x00000003,
+ #define Mono_Posix_ShutdownOption_SHUT_RDWR Mono_Posix_ShutdownOption_SHUT_RDWR
+ Mono_Posix_ShutdownOption_SHUT_WR = 0x00000002,
+ #define Mono_Posix_ShutdownOption_SHUT_WR Mono_Posix_ShutdownOption_SHUT_WR
+};
+int Mono_Posix_FromShutdownOption (int x, int *r);
+int Mono_Posix_ToShutdownOption (int x, int *r);
+
enum Mono_Posix_Signum {
Mono_Posix_Signum_SIGABRT = 0x00000006,
#define Mono_Posix_Signum_SIGABRT Mono_Posix_Signum_SIGABRT
int Mono_Posix_FromSyslogOptions (int x, int *r);
int Mono_Posix_ToSyslogOptions (int x, int *r);
+enum Mono_Posix_UnixAddressFamily {
+ Mono_Posix_UnixAddressFamily_AF_ALG = 0x00000026,
+ #define Mono_Posix_UnixAddressFamily_AF_ALG Mono_Posix_UnixAddressFamily_AF_ALG
+ Mono_Posix_UnixAddressFamily_AF_APPLETALK = 0x00000005,
+ #define Mono_Posix_UnixAddressFamily_AF_APPLETALK Mono_Posix_UnixAddressFamily_AF_APPLETALK
+ Mono_Posix_UnixAddressFamily_AF_ASH = 0x00000012,
+ #define Mono_Posix_UnixAddressFamily_AF_ASH Mono_Posix_UnixAddressFamily_AF_ASH
+ Mono_Posix_UnixAddressFamily_AF_ATMPVC = 0x00000008,
+ #define Mono_Posix_UnixAddressFamily_AF_ATMPVC Mono_Posix_UnixAddressFamily_AF_ATMPVC
+ Mono_Posix_UnixAddressFamily_AF_ATMSVC = 0x00000014,
+ #define Mono_Posix_UnixAddressFamily_AF_ATMSVC Mono_Posix_UnixAddressFamily_AF_ATMSVC
+ Mono_Posix_UnixAddressFamily_AF_AX25 = 0x00000003,
+ #define Mono_Posix_UnixAddressFamily_AF_AX25 Mono_Posix_UnixAddressFamily_AF_AX25
+ Mono_Posix_UnixAddressFamily_AF_BLUETOOTH = 0x0000001f,
+ #define Mono_Posix_UnixAddressFamily_AF_BLUETOOTH Mono_Posix_UnixAddressFamily_AF_BLUETOOTH
+ Mono_Posix_UnixAddressFamily_AF_BRIDGE = 0x00000007,
+ #define Mono_Posix_UnixAddressFamily_AF_BRIDGE Mono_Posix_UnixAddressFamily_AF_BRIDGE
+ Mono_Posix_UnixAddressFamily_AF_CAIF = 0x00000025,
+ #define Mono_Posix_UnixAddressFamily_AF_CAIF Mono_Posix_UnixAddressFamily_AF_CAIF
+ Mono_Posix_UnixAddressFamily_AF_CAN = 0x0000001d,
+ #define Mono_Posix_UnixAddressFamily_AF_CAN Mono_Posix_UnixAddressFamily_AF_CAN
+ Mono_Posix_UnixAddressFamily_AF_DECnet = 0x0000000c,
+ #define Mono_Posix_UnixAddressFamily_AF_DECnet Mono_Posix_UnixAddressFamily_AF_DECnet
+ Mono_Posix_UnixAddressFamily_AF_ECONET = 0x00000013,
+ #define Mono_Posix_UnixAddressFamily_AF_ECONET Mono_Posix_UnixAddressFamily_AF_ECONET
+ Mono_Posix_UnixAddressFamily_AF_IEEE802154 = 0x00000024,
+ #define Mono_Posix_UnixAddressFamily_AF_IEEE802154 Mono_Posix_UnixAddressFamily_AF_IEEE802154
+ Mono_Posix_UnixAddressFamily_AF_INET = 0x00000002,
+ #define Mono_Posix_UnixAddressFamily_AF_INET Mono_Posix_UnixAddressFamily_AF_INET
+ Mono_Posix_UnixAddressFamily_AF_INET6 = 0x0000000a,
+ #define Mono_Posix_UnixAddressFamily_AF_INET6 Mono_Posix_UnixAddressFamily_AF_INET6
+ Mono_Posix_UnixAddressFamily_AF_IPX = 0x00000004,
+ #define Mono_Posix_UnixAddressFamily_AF_IPX Mono_Posix_UnixAddressFamily_AF_IPX
+ Mono_Posix_UnixAddressFamily_AF_IRDA = 0x00000017,
+ #define Mono_Posix_UnixAddressFamily_AF_IRDA Mono_Posix_UnixAddressFamily_AF_IRDA
+ Mono_Posix_UnixAddressFamily_AF_ISDN = 0x00000022,
+ #define Mono_Posix_UnixAddressFamily_AF_ISDN Mono_Posix_UnixAddressFamily_AF_ISDN
+ Mono_Posix_UnixAddressFamily_AF_IUCV = 0x00000020,
+ #define Mono_Posix_UnixAddressFamily_AF_IUCV Mono_Posix_UnixAddressFamily_AF_IUCV
+ Mono_Posix_UnixAddressFamily_AF_KEY = 0x0000000f,
+ #define Mono_Posix_UnixAddressFamily_AF_KEY Mono_Posix_UnixAddressFamily_AF_KEY
+ Mono_Posix_UnixAddressFamily_AF_LLC = 0x0000001a,
+ #define Mono_Posix_UnixAddressFamily_AF_LLC Mono_Posix_UnixAddressFamily_AF_LLC
+ Mono_Posix_UnixAddressFamily_AF_NETBEUI = 0x0000000d,
+ #define Mono_Posix_UnixAddressFamily_AF_NETBEUI Mono_Posix_UnixAddressFamily_AF_NETBEUI
+ Mono_Posix_UnixAddressFamily_AF_NETLINK = 0x00000010,
+ #define Mono_Posix_UnixAddressFamily_AF_NETLINK Mono_Posix_UnixAddressFamily_AF_NETLINK
+ Mono_Posix_UnixAddressFamily_AF_NETROM = 0x00000006,
+ #define Mono_Posix_UnixAddressFamily_AF_NETROM Mono_Posix_UnixAddressFamily_AF_NETROM
+ Mono_Posix_UnixAddressFamily_AF_NFC = 0x00000027,
+ #define Mono_Posix_UnixAddressFamily_AF_NFC Mono_Posix_UnixAddressFamily_AF_NFC
+ Mono_Posix_UnixAddressFamily_AF_PACKET = 0x00000011,
+ #define Mono_Posix_UnixAddressFamily_AF_PACKET Mono_Posix_UnixAddressFamily_AF_PACKET
+ Mono_Posix_UnixAddressFamily_AF_PHONET = 0x00000023,
+ #define Mono_Posix_UnixAddressFamily_AF_PHONET Mono_Posix_UnixAddressFamily_AF_PHONET
+ Mono_Posix_UnixAddressFamily_AF_PPPOX = 0x00000018,
+ #define Mono_Posix_UnixAddressFamily_AF_PPPOX Mono_Posix_UnixAddressFamily_AF_PPPOX
+ Mono_Posix_UnixAddressFamily_AF_RDS = 0x00000015,
+ #define Mono_Posix_UnixAddressFamily_AF_RDS Mono_Posix_UnixAddressFamily_AF_RDS
+ Mono_Posix_UnixAddressFamily_AF_ROSE = 0x0000000b,
+ #define Mono_Posix_UnixAddressFamily_AF_ROSE Mono_Posix_UnixAddressFamily_AF_ROSE
+ Mono_Posix_UnixAddressFamily_AF_RXRPC = 0x00000021,
+ #define Mono_Posix_UnixAddressFamily_AF_RXRPC Mono_Posix_UnixAddressFamily_AF_RXRPC
+ Mono_Posix_UnixAddressFamily_AF_SECURITY = 0x0000000e,
+ #define Mono_Posix_UnixAddressFamily_AF_SECURITY Mono_Posix_UnixAddressFamily_AF_SECURITY
+ Mono_Posix_UnixAddressFamily_AF_SNA = 0x00000016,
+ #define Mono_Posix_UnixAddressFamily_AF_SNA Mono_Posix_UnixAddressFamily_AF_SNA
+ Mono_Posix_UnixAddressFamily_AF_TIPC = 0x0000001e,
+ #define Mono_Posix_UnixAddressFamily_AF_TIPC Mono_Posix_UnixAddressFamily_AF_TIPC
+ Mono_Posix_UnixAddressFamily_AF_UNIX = 0x00000001,
+ #define Mono_Posix_UnixAddressFamily_AF_UNIX Mono_Posix_UnixAddressFamily_AF_UNIX
+ Mono_Posix_UnixAddressFamily_AF_UNSPEC = 0x00000000,
+ #define Mono_Posix_UnixAddressFamily_AF_UNSPEC Mono_Posix_UnixAddressFamily_AF_UNSPEC
+ Mono_Posix_UnixAddressFamily_AF_VSOCK = 0x00000028,
+ #define Mono_Posix_UnixAddressFamily_AF_VSOCK Mono_Posix_UnixAddressFamily_AF_VSOCK
+ Mono_Posix_UnixAddressFamily_AF_WANPIPE = 0x00000019,
+ #define Mono_Posix_UnixAddressFamily_AF_WANPIPE Mono_Posix_UnixAddressFamily_AF_WANPIPE
+ Mono_Posix_UnixAddressFamily_AF_X25 = 0x00000009,
+ #define Mono_Posix_UnixAddressFamily_AF_X25 Mono_Posix_UnixAddressFamily_AF_X25
+};
+int Mono_Posix_FromUnixAddressFamily (int x, int *r);
+int Mono_Posix_ToUnixAddressFamily (int x, int *r);
+
+enum Mono_Posix_UnixSocketFlags {
+ Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC = 0x00080000,
+ #define Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC Mono_Posix_UnixSocketFlags_SOCK_CLOEXEC
+ Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK = 0x00000800,
+ #define Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK Mono_Posix_UnixSocketFlags_SOCK_NONBLOCK
+};
+int Mono_Posix_FromUnixSocketFlags (int x, int *r);
+int Mono_Posix_ToUnixSocketFlags (int x, int *r);
+
+enum Mono_Posix_UnixSocketOptionName {
+ Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN = 0x0000001e,
+ #define Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN Mono_Posix_UnixSocketOptionName_SO_ACCEPTCONN
+ Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER = 0x0000001a,
+ #define Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER Mono_Posix_UnixSocketOptionName_SO_ATTACH_FILTER
+ Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE = 0x00000019,
+ #define Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE Mono_Posix_UnixSocketOptionName_SO_BINDTODEVICE
+ Mono_Posix_UnixSocketOptionName_SO_BROADCAST = 0x00000006,
+ #define Mono_Posix_UnixSocketOptionName_SO_BROADCAST Mono_Posix_UnixSocketOptionName_SO_BROADCAST
+ Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT = 0x0000000e,
+ #define Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT Mono_Posix_UnixSocketOptionName_SO_BSDCOMPAT
+ Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL = 0x0000002e,
+ #define Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL Mono_Posix_UnixSocketOptionName_SO_BUSY_POLL
+ Mono_Posix_UnixSocketOptionName_SO_DEBUG = 0x00000001,
+ #define Mono_Posix_UnixSocketOptionName_SO_DEBUG Mono_Posix_UnixSocketOptionName_SO_DEBUG
+ Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER = 0x0000001b,
+ #define Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER Mono_Posix_UnixSocketOptionName_SO_DETACH_FILTER
+ Mono_Posix_UnixSocketOptionName_SO_DOMAIN = 0x00000027,
+ #define Mono_Posix_UnixSocketOptionName_SO_DOMAIN Mono_Posix_UnixSocketOptionName_SO_DOMAIN
+ Mono_Posix_UnixSocketOptionName_SO_DONTROUTE = 0x00000005,
+ #define Mono_Posix_UnixSocketOptionName_SO_DONTROUTE Mono_Posix_UnixSocketOptionName_SO_DONTROUTE
+ Mono_Posix_UnixSocketOptionName_SO_ERROR = 0x00000004,
+ #define Mono_Posix_UnixSocketOptionName_SO_ERROR Mono_Posix_UnixSocketOptionName_SO_ERROR
+ Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE = 0x00000009,
+ #define Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE Mono_Posix_UnixSocketOptionName_SO_KEEPALIVE
+ Mono_Posix_UnixSocketOptionName_SO_LINGER = 0x0000000d,
+ #define Mono_Posix_UnixSocketOptionName_SO_LINGER Mono_Posix_UnixSocketOptionName_SO_LINGER
+ Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER = 0x0000002c,
+ #define Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER Mono_Posix_UnixSocketOptionName_SO_LOCK_FILTER
+ Mono_Posix_UnixSocketOptionName_SO_MARK = 0x00000024,
+ #define Mono_Posix_UnixSocketOptionName_SO_MARK Mono_Posix_UnixSocketOptionName_SO_MARK
+ Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE = 0x0000002f,
+ #define Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE Mono_Posix_UnixSocketOptionName_SO_MAX_PACING_RATE
+ Mono_Posix_UnixSocketOptionName_SO_NOFCS = 0x0000002b,
+ #define Mono_Posix_UnixSocketOptionName_SO_NOFCS Mono_Posix_UnixSocketOptionName_SO_NOFCS
+ Mono_Posix_UnixSocketOptionName_SO_NO_CHECK = 0x0000000b,
+ #define Mono_Posix_UnixSocketOptionName_SO_NO_CHECK Mono_Posix_UnixSocketOptionName_SO_NO_CHECK
+ Mono_Posix_UnixSocketOptionName_SO_OOBINLINE = 0x0000000a,
+ #define Mono_Posix_UnixSocketOptionName_SO_OOBINLINE Mono_Posix_UnixSocketOptionName_SO_OOBINLINE
+ Mono_Posix_UnixSocketOptionName_SO_PASSCRED = 0x00000010,
+ #define Mono_Posix_UnixSocketOptionName_SO_PASSCRED Mono_Posix_UnixSocketOptionName_SO_PASSCRED
+ Mono_Posix_UnixSocketOptionName_SO_PASSSEC = 0x00000022,
+ #define Mono_Posix_UnixSocketOptionName_SO_PASSSEC Mono_Posix_UnixSocketOptionName_SO_PASSSEC
+ Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF = 0x0000002a,
+ #define Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF Mono_Posix_UnixSocketOptionName_SO_PEEK_OFF
+ Mono_Posix_UnixSocketOptionName_SO_PEERCRED = 0x00000011,
+ #define Mono_Posix_UnixSocketOptionName_SO_PEERCRED Mono_Posix_UnixSocketOptionName_SO_PEERCRED
+ Mono_Posix_UnixSocketOptionName_SO_PEERNAME = 0x0000001c,
+ #define Mono_Posix_UnixSocketOptionName_SO_PEERNAME Mono_Posix_UnixSocketOptionName_SO_PEERNAME
+ Mono_Posix_UnixSocketOptionName_SO_PEERSEC = 0x0000001f,
+ #define Mono_Posix_UnixSocketOptionName_SO_PEERSEC Mono_Posix_UnixSocketOptionName_SO_PEERSEC
+ Mono_Posix_UnixSocketOptionName_SO_PRIORITY = 0x0000000c,
+ #define Mono_Posix_UnixSocketOptionName_SO_PRIORITY Mono_Posix_UnixSocketOptionName_SO_PRIORITY
+ Mono_Posix_UnixSocketOptionName_SO_PROTOCOL = 0x00000026,
+ #define Mono_Posix_UnixSocketOptionName_SO_PROTOCOL Mono_Posix_UnixSocketOptionName_SO_PROTOCOL
+ Mono_Posix_UnixSocketOptionName_SO_RCVBUF = 0x00000008,
+ #define Mono_Posix_UnixSocketOptionName_SO_RCVBUF Mono_Posix_UnixSocketOptionName_SO_RCVBUF
+ Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE = 0x00000021,
+ #define Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE Mono_Posix_UnixSocketOptionName_SO_RCVBUFFORCE
+ Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT = 0x00000012,
+ #define Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT Mono_Posix_UnixSocketOptionName_SO_RCVLOWAT
+ Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO = 0x00000014,
+ #define Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO Mono_Posix_UnixSocketOptionName_SO_RCVTIMEO
+ Mono_Posix_UnixSocketOptionName_SO_REUSEADDR = 0x00000002,
+ #define Mono_Posix_UnixSocketOptionName_SO_REUSEADDR Mono_Posix_UnixSocketOptionName_SO_REUSEADDR
+ Mono_Posix_UnixSocketOptionName_SO_REUSEPORT = 0x0000000f,
+ #define Mono_Posix_UnixSocketOptionName_SO_REUSEPORT Mono_Posix_UnixSocketOptionName_SO_REUSEPORT
+ Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL = 0x00000028,
+ #define Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL Mono_Posix_UnixSocketOptionName_SO_RXQ_OVFL
+ Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION = 0x00000016,
+ #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION Mono_Posix_UnixSocketOptionName_SO_SECURITY_AUTHENTICATION
+ Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK = 0x00000018,
+ #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_NETWORK
+ Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT = 0x00000017,
+ #define Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT Mono_Posix_UnixSocketOptionName_SO_SECURITY_ENCRYPTION_TRANSPORT
+ Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE = 0x0000002d,
+ #define Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE Mono_Posix_UnixSocketOptionName_SO_SELECT_ERR_QUEUE
+ Mono_Posix_UnixSocketOptionName_SO_SNDBUF = 0x00000007,
+ #define Mono_Posix_UnixSocketOptionName_SO_SNDBUF Mono_Posix_UnixSocketOptionName_SO_SNDBUF
+ Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE = 0x00000020,
+ #define Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE Mono_Posix_UnixSocketOptionName_SO_SNDBUFFORCE
+ Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT = 0x00000013,
+ #define Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT Mono_Posix_UnixSocketOptionName_SO_SNDLOWAT
+ Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO = 0x00000015,
+ #define Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO Mono_Posix_UnixSocketOptionName_SO_SNDTIMEO
+ Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP = 0x0000001d,
+ #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP Mono_Posix_UnixSocketOptionName_SO_TIMESTAMP
+ Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING = 0x00000025,
+ #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPING
+ Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS = 0x00000023,
+ #define Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS Mono_Posix_UnixSocketOptionName_SO_TIMESTAMPNS
+ Mono_Posix_UnixSocketOptionName_SO_TYPE = 0x00000003,
+ #define Mono_Posix_UnixSocketOptionName_SO_TYPE Mono_Posix_UnixSocketOptionName_SO_TYPE
+ Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS = 0x00000029,
+ #define Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS Mono_Posix_UnixSocketOptionName_SO_WIFI_STATUS
+};
+int Mono_Posix_FromUnixSocketOptionName (int x, int *r);
+int Mono_Posix_ToUnixSocketOptionName (int x, int *r);
+
+enum Mono_Posix_UnixSocketProtocol {
+ Mono_Posix_UnixSocketProtocol_IPPROTO_AH = 0x00000033,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_AH Mono_Posix_UnixSocketProtocol_IPPROTO_AH
+ Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH = 0x0000005e,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH Mono_Posix_UnixSocketProtocol_IPPROTO_BEETPH
+ Mono_Posix_UnixSocketProtocol_IPPROTO_COMP = 0x0000006c,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_COMP Mono_Posix_UnixSocketProtocol_IPPROTO_COMP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP = 0x00000021,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP Mono_Posix_UnixSocketProtocol_IPPROTO_DCCP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_EGP = 0x00000008,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_EGP Mono_Posix_UnixSocketProtocol_IPPROTO_EGP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP = 0x00000062,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP Mono_Posix_UnixSocketProtocol_IPPROTO_ENCAP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_ESP = 0x00000032,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_ESP Mono_Posix_UnixSocketProtocol_IPPROTO_ESP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_GRE = 0x0000002f,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_GRE Mono_Posix_UnixSocketProtocol_IPPROTO_GRE
+ Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP = 0x00000001,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP Mono_Posix_UnixSocketProtocol_IPPROTO_ICMP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_IDP = 0x00000016,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_IDP Mono_Posix_UnixSocketProtocol_IPPROTO_IDP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP = 0x00000002,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP Mono_Posix_UnixSocketProtocol_IPPROTO_IGMP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_IP = 0x00000400,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_IP Mono_Posix_UnixSocketProtocol_IPPROTO_IP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP = 0x00000004,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP Mono_Posix_UnixSocketProtocol_IPPROTO_IPIP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6 = 0x00000029,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6 Mono_Posix_UnixSocketProtocol_IPPROTO_IPV6
+ Mono_Posix_UnixSocketProtocol_IPPROTO_MTP = 0x0000005c,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_MTP Mono_Posix_UnixSocketProtocol_IPPROTO_MTP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_PIM = 0x00000067,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_PIM Mono_Posix_UnixSocketProtocol_IPPROTO_PIM
+ Mono_Posix_UnixSocketProtocol_IPPROTO_PUP = 0x0000000c,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_PUP Mono_Posix_UnixSocketProtocol_IPPROTO_PUP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_RAW = 0x000000ff,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_RAW Mono_Posix_UnixSocketProtocol_IPPROTO_RAW
+ Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP = 0x0000002e,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP Mono_Posix_UnixSocketProtocol_IPPROTO_RSVP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP = 0x00000084,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP Mono_Posix_UnixSocketProtocol_IPPROTO_SCTP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_TCP = 0x00000006,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_TCP Mono_Posix_UnixSocketProtocol_IPPROTO_TCP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_TP = 0x0000001d,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_TP Mono_Posix_UnixSocketProtocol_IPPROTO_TP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_UDP = 0x00000011,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_UDP Mono_Posix_UnixSocketProtocol_IPPROTO_UDP
+ Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE = 0x00000088,
+ #define Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE Mono_Posix_UnixSocketProtocol_IPPROTO_UDPLITE
+ Mono_Posix_UnixSocketProtocol_SOL_SOCKET = 0x00000800,
+ #define Mono_Posix_UnixSocketProtocol_SOL_SOCKET Mono_Posix_UnixSocketProtocol_SOL_SOCKET
+};
+int Mono_Posix_FromUnixSocketProtocol (int x, int *r);
+int Mono_Posix_ToUnixSocketProtocol (int x, int *r);
+
+enum Mono_Posix_UnixSocketType {
+ Mono_Posix_UnixSocketType_SOCK_DCCP = 0x00000006,
+ #define Mono_Posix_UnixSocketType_SOCK_DCCP Mono_Posix_UnixSocketType_SOCK_DCCP
+ Mono_Posix_UnixSocketType_SOCK_DGRAM = 0x00000002,
+ #define Mono_Posix_UnixSocketType_SOCK_DGRAM Mono_Posix_UnixSocketType_SOCK_DGRAM
+ Mono_Posix_UnixSocketType_SOCK_PACKET = 0x0000000a,
+ #define Mono_Posix_UnixSocketType_SOCK_PACKET Mono_Posix_UnixSocketType_SOCK_PACKET
+ Mono_Posix_UnixSocketType_SOCK_RAW = 0x00000003,
+ #define Mono_Posix_UnixSocketType_SOCK_RAW Mono_Posix_UnixSocketType_SOCK_RAW
+ Mono_Posix_UnixSocketType_SOCK_RDM = 0x00000004,
+ #define Mono_Posix_UnixSocketType_SOCK_RDM Mono_Posix_UnixSocketType_SOCK_RDM
+ Mono_Posix_UnixSocketType_SOCK_SEQPACKET = 0x00000005,
+ #define Mono_Posix_UnixSocketType_SOCK_SEQPACKET Mono_Posix_UnixSocketType_SOCK_SEQPACKET
+ Mono_Posix_UnixSocketType_SOCK_STREAM = 0x00000001,
+ #define Mono_Posix_UnixSocketType_SOCK_STREAM Mono_Posix_UnixSocketType_SOCK_STREAM
+};
+int Mono_Posix_FromUnixSocketType (int x, int *r);
+int Mono_Posix_ToUnixSocketType (int x, int *r);
+
enum Mono_Posix_WaitOptions {
Mono_Posix_WaitOptions_WNOHANG = 0x00000001,
#define Mono_Posix_WaitOptions_WNOHANG Mono_Posix_WaitOptions_WNOHANG
struct Mono_Posix_Flock;
struct Mono_Posix_Iovec;
+struct Mono_Posix_Linger;
struct Mono_Posix_Pollfd;
struct Mono_Posix_Stat;
struct Mono_Posix_Statvfs;
struct flock;
struct iovec;
+struct linger;
struct pollfd;
struct timespec;
struct timeval;
Mono_Posix_ToIovec (struct iovec *from, struct Mono_Posix_Iovec* to);
+struct Mono_Posix_Linger {
+ int l_onoff;
+ int l_linger;
+};
+
+int
+Mono_Posix_FromLinger (struct Mono_Posix_Linger* from, struct linger *to);
+int
+Mono_Posix_ToLinger (struct linger *from, struct Mono_Posix_Linger* to);
+
+
struct Mono_Posix_Pollfd {
int fd;
short events;
int Mono_Posix_Syscall_endusershell (void);
int Mono_Posix_Syscall_fcntl (int fd, int cmd);
int Mono_Posix_Syscall_fcntl_arg (int fd, int cmd, gint64 arg);
+int Mono_Posix_Syscall_fcntl_arg_int (int fd, int cmd, int arg);
+int Mono_Posix_Syscall_fcntl_arg_ptr (int fd, int cmd, void* ptr);
int Mono_Posix_Syscall_fcntl_lock (int fd, int cmd, struct Mono_Posix_Flock* lock);
int Mono_Posix_Syscall_fgetgrent (void* stream, struct Mono_Posix_Syscall__Group* grbuf);
int Mono_Posix_Syscall_fgetpwent (void* stream, struct Mono_Posix_Syscall__Passwd* pwbuf);
int Mono_Posix_Syscall_getpwnam_r (const char* name, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp);
int Mono_Posix_Syscall_getpwuid (unsigned int uid, struct Mono_Posix_Syscall__Passwd* passwd);
int Mono_Posix_Syscall_getpwuid_r (unsigned int uid, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp);
+int Mono_Posix_Syscall_getsockopt (int socket, int level, int option_name, void* option_value, gint64* option_len);
+int Mono_Posix_Syscall_getsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value);
+int Mono_Posix_Syscall_getsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value);
int Mono_Posix_Syscall_gettimeofday (struct Mono_Posix_Timeval* tv, void* ignore);
gint64 Mono_Posix_Syscall_getxattr (const char* path, const char* name, unsigned char* value, guint64 size);
int Mono_Posix_Syscall_L_ctermid (void);
gint64 Mono_Posix_Syscall_readlink (const char* path, unsigned char* buf, guint64 bufsiz);
gint64 Mono_Posix_Syscall_readlinkat (int dirfd, const char* pathname, unsigned char* buf, guint64 bufsiz);
gint64 Mono_Posix_Syscall_readv (int fd, struct Mono_Posix_Iovec* iov, int iovcnt);
+gint64 Mono_Posix_Syscall_recv (int socket, void* buffer, guint64 length, int flags);
int Mono_Posix_Syscall_remap_file_pages (void* start, guint64 size, int prot, gint64 pgoff, int flags);
int Mono_Posix_Syscall_removexattr (const char* path, const char* name);
int Mono_Posix_Syscall_rewinddir (void* dir);
int Mono_Posix_Syscall_seekdir (void* dir, gint64 offset);
+gint64 Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags);
gint64 Mono_Posix_Syscall_sendfile (int out_fd, int in_fd, gint64* offset, guint64 count);
int Mono_Posix_Syscall_setdomainname (const char* name, guint64 len);
int Mono_Posix_Syscall_setfsent (void);
int Mono_Posix_Syscall_sethostid (gint64 hostid);
int Mono_Posix_Syscall_sethostname (const char* name, guint64 len);
int Mono_Posix_Syscall_setpwent (void);
+int Mono_Posix_Syscall_setsockopt (int socket, int level, int option_name, void* option_value, gint64 option_len);
+int Mono_Posix_Syscall_setsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value);
+int Mono_Posix_Syscall_setsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value);
int Mono_Posix_Syscall_settimeofday (struct Mono_Posix_Timeval* tv, struct Mono_Posix_Timezone* tz);
int Mono_Posix_Syscall_setusershell (void);
int Mono_Posix_Syscall_setxattr (const char* path, const char* name, unsigned char* value, guint64 size, int flags);
+int Mono_Posix_Syscall_socketpair (int domain, int type, int protocol, int* socket1, int* socket2);
int Mono_Posix_Syscall_stat (const char* file_name, struct Mono_Posix_Stat* buf);
int Mono_Posix_Syscall_statvfs (const char* path, struct Mono_Posix_Statvfs* buf);
int Mono_Posix_Syscall_stime (gint64* t);
return ret; \
}}G_STMT_END
+#define mph_have_uint_overflow(var) ((var) < 0 || (var) > UINT_MAX)
+
+#define mph_return_val_if_uint_overflow(var, ret) \
+ _mph_return_val_if_cb_(var, ret, mph_have_uint_overflow)
+
+#define mph_return_if_uint_overflow(var) mph_return_val_if_uint_overflow(var, -1)
+
#define mph_have_long_overflow(var) ((var) > LONG_MAX || (var) < LONG_MIN)
#define mph_return_val_if_long_overflow(var, ret) \
#define mph_return_if_long_overflow(var) mph_return_val_if_long_overflow(var, -1)
-#define mph_have_ulong_overflow(var) ((var) > ULONG_MAX)
+#define mph_have_ulong_overflow(var) (var) < 0 || ((var) > ULONG_MAX)
#define mph_return_val_if_ulong_overflow(var, ret) \
_mph_return_val_if_cb_(var, ret, mph_have_ulong_overflow)
#define mph_return_if_ulong_overflow(var) mph_return_val_if_ulong_overflow(var, -1)
-#define mph_have_size_t_overflow(var) ((var) > MPH_SIZE_T_MAX)
+#define mph_have_size_t_overflow(var) ((var) < 0 || (var) > MPH_SIZE_T_MAX)
#define mph_return_val_if_size_t_overflow(var, ret) \
_mph_return_val_if_cb_(var, ret, mph_have_size_t_overflow)
#define mph_return_if_time_t_overflow(var) mph_return_if_long_overflow(var)
+#define mph_return_if_socklen_t_overflow(var) mph_return_if_uint_overflow(var)
+
#define mph_return_if_val_in_list5(var,a,b,c,d,e) \
do { \
int v = (var); \
--- /dev/null
+/*
+ * <sys/socket.h> wrapper functions.
+ *
+ * Authors:
+ * Steffen Kiess (s-kiess@web.de)
+ *
+ * Copyright (C) 2015 Steffen Kiess
+ */
+
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#include <stddef.h>
+
+#include "map.h"
+#include "mph.h"
+
+G_BEGIN_DECLS
+
+int
+Mono_Posix_Syscall_socketpair (int domain, int type, int protocol, int* socket1, int* socket2)
+{
+ int filedes[2] = {-1, -1};
+ int r;
+
+ r = socketpair (domain, type, protocol, filedes);
+
+ *socket1 = filedes[0];
+ *socket2 = filedes[1];
+ return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt (int socket, int level, int option_name, void* option_value, gint64* option_len)
+{
+ socklen_t len;
+ int r;
+
+ mph_return_if_socklen_t_overflow (*option_len);
+
+ len = *option_len;
+
+ r = getsockopt (socket, level, option_name, option_value, &len);
+
+ *option_len = len;
+
+ return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value)
+{
+ struct timeval tv;
+ int r;
+ socklen_t size;
+
+ size = sizeof (struct timeval);
+ r = getsockopt (socket, level, option_name, &tv, &size);
+
+ if (r != -1 && size == sizeof (struct timeval)) {
+ if (Mono_Posix_ToTimeval (&tv, option_value) != 0)
+ return -1;
+ } else {
+ memset (option_value, 0, sizeof (struct Mono_Posix_Timeval));
+ if (r != -1)
+ errno = EINVAL;
+ }
+
+ return r;
+}
+
+int
+Mono_Posix_Syscall_getsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value)
+{
+ struct linger ling;
+ int r;
+ socklen_t size;
+
+ size = sizeof (struct linger);
+ r = getsockopt (socket, level, option_name, &ling, &size);
+
+ if (r != -1 && size == sizeof (struct linger)) {
+ if (Mono_Posix_ToLinger (&ling, option_value) != 0)
+ return -1;
+ } else {
+ memset (option_value, 0, sizeof (struct Mono_Posix_Linger));
+ if (r != -1)
+ errno = EINVAL;
+ }
+
+ return r;
+}
+
+int
+Mono_Posix_Syscall_setsockopt (int socket, int level, int option_name, void* option_value, gint64 option_len)
+{
+ mph_return_if_socklen_t_overflow (option_len);
+
+ return setsockopt (socket, level, option_name, option_value, option_len);
+}
+
+int
+Mono_Posix_Syscall_setsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value)
+{
+ struct timeval tv;
+
+ if (Mono_Posix_FromTimeval (option_value, &tv) != 0)
+ return -1;
+
+ return setsockopt (socket, level, option_name, &tv, sizeof (struct timeval));
+}
+
+int
+Mono_Posix_Syscall_setsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value)
+{
+ struct linger ling;
+
+ if (Mono_Posix_FromLinger (option_value, &ling) != 0)
+ return -1;
+
+ return setsockopt (socket, level, option_name, &ling, sizeof (struct linger));
+}
+
+gint64
+Mono_Posix_Syscall_recv (int socket, void* message, guint64 length, int flags)
+{
+ mph_return_if_size_t_overflow (length);
+
+ return recv (socket, message, length, flags);
+}
+
+gint64
+Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags)
+{
+ mph_return_if_size_t_overflow (length);
+
+ return send (socket, message, length, flags);
+}
#error Unknown architecture
#endif
+#define WINVER 0x0A00
+
+#include <SDKDDKVer.h>
+
#if _WIN32_WINNT < 0x0600
#error "Mono requires Windows Vista or later"
#endif /* _WIN32_WINNT < 0x0600 */